@woosh/meep-engine 3.59.0 → 3.60.1

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 (326) hide show
  1. package/package.json +1 -1
  2. package/src/shade/playground/probe_clipmap/index.html +12 -0
  3. package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
  4. package/src/shade/playground/probe_clipmap/main.js +5 -0
  5. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  6. package/src/shade/renderer/Renderer.js +4 -6
  7. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +63 -1
  8. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  9. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +228 -16
  10. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +27 -4
  11. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  12. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +526 -23
  13. package/src/shade/renderer/geometry/sdf/cards/MeshCardCaptureMode.d.ts +11 -0
  14. package/src/shade/renderer/geometry/sdf/cards/MeshCardCaptureMode.d.ts.map +1 -0
  15. package/src/shade/renderer/geometry/sdf/cards/MeshCardCaptureMode.js +21 -0
  16. package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.d.ts +65 -0
  17. package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.d.ts.map +1 -0
  18. package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.js +376 -0
  19. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_capture.d.ts +7 -3
  20. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_capture.d.ts.map +1 -1
  21. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_capture.js +70 -6
  22. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_args.d.ts +20 -0
  23. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_args.d.ts.map +1 -0
  24. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_args.js +80 -0
  25. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_scatter.d.ts +18 -0
  26. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_scatter.d.ts.map +1 -0
  27. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_scatter.js +113 -0
  28. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts +47 -0
  29. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts.map +1 -0
  30. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.js +80 -0
  31. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts +91 -0
  32. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts.map +1 -0
  33. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.js +902 -0
  34. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts +16 -0
  35. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts.map +1 -0
  36. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.js +67 -0
  37. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts +17 -0
  38. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts.map +1 -0
  39. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.js +145 -0
  40. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts +12 -0
  41. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts.map +1 -0
  42. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.js +105 -0
  43. package/src/shade/renderer/global_illumination/probe/octahedral/shader_lpv_build_gbuffer.d.ts.map +1 -1
  44. package/src/shade/renderer/global_illumination/probe/octahedral/shader_lpv_build_gbuffer.js +2 -1
  45. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +3 -9
  46. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  47. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +13 -31
  48. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +764 -48
  49. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +410 -0
  50. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +3 -2
  51. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  52. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +4 -3
  53. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +41 -17
  54. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
  55. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +57 -33
  56. package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.d.ts +11 -3
  57. package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.d.ts.map +1 -1
  58. package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.js +13 -4
  59. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +9 -18
  60. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
  61. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +8 -10
  62. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap.d.ts +12 -0
  63. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap.d.ts.map +1 -1
  64. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap.js +28 -0
  65. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts +1 -29
  66. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts.map +1 -1
  67. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js +1 -74
  68. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.d.ts +161 -0
  69. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.d.ts.map +1 -0
  70. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.js +219 -0
  71. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.d.ts +1 -8
  72. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.d.ts.map +1 -1
  73. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.js +1 -9
  74. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MeshSDFBrickProvider.d.ts +40 -12
  75. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MeshSDFBrickProvider.d.ts.map +1 -1
  76. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MeshSDFBrickProvider.js +373 -31
  77. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts +2 -1
  78. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts.map +1 -1
  79. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.js +2 -1
  80. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_texel.d.ts +15 -8
  81. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_texel.d.ts.map +1 -1
  82. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_texel.js +28 -14
  83. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.d.ts +23 -0
  84. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.d.ts.map +1 -0
  85. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.js +66 -0
  86. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_batch.d.ts +29 -0
  87. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_batch.d.ts.map +1 -0
  88. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_batch.js +210 -0
  89. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_command.d.ts +29 -0
  90. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_command.d.ts.map +1 -0
  91. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_command.js +86 -0
  92. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.d.ts +41 -0
  93. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.d.ts.map +1 -0
  94. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.js +439 -0
  95. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_resolve.d.ts +23 -0
  96. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_resolve.d.ts.map +1 -0
  97. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_resolve.js +135 -0
  98. package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.d.ts +3 -1
  99. package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.d.ts.map +1 -1
  100. package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.js +12 -3
  101. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +21 -18
  102. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  103. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +254 -73
  104. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +149 -8
  105. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
  106. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +181 -13
  107. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +179 -7
  108. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
  109. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +412 -31
  110. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.js +4 -4
  111. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
  112. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +4 -3
  113. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +36 -10
  114. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
  115. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +218 -29
  116. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.d.ts +5 -1
  117. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.d.ts.map +1 -1
  118. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.js +24 -14
  119. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +15 -6
  120. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts.map +1 -1
  121. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +21 -22
  122. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_guide.d.ts +36 -0
  123. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_guide.d.ts.map +1 -0
  124. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_guide.js +257 -0
  125. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.d.ts +18 -7
  126. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.d.ts.map +1 -1
  127. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +157 -51
  128. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_order.d.ts +23 -0
  129. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_order.d.ts.map +1 -0
  130. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_order.js +110 -0
  131. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts +24 -2
  132. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts.map +1 -1
  133. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.js +90 -10
  134. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.d.ts +45 -0
  135. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.d.ts.map +1 -0
  136. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.js +205 -0
  137. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +1 -1
  138. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts +16 -3
  139. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts.map +1 -1
  140. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +55 -10
  141. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts +19 -4
  142. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts.map +1 -1
  143. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js +60 -6
  144. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts +10 -9
  145. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  146. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +32 -39
  147. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts +21 -14
  148. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
  149. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +100 -30
  150. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace_command.d.ts +6 -2
  151. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace_command.d.ts.map +1 -1
  152. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace_command.js +26 -10
  153. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.d.ts +3 -2
  154. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.d.ts.map +1 -1
  155. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.js +12 -12
  156. package/src/shade/renderer/gpu_primitive/sort/SORT_DIGIT_SETTINGS_STRUCT.d.ts +10 -0
  157. package/src/shade/renderer/gpu_primitive/sort/SORT_DIGIT_SETTINGS_STRUCT.d.ts.map +1 -0
  158. package/src/shade/renderer/gpu_primitive/sort/SORT_DIGIT_SETTINGS_STRUCT.js +21 -0
  159. package/src/shade/renderer/gpu_primitive/sort/SORT_PASS_SETTINGS_STRUCT.d.ts +5 -2
  160. package/src/shade/renderer/gpu_primitive/sort/SORT_PASS_SETTINGS_STRUCT.d.ts.map +1 -1
  161. package/src/shade/renderer/gpu_primitive/sort/SORT_PASS_SETTINGS_STRUCT.js +31 -23
  162. package/src/shade/renderer/gpu_primitive/sort/SORT_SIZE_STRUCT.d.ts +10 -0
  163. package/src/shade/renderer/gpu_primitive/sort/SORT_SIZE_STRUCT.d.ts.map +1 -0
  164. package/src/shade/renderer/gpu_primitive/sort/SORT_SIZE_STRUCT.js +22 -0
  165. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_constants.d.ts +9 -0
  166. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_constants.d.ts.map +1 -0
  167. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_constants.js +18 -0
  168. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_digit.d.ts +8 -3
  169. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_digit.d.ts.map +1 -1
  170. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_digit.js +41 -32
  171. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_histogram_tile.d.ts +31 -0
  172. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_histogram_tile.d.ts.map +1 -0
  173. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_histogram_tile.js +71 -0
  174. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_scatter_tile.d.ts +47 -0
  175. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_scatter_tile.d.ts.map +1 -0
  176. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_scatter_tile.js +210 -0
  177. package/src/shade/renderer/gpu_primitive/sort/defs.d.ts +5 -4
  178. package/src/shade/renderer/gpu_primitive/sort/defs.d.ts.map +1 -1
  179. package/src/shade/renderer/gpu_primitive/sort/defs.js +5 -4
  180. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +56 -15
  181. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  182. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +410 -61
  183. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts +4 -1
  184. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts.map +1 -1
  185. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.js +16 -42
  186. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram_indirect.d.ts +15 -0
  187. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram_indirect.d.ts.map +1 -0
  188. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram_indirect.js +60 -0
  189. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_prepare.d.ts +25 -0
  190. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_prepare.d.ts.map +1 -0
  191. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_prepare.js +89 -0
  192. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts +3 -8
  193. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts.map +1 -1
  194. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.js +28 -160
  195. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter_indirect.d.ts +12 -0
  196. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter_indirect.d.ts.map +1 -0
  197. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter_indirect.js +74 -0
  198. package/src/shade/renderer/gpu_primitive/sort/verify_radix_sort.d.ts +3 -1
  199. package/src/shade/renderer/gpu_primitive/sort/verify_radix_sort.d.ts.map +1 -1
  200. package/src/shade/renderer/gpu_primitive/sort/verify_radix_sort.js +387 -188
  201. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.js +1 -1
  202. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.js +1 -1
  203. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  204. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +90 -72
  205. package/src/shade/renderer/material/resident/RESIDENT_MATERIAL_TEXTURE_LAYOUT.d.ts +5 -0
  206. package/src/shade/renderer/material/resident/RESIDENT_MATERIAL_TEXTURE_LAYOUT.d.ts.map +1 -1
  207. package/src/shade/renderer/material/resident/RESIDENT_MATERIAL_TEXTURE_LAYOUT.js +9 -0
  208. package/src/shade/renderer/path_tracer/shader/INDIRECT_TEXTURE_FILTER.d.ts +13 -0
  209. package/src/shade/renderer/path_tracer/shader/INDIRECT_TEXTURE_FILTER.d.ts.map +1 -0
  210. package/src/shade/renderer/path_tracer/shader/INDIRECT_TEXTURE_FILTER.js +14 -0
  211. package/src/shade/renderer/path_tracer/shader/IndirectTextureFilter.d.ts +10 -0
  212. package/src/shade/renderer/path_tracer/shader/IndirectTextureFilter.d.ts.map +1 -0
  213. package/src/shade/renderer/path_tracer/shader/IndirectTextureFilter.js +15 -0
  214. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_tangent_normal.d.ts +4 -3
  215. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_tangent_normal.d.ts.map +1 -1
  216. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_tangent_normal.js +6 -5
  217. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture.d.ts +17 -2
  218. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture.d.ts.map +1 -1
  219. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture.js +25 -57
  220. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_exact.d.ts +13 -0
  221. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_exact.d.ts.map +1 -0
  222. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_exact.js +70 -0
  223. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_stochastic.d.ts +10 -0
  224. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_stochastic.d.ts.map +1 -0
  225. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_stochastic.js +59 -0
  226. package/src/shade/renderer/path_tracer/shader/chunk_indirect_texture_load.d.ts +12 -0
  227. package/src/shade/renderer/path_tracer/shader/chunk_indirect_texture_load.d.ts.map +1 -0
  228. package/src/shade/renderer/path_tracer/shader/chunk_indirect_texture_load.js +49 -0
  229. package/src/shade/renderer/path_tracer/shader/chunk_ray_hit_to_opacity.d.ts.map +1 -1
  230. package/src/shade/renderer/path_tracer/shader/chunk_ray_hit_to_opacity.js +1 -0
  231. package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.d.ts.map +1 -1
  232. package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.js +1 -0
  233. package/src/shade/renderer/path_tracer/shader/chunk_sample_material.d.ts.map +1 -1
  234. package/src/shade/renderer/path_tracer/shader/chunk_sample_material.js +2 -1
  235. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts +7 -0
  236. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  237. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +15 -6
  238. package/src/shade/renderer/scene/GPUSceneContext.d.ts +7 -1
  239. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  240. package/src/shade/renderer/scene/GPUSceneContext.js +26 -1
  241. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts +7 -7
  242. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts.map +1 -1
  243. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.js +262 -294
  244. package/src/shade/renderer/shader/chunk/filter/MULTISCALE_MEAN_STRUCT.d.ts +9 -0
  245. package/src/shade/renderer/shader/chunk/filter/MULTISCALE_MEAN_STRUCT.d.ts.map +1 -0
  246. package/src/shade/renderer/shader/chunk/filter/MULTISCALE_MEAN_STRUCT.js +21 -0
  247. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts +43 -0
  248. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts.map +1 -0
  249. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js +87 -0
  250. package/src/shade/renderer/shader/chunk/noise/r/chunk_r2_canonical.d.ts +7 -1
  251. package/src/shade/renderer/shader/chunk/noise/r/chunk_r2_canonical.d.ts.map +1 -1
  252. package/src/shade/renderer/shader/chunk/noise/r/chunk_r2_canonical.js +1 -1
  253. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_reserve_workgroup.d.ts +21 -0
  254. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_reserve_workgroup.d.ts.map +1 -0
  255. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_reserve_workgroup.js +42 -0
  256. package/src/shade/renderer/wind/GPUSceneWind.d.ts +1 -1
  257. package/src/shade/wgsl/emulator/CPUBitmapData.d.ts +19 -0
  258. package/src/shade/wgsl/emulator/CPUBitmapData.d.ts.map +1 -1
  259. package/src/shade/wgsl/emulator/CPUBitmapData.js +27 -0
  260. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  261. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +65 -19
  262. package/src/view/elements/progress/segmented/GhostTrail.d.ts +116 -0
  263. package/src/view/elements/progress/segmented/GhostTrail.d.ts.map +1 -0
  264. package/src/view/elements/progress/segmented/GhostTrail.js +280 -0
  265. package/src/view/elements/progress/segmented/RESOURCE_BAR_SEGMENTS.d.ts +3 -1
  266. package/src/view/elements/progress/segmented/RESOURCE_BAR_SEGMENTS.d.ts.map +1 -1
  267. package/src/view/elements/progress/segmented/RESOURCE_BAR_SEGMENTS.js +3 -1
  268. package/src/view/elements/progress/segmented/SEGMENT_TIERS_DEFAULT.d.ts +11 -0
  269. package/src/view/elements/progress/segmented/SEGMENT_TIERS_DEFAULT.d.ts.map +1 -0
  270. package/src/view/elements/progress/segmented/SEGMENT_TIERS_DEFAULT.js +15 -0
  271. package/src/view/elements/progress/segmented/SegmentDefinition.d.ts +3 -0
  272. package/src/view/elements/progress/segmented/SegmentDefinition.d.ts.map +1 -1
  273. package/src/view/elements/progress/segmented/SegmentDefinition.js +3 -0
  274. package/src/view/elements/progress/segmented/SegmentTier.d.ts +38 -0
  275. package/src/view/elements/progress/segmented/SegmentTier.d.ts.map +1 -0
  276. package/src/view/elements/progress/segmented/SegmentTier.js +50 -0
  277. package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts +163 -10
  278. package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts.map +1 -1
  279. package/src/view/elements/progress/segmented/SegmentedResourceBarView.js +442 -101
  280. package/src/view/elements/progress/segmented/playground/index.html +78 -0
  281. package/src/view/elements/progress/segmented/playground/main.d.ts +2 -0
  282. package/src/view/elements/progress/segmented/playground/main.d.ts.map +1 -0
  283. package/src/view/elements/progress/segmented/playground/main.js +173 -0
  284. package/src/view/elements/progress/segmented/segment_cell_layout.d.ts +48 -0
  285. package/src/view/elements/progress/segmented/segment_cell_layout.d.ts.map +1 -0
  286. package/src/view/elements/progress/segmented/segment_cell_layout.js +75 -0
  287. package/src/view/elements/progress/segmented/segment_notch_place.d.ts +18 -0
  288. package/src/view/elements/progress/segmented/segment_notch_place.d.ts.map +1 -0
  289. package/src/view/elements/progress/segmented/segment_notch_place.js +28 -0
  290. package/src/view/elements/progress/segmented/segment_tick_positions.d.ts +32 -0
  291. package/src/view/elements/progress/segmented/segment_tick_positions.d.ts.map +1 -0
  292. package/src/view/elements/progress/segmented/segment_tick_positions.js +103 -0
  293. package/src/view/elements/progress/segmented/segmented-resource-bar.css +142 -0
  294. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.d.ts +0 -35
  295. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.d.ts.map +0 -1
  296. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.js +0 -238
  297. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.d.ts +0 -99
  298. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.d.ts.map +0 -1
  299. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.js +0 -139
  300. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.d.ts +0 -65
  301. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.d.ts.map +0 -1
  302. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.js +0 -393
  303. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.d.ts +0 -17
  304. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.d.ts.map +0 -1
  305. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.js +0 -36
  306. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.d.ts +0 -29
  307. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.d.ts.map +0 -1
  308. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.js +0 -108
  309. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.d.ts +0 -31
  310. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.d.ts.map +0 -1
  311. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.js +0 -113
  312. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.d.ts +0 -36
  313. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.d.ts.map +0 -1
  314. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.js +0 -85
  315. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.d.ts +0 -23
  316. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.d.ts.map +0 -1
  317. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.js +0 -273
  318. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.d.ts +0 -13
  319. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.d.ts.map +0 -1
  320. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.js +0 -151
  321. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.d.ts +0 -13
  322. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.d.ts.map +0 -1
  323. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.js +0 -133
  324. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.d.ts +0 -22
  325. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.d.ts.map +0 -1
  326. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.js +0 -135
