@woosh/meep-engine 3.22.0 → 3.23.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 (267) hide show
  1. package/package.json +1 -1
  2. package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts +118 -0
  3. package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts.map +1 -0
  4. package/src/core/geom/3d/hash-grid/PointHashGrid3.js +283 -0
  5. package/src/core/geom/3d/shape/BoxShape3D.d.ts.map +1 -1
  6. package/src/core/geom/3d/shape/BoxShape3D.js +6 -17
  7. package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -1
  8. package/src/core/geom/3d/shape/CapsuleShape3D.js +3 -14
  9. package/src/core/geom/3d/shape/CylinderShape3D.d.ts.map +1 -1
  10. package/src/core/geom/3d/shape/CylinderShape3D.js +3 -21
  11. package/src/core/geom/3d/shape/PlaneShape3D.d.ts +105 -0
  12. package/src/core/geom/3d/shape/PlaneShape3D.d.ts.map +1 -0
  13. package/src/core/geom/3d/shape/PlaneShape3D.js +251 -0
  14. package/src/core/geom/3d/shape/SphereShape3D.js +3 -3
  15. package/src/core/geom/3d/shape/json/shape_to_type.d.ts.map +1 -1
  16. package/src/core/geom/3d/shape/json/shape_to_type.js +3 -0
  17. package/src/core/geom/3d/shape/json/type_adapters.d.ts +14 -0
  18. package/src/core/geom/3d/shape/json/type_adapters.d.ts.map +1 -1
  19. package/src/core/geom/3d/shape/json/type_adapters.js +15 -0
  20. package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts +51 -0
  21. package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts.map +1 -0
  22. package/src/core/geom/3d/shape/sdf/sdf3_box.js +113 -0
  23. package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts +46 -0
  24. package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts.map +1 -0
  25. package/src/core/geom/3d/shape/sdf/sdf3_capsule.js +82 -0
  26. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts +60 -0
  27. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts.map +1 -0
  28. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.js +126 -0
  29. package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts +50 -0
  30. package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts.map +1 -0
  31. package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.js +53 -0
  32. package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts +52 -0
  33. package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts.map +1 -0
  34. package/src/core/geom/3d/shape/sdf/sdf3_plane.js +61 -0
  35. package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts +41 -0
  36. package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts.map +1 -0
  37. package/src/core/geom/3d/shape/sdf/sdf3_sphere.js +71 -0
  38. package/src/core/process/ConcurrencyGate.d.ts +103 -0
  39. package/src/core/process/ConcurrencyGate.d.ts.map +1 -0
  40. package/src/core/process/ConcurrencyGate.js +207 -0
  41. package/src/engine/asset/AssetManager.d.ts +10 -0
  42. package/src/engine/asset/AssetManager.d.ts.map +1 -1
  43. package/src/engine/asset/AssetManager.js +10 -0
  44. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +30 -13
  45. package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts +26 -0
  46. package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts.map +1 -0
  47. package/src/engine/graphics3/pose/collect_entity_playbacks.js +40 -0
  48. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
  49. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +74 -101
  50. package/src/engine/physics/cloth/MEASUREMENTS.md +1287 -4
  51. package/src/engine/physics/cloth/PLAN.md +1967 -1581
  52. package/src/engine/physics/cloth/build/ClothProxy.d.ts +147 -0
  53. package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -0
  54. package/src/engine/physics/cloth/build/ClothProxy.js +207 -0
  55. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +70 -0
  56. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -0
  57. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +256 -0
  58. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +176 -0
  59. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -0
  60. package/src/engine/physics/cloth/collider/ClothColliderIndex.js +435 -0
  61. package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts +12 -0
  62. package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts.map +1 -0
  63. package/src/engine/physics/cloth/collider/ClothColliderKind.js +38 -0
  64. package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts +120 -0
  65. package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts.map +1 -0
  66. package/src/engine/physics/cloth/collider/ClothColliderRecord.js +137 -0
  67. package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts +25 -0
  68. package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -0
  69. package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +190 -0
  70. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +44 -0
  71. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -0
  72. package/src/engine/physics/cloth/collider/cloth_collider_pack.js +173 -0
  73. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +94 -0
  74. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -0
  75. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +275 -0
  76. package/src/engine/physics/cloth/ecs/ClothCollider.d.ts +126 -0
  77. package/src/engine/physics/cloth/ecs/ClothCollider.d.ts.map +1 -0
  78. package/src/engine/physics/cloth/ecs/ClothCollider.js +199 -0
  79. package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +9 -0
  80. package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts.map +1 -0
  81. package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +32 -0
  82. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +114 -0
  83. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -0
  84. package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +243 -0
  85. package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +66 -57
  86. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +109 -1
  87. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  88. package/src/engine/physics/cloth/ecs/ClothInstance.js +479 -363
  89. package/src/engine/physics/cloth/ecs/ClothRig.d.ts +95 -0
  90. package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -0
  91. package/src/engine/physics/cloth/ecs/ClothRig.js +140 -0
  92. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +30 -1
  93. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  94. package/src/engine/physics/cloth/ecs/ClothSystem.js +1021 -773
  95. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +90 -0
  96. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -0
  97. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +374 -0
  98. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts +32 -3
  99. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts.map +1 -1
  100. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.js +283 -254
  101. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +59 -0
  102. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -0
  103. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +328 -0
  104. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +13 -0
  105. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -0
  106. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +288 -0
  107. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +58 -0
  108. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -0
  109. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +199 -0
  110. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +8 -63
  111. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  112. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +317 -645
  113. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +61 -0
  114. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  115. package/src/engine/physics/cloth/ecs/cloth_write_back.js +212 -449
  116. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts +49 -0
  117. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -0
  118. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +115 -0
  119. package/src/engine/physics/cloth/playground/README.md +155 -1
  120. package/src/engine/physics/cloth/playground/collide.html +178 -0
  121. package/src/engine/physics/cloth/playground/collide_build.d.ts +95 -0
  122. package/src/engine/physics/cloth/playground/collide_build.d.ts.map +1 -0
  123. package/src/engine/physics/cloth/playground/collide_build.js +315 -0
  124. package/src/engine/physics/cloth/playground/collide_main.d.ts +2 -0
  125. package/src/engine/physics/cloth/playground/collide_main.d.ts.map +1 -0
  126. package/src/engine/physics/cloth/playground/collide_main.js +720 -0
  127. package/src/engine/physics/cloth/playground/garment.html +182 -0
  128. package/src/engine/physics/cloth/playground/garment_build.d.ts +78 -0
  129. package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -0
  130. package/src/engine/physics/cloth/playground/garment_build.js +359 -0
  131. package/src/engine/physics/cloth/playground/garment_main.d.ts +2 -0
  132. package/src/engine/physics/cloth/playground/garment_main.d.ts.map +1 -0
  133. package/src/engine/physics/cloth/playground/garment_main.js +633 -0
  134. package/src/engine/physics/cloth/solver/ClothState.d.ts +208 -5
  135. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  136. package/src/engine/physics/cloth/solver/ClothState.js +302 -8
  137. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +87 -0
  138. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -0
  139. package/src/engine/physics/cloth/solver/cloth_contact_find.js +343 -0
  140. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +112 -0
  141. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -0
  142. package/src/engine/physics/cloth/solver/cloth_self_find.js +448 -0
  143. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts +4 -1
  144. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
  145. package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +16 -1
  146. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +112 -5
  147. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  148. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +117 -6
  149. package/src/engine/physics/cloth/solver/cloth_step.d.ts +40 -9
  150. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  151. package/src/engine/physics/cloth/solver/cloth_step.js +122 -10
  152. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts +95 -0
  153. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts.map +1 -0
  154. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js +285 -0
  155. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts +129 -0
  156. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -0
  157. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +501 -0
  158. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +75 -0
  159. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -0
  160. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +202 -0
  161. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  162. package/src/shade/playground/vgeo_viewer/README.md +18 -0
  163. package/src/shade/playground/vgeo_viewer/main.js +87 -50
  164. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  165. package/src/shade/renderer/buffer/table/GPUDatabase.js +191 -62
  166. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +94 -2
  167. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  168. package/src/shade/renderer/buffer/table/GPUTypedTable.js +414 -2
  169. package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts +14 -0
  170. package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts.map +1 -0
  171. package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.js +13 -0
  172. package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts +17 -0
  173. package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts.map +1 -0
  174. package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.js +116 -0
  175. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +9 -4
  176. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  177. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +843 -734
  178. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts +12 -0
  179. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts.map +1 -1
  180. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.js +13 -0
  181. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +17 -0
  182. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  183. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +185 -30
  184. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +17 -0
  185. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +141 -24
  186. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +204 -64
  187. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +110 -10
  188. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +19 -0
  189. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts +19 -6
  190. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts.map +1 -1
  191. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.js +26 -7
  192. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +173 -14
  193. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  194. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +458 -51
  195. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts +49 -13
  196. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts.map +1 -1
  197. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.js +52 -14
  198. package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts +20 -0
  199. package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts.map +1 -0
  200. package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.js +19 -0
  201. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts +27 -0
  202. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts.map +1 -0
  203. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.js +48 -0
  204. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts +29 -0
  205. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts.map +1 -0
  206. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.js +60 -0
  207. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts +8 -1
  208. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts.map +1 -1
  209. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.js +32 -2
  210. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +258 -0
  211. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +1 -0
  212. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +723 -0
  213. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +49 -0
  214. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +1 -0
  215. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +50 -0
  216. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  217. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  218. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts +3 -0
  219. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts.map +1 -1
  220. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js +121 -21
  221. package/src/shade/renderer/texture/virtual/README.md +6 -4
  222. package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts.map +1 -1
  223. package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +7 -0
  224. package/src/shade/renderer/texture/virtual/source/VTSourceTiled.d.ts +3 -3
  225. package/src/shade/renderer/texture/virtual/source/VTSourceTiled.js +3 -3
  226. package/src/engine/ecs/system/SystemExecutionPhase.d.ts +0 -9
  227. package/src/engine/ecs/system/SystemExecutionPhase.d.ts.map +0 -1
  228. package/src/engine/graphics/texture/virtual/NOTES.md +0 -128
  229. package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts +0 -6
  230. package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts.map +0 -1
  231. package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.js +0 -5
  232. package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts +0 -49
  233. package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts.map +0 -1
  234. package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.js +0 -264
  235. package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts +0 -44
  236. package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts.map +0 -1
  237. package/src/engine/graphics/texture/virtual/VirtualTextureUsage.js +0 -228
  238. package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts +0 -3
  239. package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts.map +0 -1
  240. package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.js +0 -73
  241. package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts +0 -14
  242. package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts.map +0 -1
  243. package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.js +0 -85
  244. package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts +0 -12
  245. package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts.map +0 -1
  246. package/src/engine/graphics/texture/virtual/debug/UsageDebugView.js +0 -63
  247. package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts +0 -12
  248. package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts.map +0 -1
  249. package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.js +0 -243
  250. package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts +0 -30
  251. package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts.map +0 -1
  252. package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.js +0 -39
  253. package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts +0 -9
  254. package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts.map +0 -1
  255. package/src/engine/graphics/texture/virtual/tile/compose_finger_print.js +0 -24
  256. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts +0 -9
  257. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts.map +0 -1
  258. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.js +0 -26
  259. package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts +0 -11
  260. package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts.map +0 -1
  261. package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.js +0 -12
  262. package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts +0 -7
  263. package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts.map +0 -1
  264. package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.js +0 -16
  265. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts +0 -7
  266. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts.map +0 -1
  267. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.js +0 -35
