@woosh/meep-engine 3.28.0 → 3.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (482) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/binary/BitSet.d.ts +16 -0
  4. package/src/core/binary/BitSet.d.ts.map +1 -1
  5. package/src/core/binary/BitSet.js +159 -49
  6. package/src/core/binary/allocator/OffsetAllocator.d.ts +48 -0
  7. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  8. package/src/core/binary/allocator/OffsetAllocator.js +208 -9
  9. package/src/core/binary/compression/compress_bytes.d.ts +20 -0
  10. package/src/core/binary/compression/compress_bytes.d.ts.map +1 -0
  11. package/src/core/binary/compression/compress_bytes.js +35 -0
  12. package/src/core/binary/compression/decompress_bytes_into.d.ts +30 -0
  13. package/src/core/binary/compression/decompress_bytes_into.d.ts.map +1 -0
  14. package/src/core/binary/compression/decompress_bytes_into.js +87 -0
  15. package/src/core/binary/compression/deflate_decompress_bound.d.ts +27 -0
  16. package/src/core/binary/compression/deflate_decompress_bound.d.ts.map +1 -0
  17. package/src/core/binary/compression/deflate_decompress_bound.js +32 -0
  18. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts +24 -0
  19. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts.map +1 -0
  20. package/src/core/geom/3d/quadric/quadric_attribute_add.js +31 -0
  21. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts +46 -0
  22. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts.map +1 -0
  23. package/src/core/geom/3d/quadric/quadric_attribute_reduce.js +104 -0
  24. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts +62 -0
  25. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts.map +1 -0
  26. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.js +158 -0
  27. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts +21 -0
  28. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts.map +1 -0
  29. package/src/core/geom/3d/quadric/quadric_attribute_size.js +24 -0
  30. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts +34 -0
  31. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts.map +1 -0
  32. package/src/core/geom/3d/quadric/quadric_attribute_solve.js +55 -0
  33. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts +28 -0
  34. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts.map +1 -0
  35. package/src/core/geom/3d/quadric/quadric_attribute_sub.js +35 -0
  36. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts +15 -0
  37. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts.map +1 -1
  38. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +35 -0
  39. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts +93 -0
  40. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts.map +1 -0
  41. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.js +128 -0
  42. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts +38 -0
  43. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts.map +1 -0
  44. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.js +113 -0
  45. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts +47 -1
  46. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
  47. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +677 -8
  48. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts +22 -0
  49. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts.map +1 -0
  50. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.js +46 -0
  51. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts +19 -0
  52. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts.map +1 -0
  53. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.js +49 -0
  54. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts +63 -0
  55. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts.map +1 -0
  56. package/src/core/graph/layout/layered/BoxLayoutOptions.js +80 -0
  57. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.d.ts +35 -0
  58. package/src/core/graph/layout/layered/LayoutBoxGraph.d.ts.map +1 -0
  59. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.js +53 -1
  60. package/src/core/graph/layout/layered/layout_assign_coordinates.d.ts.map +1 -0
  61. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.js +72 -68
  62. package/src/core/graph/layout/layered/layout_assign_layers.d.ts.map +1 -0
  63. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.js +4 -2
  64. package/src/core/graph/layout/layered/layout_break_cycles.d.ts.map +1 -0
  65. package/src/core/graph/layout/layered/layout_insert_lanes.d.ts.map +1 -0
  66. package/src/core/graph/layout/layered/layout_order_layers.d.ts.map +1 -0
  67. package/src/core/graph/layout/layered/layout_orient_links.d.ts.map +1 -0
  68. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +7 -51
  69. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  70. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +8 -69
  71. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +1 -1
  72. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +6 -6
  73. package/src/core/model/node-graph/visual/layout/route_grid_build.js +1 -1
  74. package/src/engine/graphics3/DebugDrawSystem.d.ts +7 -5
  75. package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
  76. package/src/engine/graphics3/DebugDrawSystem.js +206 -203
  77. package/src/engine/graphics3/DecalSystem.d.ts +4 -5
  78. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
  79. package/src/engine/graphics3/DecalSystem.js +5 -5
  80. package/src/engine/graphics3/FogOfWarSystem.d.ts +7 -12
  81. package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -1
  82. package/src/engine/graphics3/FogOfWarSystem.js +8 -12
  83. package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -230
  84. package/src/shade/RENDERER_CONTRACT.md +12 -7
  85. package/src/shade/playground/caldera/README.md +529 -0
  86. package/src/shade/playground/caldera/caldera_format.d.ts +151 -0
  87. package/src/shade/playground/caldera/caldera_format.d.ts.map +1 -0
  88. package/src/shade/playground/caldera/caldera_format.js +241 -0
  89. package/src/shade/playground/caldera/index.html +126 -0
  90. package/src/shade/playground/caldera/main.d.ts.map +1 -0
  91. package/src/shade/playground/caldera/main.js +1565 -0
  92. package/src/shade/playground/mesh_row_ceiling/README.md +85 -0
  93. package/src/shade/playground/mesh_row_ceiling/index.html +31 -0
  94. package/src/shade/playground/mesh_row_ceiling/main.d.ts +2 -0
  95. package/src/shade/playground/mesh_row_ceiling/main.d.ts.map +1 -0
  96. package/src/shade/playground/mesh_row_ceiling/main.js +389 -0
  97. package/src/shade/playground/vgeo_runtime/README.md +5 -3
  98. package/src/shade/playground/vgeo_runtime/main.js +3 -2
  99. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts +3 -3
  100. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -1
  101. package/src/shade/playground/vgeo_runtime/sample_asset.js +3 -3
  102. package/src/shade/playground/vgeo_scene/README.md +103 -24
  103. package/src/shade/playground/vgeo_scene/main.js +525 -24
  104. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  105. package/src/shade/renderer/GraphicsContext.js +6 -0
  106. package/src/shade/renderer/Renderer.d.ts +2 -0
  107. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  108. package/src/shade/renderer/Renderer.js +23 -0
  109. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  110. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +100 -8
  111. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +69 -33
  112. package/src/shade/renderer/extension/RenderExtension.d.ts +15 -18
  113. package/src/shade/renderer/extension/RenderExtension.d.ts.map +1 -1
  114. package/src/shade/renderer/extension/RenderExtension.js +15 -19
  115. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts +5 -5
  116. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts.map +1 -1
  117. package/src/shade/renderer/extension/RenderExtensionRegistry.js +29 -166
  118. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  119. package/src/shade/renderer/geometry/GPUGeometryManager.js +73 -16
  120. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  121. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +18 -3
  122. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +663 -0
  123. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +100 -5
  124. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  125. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +688 -81
  126. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +540 -0
  127. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +155 -64
  128. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +30 -13
  129. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +3 -3
  130. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +358 -0
  131. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +57 -7
  132. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  133. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +63 -9
  134. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts +40 -0
  135. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts.map +1 -0
  136. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.js +24 -0
  137. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts +91 -0
  138. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts.map +1 -0
  139. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.js +91 -0
  140. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts +24 -0
  141. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts.map +1 -0
  142. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.js +25 -0
  143. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts +77 -0
  144. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts.map +1 -0
  145. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.js +84 -0
  146. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts +19 -6
  147. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -1
  148. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.js +20 -7
  149. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts +19 -0
  150. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts.map +1 -0
  151. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.js +58 -0
  152. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts +18 -0
  153. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts.map +1 -0
  154. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.js +116 -0
  155. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts +18 -0
  156. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -0
  157. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +545 -0
  158. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts +16 -0
  159. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -0
  160. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +110 -0
  161. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +2 -27
  162. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -1
  163. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.js +120 -1564
  164. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts +26 -0
  165. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts.map +1 -0
  166. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.js +123 -0
  167. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts +26 -0
  168. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts.map +1 -0
  169. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.js +78 -0
  170. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts +24 -0
  171. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -0
  172. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +337 -0
  173. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts +29 -0
  174. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -0
  175. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +147 -0
  176. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts +37 -0
  177. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts.map +1 -0
  178. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.js +243 -0
  179. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts +29 -0
  180. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -0
  181. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +117 -0
  182. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts +46 -0
  183. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts.map +1 -0
  184. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.js +45 -0
  185. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts +64 -0
  186. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts.map +1 -0
  187. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js +68 -0
  188. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts +12 -7
  189. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -1
  190. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.js +33 -11
  191. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts +58 -0
  192. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts.map +1 -0
  193. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.js +79 -0
  194. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts +39 -0
  195. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts.map +1 -0
  196. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.js +68 -0
  197. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts +53 -0
  198. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts.map +1 -0
  199. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.js +243 -0
  200. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +24 -8
  201. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -1
  202. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js +250 -25
  203. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts +12 -8
  204. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -1
  205. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.js +58 -50
  206. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +8 -1
  207. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -1
  208. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.js +18 -3
  209. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts +38 -0
  210. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts.map +1 -0
  211. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.js +81 -0
  212. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts +23 -5
  213. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -1
  214. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.js +28 -21
  215. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.js +1 -1
  216. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -1
  217. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +224 -60
  218. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +15 -0
  219. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -1
  220. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.js +17 -0
  221. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +17 -0
  222. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -1
  223. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.js +19 -0
  224. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +10 -1
  225. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -1
  226. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.js +103 -9
  227. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +14 -2
  228. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -1
  229. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.js +38 -14
  230. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts +6 -2
  231. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  232. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +28 -5
  233. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts +32 -0
  234. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts.map +1 -0
  235. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.js +93 -0
  236. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +20 -6
  237. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  238. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +22 -8
  239. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts +16 -0
  240. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts.map +1 -0
  241. package/src/shade/renderer/geometry/virtual/format/attribute/{vgeo_layers_copy_vertex.js → vgeo_layers_copy_corner.js} +8 -8
  242. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts +18 -7
  243. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts.map +1 -1
  244. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +19 -8
  245. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.d.ts +3 -3
  246. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +3 -3
  247. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts +27 -0
  248. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts.map +1 -0
  249. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.js +97 -0
  250. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts +7 -3
  251. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts.map +1 -1
  252. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +21 -11
  253. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts +21 -0
  254. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts.map +1 -0
  255. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.js +41 -0
  256. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +19 -1
  257. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
  258. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +20 -1
  259. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts +25 -0
  260. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts.map +1 -0
  261. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.js +24 -0
  262. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts +5 -0
  263. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts.map +1 -1
  264. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +5 -0
  265. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.d.ts.map +1 -1
  266. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +5 -0
  267. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts +10 -3
  268. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts.map +1 -1
  269. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +37 -3
  270. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +21 -13
  271. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
  272. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +37 -13
  273. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts +8 -2
  274. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts.map +1 -1
  275. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +14 -2
  276. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +18 -0
  277. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
  278. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +19 -1
  279. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +6 -0
  280. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts +21 -0
  281. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts.map +1 -0
  282. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.js +20 -0
  283. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts +9 -0
  284. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts.map +1 -1
  285. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +10 -1
  286. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +1 -2
  287. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +10 -3
  288. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts +20 -0
  289. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts.map +1 -0
  290. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.js +43 -0
  291. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +4 -2
  292. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
  293. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +8 -4
  294. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  295. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +2 -2
  296. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts +6 -4
  297. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts.map +1 -1
  298. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.js +6 -4
  299. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +13 -2
  300. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  301. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +13 -2
  302. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +5 -1
  303. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -1
  304. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +14 -1
  305. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -1
  306. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +1 -0
  307. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts +4 -1
  308. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts.map +1 -1
  309. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.js +53 -11
  310. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
  311. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +7 -3
  312. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts +12 -2
  313. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  314. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +111 -33
  315. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts +6 -2
  316. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  317. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +112 -42
  318. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts +2 -2
  319. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  320. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +51 -21
  321. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +385 -0
  322. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
  323. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +9 -0
  324. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  325. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +34 -0
  326. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -1
  327. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +18 -0
  328. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  329. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +47 -19
  330. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +1 -0
  331. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +22 -4
  332. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +7 -2
  333. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -1
  334. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +8 -3
  335. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
  336. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +10 -0
  337. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
  338. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +13 -11
  339. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -1
  340. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +13 -11
  341. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
  342. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +4 -0
  343. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  344. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +3 -4
  345. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts +6 -2
  346. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
  347. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +90 -12
  348. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts +22 -0
  349. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts.map +1 -0
  350. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.js +21 -0
  351. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  352. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +13 -8
  353. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  354. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +3 -6
  355. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  356. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +4 -12
  357. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
  358. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  359. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +4 -5
  360. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  361. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +5 -3
  362. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.d.ts.map +1 -1
  363. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.js +11 -4
  364. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  365. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +4 -3
  366. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
  367. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +3 -0
  368. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
  369. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +94 -90
  370. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  371. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +13 -5
  372. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
  373. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +96 -89
  374. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
  375. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +3 -1
  376. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts.map +1 -1
  377. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.js +4 -1
  378. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
  379. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +100 -89
  380. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.d.ts.map +1 -1
  381. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.js +31 -7
  382. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
  383. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +1 -7
  384. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
  385. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +161 -153
  386. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  387. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +2 -7
  388. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  389. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +4 -8
  390. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  391. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +5 -8
  392. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts +25 -0
  393. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts.map +1 -0
  394. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.js +24 -0
  395. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +10 -0
  396. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  397. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +30 -21
  398. package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts.map +0 -1
  399. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts.map +0 -1
  400. package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts.map +0 -1
  401. package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts.map +0 -1
  402. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +0 -1
  403. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +0 -1
  404. package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts.map +0 -1
  405. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts +0 -61
  406. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts.map +0 -1
  407. package/src/shade/playground/vgeo_viewer/main.d.ts.map +0 -1
  408. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts +0 -18
  409. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +0 -1
  410. package/src/shade/playground/vgeo_viewer/select_cut.d.ts +0 -173
  411. package/src/shade/playground/vgeo_viewer/select_cut.d.ts.map +0 -1
  412. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts +0 -52
  413. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts.map +0 -1
  414. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts +0 -24
  415. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts.map +0 -1
  416. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts +0 -32
  417. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts.map +0 -1
  418. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts +0 -59
  419. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts.map +0 -1
  420. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts +0 -44
  421. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts.map +0 -1
  422. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts +0 -20
  423. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts.map +0 -1
  424. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts +0 -73
  425. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts.map +0 -1
  426. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts +0 -13
  427. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +0 -1
  428. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts +0 -12
  429. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts.map +0 -1
  430. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts +0 -36
  431. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts.map +0 -1
  432. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts +0 -13
  433. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts.map +0 -1
  434. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts +0 -19
  435. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts.map +0 -1
  436. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts +0 -29
  437. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts.map +0 -1
  438. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts +0 -31
  439. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts.map +0 -1
  440. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts +0 -18
  441. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts.map +0 -1
  442. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts +0 -14
  443. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts.map +0 -1
  444. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts +0 -12
  445. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts.map +0 -1
  446. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts +0 -14
  447. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts.map +0 -1
  448. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts +0 -11
  449. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts.map +0 -1
  450. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts +0 -46
  451. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts.map +0 -1
  452. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts +0 -22
  453. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +0 -1
  454. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts +0 -29
  455. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts.map +0 -1
  456. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts +0 -9
  457. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts.map +0 -1
  458. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts +0 -10
  459. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts.map +0 -1
  460. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts +0 -15
  461. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts.map +0 -1
  462. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts +0 -16
  463. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts.map +0 -1
  464. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts +0 -10
  465. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts.map +0 -1
  466. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts +0 -17
  467. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts.map +0 -1
  468. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts +0 -3
  469. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts.map +0 -1
  470. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts +0 -8
  471. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +0 -1
  472. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.d.ts +0 -0
  473. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.d.ts +0 -0
  474. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.d.ts +0 -0
  475. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.js +0 -0
  476. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.d.ts +0 -0
  477. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.js +0 -0
  478. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.d.ts +0 -0
  479. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.js +0 -0
  480. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.d.ts +0 -0
  481. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.js +0 -0
  482. /package/src/shade/playground/{vgeo_viewer → caldera}/main.d.ts +0 -0
