@woosh/meep-engine 3.24.0 → 3.26.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 (349) hide show
  1. package/package.json +1 -1
  2. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +59 -0
  3. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
  4. package/src/core/geom/3d/shape/HeightMapShape3D.js +285 -0
  5. package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
  6. package/src/core/geom/3d/shape/PosedShape3D.js +57 -0
  7. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  8. package/src/core/geom/3d/shape/TransformedShape3D.js +102 -0
  9. package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
  10. package/src/core/geom/3d/shape/UnionShape3D.js +64 -0
  11. package/src/engine/graphics3/PickingSystem.d.ts +3 -3
  12. package/src/engine/graphics3/PickingSystem.d.ts.map +1 -1
  13. package/src/engine/graphics3/PickingSystem.js +52 -55
  14. package/src/engine/graphics3/shader_picking_gather.d.ts +40 -0
  15. package/src/engine/graphics3/shader_picking_gather.d.ts.map +1 -0
  16. package/src/engine/graphics3/shader_picking_gather.js +120 -0
  17. package/src/engine/physics/cloth/MEASUREMENTS.md +1632 -0
  18. package/src/engine/physics/cloth/PLAN.md +738 -95
  19. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +84 -17
  20. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -1
  21. package/src/engine/physics/cloth/collider/ClothColliderIndex.js +451 -42
  22. package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.d.ts +52 -0
  23. package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.d.ts.map +1 -0
  24. package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.js +70 -0
  25. package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts +12 -3
  26. package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts.map +1 -1
  27. package/src/engine/physics/cloth/ecs/ClothDynamics.js +340 -331
  28. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +101 -29
  29. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  30. package/src/engine/physics/cloth/ecs/ClothInstance.js +110 -31
  31. package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.d.ts +84 -0
  32. package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.d.ts.map +1 -0
  33. package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.js +141 -0
  34. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +71 -81
  35. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  36. package/src/engine/physics/cloth/ecs/ClothSystem.js +135 -856
  37. package/src/engine/physics/cloth/ecs/ClothWorkerCore.d.ts +48 -0
  38. package/src/engine/physics/cloth/ecs/ClothWorkerCore.d.ts.map +1 -0
  39. package/src/engine/physics/cloth/ecs/ClothWorkerCore.js +107 -0
  40. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +323 -0
  41. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -0
  42. package/src/engine/physics/cloth/ecs/ClothWorld.js +1248 -0
  43. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +192 -0
  44. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -0
  45. package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +578 -0
  46. package/src/engine/physics/cloth/ecs/cloth.worker.d.ts +2 -0
  47. package/src/engine/physics/cloth/ecs/cloth.worker.d.ts.map +1 -0
  48. package/src/engine/physics/cloth/ecs/cloth.worker.js +12 -0
  49. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  50. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +2 -1
  51. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +85 -3
  52. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
  53. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +366 -271
  54. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +95 -12
  55. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
  56. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +170 -27
  57. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +19 -0
  58. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
  59. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +249 -201
  60. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +21 -0
  61. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  62. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +62 -1
  63. package/src/engine/physics/cloth/ecs/cloth_worker_protocol.d.ts +29 -0
  64. package/src/engine/physics/cloth/ecs/cloth_worker_protocol.d.ts.map +1 -0
  65. package/src/engine/physics/cloth/ecs/cloth_worker_protocol.js +78 -0
  66. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  67. package/src/engine/physics/cloth/ecs/cloth_write_back.js +18 -10
  68. package/src/engine/physics/cloth/ecs/makeClothWorker.d.ts +17 -0
  69. package/src/engine/physics/cloth/ecs/makeClothWorker.d.ts.map +1 -0
  70. package/src/engine/physics/cloth/ecs/makeClothWorker.js +18 -0
  71. package/src/engine/physics/cloth/playground/README.md +73 -2
  72. package/src/engine/physics/cloth/playground/collide_main.js +1 -1
  73. package/src/engine/physics/cloth/playground/wind.html +166 -0
  74. package/src/engine/physics/cloth/playground/wind_build.d.ts +81 -0
  75. package/src/engine/physics/cloth/playground/wind_build.d.ts.map +1 -0
  76. package/src/engine/physics/cloth/playground/wind_build.js +141 -0
  77. package/src/engine/physics/cloth/playground/wind_main.d.ts +2 -0
  78. package/src/engine/physics/cloth/playground/wind_main.d.ts.map +1 -0
  79. package/src/engine/physics/cloth/playground/wind_main.js +681 -0
  80. package/src/engine/physics/cloth/solver/ClothState.d.ts +134 -79
  81. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  82. package/src/engine/physics/cloth/solver/ClothState.js +273 -12
  83. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +29 -8
  84. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
  85. package/src/engine/physics/cloth/solver/cloth_contact_find.js +37 -9
  86. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +45 -2
  87. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  88. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +46 -2
  89. package/src/engine/physics/cloth/solver/cloth_step.d.ts +21 -2
  90. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  91. package/src/engine/physics/cloth/solver/cloth_step.js +173 -4
  92. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +40 -0
  93. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -0
  94. package/src/engine/physics/cloth/solver/cloth_step_instance.js +284 -0
  95. package/src/engine/physics/cloth/solver/cloth_wind_accelerate.d.ts +107 -0
  96. package/src/engine/physics/cloth/solver/cloth_wind_accelerate.d.ts.map +1 -0
  97. package/src/engine/physics/cloth/solver/cloth_wind_accelerate.js +263 -0
  98. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts +9 -2
  99. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts.map +1 -1
  100. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js +9 -2
  101. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts +102 -0
  102. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts.map +1 -0
  103. package/src/engine/physics/cloth/wind/AbstractClothWind.js +114 -0
  104. package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts +87 -0
  105. package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts.map +1 -0
  106. package/src/engine/physics/cloth/wind/ClothAmbientWind.js +185 -0
  107. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +79 -0
  108. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -0
  109. package/src/engine/physics/cloth/wind/ClothFluidWind.js +213 -0
  110. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +106 -0
  111. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -0
  112. package/src/engine/physics/cloth/wind/cloth_sample_air.js +297 -0
  113. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  114. package/src/shade/device/mock/texture_copy.d.ts.map +1 -1
  115. package/src/shade/device/mock/texture_copy.js +28 -0
  116. package/src/shade/playground/vgeo_runtime/README.md +94 -0
  117. package/src/shade/playground/vgeo_runtime/index.html +62 -0
  118. package/src/shade/playground/vgeo_runtime/main.d.ts +2 -0
  119. package/src/shade/playground/vgeo_runtime/main.d.ts.map +1 -0
  120. package/src/shade/playground/vgeo_runtime/main.js +399 -0
  121. package/src/shade/playground/vgeo_viewer/sample_asset.js +1 -1
  122. package/src/shade/renderer/camera/Camera.d.ts +14 -0
  123. package/src/shade/renderer/camera/Camera.d.ts.map +1 -1
  124. package/src/shade/renderer/camera/Camera.js +7 -1
  125. package/src/shade/renderer/geometry/GEOMETRY_METADATA_STRUCT.d.ts.map +1 -1
  126. package/src/shade/renderer/geometry/GEOMETRY_METADATA_STRUCT.js +16 -1
  127. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  128. package/src/shade/renderer/geometry/GPUGeometryManager.js +29 -9
  129. package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts +10 -0
  130. package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts.map +1 -1
  131. package/src/shade/renderer/geometry/GPUGeometryMetadata.js +13 -0
  132. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +46 -18
  133. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +70 -22
  134. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +97 -19
  135. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +12 -2
  136. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  137. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +14 -3
  138. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts +2 -2
  139. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +1 -1
  140. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.js +124 -6
  141. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts +22 -0
  142. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +1 -0
  143. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.js +53 -0
  144. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +8 -1
  145. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  146. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +8 -1
  147. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.d.ts +16 -0
  148. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.d.ts.map +1 -0
  149. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.js +15 -0
  150. package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.d.ts +54 -0
  151. package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.d.ts.map +1 -0
  152. package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.js +53 -0
  153. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts +13 -2
  154. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts.map +1 -1
  155. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.js +14 -2
  156. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +100 -0
  157. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  158. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +113 -0
  159. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
  160. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +5 -0
  161. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  162. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +108 -0
  163. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  164. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +23 -0
  165. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  166. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +40 -0
  167. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts +228 -0
  168. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts.map +1 -0
  169. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.js +932 -0
  170. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +176 -0
  171. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -0
  172. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +425 -0
  173. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +241 -0
  174. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +574 -0
  175. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts +120 -0
  176. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -0
  177. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +674 -0
  178. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts +287 -0
  179. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -0
  180. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +976 -0
  181. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts +42 -0
  182. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts.map +1 -0
  183. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.js +96 -0
  184. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.d.ts +16 -0
  185. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.d.ts.map +1 -0
  186. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.js +15 -0
  187. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts +19 -0
  188. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts.map +1 -0
  189. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.js +83 -0
  190. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.d.ts +9 -0
  191. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.d.ts.map +1 -0
  192. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.js +8 -0
  193. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +19 -0
  194. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -0
  195. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +160 -0
  196. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts +3 -0
  197. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts.map +1 -0
  198. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js +255 -0
  199. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts +3 -0
  200. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts.map +1 -0
  201. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.js +80 -0
  202. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts +3 -0
  203. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -0
  204. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +144 -0
  205. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts +3 -0
  206. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -0
  207. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +530 -0
  208. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts +39 -0
  209. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts.map +1 -0
  210. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.js +54 -0
  211. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.d.ts +41 -0
  212. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.d.ts.map +1 -0
  213. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.js +56 -0
  214. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts +49 -0
  215. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -0
  216. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +328 -0
  217. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +10 -0
  218. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts.map +1 -0
  219. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +51 -0
  220. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +13 -0
  221. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -0
  222. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +12 -0
  223. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +17 -0
  224. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts.map +1 -0
  225. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +99 -0
  226. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.d.ts +9 -0
  227. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.d.ts.map +1 -0
  228. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +8 -0
  229. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts +7 -0
  230. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts.map +1 -0
  231. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.js +27 -0
  232. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.d.ts +14 -0
  233. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.d.ts.map +1 -0
  234. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.js +13 -0
  235. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.d.ts +7 -0
  236. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.d.ts.map +1 -0
  237. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.js +35 -0
  238. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.d.ts +9 -0
  239. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.d.ts.map +1 -0
  240. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.js +8 -0
  241. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.d.ts +15 -0
  242. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.d.ts.map +1 -0
  243. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.js +14 -0
  244. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts +7 -0
  245. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts.map +1 -0
  246. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.js +36 -0
  247. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts +10 -0
  248. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts.map +1 -0
  249. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.js +9 -0
  250. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.d.ts +11 -0
  251. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.d.ts.map +1 -0
  252. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.js +54 -0
  253. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.d.ts +9 -0
  254. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.d.ts.map +1 -0
  255. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.js +8 -0
  256. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.d.ts +11 -0
  257. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.d.ts.map +1 -0
  258. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.js +10 -0
  259. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.d.ts +7 -0
  260. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.d.ts.map +1 -0
  261. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.js +30 -0
  262. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.d.ts +9 -0
  263. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.d.ts.map +1 -0
  264. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.js +8 -0
  265. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.d.ts +13 -0
  266. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.d.ts.map +1 -0
  267. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.js +12 -0
  268. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.d.ts +14 -0
  269. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.d.ts.map +1 -0
  270. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.js +13 -0
  271. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts +11 -0
  272. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts.map +1 -0
  273. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.js +61 -0
  274. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts +9 -0
  275. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts.map +1 -0
  276. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.js +8 -0
  277. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.d.ts +13 -0
  278. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.d.ts.map +1 -0
  279. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.js +12 -0
  280. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.d.ts +9 -0
  281. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.d.ts.map +1 -0
  282. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.js +8 -0
  283. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.d.ts +20 -0
  284. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.d.ts.map +1 -0
  285. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.js +19 -0
  286. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts +23 -0
  287. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -0
  288. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +70 -0
  289. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts +18 -0
  290. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts.map +1 -0
  291. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.js +25 -0
  292. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +35 -0
  293. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -0
  294. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +41 -0
  295. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts +32 -0
  296. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -0
  297. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +138 -0
  298. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  299. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  300. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  301. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +9 -0
  302. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  303. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +12 -1
  304. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  305. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +12 -1
  306. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  307. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +10 -0
  308. package/src/shade/renderer/scene/GPUSceneContext.d.ts +18 -0
  309. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  310. package/src/shade/renderer/scene/GPUSceneContext.js +647 -594
  311. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  312. package/src/shade/renderer/scene/rows/GPUSceneRows.js +22 -0
  313. package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.d.ts +35 -0
  314. package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.d.ts.map +1 -0
  315. package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.js +91 -0
  316. package/src/engine/graphics3/instantiate_scene_bundle.d.ts +0 -54
  317. package/src/engine/graphics3/instantiate_scene_bundle.d.ts.map +0 -1
  318. package/src/engine/graphics3/shade_node_to_entity_composition.d.ts +0 -39
  319. package/src/engine/graphics3/shade_node_to_entity_composition.d.ts.map +0 -1
  320. package/src/shade/renderer/animation/compute_skin_world_bounds.d.ts +0 -35
  321. package/src/shade/renderer/animation/compute_skin_world_bounds.d.ts.map +0 -1
  322. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.d.ts +0 -96
  323. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.d.ts.map +0 -1
  324. package/src/shade/renderer/animation/pose/pose_evaluate_world.d.ts +0 -20
  325. package/src/shade/renderer/animation/pose/pose_evaluate_world.d.ts.map +0 -1
  326. package/src/shade/renderer/animation/skin_bind_transform.d.ts +0 -25
  327. package/src/shade/renderer/animation/skin_bind_transform.d.ts.map +0 -1
  328. package/src/shade/renderer/animation/skin_frame_defect.d.ts +0 -34
  329. package/src/shade/renderer/animation/skin_frame_defect.d.ts.map +0 -1
  330. package/src/shade/renderer/animation/skin_joint_matrix.d.ts +0 -24
  331. package/src/shade/renderer/animation/skin_joint_matrix.d.ts.map +0 -1
  332. package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts +0 -70
  333. package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts.map +0 -1
  334. package/src/shade/renderer/buffer/table/GPUReadbackStagingRing.d.ts +0 -96
  335. package/src/shade/renderer/buffer/table/GPUReadbackStagingRing.d.ts.map +0 -1
  336. package/src/shade/renderer/scene/InstanceBatch.d.ts +0 -92
  337. package/src/shade/renderer/scene/InstanceBatch.d.ts.map +0 -1
  338. package/src/shade/renderer/scene/Mesh.d.ts +0 -55
  339. package/src/shade/renderer/scene/Mesh.d.ts.map +0 -1
  340. package/src/shade/renderer/scene/Node3D.d.ts +0 -159
  341. package/src/shade/renderer/scene/Node3D.d.ts.map +0 -1
  342. package/src/shade/renderer/scene/Node3DDirtyList.d.ts +0 -59
  343. package/src/shade/renderer/scene/Node3DDirtyList.d.ts.map +0 -1
  344. package/src/shade/renderer/scene/SceneNodeBinding.d.ts +0 -52
  345. package/src/shade/renderer/scene/SceneNodeBinding.d.ts.map +0 -1
  346. package/src/shade/renderer/scene/SkinnedMesh.d.ts +0 -27
  347. package/src/shade/renderer/scene/SkinnedMesh.d.ts.map +0 -1
  348. package/src/shade/renderer/scene/TransformAuthority.d.ts +0 -19
  349. package/src/shade/renderer/scene/TransformAuthority.d.ts.map +0 -1