@@ -1,6 +1,6 @@
1
1
  # `.vgeo` — Virtual Geometry Container Format
2
2
 
3
- Status: **writer and validator implemented; no reader yet.** Companion to
3
+ Status: **writer, validator and reader implemented; no GPU runtime.** Companion to
4
4
  [VIRTUAL_GEOMETRY_DESIGN.md](./VIRTUAL_GEOMETRY_DESIGN.md); every requirement pinned in
5
5
  its §5/§6 is realized here as a concrete field or invariant. Pinned structure below;
6
6
  open details are listed at the end. One `.vgeo` file = one unique geometry's complete
@@ -8,10 +8,21 @@ cluster DAG; instances share the file.
8
8
 
9
9
  The implementation lives beside this document: `format/` is the container — what a file is,
10
10
  how one is written, and `vgeo_validate_container.js`, which audits every §11 invariant in
11
- one — and `build/` is the pipeline that produces it from a `Geometry`, glTF front end
12
- included. The node command line over both is at `tools/geometry/virtual/`. One glTF yields **one file per
11
+ one; `format/read/` reads one a page at a time; and `build/` is the pipeline that produces
12
+ it from a `Geometry`, glTF front end included. The node command line over the writer and the
13
+ validator is at `meep-engine/tools/geometry/virtual/`. One glTF yields **one file per
13
14
  primitive**, in object space, with the scene's placements written to a sidecar manifest
