@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
@@ -5,27 +5,91 @@ import { clamp01 } from "../../../../core/math/clamp01.js";
5
5
  import ListView from "../../../common/ListView.js";
6
6
  import { DomSizeObserver } from "../../../util/DomSizeObserver.js";
7
7
  import View from "../../../View.js";
8
- import { CanvasView } from "../../CanvasView.js";
9
8
  import EmptyView from "../../EmptyView.js";
10
- import { RESOURCE_BAR_SEGMENTS } from "./RESOURCE_BAR_SEGMENTS.js";
9
+ import { GhostTrail } from "./GhostTrail.js";
10
+ import { SEGMENT_TIERS_DEFAULT } from "./SEGMENT_TIERS_DEFAULT.js";
11
+ import { segment_cell_layout } from "./segment_cell_layout.js";
12
+ import { segment_notch_place } from "./segment_notch_place.js";
13
+ import { segment_tick_positions } from "./segment_tick_positions.js";
14
+
15
+ /**
16
+ * A width change smaller than this, in CSS pixels, does not rebuild the notches
17
+ * @type {number}
18
+ */
19
+ const REBUILD_WIDTH_THRESHOLD_PX = 0.5;
20
+
21
+ /**
22
+ * Cell fills within this of a whole cell count as whole, so 7 of 30 rounds is 7 full cells and not 7 and a sliver
23
+ * @type {number}
24
+ */
25
+ const CELL_FILL_TOLERANCE = 1e-9;
26
+
27
+ const CELL_STATE_EMPTY = 0;
28
+ const CELL_STATE_PARTIAL = 1;
29
+ const CELL_STATE_FILLED = 2;
30
+
31
+ const CELL_STATE_CLASS = ['cell empty', 'cell partial', 'cell filled'];
32
+
33
+ /**
34
+ * @param {number} x
35
+ * @returns {number}
36
+ */
37
+ function snap_whole(x) {
38
+ const r = Math.round(x);
39
+
40
+ return Math.abs(x - r) <= CELL_FILL_TOLERANCE ? r : x;
41
+ }
11
42
 