@@ -0,0 +1,45 @@
1
+ /**
2
+ * How far two triangles may turn across a shared edge before the builder stops pretending the
3
+ * surface is smooth there, in degrees.
4
+ *
5
+ * Only ever applied to normals the builder *synthesizes*. A source that authored its own normals has
6
+ * already answered this question, and its answer is the one that ships.
7
+ *
8
+ * **What it is for.** Averaging every face around a vertex into one direction is right for a surface
9
+ * and wrong for a corner, and a mesh does not say which it is — so an angle has to. A cube is the
10
+ * whole argument: its eight corner vertices each meet three faces, and one direction for all three
11
+ * is ninety degrees wrong for two of them. Measured on Zorah's `mesh1[0]`, whose source is
12
+ * `POSITION`-only and so gets every normal from this pass, the angle between a shipped corner's
13
+ * normal and the normal of the triangle that corner belongs to ran to a mean of 8.60 degrees and a
14
+ * p99 of 37.66 at LOD 0 — the numbers `WEDGE_PLAN_2026_09_18.md` §1 records — before a single
15
+ * collapse.
16
+ *
17
+ * **Why 45.** A threshold splits a curve as readily as a corner, so it is a trade: too low and a
18
+ * coarsely tessellated cylinder gains a crease at every segment, too high and a box stays soft.
19
+ * Swept over that same primitive, over its whole DAG:
20
+ *
21
+ * | crease | vertices/triangle | LOD 0 mean | LOD 0 p99 | all levels p99 | share over 30° |
22
+ * |---|---|---|---|---|---|
23
+ * | none | 0.641 | 8.60 | 37.66 | 54.27 | 6.5% |
24
+ * | 60° | 0.646 | 8.42 | 35.26 | 52.60 | 6.2% |
25
+ * | **45°** | **0.661** | **8.05** | **32.19** | **50.29** | **5.3%** |
26
+ * | 30° | 0.724 | 7.04 | 26.88 | 45.97 | 3.6% |
27
+ * | 20° | 0.880 | 5.53 | 20.58 | 38.65 | 2.0% |
28
+ *
29
+ * A wedge is a shipped vertex, so that first column is very nearly the size of the asset: 45 degrees
30
+ * costs 3%, 30 costs 13% and 20 costs 37%. The curve is smooth because *this* mesh's residual is
31
+ * mostly tessellation rather than creases — it keeps improving as the threshold falls, right through
32
+ * the range where a cylinder would start faceting, which is the sign that the number below is a
33
+ * judgement about content and not a fact about arithmetic. Hard-surface content is where it earns
34
+ * its keep and where the choice is obvious: every edge of a box is ninety degrees, and any threshold
35
+ * under that keeps all of them.
36
+ *
37
+ * So it is also {@link VGeoBuildOptions#crease_angle}, and a conversion of one kind of content can
38
+ * say so.
39
+ *
40
+ * @type {number}
41
+ *
42
+ * @author Alex Goldring
43
+ * @copyright Company Named Limited (c) 2026
44
+ */
45
+ export const VGEO_CREASE_ANGLE = 45;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * What a full unit of each channel is worth in position error, as a fraction of the geometry's own
3
+ * bounding-box diagonal. See {@link VGeoBuildOptions#attribute_weight_ratios}.
4
+ *
5
+ * ## What the number does and does not control
6
+ *
7
+ * It does **not** control the value a coarse vertex carries. That is a least-squares fit to the
8
+ * accumulated fields, and the weight cancels out of it exactly — multiplied in when the quadric is
9
+ * built, divided out when it is solved. The fit is the larger of the two wins by a long way and it
10
+ * needs no tuning at all.
11
+ *
12
+ * What the number controls is how much the channels get to move the vertex and price the collapse.
13
+ * A collapse that would smear a crease is charged for it, in units of length, at exactly the rate
14
+ * this names.
15
+ *
16
+ * ## How it was chosen
17
+ *
18
+ * Swept from `1e-9` — the term effectively off — to `1/2`, measuring how far the shipped normal field
19
+ * sits from the source's and what happened to `self_error`, which is the number the runtime's cut is
20
+ * driven by.
21
+ *
22
+ * On a 31,874-triangle Zorah primitive, the content the defect was found on:
23
+ *
24
+ * ```
25
+ * ratio normal error, mean over the DAG self_error at the root
26
+ * 1e-9 2.076 deg 1.00x
27
+ * 1/1024 1.857 deg 1.08x
28
+ * 1/64 1.807 deg 1.35x
29
+ * 1/8 2.059 deg 18.09x
30
+ * 1/4 2.191 deg 6.81x
31
+ * 1/2 2.326 deg 14.02x
32
+ * ```
33
+ *
34
+ * Above `1/64` it is not a trade, it is a loss: eighteen times the geometric error for a normal field
35
+ * that is *worse* than leaving the term off. The reason is that this content is mostly smooth, and on
36
+ * smooth geometry there is no crease for the term to defend — a 48x24 sphere reads 5.29 degrees of
37
+ * worst-case normal error at every ratio from `1e-9` to `1/4`, unchanged to three figures.
38
+ *
39
+ * So `1/1024`: inside the 20% the plan allows `self_error` to move, worth about a tenth of a degree,
40
+ * and far enough below the cliff that no content falls off it by accident.
41
+ *
42
+ * ## When to raise it
43
+ *
44
+ * Content with hard creases, which is what the term is actually for. A cube subdivided sixteen ways
45
+ * per face — flat faces meeting at right angles, where collapsing *within* a face costs exactly zero
46
+ * geometric error and the metric has nothing else to say — goes from 14.9 degrees of worst-case
47
+ * normal error to **1.38** at `1/4`. (Subdivided twenty-four ways it reads a hundredth of a degree at
48
+ * every ratio, which is how sharply this depends on the geometry rather than on the setting.) That
49
+ * is the trade the number exists to make, and it is a per-asset decision rather than a default,
50
+ * because the same setting on Zorah costs seven times the error for nothing.
51
+ *
52
+ * The other channels take the same ratio for want of their own measurement. A texture coordinate and
53
+ * a colour are bounded the way a normal component is — roughly `[0, 1]`, roughly `[-1, 1]` — so the
54
+ * number is at least in the right place, and none of the content this was measured on carries them.
55
+ * Naming that here rather than implying they were each swept.
56
+ *
57
+ * @readonly
58
+ * @type {number[]}
59
+ *
60
+ * @author Alex Goldring
61
+ * @copyright Company Named Limited (c) 2026
62
+ */
63
+ export const VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS: number[];
64
+ //# sourceMappingURL=VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,mDALU,MAAM,EAAE,CAOhB"}
@@ -0,0 +1,68 @@
1
+ import { VGEO_ATTRIBUTE } from "../../format/attribute/VGEO_ATTRIBUTE.js";
2
+ import { VGEO_ATTRIBUTES } from "../../format/attribute/VGEO_ATTRIBUTES.js";
3
+
4
+ /**
5
+ * What a full unit of each channel is worth in position error, as a fraction of the geometry's own
6
+ * bounding-box diagonal. See {@link VGeoBuildOptions#attribute_weight_ratios}.
7
+ *
8
+ * ## What the number does and does not control
9
+ *
10
+ * It does **not** control the value a coarse vertex carries. That is a least-squares fit to the
11
+ * accumulated fields, and the weight cancels out of it exactly — multiplied in when the quadric is
12
+ * built, divided out when it is solved. The fit is the larger of the two wins by a long way and it
13
+ * needs no tuning at all.
14
+ *
15
+ * What the number controls is how much the channels get to move the vertex and price the collapse.
16
+ * A collapse that would smear a crease is charged for it, in units of length, at exactly the rate
17
+ * this names.
18
+ *
19
+ * ## How it was chosen
20
+ *
21
+ * Swept from `1e-9` — the term effectively off — to `1/2`, measuring how far the shipped normal field
22
+ * sits from the source's and what happened to `self_error`, which is the number the runtime's cut is
23
+ * driven by.
24
+ *
25
+ * On a 31,874-triangle Zorah primitive, the content the defect was found on:
26
+ *
27
+ * ```
28
+ * ratio normal error, mean over the DAG self_error at the root
29
+ * 1e-9 2.076 deg 1.00x
30
+ * 1/1024 1.857 deg 1.08x
31
+ * 1/64 1.807 deg 1.35x
32
+ * 1/8 2.059 deg 18.09x
33
+ * 1/4 2.191 deg 6.81x
34
+ * 1/2 2.326 deg 14.02x
35
+ * ```
36
+ *
37
+ * Above `1/64` it is not a trade, it is a loss: eighteen times the geometric error for a normal field
38
+ * that is *worse* than leaving the term off. The reason is that this content is mostly smooth, and on
39
+ * smooth geometry there is no crease for the term to defend — a 48x24 sphere reads 5.29 degrees of
40
+ * worst-case normal error at every ratio from `1e-9` to `1/4`, unchanged to three figures.
41
+ *
42
+ * So `1/1024`: inside the 20% the plan allows `self_error` to move, worth about a tenth of a degree,
43
+ * and far enough below the cliff that no content falls off it by accident.
44
+ *
45
+ * ## When to raise it
46
+ *
47
+ * Content with hard creases, which is what the term is actually for. A cube subdivided sixteen ways
48
+ * per face — flat faces meeting at right angles, where collapsing *within* a face costs exactly zero
49
+ * geometric error and the metric has nothing else to say — goes from 14.9 degrees of worst-case
50
+ * normal error to **1.38** at `1/4`. (Subdivided twenty-four ways it reads a hundredth of a degree at
51
+ * every ratio, which is how sharply this depends on the geometry rather than on the setting.) That
52
+ * is the trade the number exists to make, and it is a per-asset decision rather than a default,
53
+ * because the same setting on Zorah costs seven times the error for nothing.
54
+ *
55
+ * The other channels take the same ratio for want of their own measurement. A texture coordinate and
56
+ * a colour are bounded the way a normal component is — roughly `[0, 1]`, roughly `[-1, 1]` — so the
57
+ * number is at least in the right place, and none of the content this was measured on carries them.
58
+ * Naming that here rather than implying they were each swept.
59
+ *
60
+ * @readonly
61
+ * @type {number[]}
62
+ *
63
+ * @author Alex Goldring
64
+ * @copyright Company Named Limited (c) 2026
65
+ */
66
+ export const VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS = Object.freeze(
67
+ VGEO_ATTRIBUTES.map((_, attribute) => attribute === VGEO_ATTRIBUTE.POSITION ? 0 : 1 / 1024)
68
+ );
@@ -2,11 +2,15 @@
2
2
  * A level of geometry as the builder handles it: a `BinaryTopology` carrying the positions, the
3
3
  * connectivity, and the per-vertex attributes all together.
4
4
  *
5
- * Everything per-vertex lives in the topology. It has to: an edge collapse moves and removes
6
- * vertices, and the topology is the only thing that knows which. A vertex data layer is addressed
7
- * by vertex id and sized by the vertex pool, so a channel cannot fall out of step with the mesh it
8
- * describes — there is no second array to resize, no invariant to assert, and no way for the
9
- * simplifier to leave a live vertex without a slot.
5
+ * Everything per-element lives in the topology. It has to: a collapse moves and removes vertices and
6
+ * kills faces, and the topology is the only thing that knows which. A data layer is sized by its own
7
+ * pool, so a channel cannot fall out of step with the mesh it describes — there is no second array
8
+ * to resize, no invariant to assert, and no way for the simplifier to leave a live element without a
9
+ * slot.
10
+ *
11
+ * **Position is the vertex's; appearance is the corner's.** A hard edge and a texture seam are both
12
+ * one geometric vertex that shades two ways, and no per-vertex record can hold that — so the
13
+ * channels are loop data. See `WEDGE_PLAN_2026_09_18.md` §2.
10
14
  *
11
15
  * The channels are named by their index into {@link VGEO_ATTRIBUTES}, which is the format's frozen
12
16
  * table — {@link layers} has one slot per entry, holding a layer or null.
@@ -42,9 +46,10 @@ export class VirtualGeometryMesh {
42
46
  */
43
47
  topology: BinaryTopology;
44
48
  /**
45
- * One slot per {@link VGEO_ATTRIBUTES} entry, holding the vertex data layer that carries that
49
+ * One slot per {@link VGEO_ATTRIBUTES} entry, holding the **loop** data layer that carries that
46
50
  * channel or null where this geometry does not carry it.
47
- * {@link VGEO_ATTRIBUTE.POSITION}'s slot is always null — position is the topology's own.
51
+ * {@link VGEO_ATTRIBUTE.POSITION}'s slot is always null — position is the topology's own, and is
52
+ * the one value that really is a vertex's rather than a corner's.
48
53
  * @type {(BinaryDataLayer|null)[]}
49
54
  */
50
55
  layers: (BinaryDataLayer | null)[];
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualGeometryMesh.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;GAeG;AACH;IA6CI;;;;;;;;;;;;;;OAcG;IACH,0CAFa,mBAAmB,CA8G/B;IAzID;;;OAGG;IACH,sBAHW,cAAc,UACd,CAAC,kBAAgB,IAAI,CAAC,EAAE,EAUlC;IA1CD;;;OAGG;IACH,UAFU,cAAc,CAER;IAEhB;;;;;OAKG;IACH,QAFU,CAAC,kBAAgB,IAAI,CAAC,EAAE,CAEtB;IAEZ;;;;;;;;;;;;;OAaG;IACH,aAFU,OAAO,EAAE,CAEyC;IA6I5D;;;OAGG;IACH,YAFa,MAAM,EAAE,CAcpB;CACJ;+BApN8B,yEAAyE"}
1
+ {"version":3,"file":"VirtualGeometryMesh.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IA8CI;;;;;;;;;;;;;;OAcG;IACH,0CAFa,mBAAmB,CA+H/B;IA1JD;;;OAGG;IACH,sBAHW,cAAc,UACd,CAAC,kBAAgB,IAAI,CAAC,EAAE,EAUlC;IA3CD;;;OAGG;IACH,UAFU,cAAc,CAER;IAEhB;;;;;;OAMG;IACH,QAFU,CAAC,kBAAgB,IAAI,CAAC,EAAE,CAEtB;IAEZ;;;;;;;;;;;;;OAaG;IACH,aAFU,OAAO,EAAE,CAEyC;IA8J5D;;;OAGG;IACH,YAFa,MAAM,EAAE,CAcpB;CACJ;+BA1O8B,yEAAyE"}
@@ -12,11 +12,15 @@ import { VGEO_ATTRIBUTES } from "../../format/attribute/VGEO_ATTRIBUTES.js";
12
12
  * A level of geometry as the builder handles it: a `BinaryTopology` carrying the positions, the
13
13
  * connectivity, and the per-vertex attributes all together.
14
14
  *
15
- * Everything per-vertex lives in the topology. It has to: an edge collapse moves and removes
16
- * vertices, and the topology is the only thing that knows which. A vertex data layer is addressed
17
- * by vertex id and sized by the vertex pool, so a channel cannot fall out of step with the mesh it
18
- * describes — there is no second array to resize, no invariant to assert, and no way for the
19
- * simplifier to leave a live vertex without a slot.
15
+ * Everything per-element lives in the topology. It has to: a collapse moves and removes vertices and
16
+ * kills faces, and the topology is the only thing that knows which. A data layer is sized by its own
17
+ * pool, so a channel cannot fall out of step with the mesh it describes — there is no second array
18
+ * to resize, no invariant to assert, and no way for the simplifier to leave a live element without a
19
+ * slot.
20
+ *
21
+ * **Position is the vertex's; appearance is the corner's.** A hard edge and a texture seam are both
22
+ * one geometric vertex that shades two ways, and no per-vertex record can hold that — so the
23
+ * channels are loop data. See `WEDGE_PLAN_2026_09_18.md` §2.
20
24
  *
21
25
  * The channels are named by their index into {@link VGEO_ATTRIBUTES}, which is the format's frozen
22
26
  * table — {@link layers} has one slot per entry, holding a layer or null.
@@ -32,9 +36,10 @@ export class VirtualGeometryMesh {
32
36
  topology = null;
33
37
 
34
38
  /**
35
- * One slot per {@link VGEO_ATTRIBUTES} entry, holding the vertex data layer that carries that
39
+ * One slot per {@link VGEO_ATTRIBUTES} entry, holding the **loop** data layer that carries that
36
40
  * channel or null where this geometry does not carry it.
37
- * {@link VGEO_ATTRIBUTE.POSITION}'s slot is always null — position is the topology's own.
41
+ * {@link VGEO_ATTRIBUTE.POSITION}'s slot is always null — position is the topology's own, and is
42
+ * the one value that really is a vertex's rather than a corner's.
38
43
  * @type {(BinaryDataLayer|null)[]}
39
44
  */
40
45
  layers = [];
@@ -163,14 +168,17 @@ export class VirtualGeometryMesh {
163
168
 
164
169
  const topology = new BinaryTopology();
165
170
 
166
- // Declared before the vertices exist: adding a layer widens every record already in the
167
- // block, so a channel set is cheapest to state while there is nothing to widen.
171
+ // Declared before the mesh exists: adding a layer widens every record already in the block,
172
+ // and the block these go in is the *loop* block, which a triangulated source fills three
173
+ // records at a time. Cheapest to state while there is nothing to widen.
168
174
  const layers = vgeo_layers_declare(topology, carried);
169
175
 
170
176
  bt_mesh_from_indexed_geometry(
171
177
  topology, indices.subarray(0, triangle_count * 3), position.data
172
178
  );
173
179
 
180
+ const loop_pool = topology.loops;
181
+
174
182
  for (let attribute = 0; attribute < VGEO_ATTRIBUTES.length; attribute++) {
175
183
  const layer = layers[attribute];
176
184
 
@@ -182,8 +190,22 @@ export class VirtualGeometryMesh {
182
190
  const source = sources[attribute];
183
191
  const components = VGEO_ATTRIBUTES[attribute].components;
184
192
 
185
- for (let vertex = 0; vertex < vertex_count; vertex++) {
186
- layer.write(vertex, source.data, vertex * components);
193
+ /*
194
+ Per corner, through the vertex it names. A geometry's own attributes are per vertex,
195
+ which is the representation that cannot hold a seam — what a source splits, it splits by
196
+ *duplicating the vertex*, and the weld in `vgeo_normalize_source` is what then throws
197
+ that away. Reading them out per corner here is what gives the weld something to preserve
198
+ (`WEDGE_PLAN_2026_09_18.md` §6.2); until it does, every corner of a vertex gets the same
199
+ value and nothing downstream can tell.
200
+ */
201
+ for (let loop = 0; loop < loop_pool.size; loop++) {
202
+ if (!loop_pool.is_allocated(loop)) {
203
+ continue;
204
+ }
205
+
206
+ layer.write(
207
+ loop, source.data, topology.loop_read_vertex(loop) * components
208
+ );
187
209
  }
188
210
  }
189
211
 
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Which of a mesh's channels travel through a collapse as plain numbers, and where each one sits in
3
+ * the flat vector that carries them.
4
+ *
5
+ * The simplifier moves vertices and merges them, and whatever a merged vertex is to shade as has to
6
+ * be decided *at the collapse*, from the values being merged — not re-derived afterwards from the
7
+ * coarse mesh, which is a different surface (`ATTRIBUTE_PLAN_2026_09_18.md` §1.2). So the channels
8
+ * are flattened into one array indexed by vertex, handed to the simplifier, and written back.
9
+ *
10
+ * Two channels are not simply `components` wide here:
11
+ *
12
+ * - **Position** is not in the vector at all. It lives in the topology, where the quadric solve
13
+ * moves it.
14
+ * - **Tangent** contributes its `xyz` to the fitted vector and its fourth component to a second,
15
+ * **verbatim** one. That component is a handedness flag — a discrete `±1` — and the average of
16
+ * `+1` and `-1` is a number that means nothing, so it is carried rather than fitted: a survivor
17
+ * keeps the flag it had.
18
+ *
19
+ * It has to be *carried*, and leaving the stored record alone is not enough. A collapse re-points
20
+ * the victim's corners onto the survivor and they arrive with the victim's flag, so "the
21
+ * survivor's" has to be written back over them — which is what the verbatim vector is for. Left
22
+ * alone, one vertex of a cube-sphere comes out of a cut with two different tangents in two
23
+ * payloads, and that is the seam invariant broken.
24
+ *
25
+ * And the tangent is here **only when the mesh carries `UV0`**. A tangent is a direction in the
26
+ * texture parameterization; with no parameterization there is nothing for it to be tangent to, and
27
+ * the frame is an arbitrary well-conditioned basis around the normal — which
28
+ * {@link vgeo_compute_vertex_tangents} already builds, on this same condition, and which is a *pure
29
+ * function of the normal*. Deriving it is therefore both cheaper and safer than carrying it:
30
+ * Frisvad's basis turns discontinuously with the normal, so two neighbours' tangents can be nearly
31
+ * opposite and average to nothing at all.
32
+ *
33
+ * @param {(BinaryDataLayer|null)[]} layers channel set, as {@link vgeo_layers_declare} builds one
34
+ * @returns {{components: number, channels: {attribute: number, offset: number, source: number, count: number}[], verbatim_components: number, verbatim: {attribute: number, offset: number, source: number, count: number}[]}}
35
+ * two vectors: the one the simplifier fits, and the one it never touches. `source` is where a
36
+ * channel's run starts *within the layer's own record*, which is `0` for everything but the
37
+ * handedness. A mesh carrying no travelling channel at all comes back with zero of both.
38
+ *
39
+ * @author Alex Goldring
40
+ * @copyright Company Named Limited (c) 2026
41
+ */
42
+ export function vgeo_attribute_vector_layout(layers: (BinaryDataLayer | null)[]): {
43
+ components: number;
44
+ channels: {
45
+ attribute: number;
46
+ offset: number;
47
+ source: number;
48
+ count: number;
49
+ }[];
50
+ verbatim_components: number;
51
+ verbatim: {
52
+ attribute: number;
53
+ offset: number;
54
+ source: number;
55
+ count: number;
56
+ }[];
57
+ };
58
+ //# sourceMappingURL=vgeo_attribute_vector_layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_attribute_vector_layout.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qDATW,CAAC,kBAAgB,IAAI,CAAC,EAAE,GACtB;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,CAAA;CAAC,CA0C7N"}
@@ -0,0 +1,79 @@
1
+ import { VGEO_ATTRIBUTE } from "../../format/attribute/VGEO_ATTRIBUTE.js";
2
+ import { VGEO_ATTRIBUTES } from "../../format/attribute/VGEO_ATTRIBUTES.js";
3
+
4
+ /**
5
+ * Which of a mesh's channels travel through a collapse as plain numbers, and where each one sits in
6
+ * the flat vector that carries them.
7
+ *
8
+ * The simplifier moves vertices and merges them, and whatever a merged vertex is to shade as has to
9
+ * be decided *at the collapse*, from the values being merged — not re-derived afterwards from the
10
+ * coarse mesh, which is a different surface (`ATTRIBUTE_PLAN_2026_09_18.md` §1.2). So the channels
11
+ * are flattened into one array indexed by vertex, handed to the simplifier, and written back.
12
+ *
13
+ * Two channels are not simply `components` wide here:
14
+ *
15
+ * - **Position** is not in the vector at all. It lives in the topology, where the quadric solve
16
+ * moves it.
17
+ * - **Tangent** contributes its `xyz` to the fitted vector and its fourth component to a second,
18
+ * **verbatim** one. That component is a handedness flag — a discrete `±1` — and the average of
19
+ * `+1` and `-1` is a number that means nothing, so it is carried rather than fitted: a survivor
20
+ * keeps the flag it had.
21
+ *
22
+ * It has to be *carried*, and leaving the stored record alone is not enough. A collapse re-points
23
+ * the victim's corners onto the survivor and they arrive with the victim's flag, so "the
24
+ * survivor's" has to be written back over them — which is what the verbatim vector is for. Left
25
+ * alone, one vertex of a cube-sphere comes out of a cut with two different tangents in two
26
+ * payloads, and that is the seam invariant broken.
27
+ *
28
+ * And the tangent is here **only when the mesh carries `UV0`**. A tangent is a direction in the
29
+ * texture parameterization; with no parameterization there is nothing for it to be tangent to, and
30
+ * the frame is an arbitrary well-conditioned basis around the normal — which
31
+ * {@link vgeo_compute_vertex_tangents} already builds, on this same condition, and which is a *pure
32
+ * function of the normal*. Deriving it is therefore both cheaper and safer than carrying it:
33
+ * Frisvad's basis turns discontinuously with the normal, so two neighbours' tangents can be nearly
34
+ * opposite and average to nothing at all.
35
+ *
36
+ * @param {(BinaryDataLayer|null)[]} layers channel set, as {@link vgeo_layers_declare} builds one
37
+ * @returns {{components: number, channels: {attribute: number, offset: number, source: number, count: number}[], verbatim_components: number, verbatim: {attribute: number, offset: number, source: number, count: number}[]}}
38
+ * two vectors: the one the simplifier fits, and the one it never touches. `source` is where a
39
+ * channel's run starts *within the layer's own record*, which is `0` for everything but the
40
+ * handedness. A mesh carrying no travelling channel at all comes back with zero of both.
41
+ *
42
+ * @author Alex Goldring
43
+ * @copyright Company Named Limited (c) 2026
44
+ */
45
+ export function vgeo_attribute_vector_layout(layers) {
46
+ const channels = [];
47
+ const verbatim = [];
48
+
49
+ let components = 0;
50
+ let verbatim_components = 0;
51
+
52
+ for (let attribute = 0; attribute < VGEO_ATTRIBUTES.length; attribute++) {
53
+ if (attribute === VGEO_ATTRIBUTE.POSITION || layers[attribute] === null) {
54
+ continue;
55
+ }
56
+
57
+ if (attribute === VGEO_ATTRIBUTE.TANGENT && layers[VGEO_ATTRIBUTE.UV0] === null) {
58
+ continue;
59
+ }
60
+
61
+ const count = attribute === VGEO_ATTRIBUTE.TANGENT
62
+ ? 3
63
+ : VGEO_ATTRIBUTES[attribute].components;
64
+
65
+ channels.push({ attribute, offset: components, source: 0, count });
66
+
67
+ components += count;
68
+
69
+ if (attribute === VGEO_ATTRIBUTE.TANGENT) {
70
+ verbatim.push({
71
+ attribute, offset: verbatim_components, source: 3, count: 1,
72
+ });
73
+
74
+ verbatim_components += 1;
75
+ }
76
+ }
77
+
78
+ return { components, channels, verbatim_components, verbatim };
79
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Lift a mesh's travelling channels out of its layers and into one flat vector the simplifier can
3
+ * carry through a collapse.
4
+ *
5
+ * Indexed by **wedge id**, holes and all, so a set with merged-away slots needs no compaction and
6
+ * no remap — the simplifier addresses wedges by id and nothing else would line up. A dead slot
7
+ * holds whatever the wedge that used to be a root left behind, which nothing reads.
8
+ *
9
+ * The values are stored per *corner* and read per *wedge*, and a wedge is by definition a set of
10
+ * corners that carry the same value. Each corner of a wedge writes over the last and it does not
11
+ * matter which one wins — **which is a checkable claim rather than an assumed one**, and the
12
+ * difference from §6.1 is exactly that: there, a *vertex* was asserted to have one appearance, and
13
+ * a hard edge is a vertex that does not.
14
+ *
15
+ * Float64 rather than the layers' float32: a value is blended at every collapse it survives, dozens
16
+ * of times over a deep DAG, and rounding to storage precision at each step is error the vector has
17
+ * no reason to accumulate. It is narrowed once, on the way back out
18
+ * ({@link vgeo_attribute_vector_write}).
19
+ *
20
+ * Takes a stride and a channel list rather than the whole layout, because there are two vectors and
21
+ * they differ only in which list they are over — the one the simplifier fits, and the one it never
22
+ * touches (`vgeo_attribute_vector_layout`'s `verbatim`).
23
+ *
24
+ * @param {VirtualGeometryMesh} mesh
25
+ * @param {number} components stride of one wedge's record
26
+ * @param {{attribute: number, offset: number, source: number, count: number}[]} channels
27
+ * @param {BtWedgeSet} wedges which corners of each vertex shade as one
28
+ * @returns {Float64Array} `wedges.count * components` elements
29
+ *
30
+ * @author Alex Goldring
31
+ * @copyright Company Named Limited (c) 2026
32
+ */
33
+ export function vgeo_attribute_vector_read(mesh: VirtualGeometryMesh, components: number, channels: {
34
+ attribute: number;
35
+ offset: number;
36
+ source: number;
37
+ count: number;
38
+ }[], wedges: BtWedgeSet): Float64Array;
39
+ //# sourceMappingURL=vgeo_attribute_vector_read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_attribute_vector_read.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,kFARW,MAAM,YACN;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,EAAE,uBAElE,YAAY,CAgCxB"}
@@ -0,0 +1,68 @@
1
+ import { assert } from "../../../../../../core/assert.js";
2
+
3
+ /**
4
+ * One vertex's widest channel record on its way out of a layer.
5
+ * @type {Float32Array}
6
+ */
7
+ const scratch_record = new Float32Array(4);
8
+
9
+ /**
10
+ * Lift a mesh's travelling channels out of its layers and into one flat vector the simplifier can
11
+ * carry through a collapse.
12
+ *
13
+ * Indexed by **wedge id**, holes and all, so a set with merged-away slots needs no compaction and
14
+ * no remap — the simplifier addresses wedges by id and nothing else would line up. A dead slot
15
+ * holds whatever the wedge that used to be a root left behind, which nothing reads.
16
+ *
17
+ * The values are stored per *corner* and read per *wedge*, and a wedge is by definition a set of
18
+ * corners that carry the same value. Each corner of a wedge writes over the last and it does not
19
+ * matter which one wins — **which is a checkable claim rather than an assumed one**, and the
20
+ * difference from §6.1 is exactly that: there, a *vertex* was asserted to have one appearance, and
21
+ * a hard edge is a vertex that does not.
22
+ *
23
+ * Float64 rather than the layers' float32: a value is blended at every collapse it survives, dozens
24
+ * of times over a deep DAG, and rounding to storage precision at each step is error the vector has
25
+ * no reason to accumulate. It is narrowed once, on the way back out
26
+ * ({@link vgeo_attribute_vector_write}).
27
+ *
28
+ * Takes a stride and a channel list rather than the whole layout, because there are two vectors and
29
+ * they differ only in which list they are over — the one the simplifier fits, and the one it never
30
+ * touches (`vgeo_attribute_vector_layout`'s `verbatim`).
31
+ *
32
+ * @param {VirtualGeometryMesh} mesh
33
+ * @param {number} components stride of one wedge's record
34
+ * @param {{attribute: number, offset: number, source: number, count: number}[]} channels
35
+ * @param {BtWedgeSet} wedges which corners of each vertex shade as one
36
+ * @returns {Float64Array} `wedges.count * components` elements
37
+ *
38
+ * @author Alex Goldring
39
+ * @copyright Company Named Limited (c) 2026
40
+ */
41
+ export function vgeo_attribute_vector_read(mesh, components, channels, wedges) {
42
+ assert.greaterThan(components, 0, 'components');
43
+
44
+ const topology = mesh.topology;
45
+
46
+ const values = new Float64Array(wedges.count * components);
47
+
48
+ const loop_pool = topology.loops;
49
+
50
+ for (let loop = 0; loop < loop_pool.size; loop++) {
51
+ if (!loop_pool.is_allocated(loop)) {
52
+ continue;
53
+ }
54
+
55
+ const base = wedges.find(wedges.of_loop[loop]) * components;
56
+
57
+ for (const channel of channels) {
58
+ mesh.layers[channel.attribute].read(scratch_record, 0, loop);
59
+
60
+ for (let component = 0; component < channel.count; component++) {
61
+ values[base + channel.offset + component] =
62
+ scratch_record[channel.source + component];
63
+ }
64
+ }
65
+ }
66
+
67
+ return values;
68
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Put the simplifier's vector back into the mesh's layers, and square up the frame it describes.
3
+ *
4
+ * **Nothing is *derived* for a pinned vertex.** That is the whole of what pinning means here and it
5
+ * is what lets a cut place two levels of detail side by side: a vertex two groups share must carry
6
+ * byte-identical values in both payloads, or the seam that is watertight in geometry shades as a
7
+ * crease (`ATTRIBUTE_PLAN_2026_09_18.md` §3, invariant 2).
8
+ *
9
+ * Its corners are still *written*, with what the vector says it already had, and that is not a
10
+ * loophole — it is the same guarantee under corner storage. A collapse re-points the victim's corners
11
+ * onto the survivor and they arrive carrying the victim's appearance, so leaving a pinned vertex
12
+ * alone no longer means leaving its value alone. The write is exact: those float32 records are where
13
+ * the vector was read from.
14
+ *
15
+ * Two channels need more than a copy:
16
+ *
17
+ * - **The normal** is renormalized. A blend of two unit vectors is not one, and a normal that is
18
+ * not unit is not a normal. Two exactly opposing normals blend to nothing, which has no direction
19
+ * to report and so keeps whatever the vertex already carried, the same answer
20
+ * {@link bt_mesh_compute_vertex_normals} gives for a vertex whose faces cancel.
21
+ * - **The colour** is clamped to `[0, 1]`. The value a collapse carries is a *fit*, not an average,
22
+ * and a fit extrapolates — which is right for a texture coordinate and wrong for a channel with a
23
+ * range. The encoder saturates anyway, so what this stops is not a corrupt word but the drift:
24
+ * an out-of-range value left in the layer is what the next level's field is fitted from, and it
25
+ * would walk further out at every round.
26
+ * - **The tangent** is re-orthogonalized against that normal and renormalized, and its fourth
27
+ * component — handedness, a discrete `±1` — is left exactly as the survivor had it, because it is
28
+ * a flag rather than a quantity and there is no average of `+1` and `-1`. A tangent that has
29
+ * blended its way onto the normal has no perpendicular component left to keep, and falls back to
30
+ * Frisvad's basis rather than to a zero vector the octahedral encoder cannot represent.
31
+ *
32
+ * @param {VirtualGeometryMesh} mesh mutated in place
33
+ * @param {{components: number, channels: {attribute: number, offset: number, count: number}[]}} layout
34
+ * from {@link vgeo_attribute_vector_layout}, the same one {@link vgeo_attribute_vector_read} used
35
+ * @param {Float64Array} values indexed by wedge id, as the simplifier left it
36
+ * @param {Float64Array|null} verbatim indexed by wedge id, as it was read — the simplifier does not
37
+ * take it and has nothing to say about it. `null` where the layout has no such component, which
38
+ * is every mesh whose tangent is derived rather than carried.
39
+ * @param {Set<number>} pinned vertex ids nothing may be *derived* for
40
+ * @param {BtWedgeSet} wedges which corners of each vertex shade as one, as the simplifier left it
41
+ *
42
+ * @author Alex Goldring
43
+ * @copyright Company Named Limited (c) 2026
44
+ */
45
+ export function vgeo_attribute_vector_write(mesh: VirtualGeometryMesh, layout: {
46
+ components: number;
47
+ channels: {
48
+ attribute: number;
49
+ offset: number;
50
+ count: number;
51
+ }[];
52
+ }, values: Float64Array, verbatim: Float64Array | null, pinned: Set<number>, wedges: BtWedgeSet): void;
53
+ //# sourceMappingURL=vgeo_attribute_vector_write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_attribute_vector_write.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.js"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,+EAZW;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,CAAA;CAAC,UAEpF,YAAY,YACZ,YAAY,GAAC,IAAI,UAGjB,IAAI,MAAM,CAAC,4BAiHrB"}