14
- rather than baked in. The runtime side (pager, residency, cut pass) is still design only.
15
+ rather than baked in.
16
+
17
+ **Where the reader stops**, because it is the first thing a runtime needs to know. `format/read/`
18
+ implements the *mechanics* of §10 — cold start, one fetch per page from the byte range its parent
19
+ wrote down, want dedup, activation, eviction, and the mandatory reject rules of §4 and §5. It
20
+ implements none of the *policy*: no fetch scheduler, no budgets, no touch-LRU, no quarantine, and
21
+ the pinning rules are left to whoever manages residency. It also decodes neither the node table
22
+ (§6.1) nor the child-table traversal metric (§5, §6.2) — `VGeoPage` records `node_count` and stops
23
+ — because nothing consumes them yet; a GPU cut pass is the first thing that would.
24
+ `shade/playground/vgeo_viewer/` drives the reader end to end, and its `select_cut.js` is a CPU
25
+ reference traversal of the cut rule this format was shaped around.
15
26
 
16
27
  ## 1. Design constraints (inherited, binding)
17
28
 
@@ -98,8 +109,8 @@ All u64/u128 fields are naturally 8-byte aligned.
98
109
  | offset | type | field | notes |
99
110
  |-------:|-----------|--------------------------|-------|
100
111
  | 0 | u32 | magic | `'VGEO'` = 0x4F454756 |