43
+ /**
44
+ * Resource bar in the style of a MOBA health bar: the values fill it end to end, notches mark fixed amounts, and
45
+ * a ghost behind the fill trails a drop so the loss stays readable for a moment.
46
+ *
47
+ * Two modes:
48
+ * - notches (default): a continuous fill, with a notch at every multiple of each {@link SegmentTier}'s unit;
49
+ * - cells (`cells` given): `count` separate cells with exact, identical gaps, for counting rounds and the like.
50
+ *
51
+ * Notches and cells sit on whole device pixels at any pixel ratio and under a CSS scale. Colours, notch heights
52
+ * and the ghost are styled by `segmented-resource-bar.css` through `--segmented-bar-*` custom properties.
53
+ */
12
54
  export class SegmentedResourceBarView extends View {
13
55
  /**
14
56
  *
15
57
  * @param {Object} options
16
- * @param {(Vector1|ObservedInteger)[]} options.values
58
+ * @param {(Vector1|ObservedInteger)[]} options.values stacked end to end, value 0 first; their total is clamped to max
17
59
  * @param {Vector1|ObservedInteger|ReactiveExpression} [options.max=1]
18
60
  * @param {string[]} [options.classList]
61
+ * @param {{unit:number, class_name:string, width_px:number, min_spacing_px:number}[]} [options.tiers] notch tiers, finest first; see {@link SegmentTier}
62
+ * @param {{count:number, group:number}|null} [options.cells] draw `count` cells instead of notches, in groups of `group` (0 for none)
63
+ * @param {number} [options.ghost_delay_ms=100] how long the ghost holds after a drop; see {@link GhostTrail}
64
+ * @param {number} [options.ghost_duration_min_ms=300] how long the ghost takes to close the smallest loss
65
+ * @param {number} [options.ghost_duration_max_ms=800] how long it takes to close a loss of the whole bar; both
66
+ * durations are 0 under prefers-reduced-motion, so the ghost holds, then snaps
19
67
  */
20
68
  constructor({
21
69
  values,
22
70
  max = Vector1.one,
23
- classList = []
71
+ classList = [],
72
+ tiers = SEGMENT_TIERS_DEFAULT,
73
+ cells = null,
74
+ ghost_delay_ms = 100,
75
+ ghost_duration_min_ms = 300,
76
+ ghost_duration_max_ms = 800
24
77
  }) {
25
78
  super();
26
79
 
27
80
  assert.isArray(values, 'values');
28
81
  assert.defined(max, 'max');
82
+ assert.isArray(tiers, 'tiers');
83
+ assert.isFinite(ghost_delay_ms, 'ghost_delay_ms');
84
+ assert.greaterThanOrEqual(ghost_delay_ms, 0, 'ghost_delay_ms must not be negative');
85
+ assert.isFinite(ghost_duration_max_ms, 'ghost_duration_max_ms');
86
+ assert.greaterThanOrEqual(ghost_duration_min_ms, 0, 'ghost_duration_min_ms must not be negative');
87
+ assert.greaterThanOrEqual(ghost_duration_max_ms, ghost_duration_min_ms, 'ghost_duration_max_ms must not be under ghost_duration_min_ms');
88
+
89
+ if (cells !== null) {
90
+ assert.isNonNegativeInteger(cells.count, 'cells.count');
91
+ assert.isNonNegativeInteger(cells.group, 'cells.group');
92
+ }
29
93
 
30
94
  /**
31
95
  *
@@ -41,6 +105,75 @@ export class SegmentedResourceBarView extends View {
41
105
  */
42
106
  this.__value_max = max;
43
107
 
108
+ /**
109
+ * @type {{unit:number, class_name:string, width_px:number, min_spacing_px:number}[]}
110
+ * @private
111
+ */
112
+ this.__tiers = tiers;
113
+
114
+ /**
115
+ * @type {{count:number, group:number}|null}
116
+ * @private
117
+ */
118
+ this.__cells = cells;
119
+
120
+ /**
121
+ * @type {GhostTrail}
122
+ * @private
123
+ */
124
+ this.__ghost = new GhostTrail();
125
+ this.__ghost.delay_ms = ghost_delay_ms;
126
+
127
+ /**
128
+ * @type {number}
129
+ * @private
130
+ */
131
+ this.__ghost_duration_min_ms = ghost_duration_min_ms;
132
+
133
+ /**
134
+ * @type {number}
135
+ * @private
136
+ */
137
+ this.__ghost_duration_max_ms = ghost_duration_max_ms;
138
+
139
+ /**
140
+ * Total fill as a fraction of max, as last drawn
141
+ * @type {number}
142
+ * @private
143
+ */
144
+ this.__total_fraction = 0;
145
+
146
+ /**
147
+ * @type {MediaQueryList|null}
148
+ * @private
149
+ */
150
+ this.__reduced_motion = typeof matchMedia === 'function' ? matchMedia('(prefers-reduced-motion: reduce)') : null;
151
+
152
+ /**
153
+ * Watches for the device pixel ratio moving off the one the layout was built for
154
+ * @type {MediaQueryList|null}
155
+ * @private
156
+ */
157
+ this.__dpr_query = null;
158
+
159
+ this.__handle_dpr_change = this.__handle_dpr_change.bind(this);
160
+
161
+ this.__frame_pending = false;
162
+ this.__frame_id = 0;
163
+ this.__animate_ghost = this.__animate_ghost.bind(this);
164
+
165
+ // what the layout was last built for, so it is rebuilt only when one of them moves
166
+ this.__built_max = NaN;
167
+ this.__built_width = NaN;
168
+ this.__built_ratio = NaN;
169
+ this.__built_origin_phase = NaN;
170
+
171
+ /**
172
+ * scratch for {@link segment_notch_place}
173
+ * @type {Float64Array}
174
+ * @private
175
+ */
176
+ this.__place = new Float64Array(2);
44
177
 
45
178
  /**
46
179
  *
@@ -52,31 +185,93 @@ export class SegmentedResourceBarView extends View {
52
185
  this.el = document.createElement('div');
53
186
 
54
187
  this.addClass('ui-segmented-resource-bar-view');
188
+ this.addClass(cells === null ? 'mode-notches' : 'mode-cells');
55
189
 
56
190
  this.addClasses(classList);
57
191
 
192
+ // build structure; the ghost goes first so the fills paint over it
58
193
 
59
- // build structure
60
- this.__v__fill = new EmptyView({ classList: ['fill-container'] });
61
- this.addChild(this.__v__fill);
194
+ /**
195
+ * @type {HTMLElement}
196
+ * @private
197
+ */
198
+ this.__el_ghost = document.createElement('div');
199
+ this.__el_ghost.className = 'ghost';
62
200
 
201
+ /**
202
+ * @type {HTMLElement[]}
203
+ * @private
204
+ */
63
205
  this.__value_fills = [];
64
206
 
65
- for (let i = 0; i < this.__values_current.length; i++) {
66
- const v_value = new EmptyView({ classList: ['fill', `value-${i}`] });
207
+ /**
208
+ * @type {HTMLElement[]}
209
+ * @private
210
+ */
211
+ this.__notch_elements = [];
67
212
 
68
- this.__v__fill.addChild(v_value);
69
- this.__value_fills[i] = v_value;
70
- }
213
+ /**
214
+ * @type {HTMLElement[]}
215
+ * @private
216
+ */
217
+ this.__cell_elements = [];
218
+ this.__cell_fill_elements = [];
219
+ this.__cell_ghost_elements = [];
220
+ this.__cell_states = new Uint8Array(cells === null ? 0 : cells.count);
221
+
222
+ // what each cell's fill and ghost were last drawn at, so an animation frame writes only the cells that moved
223
+ this.__cell_fill_drawn = new Float64Array(cells === null ? 0 : cells.count);
224
+ this.__cell_ghost_drawn = new Float64Array(cells === null ? 0 : cells.count);
225
+
226
+ if (cells === null) {
227
+ this.el.appendChild(this.__el_ghost);
228
+
229
+ const el_fill_container = document.createElement('div');
230
+ el_fill_container.className = 'fill-container';
231
+
232
+ for (let i = 0; i < values.length; i++) {
233
+ const el_fill = document.createElement('div');
234
+ el_fill.className = `fill value-${i}`;
235
+
236
+ el_fill_container.appendChild(el_fill);
237
+ this.__value_fills[i] = el_fill;
238
+ }
239
+
240
+ this.el.appendChild(el_fill_container);
241
+
242
+ /**
243
+ * The notches' own box; what they are positioned in and what is measured to place them
244
+ * @type {HTMLElement}
245
+ * @private
246
+ */
247
+ this.__el_layout = document.createElement('div');
248
+ this.__el_layout.className = 'notches';
249
+ } else {
250
+ this.__el_layout = document.createElement('div');
251
+ this.__el_layout.className = 'cells';
252
+
253
+ for (let i = 0; i < cells.count; i++) {
254
+ const el_cell = document.createElement('div');
255
+ el_cell.className = CELL_STATE_CLASS[CELL_STATE_EMPTY];
71
256
 
72
- this.__v__ghost = new EmptyView({ classList: ['ghost'] });
73
- this.addChild(this.__v__ghost);
257
+ const el_cell_ghost = document.createElement('div');
258
+ el_cell_ghost.className = 'cell-ghost';
74
259
 
260
+ const el_cell_fill = document.createElement('div');
261
+ el_cell_fill.className = 'cell-fill';
75
262
 
76
- this.__v_segments = new CanvasView();
77
- this.__v_segments.addClass('notch-overlay');
263
+ el_cell.appendChild(el_cell_ghost);
264
+ el_cell.appendChild(el_cell_fill);
78
265
 
79
- this.addChild(this.__v_segments);
266
+ this.__el_layout.appendChild(el_cell);
267
+
268
+ this.__cell_elements[i] = el_cell;
269
+ this.__cell_ghost_elements[i] = el_cell_ghost;
270
+ this.__cell_fill_elements[i] = el_cell_fill;
271
+ }
272
+ }
273
+
274
+ this.el.appendChild(this.__el_layout);
80
275
 
81
276
 
82
277
  /**
@@ -131,15 +326,15 @@ export class SegmentedResourceBarView extends View {
131
326
  this.bindSignal(this.__value_max.onChanged, this.handleMaxChange, this);
132
327
 
133
328
  /**
134
- * We need an observer in order to know when we need to resize the canvas element that holds marks
329
+ * Tells us when the bar's width moves, so the notches or cells can be placed again
135
330
  * @type {DomSizeObserver}
136
331
  * @private
137
332
  */
138
333
  this.__sizeObserver = new DomSizeObserver();
139
334
 
140
- this.__sizeObserver.attach(this.el);
335
+ this.__sizeObserver.attach(this.__el_layout);
141
336
 
142
- this.__sizeObserver.dimensions.size.onChanged.add(this.__updateSize, this);
337
+ this.__sizeObserver.dimensions.size.onChanged.add(this.updateSegments, this);
143
338
  }
144
339
 
145
340
  link() {
@@ -147,10 +342,10 @@ export class SegmentedResourceBarView extends View {
147
342
  return;
148
343
  }
149
344
 
150
-
151
345
  super.link();
152
346
 
153
347
  this.__sizeObserver.start();
348
+ this.__watch_device_pixel_ratio();
154
349
  this.update();
155
350
  }
156
351
 
@@ -161,22 +356,22 @@ export class SegmentedResourceBarView extends View {
161
356
 
162
357
  this.__sizeObserver.stop();
163
358
 
359
+ if (this.__dpr_query !== null) {
360
+ this.__dpr_query.removeEventListener('change', this.__handle_dpr_change);
361
+ this.__dpr_query = null;
362
+ }
363
+
364
+ if (this.__frame_pending) {
365
+ cancelAnimationFrame(this.__frame_id);
366
+ this.__frame_pending = false;
367
+ }
368
+
164
369
  super.unlink();
165
370
  }
166
371
 
167
372
  update() {
168
- this.updateFill();
169
- this.updateSegments();
170
- }
171
-
172
- __updateSize() {
173
-
174
- if (this.__sizeObserver.dimensions.size.distanceSqrTo(this.__v_segments.size) < 0.5) {
175
- // change too small, ignore
176
- return;
177
- }
178
-
179
373
  this.updateSegments();
374
+ this.updateFill();
180
375
  }
181
376
 
182
377
  handleMaxChange() {
@@ -184,130 +379,276 @@ export class SegmentedResourceBarView extends View {
184
379
  this.updateFill();
185
380
  }
186
381
 
382
+ /**
383
+ * Place the notches or cells again, if the max, the bar's width (by {@link REBUILD_WIDTH_THRESHOLD_PX} or more),
384
+ * its pixel ratio or the device-pixel phase of its left edge has moved since they were last placed.
385
+ */
187
386
  updateSegments() {
387
+ const el = this.__el_layout;
388
+
188
389
  /**
189
- *
190
- * @type {Vector2}
390
+ * width as laid out, before any transform on an ancestor
391
+ * @type {number}
191
392
  */
192
- const size = this.__sizeObserver.dimensions.size;
393
+ const layout_width = el.offsetWidth;
193
394
 
395
+ if (!(layout_width > 0)) {
396
+ // not laid out (detached, display:none); nothing to place against
397
+ return;
398
+ }
194
399
 
195
- this.__v_segments.size.copy(size);
400
+ const rect = el.getBoundingClientRect();
196
401
 
197
- const vSegments = this.__v_segments;
402
+ const dpr = typeof devicePixelRatio === 'number' && devicePixelRatio > 0 ? devicePixelRatio : 1;
198
403
 
199
- vSegments.clear();
404
+ // a CSS scale on an ancestor shows each CSS pixel of the bar as `scale` page pixels
405
+ const scale = rect.width / layout_width;
200
406
 
201
- /**
202
- *
203
- * @type {CanvasRenderingContext2D}
204
- */
205
- const ctx = vSegments.context2d;
407
+ // device pixels per CSS pixel of the bar
408
+ const ratio = dpr * scale;
206
409
 
207
- const maxValue = this.__value_max.getValue();
410
+ const origin_device = rect.left * dpr;
411
+ const origin_phase = origin_device - Math.round(origin_device);
208
412
 
209
- // figure out what segments to use
210
- let major_segment_index = 0;
413
+ const max = this.__value_max.getValue();
211
414
 
212
- const max_segment_index = RESOURCE_BAR_SEGMENTS.length - 1;
213
- for (let i = max_segment_index; i >= 0; i--) {
214
- const segmentDefinition = RESOURCE_BAR_SEGMENTS[i];
415
+ if (
416
+ max === this.__built_max
417
+ && Math.abs(layout_width - this.__built_width) < REBUILD_WIDTH_THRESHOLD_PX
418
+ && ratio === this.__built_ratio
419
+ && origin_phase === this.__built_origin_phase
420
+ ) {
421
+ return;
422
+ }
215
423
 
216
- if (segmentDefinition.value <= maxValue && (i >= max_segment_index || RESOURCE_BAR_SEGMENTS[i + 1].value > maxValue)) {
217
- //we found major segment
218
- major_segment_index = i;
219
- }
424
+ this.__built_max = max;
425
+ this.__built_width = layout_width;
426
+ this.__built_ratio = ratio;
427
+ this.__built_origin_phase = origin_phase;
428
+
429
+ // the bar's left edge in its own CSS pixels, such that left * ratio lands where the page puts it
430
+ const local_left = origin_device / ratio;
220
431
 
432
+ if (this.__cells === null) {
433
+ this.__place_notches(max, layout_width, local_left, ratio);
434
+ } else {
435
+ this.__place_cells(layout_width, local_left, ratio);
221
436
  }
437
+ }
222
438
 
223
- const major_spec = RESOURCE_BAR_SEGMENTS[major_segment_index];
224
- const minor_spec = RESOURCE_BAR_SEGMENTS[major_segment_index - 1];
439
+ /**
440
+ * @param {number} max
441
+ * @param {number} width
442
+ * @param {number} left
443
+ * @param {number} ratio
444
+ * @private
445
+ */
446
+ __place_notches(max, width, left, ratio) {
447
+ const tiers = this.__tiers;
448
+ const ticks = segment_tick_positions(max, width, tiers);
225
449
 
450
+ const tick_count = ticks.length;
451
+ const elements = this.__notch_elements;
452
+ const container = this.__el_layout;
226
453
 
227
- const majorSegmentValue = major_spec.value;
454
+ while (elements.length < tick_count) {
455
+ const el = document.createElement('div');
228
456
 
229
- if (minor_spec === undefined) {
230
- //no minor spec, only paint major
457
+ container.appendChild(el);
458
+ elements.push(el);
459
+ }
231
460
 
232
- /**
233
- *
234
- * @type {number}
235
- */
236
- const stepCount = maxValue / majorSegmentValue;
461
+ while (elements.length > tick_count) {
462
+ container.removeChild(elements.pop());
463
+ }
237
464
 
238
- const segmentWidth = size.x / stepCount;
465
+ const place = this.__place;
239
466
 
467
+ for (let i = 0; i < tick_count; i++) {
468
+ const tick = ticks[i];
469
+ const tier = tiers[tick.tier];
240
470
 
241
- for (let i = 1; i < stepCount; i++) {
471
+ segment_notch_place(place, 0, tick.value / max, tier.width_px, left, width, ratio);
242
472
 
243
- const x = i * segmentWidth;
473
+ const el = elements[i];
244
474
 
245
- // major notch
475
+ el.className = `notch ${tier.class_name}`;
246
476
 
247
- major_spec.draw(ctx, x, size.y);
477
+ const style = el.style;
248
478
 
249
- }
479
+ style.left = `${place[0]}px`;
480
+ style.width = `${place[1]}px`;
481
+ }
482
+ }
250
483
 
251
- } else {
484
+ /**
485
+ * @param {number} width
486
+ * @param {number} left
487
+ * @param {number} ratio
488
+ * @private
489
+ */
490
+ __place_cells(width, left, ratio) {
491
+ const cells = this.__cells;
252
492
 
253
- const minorSegmentValue = minor_spec.value;
493
+ const layout = segment_cell_layout(width, cells.count, cells.group, ratio);
254
494
 
255
- const majorMultiplier = majorSegmentValue / minorSegmentValue;
495
+ const origin_device = left * ratio;
496
+ const origin_shift_device = Math.round(origin_device) - origin_device;
256
497
 
257
- /**
258
- *
259
- * @type {number}
260
- */
261
- const stepCount = maxValue / minorSegmentValue;
498
+ const cell_x = layout.cell_x_device;
499
+ const cell_width = layout.cell_width_device;
500
+ const elements = this.__cell_elements;
262
501
 
263
- const minorSegmentWidth = size.x / stepCount;
502
+ for (let i = 0; i < cells.count; i++) {
503
+ const style = elements[i].style;
264
504
 
265
- const displayMinor = minorSegmentWidth >= 2;
505
+ style.left = `${(cell_x[i] + origin_shift_device) / ratio}px`;
506
+ style.width = `${cell_width[i] / ratio}px`;
507
+ }
508
+ }
266
509
 
267
- for (let i = 1; i < stepCount; i++) {
510
+ updateFill() {
511
+ const m = this.__value_max.getValue();
268
512
 
269
- const x = i * minorSegmentWidth;
513
+ const values = this.__values_current;
514
+ const value_count = values.length;
270
515
 
271
- if (i % majorMultiplier === 0) {
272
- // major notch
516
+ const fills = this.__value_fills;
517
+ const draw_fills = fills.length > 0;
273
518
 
274
- major_spec.draw(ctx, x, size.y);
519
+ let total = 0;
275
520
 
276
- } else if (displayMinor) {
277
- // minor notch
521
+ for (let i = 0; i < value_count; i++) {
522
+ const value = Math.max(0, values[i].getValue());
278
523
 
279
- minor_spec.draw(ctx, x, size.y);
524
+ const f0 = m > 0 ? clamp01(total / m) : 0;
280
525
 
281
- }
526
+ total += value;
527
+
528
+ const f1 = m > 0 ? clamp01(total / m) : 0;
282
529
 
530
+ if (draw_fills) {
531
+ const style = fills[i].style;
532
+
533
+ style.left = `${f0 * 100}%`;
534
+ style.width = `${(f1 - f0) * 100}%`;
283
535
  }
284
536
  }
537
+
538
+ const total_fraction = m > 0 ? clamp01(total / m) : 0;
539
+
540
+ this.__total_fraction = total_fraction;
541
+
542
+ const now = performance.now();
543
+
544
+ const ghost = this.__ghost;
545
+
546
+ const reduced_motion = this.__reduced_motion !== null && this.__reduced_motion.matches;
547
+
548
+ ghost.duration_min_ms = reduced_motion ? 0 : this.__ghost_duration_min_ms;
549
+ ghost.duration_max_ms = reduced_motion ? 0 : this.__ghost_duration_max_ms;
550
+ ghost.set(total_fraction, now);
551
+
552
+ this.__draw(now);
553
+ }
554
+
555
+ /**
556
+ * Draw the cells (in cell mode) and the ghost as they stand at `time_ms`, and keep animating until the ghost settles
557
+ * @param {number} time_ms
558
+ * @private
559
+ */
560
+ __draw(time_ms) {
561
+ const ghost_fraction = this.__ghost.sample(time_ms);
562
+
563
+ if (this.__cells === null) {
564
+ this.__el_ghost.style.width = `${ghost_fraction * 100}%`;
565
+ } else {
566
+ this.__draw_cells(this.__total_fraction, ghost_fraction);
567
+ }
568
+
569
+ if (!this.__ghost.is_settled(time_ms) && this.isLinked && !this.__frame_pending) {
570
+ this.__frame_pending = true;
571
+ this.__frame_id = requestAnimationFrame(this.__animate_ghost);
572
+ }
285
573
  }
286
574
 
287
- updateFill() {
288
- const m = this.__value_max.getValue();
575
+ /**
576
+ * @param {number} total_fraction
577
+ * @param {number} ghost_fraction
578
+ * @private
579
+ */
580
+ __draw_cells(total_fraction, ghost_fraction) {
581
+ const count = this.__cells.count;
289
582
 
290
- let total_current = 0;
583
+ const fill_cells = snap_whole(total_fraction * count);
584
+ const ghost_cells = snap_whole(ghost_fraction * count);
291
585
 
292
- for (let i = 0; i < this.__values_current.length; i++) {
293
- const v = this.__values_current[i];
586
+ const states = this.__cell_states;
587
+
588
+ for (let i = 0; i < count; i++) {
589
+ const fill = clamp01(fill_cells - i);
590
+ const ghost = clamp01(ghost_cells - i);
591
+
592
+ const state = fill >= 1 ? CELL_STATE_FILLED : (fill > 0 ? CELL_STATE_PARTIAL : CELL_STATE_EMPTY);
593
+
594
+ if (states[i] !== state) {
595
+ states[i] = state;
596
+ this.__cell_elements[i].className = CELL_STATE_CLASS[state];
597
+ }
598
+
599
+ if (this.__cell_fill_drawn[i] !== fill) {
600
+ this.__cell_fill_drawn[i] = fill;
601
+ this.__cell_fill_elements[i].style.width = `${fill * 100}%`;
602
+ }
294
603
 
295
- const value = v.getValue();
604
+ if (this.__cell_ghost_drawn[i] !== ghost) {
605
+ this.__cell_ghost_drawn[i] = ghost;
606
+ this.__cell_ghost_elements[i].style.width = `${ghost * 100}%`;
607
+ }
608
+ }
609
+ }
296
610
 
297
- total_current += value;
611
+ /**
612
+ * @private
613
+ */
614
+ __animate_ghost() {
615
+ this.__frame_pending = false;
298
616
 
299
- const v_fraction = clamp01(v / m);
617
+ if (!this.isLinked) {
618
+ return;
619
+ }
300
620
 
301
- const fill_view = this.__value_fills[i];
621
+ this.__draw(performance.now());
622
+ }
302
623
 
303
- fill_view.el.style.width = `${v_fraction * 100}%`;
624
+ /**
625
+ * Arm a one-shot watch on the current device pixel ratio; it fires when the window moves to another screen or the
626
+ * page is zoomed, neither of which resizes the bar in CSS pixels
627
+ * @private
628
+ */
629
+ __watch_device_pixel_ratio() {
630
+ if (typeof matchMedia !== 'function' || typeof devicePixelRatio !== 'number') {
631
+ return;
304
632
  }
305
633
 
634
+ const query = matchMedia(`(resolution: ${devicePixelRatio}dppx)`);
635
+
636
+ query.addEventListener('change', this.__handle_dpr_change, { once: true });
306
637
 
307
- const f = clamp01(total_current / m);
638
+ this.__dpr_query = query;
639
+ }
640
+
641
+ /**
642
+ * @private
643
+ */
644
+ __handle_dpr_change() {
645
+ this.__dpr_query = null;
308
646
 
309
- const width = `${f * 100}%`;
647
+ if (!this.isLinked) {
648
+ return;
649
+ }
310
650
 
311
- this.__v__ghost.el.style.width = width;
651
+ this.updateSegments();
652
+ this.__watch_device_pixel_ratio();
312
653
  }
313
654
  }