@@ -0,0 +1,902 @@
1
+ import { assert } from "../../../../../core/assert.js";
2
+ import { BufferDescriptor } from "../../../../descriptor/buffer/BufferDescriptor.js";
3
+ import { BufferResourceDescriptor } from "../../../../device/graph/BufferResourceDescriptor.js";
4
+ import { graph_read_buffer } from "../../../buffer/graph_read_buffer.js";
5
+ import { graph_build_indirect_dispatch_command } from "../../../gpu_primitive/indirect/IndirectComputeCommandBuildPass.js";
6
+ import {
7
+ graph_prefix_scan_csdldf,
8
+ prefix_scan_csdldf_output_descriptor
9
+ } from "../../../gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js";
10
+ import { graph_create_buffer } from "../../../shader/graph/graph_create_buffer.js";
11
+ import { Attribute } from "../../Attribute.js";
12
+ import { Geometry } from "../../Geometry.js";
13
+ import { MeshoptClusterizer } from "../../meshlet/build/meshoptimizer/meshopt_clusterizer.js";
14
+ import { meshlet_geometry_build_from_geometry } from "../../meshlet_geometry_build_from_geometry.js";
15
+ import { MeshSDFState } from "../../sdf/MESH_SDF.js";
16
+ import { MeshSDFLayout } from "../../sdf/MeshSDFLayout.js";
17
+ import { StandardAttributes } from "../../StandardAttributes.js";
18
+ import { vgeo_feedback_slot_stats } from "../runtime/cut/vgeo_cut_feedback_layout.js";
19
+ import { graph_vgeo_cut_descent } from "../runtime/graph_vgeo_cut_descent.js";
20
+ import { VGEO_CUT_STAT } from "../runtime/layout/VGEO_CUT_STAT.js";
21
+ import { VGEO_CUT_STAT_COUNT } from "../runtime/layout/VGEO_CUT_STAT_COUNT.js";
22
+ import { VGEO_GEOMETRY_ROW_NONE } from "../runtime/layout/VGEO_GEOMETRY_ROW_NONE.js";
23
+ import { VGEO_INSTANCE_WORDS } from "../runtime/layout/VGEO_INSTANCE_WORDS.js";
24
+ import { VGeoViewCut } from "../runtime/VGeoViewCut.js";
25
+ import { shader_vgeo_sdf_collect, VGEO_SDF_COLLECT_WORKGROUP_SIZE } from "./shader_vgeo_sdf_collect.js";
26
+ import { shader_vgeo_sdf_decode } from "./shader_vgeo_sdf_decode.js";
27
+ import { shader_vgeo_sdf_traverse } from "./shader_vgeo_sdf_traverse.js";
28
+ import {
29
+ VGEO_SDF_CLUSTER_WORDS,
30
+ VGEO_SDF_COUNTER,
31
+ VGEO_SDF_COUNTER_WORDS,
32
+ VGEO_SDF_JOB_STRUCT,
33
+ vgeo_sdf_header_words
34
+ } from "./VGEO_SDF.js";
35
+
36
+ /**
37
+ * @typedef {import("../../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} FrameGraph
38
+ * @typedef {import("../../GPUGeometryManager.js").GPUGeometryManager} GPUGeometryManager
39
+ * @typedef {import("../../GPUGeometryMetadata.js").GPUGeometryMetadata} GPUGeometryMetadata
40
+ * @typedef {import("../../MeshletGeometry.js").MeshletGeometry} MeshletGeometry
41
+ * @typedef {import("../runtime/GPUVirtualGeometryRuntime.js").GPUVirtualGeometryRuntime} GPUVirtualGeometryRuntime
42
+ */
43
+
44
+ /** The slot holds no geometry. */
45
+ const JOB_FREE = 0;
46
+ /** Cut each frame, its counters read back. */
47
+ const JOB_CUT = 1;
48
+ /** Its last cut read back stood nothing in: the next frame it is cut, its mesh is written out too. */
49
+ const JOB_READY = 2;
50
+ /** Written out in a frame whose readback has not landed. */
51
+ const JOB_DECODING = 3;
52
+ /** Its mesh is read back: its proxy is built on the host. */
53
+ const JOB_BUILD = 4;
54
+ /** Its proxy is baked by the mesh path. */
55
+ const JOB_BAKING = 5;
56
+ /** Its proxy's cache is resident: given to the geometry at the next update. */
57
+ const JOB_BAKED = 6;
58
+
59
+ /**
60
+ * Frames whose readback may be in flight before a frame's cut is skipped, as the bake's log: a mapping lands a frame or
61
+ * two after its copy, and past this the device is behind.
62
+ * @type {number}
63
+ */
64
+ const MAX_FRAMES_IN_FLIGHT = 3;
65
+
66
+ /**
67
+ * Geometries extracted at once: the jobs cut each frame until their cut stands nothing in. One whose proxy is built,
68
+ * baking or waiting to be given its cache keeps its slot until then.
69
+ * @type {number}
70
+ */
71
+ const DEFAULT_JOB_CAPACITY = 32;
72
+
73
+ /**
74
+ * Entries the cluster list starts with: a cut of a typical geometry at half its cache's voxel is under 128 clusters
75
+ * (S8, step 0), for each of {@link DEFAULT_JOB_CAPACITY} jobs. It doubles past what a frame's cut took.
76
+ * @type {number}
77
+ */
78
+ const INITIAL_CLUSTER_CAPACITY = DEFAULT_JOB_CAPACITY * 128;
79
+
80
+ /**
81
+ * One geometry being extracted.
82
+ */
83
+ class VGeoSDFJob {
84
+ /**
85
+ * Bumped each time the slot takes a geometry: a readback of a frame cut for an earlier one is not this one's.
86
+ * @type {number}
87
+ */
88
+ generation = 0;
89
+
90
+ phase = JOB_FREE;
91
+
92
+ /**
93
+ * The geometry, whose cache is asked for.
94
+ * @type {GPUGeometryMetadata|null}
95
+ */
96
+ record = null;
97
+
98
+ /**
99
+ * What puts its error against a τ of 1: one over half its cache's level-0 voxel, in its own units.
100
+ * @type {number}
101
+ */
102
+ projection_k = 0;
103
+
104
+ /** What its last complete cut held. */
105
+ vertex_count = 0;
106
+ triangle_count = 0;
107
+
108
+ /** @type {Float32Array|null} */
109
+ positions = null;
110
+
111
+ /** @type {Uint32Array|null} */
112
+ indices = null;
113
+
114
+ /** @type {MeshletGeometry|null} */
115
+ proxy = null;
116
+
117
+ /** @type {GPUGeometryMetadata|null} */
118
+ proxy_record = null;
119
+ }
120
+
121
+ /**
122
+ * The jobs one recorded frame cut, for its readback.
123
+ */
124
+ class VGeoSDFFrame {
125
+ busy = false;
126
+
127
+ count = 0;
128
+
129
+ /** @type {VGeoSDFJob[]} */
130
+ jobs = [];
131
+
132
+ /**
133
+ * @param {number} capacity
134
+ */
135
+ constructor(capacity) {
136
+ this.generations = new Uint32Array(capacity);
137
+ this.decoding = new Uint8Array(capacity);
138
+ this.vertex_bases = new Uint32Array(capacity);
139
+ this.triangle_bases = new Uint32Array(capacity);
140
+ }
141
+
142
+ vertex_offset = 0;
143
+ index_offset = 0;
144
+ }
145
+
146
+ /**
147
+ * The geometry caches of virtual geometry (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §7.8, as S8 built it): a
148
+ * {@link MeshSDFSource} of {@link GPUGeometrySDFManager}, which bakes a geometry's field from its tree, and a virtual
149
+ * geometry has none. Each virtual geometry whose cache is asked for gets a proxy, the triangles of a cut of it, baked by
150
+ * the mesh path as any geometry is, and its resident cache adopted into the geometry. Its instances are then composed
151
+ * from it as a mesh's are.
152
+ *
153
+ * **The cut.** A geometry is cut whole by the camera cut's own descent (`shader_vgeo_sdf_traverse`), at an error under
154
+ * half its cache's level-0 voxel, in its own space, under a feedback slot of the extraction's own: a cluster's page not
155
+ * resident is wanted there, as a view's are, and since a want lasts one reading the job is cut again each frame until
156
+ * its cut stands nothing in. Its counters are read back each frame.
157
+ *
158
+ * **The mesh.** The frame after a cut that stood nothing in, the job's clusters are written out too, its vertices as
159
+ * stored and its triangles as indices into them (`shader_vgeo_sdf_decode`), in room the last cut's counts made, and
160
+ * read back with that frame's counters. A frame that cut it otherwise (a page evicted since, the cut grown) is not
161
+ * taken, and the job is cut again.
162
+ *
163
+ * **The proxy.** One a frame, on the host: an ordinary geometry built from the mesh
164
+ * (`meshlet_geometry_build_from_geometry`, which costs 2.2 to 4.1 µs a triangle, measured), added to the geometry
165
+ * manager, its cache held with the side the geometry's holders draw. When its bake turns resident the next update gives
166
+ * it to the geometry ({@link GPUGeometrySDFManager#adopt}) and removes the proxy.
167
+ *
168
+ * A geometry no longer asked for when its turn comes is let go, and one whose holders ask again is extracted again.
169
+ * Settings that change the caches' voxel restart every job.
170
+ */
171
+ export class VGeoSDFProxies {
172
+
173
+ /** @type {GPUDevice} */
174
+ #device;
175
+
176
+ /** @type {GPUVirtualGeometryRuntime} */
177
+ #runtime;
178
+
179
+ /** @type {GPUGeometryManager} */
180
+ #geometries;
181
+
182
+ /** @type {import("../../sdf/GPUGeometrySDFManager.js").GPUGeometrySDFManager} */
183
+ #sdf;
184
+
185
+ /**
186
+ * The extraction's cut: its slot, its params and its wavefront bound.
187
+ * @type {VGeoViewCut}
188
+ */
189
+ #cut;
190
+
191
+ /** @type {VGeoSDFJob[]} */
192
+ #jobs = [];
193
+
194
+ /**
195
+ * Geometries asked for and not yet a job's, in the order asked; a geometry asked for again or let go since may be
196
+ * here, and is passed over.
197
+ * @type {GPUGeometryMetadata[]}
198
+ */
199
+ #requested = [];
200
+
201
+ /** @type {VGeoSDFFrame[]} */
202
+ #frames = [];
203
+
204
+ #cluster_capacity = INITIAL_CLUSTER_CAPACITY;
205
+
206
+ /**
207
+ * The frame's jobs as the passes read them, `VGEO_SDF_JOB_STRUCT` each.
208
+ * @type {GPUBuffer}
209
+ */
210
+ #jobs_buffer;
211
+
212
+ #jobs_scratch;
213
+
214
+ #settings = { job_count: 0, cluster_capacity: 0, vertex_offset: 0, index_offset: 0 };
215
+
216
+ #collect_data = { instances: -1, claim_widths: -1 };
217
+ #collect_bindings = {};
218
+ #decode_data = { command: -1, clusters: -1, counters: -1, payload: -1 };
219
+ #decode_bindings = {};
220
+ #header_data = { counters: -1, feedback: -1, payload: -1 };
221
+
222
+ /** Where the extraction's slot keeps its counters in the frame's feedback, for the frame being recorded. */
223
+ #stats_base = 0;
224
+
225
+ #voxel_size;
226
+ #max_bricks;
227
+
228
+ #layout = new MeshSDFLayout();
229
+
230
+ #clusterizer_ready = false;
231
+
232
+ #extracted_count = 0;
233
+ #adopted_count = 0;
234
+ #triangles_extracted = 0;
235
+
236
+ #destroyed = false;
237
+
238
+ /**
239
+ * @param {Object} options
240
+ * @param {GPUDevice} options.device
241
+ * @param {GPUVirtualGeometryRuntime} options.runtime whose geometries' caches this makes
242
+ * @param {GPUGeometryManager} options.geometries the scene's, whose caches the virtual geometries' are
243
+ * @param {number} [options.job_capacity] geometries extracted at once
244
+ */
245
+ constructor({ device, runtime, geometries, job_capacity = DEFAULT_JOB_CAPACITY }) {
246
+ assert.defined(device, 'device');
247
+ assert.defined(runtime, 'runtime');
248
+ assert.defined(geometries, 'geometries');
249
+ assert.isPositiveInteger(job_capacity, 'job_capacity');
250
+
251
+ this.#device = device;
252
+ this.#runtime = runtime;
253
+ this.#geometries = geometries;
254
+ this.#sdf = geometries.sdf;
255
+ this.#cut = new VGeoViewCut({ device, label: 'vgeo sdf proxies' });
256
+
257
+ this.#voxel_size = this.#sdf.voxel_size;
258
+ this.#max_bricks = this.#sdf.max_bricks;
259
+
260
+ for (let i = 0; i < job_capacity; i++) {
261
+ this.#jobs.push(new VGeoSDFJob());
262
+ }
263
+
264
+ for (let i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
265
+ this.#frames.push(new VGeoSDFFrame(job_capacity));
266
+ }
267
+
268
+ this.#jobs_buffer = device.createBuffer(BufferDescriptor.fromJSON({
269
+ label: 'VGeoSDFProxies/jobs',
270
+ size: job_capacity * VGEO_SDF_JOB_STRUCT.size,
271
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
272
+ }));
273
+
274
+ this.#jobs_scratch = new DataView(new ArrayBuffer(job_capacity * VGEO_SDF_JOB_STRUCT.size));
275
+
276
+ const ready = MeshoptClusterizer.ready;
277
+
278
+ if (ready === undefined) {
279
+ this.#clusterizer_ready = true;
280
+ } else {
281
+ ready.then(() => {
282
+ this.#clusterizer_ready = true;
283
+ });
284
+ }
285
+
286
+ this.#sdf.onRequested.add(this.#requested_one, this);
287
+ this.#sdf.onBaked.add(this.#baked, this);
288
+ this.#sdf.add_source(this);
289
+ }
290
+
291
+ /**
292
+ * The extraction's cut, whose `stats` say what the last reading of its slot counted.
293
+ * @returns {VGeoViewCut}
294
+ */
295
+ get cut() {
296
+ return this.#cut;
297
+ }
298
+
299
+ /**
300
+ * Geometries being extracted.
301
+ * @returns {number}
302
+ */
303
+ get job_count() {
304
+ let count = 0;
305
+
306
+ for (const job of this.#jobs) {
307
+ if (job.phase !== JOB_FREE) {
308
+ count++;
309
+ }
310
+ }
311
+
312
+ return count;
313
+ }
314
+
315
+ /**
316
+ * Geometries asked for that wait for a job, those let go since included.
317
+ * @returns {number}
318
+ */
319
+ get requested_count() {
320
+ return this.#requested.length;
321
+ }
322
+
323
+ /**
324
+ * Proxies built so far.
325
+ * @returns {number}
326
+ */
327
+ get extracted_count() {
328
+ return this.#extracted_count;
329
+ }
330
+
331
+ /**
332
+ * Caches given to their geometries so far.
333
+ * @returns {number}
334
+ */
335
+ get adopted_count() {
336
+ return this.#adopted_count;
337
+ }
338
+
339
+ /**
340
+ * Triangles of the proxies built so far.
341
+ * @returns {number}
342
+ */
343
+ get triangles_extracted() {
344
+ return this.#triangles_extracted;
345
+ }
346
+
347
+ /**
348
+ * Entries the cluster list holds.
349
+ * @returns {number}
350
+ */
351
+ get cluster_capacity() {
352
+ return this.#cluster_capacity;
353
+ }
354
+
355
+ /**
356
+ * @param {GPUGeometryMetadata} record
357
+ */
358
+ #requested_one(record) {
359
+ if (record.vg_row !== VGEO_GEOMETRY_ROW_NONE) {
360
+ this.#requested.push(record);
361
+ }
362
+ }
363
+
364
+ /**
365
+ * @param {number} id
366
+ */
367
+ #baked(id) {
368
+ for (const job of this.#jobs) {
369
+ if (job.phase === JOB_BAKING && job.proxy_record.index === id) {
370
+ job.phase = JOB_BAKED;
371
+ }
372
+ }
373
+ }
374
+
375
+ /**
376
+ * The frame's work, ahead of the caches' bake: the caches baked given to their geometries, a proxy built, jobs
377
+ * started, and the jobs' cut recorded into `graph` while the runtime's frame is open.
378
+ *
379
+ * @param {FrameGraph} graph
380
+ */
381
+ graph_update(graph) {
382
+ assert.notOk(this.#destroyed, 'destroyed');
383
+
384
+ const sdf = this.#sdf;
385
+
386
+ if (sdf.voxel_size !== this.#voxel_size || sdf.max_bricks !== this.#max_bricks) {
387
+ // a cut for the old voxel bakes a proxy finer or coarser than the cache it is for
388
+ this.#restart();
389
+
390
+ this.#voxel_size = sdf.voxel_size;
391
+ this.#max_bricks = sdf.max_bricks;
392
+ }
393
+
394
+ this.#adopt();
395
+ this.#build();
396
+ this.#start();
397
+
398
+ if (this.#runtime.frame_open) {
399
+ this.#record(graph);
400
+ }
401
+ }
402
+
403
+ /**
404
+ * Give each geometry whose proxy is baked its cache, and remove the proxy.
405
+ */
406
+ #adopt() {
407
+ const sdf = this.#sdf;
408
+
409
+ for (const job of this.#jobs) {
410
+ if (job.phase !== JOB_BAKED) {
411
+ continue;
412
+ }
413
+
414
+ if (sdf.adopt(job.record, job.proxy_record)) {
415
+ this.#adopted_count++;
416
+ } else if (sdf.is_requested(job.record)) {
417
+ // the proxy's cache is not the one it was baked to: a proxy equal to another's is that one's record
418
+ this.#requested.push(job.record);
419
+ }
420
+
421
+ this.#free(job);
422
+ }
423
+ }
424
+
425
+ /**
426
+ * Build the proxy of the first job whose mesh is read back, and hold its cache.
427
+ */
428
+ #build() {
429
+ if (!this.#clusterizer_ready) {
430
+ return;
431
+ }
432
+
433
+ const sdf = this.#sdf;
434
+
435
+ for (const job of this.#jobs) {
436
+ if (job.phase !== JOB_BUILD) {
437
+ continue;
438
+ }
439
+
440
+ if (!sdf.is_requested(job.record)) {
441
+ // let go since its cut was taken
442
+ this.#free(job);
443
+ continue;
444
+ }
445
+
446
+ const mesh = new Geometry();
447
+
448
+ mesh.name = 'vgeo sdf proxy';
449
+ mesh.index = Attribute.from(job.indices, 1, StandardAttributes.Index);
450
+ mesh.addAttribute(Attribute.from(job.positions, 3, StandardAttributes.Position));
451
+
452
+ const proxy = meshlet_geometry_build_from_geometry(mesh);
453
+
454
+ this.#geometries.add(proxy);
455
+
456
+ job.proxy = proxy;
457
+ job.proxy_record = this.#geometries.get_metadata(proxy);
458
+ job.positions = null;
459
+ job.indices = null;
460
+ job.phase = JOB_BAKING;
461
+
462
+ this.#extracted_count++;
463
+ this.#triangles_extracted += job.triangle_count;
464
+
465
+ sdf.acquire(job.proxy_record, sdf.holds_two_sided(job.record));
466
+
467
+ if (sdf.state_of(job.proxy_record) === MeshSDFState.Resident) {
468
+ // a record a resident proxy of the same mesh already had
469
+ job.phase = JOB_BAKED;
470
+ }
471
+
472
+ return;
473
+ }
474
+ }
475
+
476
+ /**
477
+ * Give the free slots the geometries asked for, in the order asked.
478
+ */
479
+ #start() {
480
+ const sdf = this.#sdf;
481
+ const requested = this.#requested;
482
+ const layout = this.#layout;
483
+
484
+ let taken = 0;
485
+
486
+ for (const job of this.#jobs) {
487
+ if (job.phase !== JOB_FREE) {
488
+ continue;
489
+ }
490
+
491
+ while (taken < requested.length) {
492
+ const record = requested[taken++];
493
+
494
+ if (!sdf.is_requested(record) || this.#extracting(record)) {
495
+ continue;
496
+ }
497
+
498
+ layout.compute(record.geometry.bounding_box, sdf.voxel_size, sdf.max_bricks);
499
+
500
+ job.generation++;
501
+ job.record = record;
502
+ job.projection_k = 1 / (0.5 * layout.voxel);
503
+ job.phase = JOB_CUT;
504
+
505
+ break;
506
+ }
507
+ }
508
+
509
+ requested.copyWithin(0, taken);
510
+ requested.length -= taken;
511
+ }
512
+
513
+ /**
514
+ * @param {GPUGeometryMetadata} record
515
+ * @returns {boolean} whether a job holds it
516
+ */
517
+ #extracting(record) {
518
+ for (const job of this.#jobs) {
519
+ if (job.phase !== JOB_FREE && job.record === record) {
520
+ return true;
521
+ }
522
+ }
523
+
524
+ return false;
525
+ }
526
+
527
+ /**
528
+ * Let every job go, and ask again for the geometries still asked for.
529
+ */
530
+ #restart() {
531
+ for (const job of this.#jobs) {
532
+ if (job.phase === JOB_FREE) {
533
+ continue;
534
+ }
535
+
536
+ if (this.#sdf.is_requested(job.record)) {
537
+ this.#requested.push(job.record);
538
+ }
539
+
540
+ this.#free(job);
541
+ }
542
+ }
543
+
544
+ /**
545
+ * @param {VGeoSDFJob} job
546
+ */
547
+ #free(job) {
548
+ if (job.proxy !== null) {
549
+ this.#geometries.remove(job.proxy);
550
+ }
551
+
552
+ job.phase = JOB_FREE;
553
+ job.record = null;
554
+ job.positions = null;
555
+ job.indices = null;
556
+ job.proxy = null;
557
+ job.proxy_record = null;
558
+ }
559
+
560
+ /**
561
+ * @returns {VGeoSDFFrame|null}
562
+ */
563
+ #take_frame() {
564
+ for (const frame of this.#frames) {
565
+ if (!frame.busy) {
566
+ return frame;
567
+ }
568
+ }
569
+
570
+ return null;
571
+ }
572
+
573
+ /**
574
+ * Record the cut of the jobs that cut, and the write-out of those whose last cut stood nothing in.
575
+ *
576
+ * @param {FrameGraph} graph
577
+ */
578
+ #record(graph) {
579
+ const frame = this.#take_frame();
580
+
581
+ if (frame === null) {
582
+ return;
583
+ }
584
+
585
+ const runtime = this.#runtime;
586
+ const view = this.#jobs_scratch;
587
+ const stride = VGEO_SDF_JOB_STRUCT.size;
588
+
589
+ let count = 0;
590
+ let vertices = 0;
591
+ let triangles = 0;
592
+
593
+ for (const job of this.#jobs) {
594
+ if (job.phase !== JOB_CUT && job.phase !== JOB_READY) {
595
+ continue;
596
+ }
597
+
598
+ if (!this.#sdf.is_requested(job.record)) {
599
+ // let go since it was asked for: dropped, or forgotten
600
+ this.#free(job);
601
+ continue;
602
+ }
603
+
604
+ const decode = job.phase === JOB_READY;
605
+ const at = count * stride;
606
+
607
+ frame.jobs[count] = job;
608
+ frame.generations[count] = job.generation;
609
+ frame.decoding[count] = decode ? 1 : 0;
610
+ frame.vertex_bases[count] = vertices;
611
+ frame.triangle_bases[count] = triangles;
612
+
613
+ view.setUint32(at + VGEO_SDF_JOB_STRUCT.get("vg_row").offset, job.record.vg_row, true);
614
+ view.setFloat32(at + VGEO_SDF_JOB_STRUCT.get("projection_k").offset, job.projection_k, true);
615
+ view.setUint32(at + VGEO_SDF_JOB_STRUCT.get("decode").offset, decode ? 1 : 0, true);
616
+ view.setUint32(at + VGEO_SDF_JOB_STRUCT.get("vertex_base").offset, vertices, true);
617
+ view.setUint32(at + VGEO_SDF_JOB_STRUCT.get("triangle_base").offset, triangles, true);
618
+ view.setUint32(at + VGEO_SDF_JOB_STRUCT.get("vertex_count").offset, decode ? job.vertex_count : 0, true);
619
+ view.setUint32(at + VGEO_SDF_JOB_STRUCT.get("triangle_count").offset, decode ? job.triangle_count : 0, true);
620
+
621
+ if (decode) {
622
+ vertices += job.vertex_count;
623
+ triangles += job.triangle_count;
624
+ job.phase = JOB_DECODING;
625
+ }
626
+
627
+ count++;
628
+ }
629
+
630
+ if (count === 0) {
631
+ return;
632
+ }
633
+
634
+ frame.busy = true;
635
+ frame.count = count;
636
+
637
+ const header_words = vgeo_sdf_header_words(count);
638
+
639
+ frame.vertex_offset = header_words;
640
+ frame.index_offset = header_words + 3 * vertices;
641
+
642
+ const payload_bytes = 4 * (frame.index_offset + 3 * triangles);
643
+
644
+ this.#device.queue.writeBuffer(this.#jobs_buffer, 0, view.buffer, 0, count * stride);
645
+
646
+ const settings = this.#settings;
647
+
648
+ settings.job_count = count;
649
+ settings.cluster_capacity = this.#cluster_capacity;
650
+ settings.vertex_offset = frame.vertex_offset;
651
+ settings.index_offset = frame.index_offset;
652
+
653
+ // this frame's slot for the cut, and its params: a τ of 1, since its records carry the error's own scale
654
+ const slot = runtime.slot_of(this.#cut);
655
+
656
+ this.#cut.write_params({ runtime, slot, tau: 1 });
657
+ this.#stats_base = vgeo_feedback_slot_stats(slot);
658
+
659
+ // ----- the records: a job's geometry whole, then their claim widths scanned -----
660
+
661
+ const collect_data = this.#collect_data;
662
+ const collect = graph.add("VGeo SDF Collect", collect_data, this.#execute_collect);
663
+
664
+ collect_data.instances = collect.create("vgeo sdf instances", BufferResourceDescriptor.from(
665
+ count * VGEO_INSTANCE_WORDS * 4, GPUBufferUsage.STORAGE
666
+ ));
667
+ collect_data.claim_widths = collect.create("vgeo sdf claim widths", BufferResourceDescriptor.from(
668
+ 16 + count * 4, GPUBufferUsage.STORAGE, 0, 16
669
+ ));
670
+
671
+ const prefix_sums = graph_prefix_scan_csdldf({
672
+ graph,
673
+ input: collect_data.claim_widths,
674
+ output: graph_create_buffer(graph, "vgeo sdf claim offsets", prefix_scan_csdldf_output_descriptor(count)),
675
+ element_max_count: count,
676
+ });
677
+
678
+ // ----- the cut: the camera cut's own descent, its clusters onto the list -----
679
+
680
+ const counters = graph_create_buffer(graph, "vgeo sdf counters", BufferResourceDescriptor.empty(
681
+ count * VGEO_SDF_COUNTER_WORDS * 4, GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
682
+ ));
683
+ const clusters = graph_create_buffer(graph, "vgeo sdf clusters", BufferResourceDescriptor.from(
684
+ 16 + this.#cluster_capacity * VGEO_SDF_CLUSTER_WORDS * 4, GPUBufferUsage.STORAGE, 0, 16
685
+ ));
686
+
687
+ const descent = graph_vgeo_cut_descent({
688
+ graph,
689
+ runtime,
690
+ cut: this.#cut,
691
+ instances: collect_data.instances,
692
+ prefix_sums,
693
+ feedback: runtime.feedback_in(graph),
694
+ traverse: shader_vgeo_sdf_traverse,
695
+ bindings: { settings },
696
+ outputs: { vgeo_sdf_counters: counters, vgeo_sdf_clusters: clusters },
697
+ });
698
+
699
+ runtime.publish_feedback(graph, descent.feedback);
700
+
701
+ // ----- the write-out: a workgroup a listed cluster, every job's sizes and the ready jobs' meshes -----
702
+
703
+ const command = graph_build_indirect_dispatch_command(graph, descent.outputs.vgeo_sdf_clusters, 1, true);
704
+
705
+ const decode_data = this.#decode_data;
706
+ const decode = graph.add("VGeo SDF Decode", decode_data, this.#execute_decode);
707
+
708
+ decode_data.command = decode.read(command);
709
+ decode_data.clusters = decode.read(descent.outputs.vgeo_sdf_clusters);
710
+ decode_data.counters = decode.write(descent.outputs.vgeo_sdf_counters);
711
+ decode_data.payload = decode.create("vgeo sdf payload", BufferResourceDescriptor.from(
712
+ payload_bytes, GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST
713
+ ));
714
+
715
+ // ----- the header: the jobs' counters and the cut's own, ahead of the meshes, then read back -----
716
+
717
+ const header_data = this.#header_data;
718
+ const header = graph.add("VGeo SDF Header", header_data, this.#execute_header);
719
+
720
+ header_data.counters = header.read(decode_data.counters);
721
+ header_data.feedback = header.read(descent.feedback);
722
+ header_data.payload = header.write(decode_data.payload);
723
+
724
+ graph_read_buffer({ graph, buffer: header_data.payload, offset: 0, size: payload_bytes })
725
+ .then(reference => {
726
+ try {
727
+ if (!this.#destroyed) {
728
+ this.#apply(new Uint32Array(reference.getValue()), frame);
729
+ }
730
+ } finally {
731
+ reference.release();
732
+ }
733
+ })
734
+ .catch(error => {
735
+ if (!this.#destroyed) {
736
+ console.warn('VGeoSDFProxies: readback failed', error);
737
+ this.#lose(frame);
738
+ }
739
+ })
740
+ .finally(() => {
741
+ frame.busy = false;
742
+ });
743
+ }
744
+
745
+ #execute_collect = (data, resources, execution) => {
746
+ const b = this.#collect_bindings;
747
+
748
+ b.settings = this.#settings;
749
+ b.vgeo_sdf_jobs = this.#jobs_buffer;
750
+ b.vg_geometries = this.#runtime.pool.buffer_geometries;
751
+ b.instances = resources.get(data.instances);
752
+ b.claim_widths = resources.get(data.claim_widths);
753
+
754
+ shader_vgeo_sdf_collect.dispatch({
755
+ encoder: execution.encoder,
756
+ group_count_x: Math.ceil(this.#settings.job_count / VGEO_SDF_COLLECT_WORKGROUP_SIZE),
757
+ bindings: b,
758
+ });
759
+ };
760
+
761
+ #execute_decode = (data, resources, execution) => {
762
+ const meshlets = this.#geometries.meshlets;
763
+ const b = this.#decode_bindings;
764
+
765
+ b.settings = this.#settings;
766
+ b.vgeo_sdf_jobs = this.#jobs_buffer;
767
+ b.vgeo_sdf_counters = resources.get(data.counters);
768
+ b.vgeo_sdf_clusters = resources.get(data.clusters);
769
+ b.meshlet_metadata = meshlets.buffer_metadata;
770
+ b.meshlet_data = meshlets.buffer_data;
771
+ b.vgeo_sdf_payload = resources.get(data.payload);
772
+
773
+ shader_vgeo_sdf_decode.dispatchIndirect({
774
+ encoder: execution.encoder,
775
+ command: resources.get(data.command),
776
+ command_offset: 0,
777
+ bindings: b,
778
+ });
779
+ };
780
+
781
+ #execute_header = (data, resources, execution) => {
782
+ const encoder = execution.encoder;
783
+ const payload = resources.get(data.payload);
784
+ const counter_bytes = 4 * this.#settings.job_count * VGEO_SDF_COUNTER_WORDS;
785
+
786
+ encoder.copyBufferToBuffer(resources.get(data.counters), 0, payload, 0, counter_bytes);
787
+ encoder.copyBufferToBuffer(resources.get(data.feedback), 4 * this.#stats_base, payload, counter_bytes, 4 * VGEO_CUT_STAT_COUNT);
788
+ };
789
+
790
+ /**
791
+ * A recorded frame's readback: each job's cut taken, its mesh too where the frame wrote it out.
792
+ *
793
+ * @param {Uint32Array} words
794
+ * @param {VGeoSDFFrame} frame
795
+ */
796
+ #apply(words, frame) {
797
+ const stats = frame.count * VGEO_SDF_COUNTER_WORDS;
798
+
799
+ // a subtree the cut left undescended is missing from every job's list, and no counter of a job says which
800
+ const holes = words[stats + VGEO_CUT_STAT.QUEUE_DROPPED] > 0
801
+ || words[stats + VGEO_CUT_STAT.QUEUE_REMAINING] > 0
802
+ || words[stats + VGEO_CUT_STAT.INSTANCES_DROPPED] > 0;
803
+
804
+ let taken = 0;
805
+ let dropped = false;
806
+
807
+ for (let i = 0; i < frame.count; i++) {
808
+ const job = frame.jobs[i];
809
+ const c = i * VGEO_SDF_COUNTER_WORDS;
810
+
811
+ taken += words[c + VGEO_SDF_COUNTER.TAKEN];
812
+ dropped ||= words[c + VGEO_SDF_COUNTER.DROPPED] > 0;
813
+
814
+ if (job.generation !== frame.generations[i]) {
815
+ // the slot holds another geometry now
816
+ continue;
817
+ }
818
+
819
+ const complete = !holes
820
+ && words[c + VGEO_SDF_COUNTER.TAKEN] > 0
821
+ && words[c + VGEO_SDF_COUNTER.STAND_INS] === 0
822
+ && words[c + VGEO_SDF_COUNTER.DROPPED] === 0;
823
+
824
+ if (frame.decoding[i] === 0) {
825
+ if (job.phase === JOB_CUT && complete) {
826
+ job.vertex_count = words[c + VGEO_SDF_COUNTER.VERTICES];
827
+ job.triangle_count = words[c + VGEO_SDF_COUNTER.TRIANGLES];
828
+ job.phase = JOB_READY;
829
+ }
830
+
831
+ continue;
832
+ }
833
+
834
+ if (job.phase !== JOB_DECODING) {
835
+ continue;
836
+ }
837
+
838
+ const whole = complete
839
+ && words[c + VGEO_SDF_COUNTER.VERTICES] === job.vertex_count
840
+ && words[c + VGEO_SDF_COUNTER.TRIANGLES] === job.triangle_count
841
+ && words[c + VGEO_SDF_COUNTER.VERTICES_WRITTEN] === job.vertex_count
842
+ && words[c + VGEO_SDF_COUNTER.TRIANGLES_WRITTEN] === job.triangle_count;
843
+
844
+ if (!whole) {
845
+ // cut otherwise than the cut its room was made for
846
+ job.phase = JOB_CUT;
847
+ continue;
848
+ }
849
+
850
+ const first_vertex = frame.vertex_offset + 3 * frame.vertex_bases[i];
851
+ const first_index = frame.index_offset + 3 * frame.triangle_bases[i];
852
+
853
+ job.positions = new Float32Array(words.buffer, words.byteOffset + 4 * first_vertex, 3 * job.vertex_count).slice();
854
+ job.indices = words.slice(first_index, first_index + 3 * job.triangle_count);
855
+ job.phase = JOB_BUILD;
856
+ }
857
+
858
+ if (dropped) {
859
+ while (this.#cluster_capacity < taken) {
860
+ this.#cluster_capacity *= 2;
861
+ }
862
+ }
863
+ }
864
+
865
+ /**
866
+ * A frame whose readback was lost: the jobs it wrote out are cut again.
867
+ *
868
+ * @param {VGeoSDFFrame} frame
869
+ */
870
+ #lose(frame) {
871
+ for (let i = 0; i < frame.count; i++) {
872
+ const job = frame.jobs[i];
873
+
874
+ if (frame.decoding[i] === 1 && job.generation === frame.generations[i] && job.phase === JOB_DECODING) {
875
+ job.phase = JOB_CUT;
876
+ }
877
+ }
878
+ }
879
+
880
+ destroy() {
881
+ if (this.#destroyed) {
882
+ return;
883
+ }
884
+
885
+ this.#destroyed = true;
886
+
887
+ const sdf = this.#sdf;
888
+
889
+ sdf.remove_source(this);
890
+ sdf.onRequested.remove(this.#requested_one, this);
891
+ sdf.onBaked.remove(this.#baked, this);
892
+
893
+ for (const job of this.#jobs) {
894
+ this.#free(job);
895
+ }
896
+
897
+ this.#requested.length = 0;
898
+
899
+ this.#cut.destroy();
900
+ this.#jobs_buffer.destroy();
901
+ }
902
+ }