101
- | 4 | u16 | format_version | breaking layout changes only |
102
- | 6 | u16 | min_reader_version | reader MUST reject if its version is lower |
112
+ | 4 | u16 | format_version | 3 today; breaking layout changes only |
113
+ | 6 | u16 | min_reader_version | 3 today; reader MUST reject if its version is lower |
103
114
  | 8 | u16 | header_size | = 256 |
104
115
  | 10 | u8 | hash_algo | 0 = xxHash3; readers MUST reject unknown values |
105
116
  | 11 | u8 | reserved | |
@@ -378,7 +389,7 @@ in the cut test):
378
389
  | 56 | [f32; 6] | aabb | this cluster's object-space AABB — culling, GPU metadata `bounds_box`, and the (future) dequantization grid |
379
390
  | 80 | u16 | child_ref | index into this frame's child table; `SAME_PAGE` when the child group is in this page; `NO_CHILD` for leaves |
380
391
  | 82 | u16 | child_group | group index within the child page (or this page, for `SAME_PAGE`); `NO_GROUP` for leaves |
381
- | 84 | u32 | cone_reserved | reserved for backface-cone culling — **write 0**. No cull pass consumes a cone today and the producer needs a `BinaryTopology` port; the sub-encoding is pinned together with that pass, not before |
392
+ | 84 | u32 | cone_reserved | reserved — **write 0**. Named for a backface-cone cull pass that is now **declined outright** (design §9, plan §5), so no sub-encoding will ever be pinned here. Kept rather than reclaimed: removing it moves `format_version`, a constant-zero column costs nothing after the page codec, and there are ten more reserved bytes beside it at 102 and 104 anyway. A candidate to rename and reuse the next time the version moves for some other reason |
382
393
  | 88 | u32 | encoding_flags | frozen bit table in §8 |