@@ -104,6 +104,28 @@ export class VGeoPage {
104
104
  * @type {Uint32Array}
105
105
  */
106
106
  child_decoded_size: Uint32Array;
107
+ /**
108
+ * `4 · child_page_count` — the copy of each child page's own metric sphere (format §5, §6.2).
109
+ *
110
+ * It is a *copy*, which is the point: it is readable before that page is fetched, and §11.11
111
+ * requires it to equal the page's own header metric so that a traversal trusting it cannot skip
112
+ * a page it needed.
113
+ *
114
+ * The GPU cut does not read it, and `runtime/RUNTIME_PLAN.md` §4.8 says why — a want is emitted
115
+ * from a cluster that has already passed a strictly tighter test. What wants it is a prefetch,
116
+ * which has no cluster-level evidence to be tighter than.
117
+ *
118
+ * @type {Float32Array}
119
+ */
120
+ child_metric_sphere: Float32Array;
121
+ /**
122
+ * @type {Float32Array}
123
+ */
124
+ child_metric_min_self_error: Float32Array;
125
+ /**
126
+ * @type {Float32Array}
127
+ */
128
+ child_metric_max_parent_error: Float32Array;
107
129
  /**
108
130
  * Per group: index of its first cluster within this page.
109
131
  * @type {Uint16Array}
@@ -136,11 +158,32 @@ export class VGeoPage {
136
158
  * @type {Float32Array}
137
159
  */
138
160
  parent_error: Float32Array;
161
+ /**
162
+ * `4 · cluster_count` — the LOD-metric sphere of the step that *consumed* each cluster; a root's
163
+ * duplicates its own.
164
+ *
165
+ * Half the cut rule is `project(parent_sphere, parent_error) > τ`, and a traversal never has to
166
+ * evaluate it: arriving through the parent step is that test. An evaluator does, which is why
167
+ * this column exists at all and why nothing read it before the GPU runtime.
168
+ *
169
+ * @type {Float32Array}
170
+ */
171
+ parent_sphere: Float32Array;
139
172
  /**
140
173
  * `4 · cluster_count` — each cluster's own tight sphere, for culling and never for the cut test.
141
174
  * @type {Float32Array}
142
175
  */
143
176
  bounds_sphere: Float32Array;
177
+ /**
178
+ * `6 · cluster_count` — each cluster's object-space AABB, in `min xyz, max xyz` order.
179
+ *
180
+ * This is the meshlet metadata's `bounds_box` verbatim (format §8): the HZB filter and the
181
+ * small-primitive cull read it, so a VG cluster that reaches the raster path without it cannot
182
+ * be culled by anything downstream.
183
+ *
184
+ * @type {Float32Array}
185
+ */
186
+ aabb: Float32Array;
144
187
  /**
145
188
  * Index into {@link child_page_index}, or `VGEO_SAME_PAGE`, or `VGEO_NO_CHILD` for a leaf.
146
189
  * @type {Uint16Array}
@@ -160,6 +203,12 @@ export class VGeoPage {
160
203
  * @type {Uint32Array}
161
204
  */
162
205
  cluster_payload_offset: Uint32Array;
206
+ /**
207
+ * How many bytes each cluster's payload runs to — the length of the copy into the meshlet data
208
+ * pool, which format §8 makes a copy and nothing more.
209
+ * @type {Uint32Array}
210
+ */
211
+ cluster_payload_size: Uint32Array;
163
212
  /**
164
213
  * @type {Uint8Array}
165
214
  */
@@ -173,6 +222,57 @@ export class VGeoPage {
173
222
  * @type {Uint16Array}
174
223
  */
175
224
  group_of_cluster: Uint16Array;
225
+ /**
226
+ * `4 · node_count` — the sphere bounding everything under each node of this page's tree.
227
+ *
228
+ * The tree (format §6.1) is over **this page's groups and nothing else**: it arrives with the
229
+ * page, leaves with it, and can never name anything that is not here. Node 0 is the root, an
230
+ * interior node's children are a contiguous run at a strictly greater index, and the leaves
231
+ * partition the group table — so a walk starts at 0, never special-cases a single-group page,
232
+ * and needs no cycle check.
233
+ *
234
+ * @type {Float32Array}
235
+ */
236
+ node_sphere: Float32Array;
237
+ /**
238
+ * The finest error covered by each node. Ranks a prefetch; the cut does not read it.
239
+ * @type {Float32Array}
240
+ */
241
+ node_min_self_error: Float32Array;
242
+ /**
243
+ * The coarsest parent error covered by each node, `+∞` where the root is covered.
244
+ *
245
+ * The load-bearing one: a cluster draws only while `project(parent) > τ`, so a node whose
246
+ * *largest* parent error still projects to no more than τ has nothing drawable anywhere under
247
+ * it and the whole subtree can be skipped.
248
+ *
249
+ * @type {Float32Array}
250
+ */
251
+ node_max_parent_error: Float32Array;
252
+ /**
253
+ * First child of each node — a node index when interior, a **group** index when a leaf.
254
+ * @type {Uint16Array}
255
+ */
256
+ node_child_first: Uint16Array;
257
+ /**
258
+ * `1..4`.
259
+ * @type {Uint16Array}
260
+ */
261
+ node_child_count: Uint16Array;
262
+ /**
263
+ * Bit 0 ({@link VGEO_NODE_FLAG_LEAF}): the children are groups rather than nodes.
264
+ * @type {Uint16Array}
265
+ */
266
+ node_flags: Uint16Array;
267
+ /**
268
+ * This page's own traversal metric — sphere xyzw, then `min_self_error`, `max_parent_error`.
269
+ *
270
+ * Format §11.10 makes it equal to node 0's, which is why a traversal that always enters a page
271
+ * at node 0 never reads this and never has to reconcile the two.
272
+ *
273
+ * @type {Float32Array}
274
+ */
275
+ metric: Float32Array;
176
276
  /**
177
277
  * How many of this page's clusters store a normal per vertex rather than one constant-compressed
178
278
  * word for the whole cluster.
@@ -1 +1 @@
1
- {"version":3,"file":"VGeoPage.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/read/VGeoPage.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IACI;;;OAGG;IACH,OAFU,MAAM,CAEN;IAEV;;;OAGG;IACH,cAFU,MAAM,CAEC;IAEjB;;OAEG;IACH,YAFU,MAAM,CAED;IAEf;;;;;OAKG;IACH,OAFU,MAAM,CAEN;IAEV;;;OAGG;IACH,aAFU,MAAM,CAEA;IAEhB;;;OAGG;IACH,cAFU,MAAM,CAEC;IAEjB;;;OAGG;IACH,OAFU,UAAU,CAEM;IAE1B;;;;;OAKG;IACH,MAFU,QAAQ,CAEsB;IAExC;;OAEG;IACH,WAFU,MAAM,CAEF;IAEd;;OAEG;IACH,WAFU,MAAM,CAEF;IAEd;;;OAGG;IACH,gBAFU,MAAM,CAEG;IAEnB;;OAEG;IACH,cAFU,MAAM,CAEC;IAEjB;;OAEG;IACH,YAFU,MAAM,CAED;IAEf;;;OAGG;IACH,kBAFU,WAAW,CAEiB;IAEtC;;;;;OAKG;IACH,oBAFU,YAAY,CAEmB;IAEzC;;OAEG;IACH,kBAFU,WAAW,CAEiB;IAEtC;;;OAGG;IACH,oBAFU,WAAW,CAEmB;IAExC;;;OAGG;IACH,qBAFU,WAAW,CAEoB;IAEzC;;OAEG;IACH,qBAFU,WAAW,CAEoB;IAEzC;;;;OAIG;IACH,oBAFU,WAAW,CAEmB;IAExC;;OAEG;IACH,eAFU,MAAM,CAEE;IAElB;;;OAGG;IACH,aAFU,YAAY,CAEY;IAElC;;OAEG;IACH,YAFU,YAAY,CAEW;IAEjC;;OAEG;IACH,cAFU,YAAY,CAEa;IAEnC;;;OAGG;IACH,eAFU,YAAY,CAEc;IAEpC;;;OAGG;IACH,WAFU,WAAW,CAEU;IAE/B;;;OAGG;IACH,aAFU,WAAW,CAEY;IAEjC;;OAEG;IACH,gBAFU,WAAW,CAEe;IAEpC;;;OAGG;IACH,wBAFU,WAAW,CAEuB;IAE5C;;OAEG;IACH,cAFU,UAAU,CAEa;IAEjC;;OAEG;IACH,gBAFU,UAAU,CAEe;IAEnC;;;OAGG;IACH,kBAFU,WAAW,CAEiB;IAEtC;;;;;;;;;;;;OAYG;IACH,iCAFU,MAAM,CAEoB;IAEpC;;;;;OAKG;IACH,oBAHW,MAAM,GACJ,MAAM,CAIlB;CACJ"}
1
+ {"version":3,"file":"VGeoPage.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/read/VGeoPage.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IACI;;;OAGG;IACH,OAFU,MAAM,CAEN;IAEV;;;OAGG;IACH,cAFU,MAAM,CAEC;IAEjB;;OAEG;IACH,YAFU,MAAM,CAED;IAEf;;;;;OAKG;IACH,OAFU,MAAM,CAEN;IAEV;;;OAGG;IACH,aAFU,MAAM,CAEA;IAEhB;;;OAGG;IACH,cAFU,MAAM,CAEC;IAEjB;;;OAGG;IACH,OAFU,UAAU,CAEM;IAE1B;;;;;OAKG;IACH,MAFU,QAAQ,CAEsB;IAExC;;OAEG;IACH,WAFU,MAAM,CAEF;IAEd;;OAEG;IACH,WAFU,MAAM,CAEF;IAEd;;;OAGG;IACH,gBAFU,MAAM,CAEG;IAEnB;;OAEG;IACH,cAFU,MAAM,CAEC;IAEjB;;OAEG;IACH,YAFU,MAAM,CAED;IAEf;;;OAGG;IACH,kBAFU,WAAW,CAEiB;IAEtC;;;;;OAKG;IACH,oBAFU,YAAY,CAEmB;IAEzC;;OAEG;IACH,kBAFU,WAAW,CAEiB;IAEtC;;;OAGG;IACH,oBAFU,WAAW,CAEmB;IAExC;;;;;;;;;;;;OAYG;IACH,qBAFU,YAAY,CAEoB;IAE1C;;OAEG;IACH,6BAFU,YAAY,CAE4B;IAElD;;OAEG;IACH,+BAFU,YAAY,CAE8B;IAEpD;;;OAGG;IACH,qBAFU,WAAW,CAEoB;IAEzC;;OAEG;IACH,qBAFU,WAAW,CAEoB;IAEzC;;;;OAIG;IACH,oBAFU,WAAW,CAEmB;IAExC;;OAEG;IACH,eAFU,MAAM,CAEE;IAElB;;;OAGG;IACH,aAFU,YAAY,CAEY;IAElC;;OAEG;IACH,YAFU,YAAY,CAEW;IAEjC;;OAEG;IACH,cAFU,YAAY,CAEa;IAEnC;;;;;;;;;OASG;IACH,eAFU,YAAY,CAEc;IAEpC;;;OAGG;IACH,eAFU,YAAY,CAEc;IAEpC;;;;;;;;OAQG;IACH,MAFU,YAAY,CAEK;IAE3B;;;OAGG;IACH,WAFU,WAAW,CAEU;IAE/B;;;OAGG;IACH,aAFU,WAAW,CAEY;IAEjC;;OAEG;IACH,gBAFU,WAAW,CAEe;IAEpC;;;OAGG;IACH,wBAFU,WAAW,CAEuB;IAE5C;;;;OAIG;IACH,sBAFU,WAAW,CAEqB;IAE1C;;OAEG;IACH,cAFU,UAAU,CAEa;IAEjC;;OAEG;IACH,gBAFU,UAAU,CAEe;IAEnC;;;OAGG;IACH,kBAFU,WAAW,CAEiB;IAEtC;;;;;;;;;;OAUG;IACH,aAFU,YAAY,CAEY;IAElC;;;OAGG;IACH,qBAFU,YAAY,CAEoB;IAE1C;;;;;;;;OAQG;IACH,uBAFU,YAAY,CAEsB;IAE5C;;;OAGG;IACH,kBAFU,WAAW,CAEiB;IAEtC;;;OAGG;IACH,kBAFU,WAAW,CAEiB;IAEtC;;;OAGG;IACH,YAFU,WAAW,CAEW;IAEhC;;;;;;;OAOG;IACH,QAFU,YAAY,CAEO;IAE7B;;;;;;;;;;;;OAYG;IACH,iCAFU,MAAM,CAEoB;IAEpC;;;;;OAKG;IACH,oBAHW,MAAM,GACJ,MAAM,CAIlB;CACJ"}
@@ -121,6 +121,31 @@ export class VGeoPage {
121
121
  */
122
122
  child_decoded_size = new Uint32Array(0);
123
123
 
124
+ /**
125
+ * `4 · child_page_count` — the copy of each child page's own metric sphere (format §5, §6.2).
126
+ *
127
+ * It is a *copy*, which is the point: it is readable before that page is fetched, and §11.11
128
+ * requires it to equal the page's own header metric so that a traversal trusting it cannot skip
129
+ * a page it needed.
130
+ *
131
+ * The GPU cut does not read it, and `runtime/RUNTIME_PLAN.md` §4.8 says why — a want is emitted
132
+ * from a cluster that has already passed a strictly tighter test. What wants it is a prefetch,
133
+ * which has no cluster-level evidence to be tighter than.
134
+ *
135
+ * @type {Float32Array}
136
+ */
137
+ child_metric_sphere = new Float32Array(0);
138
+
139
+ /**
140
+ * @type {Float32Array}
141
+ */
142
+ child_metric_min_self_error = new Float32Array(0);
143
+
144
+ /**
145
+ * @type {Float32Array}
146
+ */
147
+ child_metric_max_parent_error = new Float32Array(0);
148
+
124
149
  /**
125
150
  * Per group: index of its first cluster within this page.
126
151
  * @type {Uint16Array}
@@ -160,12 +185,35 @@ export class VGeoPage {
160
185
  */
161
186
  parent_error = new Float32Array(0);
162
187
 
188
+ /**
189
+ * `4 · cluster_count` — the LOD-metric sphere of the step that *consumed* each cluster; a root's
190
+ * duplicates its own.
191
+ *
192
+ * Half the cut rule is `project(parent_sphere, parent_error) > τ`, and a traversal never has to
193
+ * evaluate it: arriving through the parent step is that test. An evaluator does, which is why
194
+ * this column exists at all and why nothing read it before the GPU runtime.
195
+ *
196
+ * @type {Float32Array}
197
+ */
198
+ parent_sphere = new Float32Array(0);
199
+
163
200
  /**
164
201
  * `4 · cluster_count` — each cluster's own tight sphere, for culling and never for the cut test.
165
202
  * @type {Float32Array}
166
203
  */
167
204
  bounds_sphere = new Float32Array(0);
168
205
 
206
+ /**
207
+ * `6 · cluster_count` — each cluster's object-space AABB, in `min xyz, max xyz` order.
208
+ *
209
+ * This is the meshlet metadata's `bounds_box` verbatim (format §8): the HZB filter and the
210
+ * small-primitive cull read it, so a VG cluster that reaches the raster path without it cannot
211
+ * be culled by anything downstream.
212
+ *
213
+ * @type {Float32Array}
214
+ */
215
+ aabb = new Float32Array(0);
216
+
169
217
  /**
170
218
  * Index into {@link child_page_index}, or `VGEO_SAME_PAGE`, or `VGEO_NO_CHILD` for a leaf.
171
219
  * @type {Uint16Array}
@@ -189,6 +237,13 @@ export class VGeoPage {
189
237
  */
190
238
  cluster_payload_offset = new Uint32Array(0);
191
239
 
240
+ /**
241
+ * How many bytes each cluster's payload runs to — the length of the copy into the meshlet data
242
+ * pool, which format §8 makes a copy and nothing more.
243
+ * @type {Uint32Array}
244
+ */
245
+ cluster_payload_size = new Uint32Array(0);
246
+
192
247
  /**
193
248
  * @type {Uint8Array}
194
249
  */
@@ -205,6 +260,64 @@ export class VGeoPage {
205
260
  */
206
261
  group_of_cluster = new Uint16Array(0);
207
262
 
263
+ /**
264
+ * `4 · node_count` — the sphere bounding everything under each node of this page's tree.
265
+ *
266
+ * The tree (format §6.1) is over **this page's groups and nothing else**: it arrives with the
267
+ * page, leaves with it, and can never name anything that is not here. Node 0 is the root, an
268
+ * interior node's children are a contiguous run at a strictly greater index, and the leaves
269
+ * partition the group table — so a walk starts at 0, never special-cases a single-group page,
270
+ * and needs no cycle check.
271
+ *
272
+ * @type {Float32Array}
273
+ */
274
+ node_sphere = new Float32Array(0);
275
+
276
+ /**
277
+ * The finest error covered by each node. Ranks a prefetch; the cut does not read it.
278
+ * @type {Float32Array}
279
+ */
280
+ node_min_self_error = new Float32Array(0);
281
+
282
+ /**
283
+ * The coarsest parent error covered by each node, `+∞` where the root is covered.
284
+ *
285
+ * The load-bearing one: a cluster draws only while `project(parent) > τ`, so a node whose
286
+ * *largest* parent error still projects to no more than τ has nothing drawable anywhere under
287
+ * it and the whole subtree can be skipped.
288
+ *
289
+ * @type {Float32Array}
290
+ */
291
+ node_max_parent_error = new Float32Array(0);
292
+
293
+ /**
294
+ * First child of each node — a node index when interior, a **group** index when a leaf.
295
+ * @type {Uint16Array}
296
+ */
297
+ node_child_first = new Uint16Array(0);
298
+
299
+ /**
300
+ * `1..4`.
301
+ * @type {Uint16Array}
302
+ */
303
+ node_child_count = new Uint16Array(0);
304
+
305
+ /**
306
+ * Bit 0 ({@link VGEO_NODE_FLAG_LEAF}): the children are groups rather than nodes.
307
+ * @type {Uint16Array}
308
+ */
309
+ node_flags = new Uint16Array(0);
310
+
311
+ /**
312
+ * This page's own traversal metric — sphere xyzw, then `min_self_error`, `max_parent_error`.
313
+ *
314
+ * Format §11.10 makes it equal to node 0's, which is why a traversal that always enters a page
315
+ * at node 0 never reads this and never has to reconcile the two.
316
+ *
317
+ * @type {Float32Array}
318
+ */
319
+ metric = new Float32Array(6);
320
+
208
321
  /**
209
322
  * How many of this page's clusters store a normal per vertex rather than one constant-compressed
210
323
  * word for the whole cluster.
@@ -1 +1 @@
1
- {"version":3,"file":"vgeo_read_header.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js"],"names":[],"mappings":"AA2BA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wCATW,UAAU,GAER,mBAAmB,CA4G/B;AAED;;;;;;;;;;;;;;;GAeG;AACH,+CAJW,UAAU,GACR,MAAM,CA4BlB;AAlLD;;;;;;;GAOG;AACH,kCAFU,MAAM,CAEoC;oCAjBhB,0BAA0B"}
1
+ {"version":3,"file":"vgeo_read_header.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js"],"names":[],"mappings":"AA2BA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wCATW,UAAU,GAER,mBAAmB,CAiH/B;AAED;;;;;;;;;;;;;;;GAeG;AACH,+CAJW,UAAU,GACR,MAAM,CA4BlB;AAvLD;;;;;;;GAOG;AACH,kCAFU,MAAM,CAEoC;oCAjBhB,0BAA0B"}
@@ -90,6 +90,11 @@ export function vgeo_read_header(bytes) {
90
90
  throw new Error(`the file requires feature flags 0x${required.toString(16)}`);
91
91
  }
92
92
 
93
+ // Ignorable by definition: §4 requires a reader to read on through bits it does not know, so
94
+ // nothing is rejected here. It is carried because one bit is defined — the page-size guarantee —
95
+ // and a runtime that allocates fixed-stride slots has to be able to ask for it.
96
+ result.feature_flags_ignorable = view.getUint32(VGEO_HEADER_OFFSET.FEATURE_FLAGS_IGNORABLE, LE);
97
+
93
98
  result.payload_encoding = view.getUint32(VGEO_HEADER_OFFSET.PAYLOAD_ENCODING, LE);
94
99
 
95
100
  if (result.payload_encoding !== VGEO_PAYLOAD_ENCODING_SHADE_MESHLET_V1) {
@@ -1 +1 @@
1
- {"version":3,"file":"vgeo_read_page.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js"],"names":[],"mappings":"AAgCA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,4CAVW,UAAU,cACV,MAAM,GAEJ,QAAQ,CA+EpB;yBA9GwB,eAAe"}
1
+ {"version":3,"file":"vgeo_read_page.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js"],"names":[],"mappings":"AAmCA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,4CAVW,UAAU,cACV,MAAM,GAEJ,QAAQ,CAgFpB;yBA/GwB,eAAe"}
@@ -11,6 +11,9 @@ import { VGEO_FRAME_HEADER_SIZE } from "../frame/VGEO_FRAME_HEADER_SIZE.js";
11
11
  import { VGEO_FRAME_OFFSET } from "../frame/VGEO_FRAME_OFFSET.js";
12
12
  import { vgeo_frame_decode_bound } from "../frame/vgeo_frame_decode_bound.js";
13
13
  import { VGEO_GROUP_RECORD_SIZE } from "../page/VGEO_GROUP_RECORD_SIZE.js";
14
+ import { VGEO_METRIC_OFFSET } from "../page/VGEO_METRIC_OFFSET.js";
15
+ import { VGEO_NODE_OFFSET } from "../page/VGEO_NODE_OFFSET.js";
16
+ import { VGEO_NODE_RECORD_SIZE } from "../page/VGEO_NODE_RECORD_SIZE.js";
14
17
  import { VGEO_PAGE_HEADER_SIZE } from "../page/VGEO_PAGE_HEADER_SIZE.js";
15
18
  import { VGEO_PAGE_MAGIC } from "../frame/VGEO_PAGE_MAGIC.js";
16
19
  import { VGEO_PAGE_OFFSET } from "../page/VGEO_PAGE_OFFSET.js";
@@ -122,11 +125,34 @@ export function vgeo_read_page(frame_bytes, page_index) {
122
125
  read_child_table(result, frame_view, frame);
123
126
  read_page_header(result);
124
127
  read_group_table(result);
128
+ read_node_table(result);
125
129
  read_cluster_table(result);
126
130
 
127
131
  return result;
128
132
  }
129
133
 
134
+ /**
135
+ * One traversal metric (§6.2) out of `view` at `offset`, into three parallel columns at `index`.
136
+ *
137
+ * The same 24 bytes appear in three places — a child-table entry, a page header, a node — which is
138
+ * what lets one reader serve all three and what §11.10/§11.11 cross-check against each other.
139
+ *
140
+ * @param {DataView} view
141
+ * @param {number} offset of the metric's first byte
142
+ * @param {Float32Array} sphere `4 · n`
143
+ * @param {Float32Array} min_self_error
144
+ * @param {Float32Array} max_parent_error
145
+ * @param {number} index
146
+ */
147
+ function read_metric(view, offset, sphere, min_self_error, max_parent_error, index) {
148
+ for (let c = 0; c < 4; c++) {
149
+ sphere[index * 4 + c] = view.getFloat32(offset + VGEO_METRIC_OFFSET.SPHERE + c * 4, LE);
150
+ }
151
+
152
+ min_self_error[index] = view.getFloat32(offset + VGEO_METRIC_OFFSET.MIN_SELF_ERROR, LE);
153
+ max_parent_error[index] = view.getFloat32(offset + VGEO_METRIC_OFFSET.MAX_PARENT_ERROR, LE);
154
+ }
155
+
130
156
  /**
131
157
  * The child table is plaintext inside the frame, never compressed — which is exactly what lets a
132
158
  * traversal read fetch ranges without decoding anything. So it is read from the frame's own bytes
@@ -143,6 +169,9 @@ function read_child_table(page, frame_view, frame) {
143
169
  page.child_frame_offset = new Float64Array(count);
144
170
  page.child_fetch_size = new Uint32Array(count);
145
171
  page.child_decoded_size = new Uint32Array(count);
172
+ page.child_metric_sphere = new Float32Array(count * 4);
173
+ page.child_metric_min_self_error = new Float32Array(count);
174
+ page.child_metric_max_parent_error = new Float32Array(count);
146
175
 
147
176
  for (let i = 0; i < count; i++) {
148
177
  const entry = VGEO_FRAME_HEADER_SIZE + i * VGEO_CHILD_TABLE_ENTRY_SIZE;
@@ -159,7 +188,74 @@ function read_child_table(page, frame_view, frame) {
159
188
 
160
189
  page.child_fetch_size[i] = frame_view.getUint32(entry + VGEO_CHILD_OFFSET.FETCH_SIZE, LE);
161
190
  page.child_decoded_size[i] = frame_view.getUint32(entry + VGEO_CHILD_OFFSET.DECODED_SIZE, LE);
191
+
192
+ read_metric(
193
+ frame_view, entry + VGEO_CHILD_OFFSET.METRIC,
194
+ page.child_metric_sphere,
195
+ page.child_metric_min_self_error,
196
+ page.child_metric_max_parent_error,
197
+ i
198
+ );
199
+ }
200
+ }
201
+
202
+ /**
203
+ * The tree over this page's groups (§6.1).
204
+ *
205
+ * Its extent is checked before it is walked for the same reason the cluster table's is: `node_count`
206
+ * and `node_table_offset` are file bytes, and a page that decoded short would otherwise be read
207
+ * past.
208
+ *
209
+ * @param {VGeoPage} page
210
+ */
211
+ function read_node_table(page) {
212
+ const data = page.data;
213
+
214
+ const count = page.node_count;
215
+
216
+ const table = data.getUint32(VGEO_PAGE_OFFSET.NODE_TABLE_OFFSET, LE);
217
+
218
+ const end = table + count * VGEO_NODE_RECORD_SIZE;
219
+
220
+ if (end > page.bytes.byteLength) {
221
+ throw new Error(
222
+ `page ${page.index}: its ${count} node records end at ${end},`
223
+ + ` past the ${page.bytes.byteLength} bytes it decoded to`
224
+ );
162
225
  }
226
+
227
+ page.node_sphere = new Float32Array(count * 4);
228
+ page.node_min_self_error = new Float32Array(count);
229
+ page.node_max_parent_error = new Float32Array(count);
230
+ page.node_child_first = new Uint16Array(count);
231
+ page.node_child_count = new Uint16Array(count);
232
+ page.node_flags = new Uint16Array(count);
233
+
234
+ for (let i = 0; i < count; i++) {
235
+ const record = table + i * VGEO_NODE_RECORD_SIZE;
236
+
237
+ read_metric(
238
+ data, record + VGEO_NODE_OFFSET.METRIC,
239
+ page.node_sphere, page.node_min_self_error, page.node_max_parent_error, i
240
+ );
241
+
242
+ page.node_child_first[i] = data.getUint16(record + VGEO_NODE_OFFSET.CHILD_FIRST, LE);
243
+ page.node_child_count[i] = data.getUint16(record + VGEO_NODE_OFFSET.CHILD_COUNT, LE);
244
+ page.node_flags[i] = data.getUint16(record + VGEO_NODE_OFFSET.FLAGS, LE);
245
+ }
246
+
247
+ for (let c = 0; c < 4; c++) {
248
+ page.metric[c] = data.getFloat32(
249
+ VGEO_PAGE_OFFSET.METRIC + VGEO_METRIC_OFFSET.SPHERE + c * 4, LE
250
+ );
251
+ }
252
+
253
+ page.metric[4] = data.getFloat32(
254
+ VGEO_PAGE_OFFSET.METRIC + VGEO_METRIC_OFFSET.MIN_SELF_ERROR, LE
255
+ );
256
+ page.metric[5] = data.getFloat32(
257
+ VGEO_PAGE_OFFSET.METRIC + VGEO_METRIC_OFFSET.MAX_PARENT_ERROR, LE
258
+ );
163
259
  }
164
260
 
165
261
  /**
@@ -224,13 +320,16 @@ function read_cluster_table(page) {
224
320
  }
225
321
 
226
322
  page.self_sphere = new Float32Array(count * 4);
323
+ page.parent_sphere = new Float32Array(count * 4);
227
324
  page.bounds_sphere = new Float32Array(count * 4);
325
+ page.aabb = new Float32Array(count * 6);
228
326
  page.self_error = new Float32Array(count);
229
327
  page.parent_error = new Float32Array(count);
230
328
  page.child_ref = new Uint16Array(count);
231
329
  page.child_group = new Uint16Array(count);
232
330
  page.encoding_flags = new Uint32Array(count);
233
331
  page.cluster_payload_offset = new Uint32Array(count);
332
+ page.cluster_payload_size = new Uint32Array(count);
234
333
  page.vertex_count = new Uint8Array(count);
235
334
  page.triangle_count = new Uint8Array(count);
236
335
  page.group_of_cluster = new Uint16Array(count);
@@ -241,10 +340,17 @@ function read_cluster_table(page) {
241
340
  for (let c = 0; c < 4; c++) {
242
341
  page.self_sphere[i * 4 + c] =
243
342
  data.getFloat32(record + VGEO_CLUSTER_OFFSET.SELF_SPHERE + c * 4, LE);
343
+ page.parent_sphere[i * 4 + c] =
344
+ data.getFloat32(record + VGEO_CLUSTER_OFFSET.PARENT_SPHERE + c * 4, LE);
244
345
  page.bounds_sphere[i * 4 + c] =
245
346
  data.getFloat32(record + VGEO_CLUSTER_OFFSET.BOUNDS_SPHERE + c * 4, LE);
246
347
  }
247
348
 
349
+ for (let c = 0; c < 6; c++) {
350
+ page.aabb[i * 6 + c] =
351
+ data.getFloat32(record + VGEO_CLUSTER_OFFSET.AABB + c * 4, LE);
352
+ }
353
+
248
354
  page.self_error[i] = data.getFloat32(record + VGEO_CLUSTER_OFFSET.SELF_ERROR, LE);
249
355
  page.parent_error[i] = data.getFloat32(record + VGEO_CLUSTER_OFFSET.PARENT_ERROR, LE);
250
356
  page.child_ref[i] = data.getUint16(record + VGEO_CLUSTER_OFFSET.CHILD_REF, LE);
@@ -252,6 +358,8 @@ function read_cluster_table(page) {
252
358
  page.encoding_flags[i] = data.getUint32(record + VGEO_CLUSTER_OFFSET.ENCODING_FLAGS, LE);
253
359
  page.cluster_payload_offset[i] =
254
360
  data.getUint32(record + VGEO_CLUSTER_OFFSET.PAYLOAD_OFFSET, LE);
361
+ page.cluster_payload_size[i] =
362
+ data.getUint32(record + VGEO_CLUSTER_OFFSET.PAYLOAD_SIZE, LE);
255
363
  page.vertex_count[i] = data.getUint8(record + VGEO_CLUSTER_OFFSET.VERTEX_COUNT);
256
364
  page.triangle_count[i] = data.getUint8(record + VGEO_CLUSTER_OFFSET.TRIANGLE_COUNT);
257
365
 
@@ -1 +1 @@
1
- {"version":3,"file":"vgeo_validate_container.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js"],"names":[],"mappings":"AA+/CA;;;;;GAKG;AACH,gDAHW,YAAY,GACV,UAAU,EAAE,CAkFxB;6BArlD4B,4CAA4C;2BA8C9C,iBAAiB"}
1
+ {"version":3,"file":"vgeo_validate_container.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js"],"names":[],"mappings":"AAshDA;;;;;GAKG;AACH,gDAHW,YAAY,GACV,UAAU,EAAE,CAkFxB;6BA5mD4B,4CAA4C;2BA+C9C,iBAAiB"}
@@ -14,6 +14,7 @@ import { VGEO_DIRECTORY_FLAG_ROOT_PAGE } from "./directory/VGEO_DIRECTORY_FLAG_R
14
14
  import { VGEO_DIRECTORY_RECORD_SIZE } from "./directory/VGEO_DIRECTORY_RECORD_SIZE.js";
15
15
  import { vgeo_decode_frame_blob } from "./frame/vgeo_decode_frame_blob.js";
16
16
  import { VGEO_ENCODING_FLAGS_MASK } from "./payload/VGEO_ENCODING_FLAGS_MASK.js";
17
+ import { VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES } from "./header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.js";
17
18
  import { VGEO_FORMAT_VERSION } from "./header/VGEO_FORMAT_VERSION.js";
18
19
  import { VGEO_FRAME_ALIGNMENT } from "./frame/VGEO_FRAME_ALIGNMENT.js";
19
20
  import { vgeo_frame_decode_bound } from "./frame/vgeo_frame_decode_bound.js";
@@ -437,6 +438,24 @@ function check_frames(buffer, frames, out) {
437
438
  }
438
439
  }
439
440
 
441
+ buffer.position = VGEO_HEADER_OFFSET.FEATURE_FLAGS_IGNORABLE;
442
+
443
+ const feature_flags_ignorable = buffer.readUint32();
444
+
445
+ buffer.position = VGEO_HEADER_OFFSET.NOMINAL_PAGE_SIZE;
446
+
447
+ const nominal_page_size = buffer.readUint32();
448
+
449
+ // §11.14, and only when the file claims it. Unset, `nominal_page_size` is the advisory build
450
+ // parameter it has always been and there is nothing here to be wrong; set, it is a promise a
451
+ // reader is entitled to size fixed-stride page slots against, and one page past it is that
452
+ // reader's buffer overrun. Every *other* bit of this word is ignored, per §4.
453
+ const bounded_pages = (feature_flags_ignorable & VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES) !== 0;
454
+
455
+ if (bounded_pages && nominal_page_size === 0) {
456
+ out.push(new VGeoDefect(VGEO_DEFECT.HEADER, 'the bounded-pages feature bit is set and nominal_page_size is 0, which no page can be within'));
457
+ }
458
+
440
459
  buffer.position = VGEO_HEADER_OFFSET.ASSET_ID;
441
460
 
442
461
  const asset_id_low = buffer.readUint64();
@@ -471,6 +490,10 @@ function check_frames(buffer, frames, out) {
471
490
  out.push(new VGeoDefect(VGEO_DEFECT.FRAME, `page ${frame.page_index}: decoded_size ${frame.decoded_size} is more than codec ${frame.codec} could produce from ${frame.stored_size} stored bytes`));
472
491
  }
473
492
 
493
+ if (bounded_pages && frame.decoded_size > nominal_page_size) {
494
+ out.push(new VGeoDefect(VGEO_DEFECT.FRAME, `page ${frame.page_index}: decoded_size ${frame.decoded_size} is past the ${nominal_page_size} byte page size this container guarantees`));
495
+ }
496
+
474
497
  if (frame.frame_offset % VGEO_FRAME_ALIGNMENT !== 0) {
475
498
  out.push(new VGeoDefect(VGEO_DEFECT.FRAME, `page ${frame.page_index}: frame_offset ${frame.frame_offset} is not ${VGEO_FRAME_ALIGNMENT}-aligned`));
476
499
  }
@@ -1 +1 @@
1
- {"version":3,"file":"vgeo_write_container.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/format/vgeo_write_container.js"],"names":[],"mappings":"AAgRA;;;;;;;;GAQG;AACH,4CANW,qBAAqB,8BAGnB,YAAY,CA8MxB;6BAne4B,4CAA4C"}
1
+ {"version":3,"file":"vgeo_write_container.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/format/vgeo_write_container.js"],"names":[],"mappings":"AAmTA;;;;;;;;GAQG;AACH,4CANW,qBAAqB,8BAGnB,YAAY,CAmNxB;6BA3gB4B,4CAA4C"}
@@ -12,6 +12,7 @@ import { vgeo_directory_block_count } from "./directory/vgeo_directory_block_cou
12
12
  import { VGEO_DIRECTORY_FLAG_ROOT_PAGE } from "./directory/VGEO_DIRECTORY_FLAG_ROOT_PAGE.js";
13
13
  import { VGEO_DIRECTORY_RECORD_SIZE } from "./directory/VGEO_DIRECTORY_RECORD_SIZE.js";
14
14
  import { vgeo_encode_frame_blob } from "./frame/vgeo_encode_frame_blob.js";
15
+ import { VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES } from "./header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.js";
15
16
  import { VGEO_FORMAT_VERSION } from "./header/VGEO_FORMAT_VERSION.js";
16
17
  import { VGEO_FRAME_ALIGNMENT } from "./frame/VGEO_FRAME_ALIGNMENT.js";
17
18
  import { VGEO_FRAME_HEADER_SIZE } from "./frame/VGEO_FRAME_HEADER_SIZE.js";
@@ -270,6 +271,40 @@ function build_page_blob(page, child_pages) {
270
271
  return buffer.raw_bytes;
271
272
  }
272
273
 
274
+ /**
275
+ * Check the page-size bound the caller stated, and report the feature bits the header should carry.
276
+ *
277
+ * This is the one place in the pipeline that knows what a page actually costs decoded, so it is the
278
+ * one place that can honestly set {@link VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES} — the bit that
279
+ * promises a reader every page fits `nominal_page_size`, and so lets a VRAM tier allocate
280
+ * fixed-stride page slots. The assembler already lays pages out against the cap; this refuses to
281
+ * write a file that claims a size it does not keep, however the page list was produced.
282
+ *
283
+ * A `nominal_page_size` of zero states no size at all — the synthetic containers the reader and
284
+ * residency specs write straight to this function do that — and then there is nothing to check and
285
+ * no promise to make.
286
+ *
287
+ * @param {PageBlob[]} blobs in page order
288
+ * @param {number} nominal_page_size
289
+ * @returns {number} `feature_flags_ignorable`
290
+ */
291
+ function page_size_guarantee(blobs, nominal_page_size) {
292
+ if (nominal_page_size === 0) {
293
+ return 0;
294
+ }
295
+
296
+ blobs.forEach((blob, index) => {
297
+ if (blob.decoded_size > nominal_page_size) {
298
+ throw new Error(
299
+ `virtual geometry: page ${index} decodes to ${blob.decoded_size} bytes, past the`
300
+ + ` ${nominal_page_size} this container states as its page size (VGEO_FORMAT §11.14)`
301
+ );
302
+ }
303
+ });
304
+
305
+ return VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES;
306
+ }
307
+
273
308
  /**
274
309
  * Turn an assembled page list into the finished container.
275
310
  *
@@ -314,6 +349,8 @@ export function vgeo_write_container(pages, options) {
314
349
  return blob;
315
350
  });
316
351
 
352
+ const feature_flags_ignorable = page_size_guarantee(blobs, options.nominal_page_size);
353
+
317
354
  // The level table sits between the header and the root page, so that one fetch of the file's
318
355
  // head brings the header, the whole table, and the always-resident page together.
319
356
  const level_table_size = options.levels.length * VGEO_LEVEL_RECORD_SIZE;
@@ -355,6 +392,9 @@ export function vgeo_write_container(pages, options) {
355
392
  buffer.writeUint16(VGEO_HEADER_SIZE);
356
393
  buffer.writeUint8(VGEO_HASH_ALGO_XXH3);
357
394
 
395
+ buffer.position = VGEO_HEADER_OFFSET.FEATURE_FLAGS_IGNORABLE;
396
+ buffer.writeUint32(feature_flags_ignorable);
397
+
358
398
  buffer.position = VGEO_HEADER_OFFSET.PAYLOAD_ENCODING;
359
399
  buffer.writeUint32(VGEO_PAYLOAD_ENCODING_SHADE_MESHLET_V1);
360
400