383
394
  | 92 | u32 | payload_offset | into this page's payload section; ≡ 0 (mod 4) |
384
395
  | 96 | u32 | payload_size | bytes; ≡ 0 (mod 4) |
@@ -462,21 +473,46 @@ the directory fetch it at block granularity and MUST verify.
462
473
 
463
474
  ## 10. Reader requirements
464
475
 
465
- Standard runtime operation is **pure traversal** — the directory is not involved:
476
+ Standard runtime operation is **pure traversal** — the directory is not involved. Every item
477
+ below is marked with what `format/read/` does about it: *(shipped)*, *(open)*, or a split where
478
+ the mechanics are there and the policy is the caller's. Where a requirement is *policy*, the
479
+ implementation is `renderer/geometry/virtual/residency/` rather than `format/read/` — a sibling of
480
+ the format, not part of it, because what may be resident and what may be in flight are questions
481
+ about a scene and not about a container.
466
482
 
467
- - Cold start: fetch `[0, 256)`, verify `header_checksum`, magic, versions (§4 reject
483
+ - **Cold start** *(shipped)*: fetch `[0, 256)`, verify `header_checksum`, magic, versions (§4 reject
468
484
  rules), then fetch `[root_page_offset, root_page_offset + root_page_fetch_size)` — the
469
485
  level table (§4.1) sits between the two, so a head prefix covering both brings the whole
470
486
  always-resident set in one request. The root frame's `decoded_size` MUST equal
471
487
  `root_page_decoded_size` and its frame extent MUST match `root_page_fetch_size`, else
472
488
  reject. Or speculatively fetch one larger head prefix — coarse-first layout makes every
473
489
  prefix byte useful.
474
- - **Refinement**: a want is a `child_ref` in an installed page; its child-table entry
490
+
491
+ **How much of that prefix to keep, and for how long, is not a free choice at scale.** The
492
+ always-resident set is small: invariant §11.7 puts exactly one root cluster in the file and the
493
+ assembler gives the root page the complete topmost level, so a measured root page is one cluster —
494
+ 1,732 B and 1,472 B on two torus builds, header and level table included coming to about 2.4 KB.
495
+ A prefix past that is speculation about the *next* band, and at the hundreds-of-KB pages design §5
496
+ targets it buys one page. `VGeoReadOptions.head_prefix_bytes` therefore defaults to 64 KiB rather
497
+ than the 256 KiB it did, and the reader **releases the prefix** the first time a read falls
498
+ outside it (`VGeoContainerReader.release_head`, and `head_bytes` to see it). Measured, at the old
499
+ default a 256 KiB prefix over a 22 MB container covered 105 of its 4,000 pages and served nothing
500
+ after those installed — while sitting outside `resident_bytes` and outside anything `evict` could
501
+ reach, which across a thousand open assets was a quarter of a gigabyte no budget could see.
502
+ - **Refinement** *(shipped)*: a want is a `child_ref` in an installed page; its child-table entry
475
503
  carries the exact byte range — one round-trip per cold page, no metadata fetch ever.
476
504
  Wants dedup on `page_index` across clusters, groups, and instances. A want whose
477
505
  target page is **already installed** resolves as an activation recheck of the
478
506
  referenced group (below), never a fetch.
479
- - **Activation (closure without dependency lists)** — the selectable invariant:
507
+
508
+ A want that goes stale mid-flight is cancellable: `VGeoByteSource.read` takes a per-read
509
+ `AbortSignal`, `vgeo_fetch_byte_source` passes it to `fetch` alongside the source's own, and
510
+ `VGeoContainerReader.cancel` abandons one page's request without touching the others.
511
+ **What a stale want does, decided:** it is aborted while it can still be aborted, and installed
512
+ once it cannot — the bytes are already paid for, and refusing to keep them costs the fetch *and*
513
+ the page. An arrival nobody wanted enters residency untouched, which under LRU on last-touched
514
+ makes it the first eviction candidate and free if the camera comes back.
515
+ - **Activation (closure without dependency lists)** *(shipped)* — the selectable invariant:
480
516
 
481
517
  *A group `g` is selectable iff every one of its `parent_cluster_count` references is
482
518
  live — the referencing cluster's page is installed and that cluster's own group is
@@ -497,30 +533,112 @@ Standard runtime operation is **pure traversal** — the directory is not involv
497
533
  ancestors keep covering that surface — **no holes and no double-draw, in any arrival
498
534
  order**, because a group never draws before all pages holding its parents are
499
535
  installed and selectable.
500
- - **In-flight protection**: a fetch discovered through parent page P pins P until the
536
+ - **In-flight protection** *(open)*: a fetch discovered through parent page P pins P until the
501
537
  child installs — known at queue time, purely local. Arrivals verify the
502
538
  identity-seeded frame checksum; activation makes any arrival order safe beyond that.
503
- - **Eviction**: within each residency tier, a page is evictable only while it has no
504
- resident child pages in that tier — checked against its own child table (`SAME_PAGE`
505
- references never pin). Leaves-first order emerges from the rule; the root page is
506
- pinned.
507
- - Verify every ranged response is `206` with the requested `Content-Range`; a `200`
539
+ The reader dedups in-flight fetches by page index but pins nothing.
540
+ Still open, and now for a nameable reason rather than for want of an owner: a `VGeoPageWant`
541
+ carries the page it names and not the page it was *discovered through*, so neither the reader nor
542
+ the manager can pin P without the cut telling them which P it was. It is an efficiency item and not
543
+ a correctness one — evicting P while its child is on the wire wastes the fetch, because the child
544
+ installs non-selectable and activation is safe at every arrival order — and closing it means adding
545
+ the source page to the want, which is a change to the cut as much as to the reader.
546
+ - **Eviction** *(mechanics shipped in the reader, policy shipped above it)*: within each residency tier, a page is
547
+ evictable only while it has no resident child pages in that tier — checked against its own
548
+ child table (`SAME_PAGE` references never pin). Leaves-first order emerges from the rule;
549
+ the root page is pinned. `VGeoContainerReader.evict` does the dropping and the activation
550
+ retraction that goes with it — deliberately including the case where a caller evicts against
551
+ this rule, where the cascade is what stops an orphaned child page from staying drawable — but
552
+ it chooses nothing: which page to drop, and when, is the budget owner's.
553
+ `VGeoContainerReader.resident_child_count` is the lookup the rule is written in terms of, and it is
554
+ the whole of what the reader contributes.
555
+ - **The budget owner** *(shipped, above the reader)*: `VGeoResidencyManager`. Readers register with
556
+ one; it holds the RAM tier's byte budget across every registered reader, admits a want against it
557
+ *before* the fetch out of the `decoded_size` the child table already carries, and evicts on the
558
+ rule above ordered by design §6's LRU on **last-touched** with a protect window no shorter than
559
+ feedback latency. It reaches nothing private: it is written entirely against the reader's public
560
+ surface, which is the test that the split is real rather than nominal.
561
+
562
+ A shared **fetch scheduler** comes with it, and has to: `VGeoReadOptions.max_concurrent_fetches`
563
+ bounds one reader and cannot do better, and four readers at that cap were measured issuing sixteen
564
+ concurrent range requests, eight readers at the default 6 issuing 48. `VGeoResidencyManager`
565
+ holds one total across every reader in a single `ConcurrencyGate` (`core/process/`), as one
566
+ priority queue — so a want's priority, which is pixels of projected error and therefore
567
+ comparable across assets by construction, is compared globally rather than within whichever
568
+ reader happened to ask first.
569
+
570
+ **Most of that shape already exists in this engine twice, and the bullet is more useful read as
571
+ the third one than as new work.** `renderer/texture/virtual/VTPhysicalCache` keeps a
572
+ `#last_touch` stamp per slot, a lock flag for slots that may never go, and
573
+ `find_eviction_candidate(current_frame, protect_window)` — LRU on last-touch under a protect
574
+ window justified by feedback latency, which is the rule above. Design §6 said so when it pinned
575
+ that rule ("the VT system already keys on touch for this reason"), so the resemblance is
576
+ convergent by instruction rather than accidental. `engine/asset/AssetManager` caps concurrent
577
+ top-level loads on `load_concurrency` for the reason the gate holds a total, and inverts
578
+ priority into a `BinaryHeap` the same way in `get_pending_asset_priority_score` — being the
579
+ third place to want that, and the second to write that inversion, is why the gate is now
580
+ `core/process/ConcurrencyGate` rather than a file in this directory, and `AssetManager` keeps
581
+ its own queue anyway for the reasons its `load_concurrency` doc records.
582
+ `VirtualTextureManager` caps `max_concurrent_loads` at 32 and drops queued requests untouched
583
+ for `queue_stale_window` frames, which is a stale-want policy of the kind `cancel` answers here.
584
+
585
+ **The narrow claim that survives that** is a *byte* budget across *several* readers, admitted
586
+ against before the fetch: `VTPhysicalCache` budgets a count of fixed-size slots and
587
+ `AssetManager` budgets nothing and evicts nothing. The retry-into-quarantine and the per-fetch
588
+ `AbortSignal` above are likewise new here — `AssetManager` records a failure and lets a later
589
+ `get` retry, and neither precedent can abort one request. Granularity is why the pages are not
590
+ simply `AssetManager` entries: an `AssetDescription` is a path and a type, where a page is a
591
+ byte range in a container the format gives no global id to (a cluster is a page plus an index),
592
+ at the 4,000 and 20,000 pages per container measured above and a thousand assets open at once.
593
+ - *(shipped)* Verify every ranged response is `206` with the requested `Content-Range`; a `200`
508
594
  means the server ignored the range — abort the transfer immediately (design §6).
509
- - Verify frame checksums (identity-seeded, §5) before decode, and `decoded_size`
595
+ `vgeo_fetch_byte_source` checks the status *and* the returned range: a proxy can answer 206
596
+ with a range other than the one asked for.
597
+ - *(shipped)* Verify frame checksums (identity-seeded, §5) before decode, and `decoded_size`
510
598
  against the child-table entry used to fetch and against the codec's decode bound
511
599
  (§5) before allocating for it. On mismatch: bounded retries with
512
600
  backoff, then **quarantine** the page — the clamped cut keeps a coarse stand-in
513
601
  correct indefinitely — and surface telemetry. Never retry-loop: corruption at a
514
602
  content-addressed URL is deterministic.
515
- - After install, stamp each cluster's selection row with its own page index and its
516
- child page index/group (touch and want emission, design §6/§7).
517
- - Fetch batching: coalesce adjacent wanted pages into contiguous single ranges; ranges
603
+ The decode bound and the exact-length decode are unconditional. The frame checksum is
604
+ `VGeoReadOptions.verify_frames`, off by default because a tool reading a file it just built is not
605
+ defending against a network — a runtime registering a reader with `VGeoResidencyManager` should
606
+ turn it on, and it is what lets the retries see corruption rather than only outages.
607
+ Retry and backoff are `fetch_retries` (2) and `fetch_retry_backoff_ms` (50, doubling); after them
608
+ the page enters `VGeoContainerReader.quarantine()` with its reason and is never fetched again, and
609
+ `install_wants` skips it rather than failing the batch — one bad page out of a thousand assets'
610
+ worth costs exactly that page. *When* to lift a quarantine is policy and is not the reader's:
611
+ a checksum that failed at a content-addressed URL will fail again, while a run of 503s from one
612
+ edge node is a different thing that a manager watching other assets arrive can tell apart, so
613
+ `clear_quarantine` exists and `VGeoResidencyManager.clear_quarantines` is who calls it.
614
+ - *(open)* After install, stamp each cluster's selection row with its own page index and its
615
+ child page index/group (touch and want emission, design §6/§7). There is no selection buffer
616
+ yet; `VGeoPage` keeps a page's tables and the traversal reads them directly.
617
+ - *(open)* Fetch batching: coalesce adjacent wanted pages into contiguous single ranges; ranges
518
618
  never cross a band boundary by construction (coarse-first ordering), so coalescing
519
619
  lives within bands — the within-band spatial curve (§12) is what carries fetch
520
620
  locality and must be chosen with that as a criterion. Fetching through small unwanted
521
621
  gaps is permitted under an implementation waste threshold.
522
- - Never assume `nominal_page_size`; per-page sizes come from child tables (traversal),
523
- frames (prefix scan), or the directory (special tasks).
622
+ - *(shipped)* Never assume `nominal_page_size`; per-page sizes come from child tables
623
+ (traversal), frames (prefix scan), or the directory (special tasks).
624
+ - *(shipped)* **Nothing a runtime holds may be able to read the whole file.** The whole-file audit
625
+ (§11, every checksum, the directory against a frame scan) and the install-every-page sweep are in
626
+ `format/read/tool/` as `vgeo_audit_container` and `vgeo_install_all_pages`, not on the reader —
627
+ `VGeoContainerReader.validate` and `.install_all_pages` remain as deprecated shims for the
628
+ playground and the specs, and they reach the tools through a dynamic import so that a bundle that
629
+ only opens containers does not carry the validator at all. The audit takes the container as one
630
+ `ArrayBuffer`, because every §11 invariant is a cross-check between two places in the file; that is
631
+ a ceiling and not a slope, so it refuses above `VGEO_MAX_AUDIT_BYTES` (1 GiB) naming the size,
632
+ rather than failing in the allocator. Measured: a 514 MiB container audited in 19.4 s, and
633
+ installing every page of a 2,000-page container of 544 KB pages made 514 MiB resident in 210 ms.
634
+ - *(shipped)* The reverse-reference index of the activation rule is bounded by the **residency
635
+ frontier**, not by how many pages a session has visited, and it is worth knowing which because it
636
+ has the shape of an index that leaks. An entry exists only while a resident, selectable cluster
637
+ refers into an absent page, and install/activation and evict/deactivation are symmetric. Measured
638
+ on a 20,000-page container with the 3,280 pages of its eight coarse bands pinned resident:
639
+ `pending_reference_page_count` was 6,561 after pinning and still 6,561 after touring all 6,561
640
+ pages of the band below them a window at a time and evicting each window. Dropping the pinned
641
+ pages too leaves 3.
524
642
 
525
643
  Build consequence (accepted): child tables hold downstream offsets — the format is
526
644
  optimized for reading, and the builder pays for it. Preferred strategy: emit frames
@@ -603,5 +721,4 @@ clustering and simplification dominate regardless.
603
721
  - Spatial ordering curve within a level band (Morton over group centroids is the
604
722
  default candidate; chosen with fetch-coalescing locality as an explicit criterion,
605
723
  §10).
606
- - Backface-cone cull pass and, with it, the `cone_reserved` sub-encoding.
607
724
  - Multi-geometry containers (v1: one geometry per file; scenes reference many files).