@drawcall/lod 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/README.md +8 -6
  2. package/dist/bake.d.ts +22 -0
  3. package/dist/bake.js +88 -0
  4. package/dist/bake.js.map +1 -0
  5. package/dist/baked/codec.d.ts +3 -6
  6. package/dist/baked/codec.js +48 -154
  7. package/dist/baked/codec.js.map +1 -1
  8. package/dist/baked/coverage.d.ts +6 -3
  9. package/dist/baked/coverage.js +6 -3
  10. package/dist/baked/coverage.js.map +1 -1
  11. package/dist/baked/fields.d.ts +9 -0
  12. package/dist/baked/fields.js +22 -0
  13. package/dist/baked/fields.js.map +1 -0
  14. package/dist/baked/index.d.ts +12 -6
  15. package/dist/baked/index.js +22 -20
  16. package/dist/baked/index.js.map +1 -1
  17. package/dist/baked/interior/faces.d.ts +4 -3
  18. package/dist/baked/interior/faces.js +13 -10
  19. package/dist/baked/interior/faces.js.map +1 -1
  20. package/dist/baked/interior/material.d.ts +7 -10
  21. package/dist/baked/interior/material.js +29 -36
  22. package/dist/baked/interior/material.js.map +1 -1
  23. package/dist/baked/interior/rooms.js +1 -1
  24. package/dist/baked/interior/rooms.js.map +1 -1
  25. package/dist/baked/low.js +5 -4
  26. package/dist/baked/low.js.map +1 -1
  27. package/dist/baked/raster.js +6 -6
  28. package/dist/baked/raster.js.map +1 -1
  29. package/dist/baked/textures.d.ts +17 -0
  30. package/dist/baked/textures.js +95 -0
  31. package/dist/baked/textures.js.map +1 -0
  32. package/dist/baked/transfer.js +19 -18
  33. package/dist/baked/transfer.js.map +1 -1
  34. package/dist/baked/unwrap.js +4 -3
  35. package/dist/baked/unwrap.js.map +1 -1
  36. package/dist/baked/xatlas.js.map +1 -1
  37. package/dist/codec/container.d.ts +8 -0
  38. package/dist/codec/container.js +63 -0
  39. package/dist/codec/container.js.map +1 -0
  40. package/dist/codec/mesh.d.ts +8 -0
  41. package/dist/{mesh/codec.js → codec/mesh.js} +80 -52
  42. package/dist/codec/mesh.js.map +1 -0
  43. package/dist/dispose.d.ts +7 -4
  44. package/dist/dispose.js +20 -22
  45. package/dist/dispose.js.map +1 -1
  46. package/dist/gpu.d.ts +39 -0
  47. package/dist/gpu.js +41 -0
  48. package/dist/gpu.js.map +1 -0
  49. package/dist/impostor/bake/atlas.d.ts +4 -4
  50. package/dist/impostor/bake/atlas.js +12 -12
  51. package/dist/impostor/bake/atlas.js.map +1 -1
  52. package/dist/impostor/bake/fit.d.ts +8 -0
  53. package/dist/impostor/bake/fit.js +28 -0
  54. package/dist/impostor/bake/fit.js.map +1 -0
  55. package/dist/impostor/bake/index.d.ts +22 -14
  56. package/dist/impostor/bake/index.js +41 -134
  57. package/dist/impostor/bake/index.js.map +1 -1
  58. package/dist/impostor/bake/materials.d.ts +3 -3
  59. package/dist/impostor/bake/materials.js +51 -13
  60. package/dist/impostor/bake/materials.js.map +1 -1
  61. package/dist/impostor/bake/sheet.d.ts +8 -0
  62. package/dist/impostor/bake/sheet.js +90 -0
  63. package/dist/impostor/bake/sheet.js.map +1 -0
  64. package/dist/impostor/bake/source.d.ts +2 -2
  65. package/dist/impostor/bake/source.js +8 -19
  66. package/dist/impostor/bake/source.js.map +1 -1
  67. package/dist/impostor/codec.d.ts +4 -5
  68. package/dist/impostor/codec.js +36 -109
  69. package/dist/impostor/codec.js.map +1 -1
  70. package/dist/impostor/impostor.d.ts +31 -7
  71. package/dist/impostor/impostor.js +21 -6
  72. package/dist/impostor/impostor.js.map +1 -1
  73. package/dist/impostor/ktx2/encode.d.ts +26 -0
  74. package/dist/impostor/ktx2/encode.js +117 -0
  75. package/dist/impostor/ktx2/encode.js.map +1 -0
  76. package/dist/impostor/ktx2/transcode.d.ts +3 -0
  77. package/dist/impostor/ktx2/transcode.js +99 -0
  78. package/dist/impostor/ktx2/transcode.js.map +1 -0
  79. package/dist/impostor/ktx2/uastc.d.ts +7 -0
  80. package/dist/impostor/ktx2/uastc.js +64 -0
  81. package/dist/impostor/ktx2/uastc.js.map +1 -0
  82. package/dist/impostor/ktx2/wasm/encoder.d.ts +4 -0
  83. package/dist/impostor/ktx2/wasm/encoder.js +10 -0
  84. package/dist/impostor/ktx2/wasm/encoder.js.map +1 -0
  85. package/dist/impostor/ktx2/wasm/transcoder.d.ts +3 -0
  86. package/dist/impostor/ktx2/wasm/transcoder.js +9 -0
  87. package/dist/impostor/ktx2/wasm/transcoder.js.map +1 -0
  88. package/dist/impostor/ktx2/worker.d.ts +1 -0
  89. package/dist/impostor/ktx2/worker.js +12 -0
  90. package/dist/impostor/ktx2/worker.js.map +1 -0
  91. package/dist/impostor/mesh/card.d.ts +3 -3
  92. package/dist/impostor/mesh/card.js +7 -7
  93. package/dist/impostor/mesh/card.js.map +1 -1
  94. package/dist/impostor/mesh/index.d.ts +5 -4
  95. package/dist/impostor/mesh/index.js +8 -9
  96. package/dist/impostor/mesh/index.js.map +1 -1
  97. package/dist/impostor/mesh/material.d.ts +18 -9
  98. package/dist/impostor/mesh/material.js +40 -27
  99. package/dist/impostor/mesh/material.js.map +1 -1
  100. package/dist/impostor/mesh/surface.d.ts +1 -1
  101. package/dist/impostor/mesh/surface.js +13 -9
  102. package/dist/impostor/mesh/surface.js.map +1 -1
  103. package/dist/impostor/mesh/textures.d.ts +3 -3
  104. package/dist/impostor/mesh/textures.js +24 -34
  105. package/dist/impostor/mesh/textures.js.map +1 -1
  106. package/dist/index.d.ts +15 -10
  107. package/dist/index.js +13 -8
  108. package/dist/index.js.map +1 -1
  109. package/dist/instanced/camera.d.ts +46 -0
  110. package/dist/instanced/camera.js +70 -0
  111. package/dist/instanced/camera.js.map +1 -0
  112. package/dist/instanced/chunk.d.ts +97 -0
  113. package/dist/instanced/chunk.js +156 -0
  114. package/dist/instanced/chunk.js.map +1 -0
  115. package/dist/instanced/chunks.d.ts +60 -0
  116. package/dist/instanced/chunks.js +208 -0
  117. package/dist/instanced/chunks.js.map +1 -0
  118. package/dist/instanced/cull.d.ts +28 -0
  119. package/dist/instanced/cull.js +22 -0
  120. package/dist/instanced/cull.js.map +1 -0
  121. package/dist/instanced/index.d.ts +96 -66
  122. package/dist/instanced/index.js +229 -288
  123. package/dist/instanced/index.js.map +1 -1
  124. package/dist/instanced/key.d.ts +19 -0
  125. package/dist/instanced/key.js +45 -0
  126. package/dist/instanced/key.js.map +1 -0
  127. package/dist/instanced/levels.d.ts +60 -0
  128. package/dist/instanced/levels.js +130 -0
  129. package/dist/instanced/levels.js.map +1 -0
  130. package/dist/instanced/lists.d.ts +70 -0
  131. package/dist/instanced/lists.js +133 -0
  132. package/dist/instanced/lists.js.map +1 -0
  133. package/dist/instanced/measure.d.ts +28 -0
  134. package/dist/instanced/measure.js +203 -0
  135. package/dist/instanced/measure.js.map +1 -0
  136. package/dist/instanced/meshes.d.ts +42 -51
  137. package/dist/instanced/meshes.js +158 -180
  138. package/dist/instanced/meshes.js.map +1 -1
  139. package/dist/instanced/mirror.d.ts +20 -0
  140. package/dist/instanced/mirror.js +37 -0
  141. package/dist/instanced/mirror.js.map +1 -0
  142. package/dist/instanced/pages/buffers.d.ts +37 -0
  143. package/dist/instanced/pages/buffers.js +15 -0
  144. package/dist/instanced/pages/buffers.js.map +1 -0
  145. package/dist/instanced/pages/chunk.d.ts +51 -0
  146. package/dist/instanced/pages/chunk.js +81 -0
  147. package/dist/instanced/pages/chunk.js.map +1 -0
  148. package/dist/instanced/pages/index.d.ts +74 -0
  149. package/dist/instanced/pages/index.js +269 -0
  150. package/dist/instanced/pages/index.js.map +1 -0
  151. package/dist/instanced/pages/passes.d.ts +21 -0
  152. package/dist/instanced/pages/passes.js +52 -0
  153. package/dist/instanced/pages/passes.js.map +1 -0
  154. package/dist/instanced/pages/slots.d.ts +11 -0
  155. package/dist/instanced/pages/slots.js +90 -0
  156. package/dist/instanced/pages/slots.js.map +1 -0
  157. package/dist/instanced/pages/workgroup.d.ts +14 -0
  158. package/dist/instanced/pages/workgroup.js +38 -0
  159. package/dist/instanced/pages/workgroup.js.map +1 -0
  160. package/dist/instanced/raycast.d.ts +13 -11
  161. package/dist/instanced/raycast.js +33 -40
  162. package/dist/instanced/raycast.js.map +1 -1
  163. package/dist/instanced/rows.d.ts +108 -0
  164. package/dist/instanced/rows.js +209 -0
  165. package/dist/instanced/rows.js.map +1 -0
  166. package/dist/instanced/shape.d.ts +25 -0
  167. package/dist/instanced/shape.js +51 -0
  168. package/dist/instanced/shape.js.map +1 -0
  169. package/dist/instanced/sort.d.ts +63 -0
  170. package/dist/instanced/sort.js +162 -0
  171. package/dist/instanced/sort.js.map +1 -0
  172. package/dist/instanced/update.d.ts +30 -0
  173. package/dist/instanced/update.js +207 -0
  174. package/dist/instanced/update.js.map +1 -0
  175. package/dist/levels/bounds.d.ts +21 -0
  176. package/dist/levels/bounds.js +42 -0
  177. package/dist/levels/bounds.js.map +1 -0
  178. package/dist/levels/cameras.d.ts +48 -0
  179. package/dist/levels/cameras.js +122 -0
  180. package/dist/levels/cameras.js.map +1 -0
  181. package/dist/levels/compile/contexts.d.ts +30 -0
  182. package/dist/levels/compile/contexts.js +18 -0
  183. package/dist/levels/compile/contexts.js.map +1 -0
  184. package/dist/levels/compile/index.d.ts +39 -0
  185. package/dist/levels/compile/index.js +185 -0
  186. package/dist/levels/compile/index.js.map +1 -0
  187. package/dist/levels/compile/pipelines.d.ts +26 -0
  188. package/dist/levels/compile/pipelines.js +177 -0
  189. package/dist/levels/compile/pipelines.js.map +1 -0
  190. package/dist/levels/compiles.d.ts +29 -0
  191. package/dist/levels/compiles.js +50 -0
  192. package/dist/levels/compiles.js.map +1 -0
  193. package/dist/levels/draw.d.ts +102 -0
  194. package/dist/levels/draw.js +401 -0
  195. package/dist/levels/draw.js.map +1 -0
  196. package/dist/levels/fade.d.ts +69 -0
  197. package/dist/levels/fade.js +150 -0
  198. package/dist/levels/fade.js.map +1 -0
  199. package/dist/levels/index.d.ts +99 -0
  200. package/dist/levels/index.js +155 -0
  201. package/dist/levels/index.js.map +1 -0
  202. package/dist/levels/item.d.ts +38 -0
  203. package/dist/levels/item.js +97 -0
  204. package/dist/levels/item.js.map +1 -0
  205. package/dist/levels/load.d.ts +31 -0
  206. package/dist/levels/load.js +142 -0
  207. package/dist/levels/load.js.map +1 -0
  208. package/dist/levels/manager.d.ts +159 -0
  209. package/dist/levels/manager.js +339 -0
  210. package/dist/levels/manager.js.map +1 -0
  211. package/dist/{material.js → levels/material.js} +4 -3
  212. package/dist/levels/material.js.map +1 -0
  213. package/dist/levels/renderer.d.ts +29 -0
  214. package/dist/levels/renderer.js +41 -0
  215. package/dist/levels/renderer.js.map +1 -0
  216. package/dist/levels/requests.d.ts +49 -0
  217. package/dist/levels/requests.js +95 -0
  218. package/dist/levels/requests.js.map +1 -0
  219. package/dist/levels/screen.d.ts +14 -0
  220. package/dist/levels/screen.js +21 -0
  221. package/dist/levels/screen.js.map +1 -0
  222. package/dist/levels/wait.d.ts +27 -0
  223. package/dist/levels/wait.js +61 -0
  224. package/dist/levels/wait.js.map +1 -0
  225. package/dist/loader/build.d.ts +10 -0
  226. package/dist/loader/build.js +28 -0
  227. package/dist/loader/build.js.map +1 -0
  228. package/dist/loader/cache.d.ts +6 -9
  229. package/dist/loader/cache.js +17 -24
  230. package/dist/loader/cache.js.map +1 -1
  231. package/dist/loader/context.d.ts +46 -0
  232. package/dist/loader/context.js +91 -0
  233. package/dist/loader/context.js.map +1 -0
  234. package/dist/loader/{provenance.d.ts → dependencies.d.ts} +5 -3
  235. package/dist/loader/{provenance.js → dependencies.js} +12 -4
  236. package/dist/loader/dependencies.js.map +1 -0
  237. package/dist/loader/index.d.ts +62 -0
  238. package/dist/loader/index.js +284 -0
  239. package/dist/loader/index.js.map +1 -0
  240. package/dist/loader/level.d.ts +41 -0
  241. package/dist/loader/level.js +140 -0
  242. package/dist/loader/level.js.map +1 -0
  243. package/dist/loader/request.d.ts +87 -0
  244. package/dist/loader/request.js +59 -0
  245. package/dist/loader/request.js.map +1 -0
  246. package/dist/loader/url.d.ts +5 -2
  247. package/dist/loader/url.js +10 -6
  248. package/dist/loader/url.js.map +1 -1
  249. package/dist/lod.d.ts +81 -40
  250. package/dist/lod.js +196 -149
  251. package/dist/lod.js.map +1 -1
  252. package/dist/meshopt.d.ts +6 -0
  253. package/dist/meshopt.js +19 -0
  254. package/dist/meshopt.js.map +1 -0
  255. package/dist/simplify/cards.d.ts +14 -0
  256. package/dist/simplify/cards.js +128 -0
  257. package/dist/simplify/cards.js.map +1 -0
  258. package/dist/{simplify.d.ts → simplify/index.d.ts} +7 -4
  259. package/dist/{simplify.js → simplify/index.js} +41 -23
  260. package/dist/simplify/index.js.map +1 -0
  261. package/dist/{bounds.d.ts → source/detail.d.ts} +4 -23
  262. package/dist/{bounds.js → source/detail.js} +19 -51
  263. package/dist/source/detail.js.map +1 -0
  264. package/dist/source/deviation.js +6 -6
  265. package/dist/source/deviation.js.map +1 -1
  266. package/dist/source/{shading.d.ts → evaluator.d.ts} +10 -10
  267. package/dist/source/{shading.js → evaluator.js} +5 -5
  268. package/dist/source/evaluator.js.map +1 -0
  269. package/dist/source/{trace.d.ts → raycaster.d.ts} +6 -6
  270. package/dist/source/{trace.js → raycaster.js} +8 -8
  271. package/dist/source/raycaster.js.map +1 -0
  272. package/dist/source/{texels.d.ts → sampler.d.ts} +1 -1
  273. package/dist/source/{texels.js → sampler.js} +3 -3
  274. package/dist/source/sampler.js.map +1 -0
  275. package/dist/source/source.d.ts +1 -1
  276. package/dist/source/source.js +1 -1
  277. package/dist/source/source.js.map +1 -1
  278. package/dist/source/surface.js +1 -1
  279. package/dist/source/surface.js.map +1 -1
  280. package/dist/task.d.ts +6 -0
  281. package/dist/{pause.js → task.js} +5 -5
  282. package/dist/task.js.map +1 -0
  283. package/dist/three.d.ts +13 -24
  284. package/dist/three.js +26 -53
  285. package/dist/three.js.map +1 -1
  286. package/dist/tsl.d.ts +8 -12
  287. package/dist/tsl.js +11 -39
  288. package/dist/tsl.js.map +1 -1
  289. package/dist/typegpu.d.ts +37 -0
  290. package/dist/typegpu.js +37 -0
  291. package/dist/typegpu.js.map +1 -0
  292. package/dist/wind/bounds.js +2 -2
  293. package/dist/wind/bounds.js.map +1 -1
  294. package/dist/wind/hooks.d.ts +7 -4
  295. package/dist/wind/hooks.js +5 -2
  296. package/dist/wind/hooks.js.map +1 -1
  297. package/dist/wind/index.d.ts +2 -2
  298. package/dist/wind/index.js +15 -15
  299. package/dist/wind/index.js.map +1 -1
  300. package/dist/wind/sway.d.ts +2 -0
  301. package/dist/wind/sway.js +4 -1
  302. package/dist/wind/sway.js.map +1 -1
  303. package/package.json +18 -8
  304. package/skills/lod/SKILL.md +108 -31
  305. package/dist/bounds.js.map +0 -1
  306. package/dist/compile.d.ts +0 -4
  307. package/dist/compile.js +0 -100
  308. package/dist/compile.js.map +0 -1
  309. package/dist/deferred.d.ts +0 -12
  310. package/dist/deferred.js +0 -27
  311. package/dist/deferred.js.map +0 -1
  312. package/dist/fade.d.ts +0 -36
  313. package/dist/fade.js +0 -112
  314. package/dist/fade.js.map +0 -1
  315. package/dist/instanced/args.d.ts +0 -20
  316. package/dist/instanced/args.js +0 -77
  317. package/dist/instanced/args.js.map +0 -1
  318. package/dist/instanced/blocks.d.ts +0 -66
  319. package/dist/instanced/blocks.js +0 -294
  320. package/dist/instanced/blocks.js.map +0 -1
  321. package/dist/instanced/dirty.d.ts +0 -15
  322. package/dist/instanced/dirty.js +0 -96
  323. package/dist/instanced/dirty.js.map +0 -1
  324. package/dist/instanced/parts.d.ts +0 -14
  325. package/dist/instanced/parts.js +0 -79
  326. package/dist/instanced/parts.js.map +0 -1
  327. package/dist/instanced/select.d.ts +0 -92
  328. package/dist/instanced/select.js +0 -315
  329. package/dist/instanced/select.js.map +0 -1
  330. package/dist/instanced/store.d.ts +0 -31
  331. package/dist/instanced/store.js +0 -96
  332. package/dist/instanced/store.js.map +0 -1
  333. package/dist/levels.d.ts +0 -95
  334. package/dist/levels.js +0 -171
  335. package/dist/levels.js.map +0 -1
  336. package/dist/loader/bundle.d.ts +0 -25
  337. package/dist/loader/bundle.js +0 -241
  338. package/dist/loader/bundle.js.map +0 -1
  339. package/dist/loader/provenance.js.map +0 -1
  340. package/dist/loader.d.ts +0 -55
  341. package/dist/loader.js +0 -239
  342. package/dist/loader.js.map +0 -1
  343. package/dist/material.js.map +0 -1
  344. package/dist/mesh/codec.d.ts +0 -4
  345. package/dist/mesh/codec.js.map +0 -1
  346. package/dist/pause.d.ts +0 -6
  347. package/dist/pause.js.map +0 -1
  348. package/dist/queue.d.ts +0 -2
  349. package/dist/queue.js +0 -33
  350. package/dist/queue.js.map +0 -1
  351. package/dist/renderer.d.ts +0 -21
  352. package/dist/renderer.js +0 -83
  353. package/dist/renderer.js.map +0 -1
  354. package/dist/residency.d.ts +0 -44
  355. package/dist/residency.js +0 -205
  356. package/dist/residency.js.map +0 -1
  357. package/dist/simplify.js.map +0 -1
  358. package/dist/source/shading.js.map +0 -1
  359. package/dist/source/texels.js.map +0 -1
  360. package/dist/source/trace.js.map +0 -1
  361. package/dist/view.d.ts +0 -45
  362. package/dist/view.js +0 -131
  363. package/dist/view.js.map +0 -1
  364. /package/dist/{material.d.ts → levels/material.d.ts} +0 -0
@@ -0,0 +1,339 @@
1
+ import { nextTask } from "../task.js";
2
+ import { isObject3D, isScene, rootOf } from "../three.js";
3
+ import { CameraRenders } from "./cameras.js";
4
+ import { has } from "./draw.js";
5
+ import { LoadingItem } from "./item.js";
6
+ import { CameraRequests } from "./requests.js";
7
+ import { ChunkWait } from "./wait.js";
8
+ import { ContextCompiles } from "./compiles.js";
9
+ /** How long an arriving level fades in for, over what drew in its place. */
10
+ export const ARRIVAL_MS = 200;
11
+ /**
12
+ * Loads a Lod's or InstancedLod's levels as its cameras request them, never blocking a render. The coarsest level that
13
+ * draws something loads first, as nothing draws before it has (see levelsToDraw); the other levels a camera wants
14
+ * start loading once it has loaded. Each level's load runs once; once the render that asked for it has ended, the Lod
15
+ * prepares it (`prepare`), it compiles for the render context of every camera rendering the Lod and joins the loaded
16
+ * levels. Levels join only between arrivals, each of which fades in for ARRIVAL_MS from the levels loaded `before` it.
17
+ * Each render context seen for the first time compiles in the background every loaded level that draws something,
18
+ * given ones included, that no camera rendering the Lod wants: three skips a draw whose pipeline a compileAsync is
19
+ * still building, in any context that shares it, so a level a camera may draw now builds as it first draws instead.
20
+ * Nothing is evicted: a level stays loaded until the Lod is disposed.
21
+ *
22
+ * A Lod draws with its LodGpu's renderer, whose renders it learns its cameras from. It holds an item on its LoadingManager while anything a camera wants is missing, compiling or arriving,
23
+ * and an InstancedLod's while the GPU has not shown its chunks taken in (see `chunksChanged`).
24
+ */
25
+ export class LodLevelLoadManager {
26
+ lod;
27
+ gpu;
28
+ name;
29
+ levels;
30
+ prepare;
31
+ drawnBy;
32
+ /** The bits of the levels that draw: given ones from the start, deferred ones once loaded and compiled. */
33
+ loaded = 0;
34
+ /** The bits loaded before the latest arrival (see `progress`). */
35
+ before = 0;
36
+ /** The first failure; it stops further loading. */
37
+ error;
38
+ /** Whether a render has updated the Lod: its shaders are being or have been built. */
39
+ started = false;
40
+ /** What draws the Lod: its LodGpu's renderer. */
41
+ renderer;
42
+ /** The cameras rendering the Lod, and what they asked for. */
43
+ requests;
44
+ /** Its item on a LoadingManager. */
45
+ item;
46
+ /**
47
+ * The bits of the levels that draw nothing, the coarsest level that draws something, and the order levels load in: it
48
+ * first, then coarse to fine.
49
+ */
50
+ empty;
51
+ coarsest;
52
+ order;
53
+ /** When the latest arrival began. */
54
+ arrival;
55
+ /** Compiled levels waiting for the arrival under way to end. */
56
+ ready = new Map();
57
+ /** Levels being prepared and compiled to join the loaded ones. */
58
+ arriving = new Map();
59
+ /** The background compiles of loaded levels, per render context. */
60
+ compiles;
61
+ /** Per level, its load once started. */
62
+ loads = new Map();
63
+ /** What renders told of the cameras that drew the Lod. */
64
+ seen = new CameraRenders();
65
+ disposed = false;
66
+ /** What `LodLevel.hold` answered, each called once the Lod is disposed. */
67
+ releases;
68
+ /** An InstancedLod's chunks, while they wait to be shown taken in (see `chunksChanged`); null for a Lod. */
69
+ wait;
70
+ constructor(lod, gpu,
71
+ /** The LoadingManager item's name, which errors name too: the kind of Lod and its uuid. */
72
+ name,
73
+ /** The levels as the Lod was given them: it holds them (see `LodLevel.hold`) until it is disposed. */
74
+ levels,
75
+ /** The levels as levelsToDraw reads them, for the ones that draw nothing and the coarsest that draws something. */
76
+ { empty, coarsest }, prepare,
77
+ /** What draws a loaded level, compiled for each render context it is wanted in. */
78
+ drawnBy,
79
+ /** An InstancedLod's read of whether the GPU shows every chunk taken in (see `ChunkWait`); null for a Lod. */
80
+ readChunks) {
81
+ this.lod = lod;
82
+ this.gpu = gpu;
83
+ this.name = name;
84
+ this.levels = levels;
85
+ this.prepare = prepare;
86
+ this.drawnBy = drawnBy;
87
+ if (gpu.disposed)
88
+ throw new Error("LodGpu: disposed");
89
+ this.loaded = this.before = levels.reduce((bits, level, i) => (level.object ? bits | (1 << i) : bits), 0);
90
+ this.empty = empty;
91
+ this.coarsest = coarsest;
92
+ this.order = levels.length === 0 ? [] : [coarsest, ...[...levels.keys()].reverse().filter((level) => level !== coarsest)];
93
+ this.releases = [...new Set(levels.flatMap(({ hold }) => (hold ? [hold] : [])))].map((hold) => hold());
94
+ this.renderer = gpu.renderer;
95
+ this.requests = new CameraRequests(this.renderer, this.seen);
96
+ this.compiles = new ContextCompiles((context, bits) => this.compileLevels(context, bits), (error) => this.report(error));
97
+ this.item = new LoadingItem(lod, name, this.renderer);
98
+ this.wait =
99
+ readChunks &&
100
+ new ChunkWait(readChunks, () => this.sync(), (error) => this.report(error));
101
+ }
102
+ /** How far the latest arrival has faded in, in [0, 1]: 1 once it has. */
103
+ get progress() {
104
+ if (this.arrival === undefined)
105
+ return 1;
106
+ return Math.min((performance.now() - this.arrival) / ARRIVAL_MS, 1);
107
+ }
108
+ get pending() {
109
+ if (this.disposed || this.error)
110
+ return false;
111
+ if (this.arriving.size > 0 || this.ready.size > 0 || (this.requests.needed() & ~this.loaded) !== 0)
112
+ return true;
113
+ return this.compiles.running(this.requests);
114
+ }
115
+ /**
116
+ * `camera`, a shadow map's when `shadow`, wants the levels of the bits `wanted` (see levelsToLoad): load what is
117
+ * missing, and answer the bits of the levels loaded now. Outside a Scene a missing level is an error, as no render of it would load it.
118
+ */
119
+ request(camera, wanted, shadow) {
120
+ this.started = true;
121
+ const scene = rootOf(this.lod);
122
+ if (this.disposed || this.error)
123
+ return this.loaded;
124
+ if (!isScene(scene)) {
125
+ if ((wanted & ~this.loaded) !== 0)
126
+ throw new Error(`${this.name}: render a Scene that holds it to load the levels it needs`);
127
+ return this.loaded;
128
+ }
129
+ this.item.touch();
130
+ const frame = this.requests.set(scene, camera, wanted, shadow);
131
+ this.load(camera, shadow, frame);
132
+ this.wait?.render();
133
+ this.sync();
134
+ return this.loaded;
135
+ }
136
+ /**
137
+ * An InstancedLod's chunks were added or removed: hold the item until, a few renders later, the GPU shows each taken
138
+ * in, so that a host waiting for its LoadingManager sees them drawn. A chunk the pool lacks room for is the
139
+ * InstancedLod's error.
140
+ */
141
+ chunksChanged() {
142
+ if (!this.wait)
143
+ throw new Error(`LodLevelLoadManager: chunksChanged on ${this.name}, a Lod without chunks`);
144
+ this.wait.changed();
145
+ this.sync();
146
+ }
147
+ /**
148
+ * The height `camera`, a shadow map's when `shadow`, draws at (see CameraRenders.heightOf), which levels are chosen
149
+ * at.
150
+ */
151
+ heightOf(camera, shadow) {
152
+ return this.seen.heightOf(camera, this.renderer, shadow);
153
+ }
154
+ /** What compiles for `cameras` are for: the shadow maps they drew, and the targets disposed. */
155
+ compileFor(cameras) {
156
+ return { shadows: this.seen.shadowsOf(cameras), isDisposed: (target) => this.seen.isDisposed(target) };
157
+ }
158
+ /**
159
+ * Load what the cameras still rendering the Lod want, in `order`, compile for `camera`'s render context every loaded
160
+ * level that draws something, none of them wants and is not yet compiled for it, and prepare the levels that have
161
+ * loaded. `shadow` is whether a shadow map renders it, in the renderer's `frame`.
162
+ */
163
+ load(camera, shadow, frame) {
164
+ const needed = this.requests.needed();
165
+ const coarsestLoaded = !this.levelAt(this.coarsest).load || this.loads.get(this.coarsest)?.object !== undefined;
166
+ for (const level of this.order) {
167
+ const { load } = this.levelAt(level);
168
+ if (!load || !has(needed, level) || this.loads.has(level) || (!coarsestLoaded && level !== this.coarsest))
169
+ continue;
170
+ this.start(level, load);
171
+ }
172
+ // What draws never changes halfway through a frame: once a camera updated the Lod in it, as for an InstancedLod
173
+ // its indirect draws, a shadow map rendered later joins nothing. The camera's next update does; a Lod only shadow
174
+ // maps update joins in theirs.
175
+ if (!shadow || this.requests.cameraFrame !== frame)
176
+ this.join();
177
+ const context = this.seen.contextOf(camera);
178
+ if (!context)
179
+ return;
180
+ this.compiles.compile(context, this.compiles.claim(context, this.loaded & ~this.empty & ~needed));
181
+ const missing = needed & ~this.loaded;
182
+ for (const level of this.order) {
183
+ if (!has(missing, level) || !this.loads.get(level)?.object || this.arriving.has(level) || this.ready.has(level))
184
+ continue;
185
+ this.arrive(level, context);
186
+ }
187
+ }
188
+ /** Run level `level`'s `load`, holding the object it makes. */
189
+ start(level, load) {
190
+ const entry = {
191
+ promise: Promise.resolve()
192
+ .then(load)
193
+ .then((object) => {
194
+ if (!isObject3D(object))
195
+ throw new Error(`${this.name}: level ${level}'s load must return an Object3D`);
196
+ entry.object = object;
197
+ return object;
198
+ })
199
+ .catch((error) => {
200
+ entry.error = error instanceof Error ? error : new Error(`${this.name}: level ${level} failed to load`, { cause: error });
201
+ throw entry.error;
202
+ }),
203
+ };
204
+ this.loads.set(level, entry);
205
+ void entry.promise.catch((error) => this.report(error));
206
+ }
207
+ levelAt(level) {
208
+ const found = this.levels[level];
209
+ if (!found)
210
+ throw new Error(`${this.name}: no level ${level}`);
211
+ return found;
212
+ }
213
+ /** Compile the loaded levels of `bits` for `context`: a background compile (see ContextCompiles). */
214
+ async compileLevels(context, bits) {
215
+ // A context whose target was disposed meanwhile is dropped: compiling would revive the target.
216
+ if (this.disposed || !this.seen.holds(context))
217
+ return;
218
+ const objects = this.order.filter((level) => has(bits, level)).flatMap((level) => this.drawnBy(level));
219
+ const compileFor = this.compileFor(this.requests.cameras());
220
+ await Promise.all(objects.map((object) => this.gpu.compiler.compileAsync(object, context, compileFor)));
221
+ }
222
+ /**
223
+ * Prepare `level` once the render that asked for it has ended, if a camera still wants it then, and compile it for
224
+ * the render context of every camera still rendering the Lod, `context` among them, to join the loaded levels: a
225
+ * slow level never holds another's, and no camera draws it uncompiled.
226
+ */
227
+ arrive(level, context) {
228
+ // A render runs within one task: the next starts after it has ended.
229
+ const done = nextTask()
230
+ .then(async () => {
231
+ const object = this.loads.get(level)?.object;
232
+ if (this.disposed || !object || !has(this.requests.needed(), level))
233
+ return;
234
+ const cameras = this.requests.cameras();
235
+ // Contexts whose targets were disposed meanwhile are dropped. A camera that starts rendering the Lod while it
236
+ // arrives draws it with pipelines built in that frame.
237
+ const seen = [context, ...cameras.flatMap((camera) => this.seen.contextOf(camera) ?? [])];
238
+ const contexts = new Set(seen.filter((other) => this.seen.holds(other)));
239
+ for (const other of contexts)
240
+ this.compiles.claim(other, 1 << level);
241
+ const prepared = this.prepare(level, object);
242
+ try {
243
+ const compileFor = this.compileFor(cameras);
244
+ await Promise.all([...contexts].map((other) => this.gpu.compiler.compileAsync(prepared.object, other, compileFor)));
245
+ }
246
+ catch (error) {
247
+ prepared.discard();
248
+ throw error;
249
+ }
250
+ if (this.disposed)
251
+ return prepared.discard();
252
+ this.ready.set(level, prepared);
253
+ })
254
+ .catch((error) => this.report(error))
255
+ .finally(() => {
256
+ this.arriving.delete(level);
257
+ this.join();
258
+ });
259
+ this.arriving.set(level, done);
260
+ }
261
+ /** Let compiled levels join the loaded ones, between arrivals: what draws never changes halfway through a fade. */
262
+ join() {
263
+ if (this.disposed || this.ready.size === 0 || this.progress < 1)
264
+ return;
265
+ this.before = this.loaded;
266
+ for (const [level, prepared] of this.ready) {
267
+ prepared.join();
268
+ this.loaded |= 1 << level;
269
+ }
270
+ this.ready.clear();
271
+ this.arrival = performance.now();
272
+ queueMicrotask(() => {
273
+ if (!this.disposed)
274
+ this.lod.dispatchEvent({ type: "levelschange" });
275
+ });
276
+ }
277
+ /**
278
+ * Hold the item while levels a camera wants are missing, compiling or arriving, or chunks wait to be shown taken in,
279
+ * and end it once they are done, so a host waiting for its LoadingManager renders its cameras complete. Called at
280
+ * the end of each request.
281
+ */
282
+ sync() {
283
+ this.item.sync(!this.disposed && !this.error && (this.pending || (this.wait !== null && this.wait.waiting) || this.progress < 1));
284
+ }
285
+ /**
286
+ * The one failure rule, for a level that fails and for anything that throws while three renders, where a throw would
287
+ * leave its internal target bound: note the error, log it, report it on the LoadingManager the item is held on and
288
+ * end the item, and dispatch `levelserror`. Only the first is reported; it stops further loading.
289
+ */
290
+ report(error) {
291
+ if (this.disposed || this.error)
292
+ return;
293
+ const failure = (this.error = error instanceof Error ? error : new Error("Lod: level failed", { cause: error }));
294
+ console.error(failure);
295
+ this.item.fail();
296
+ this.lod.dispatchEvent({ type: "levelserror", error: failure });
297
+ }
298
+ /** Run `action`, part of an update or a draw callback, reporting what it throws instead. */
299
+ guard(action) {
300
+ try {
301
+ action();
302
+ }
303
+ catch (error) {
304
+ this.report(error);
305
+ }
306
+ }
307
+ /**
308
+ * Stop loading, then `release` what the Lod made of its levels and let go of what it holds of them (see
309
+ * `LodLevel.hold`), once nothing preparing, compiling or loading still uses them. What the levels gave or loaded is
310
+ * not freed: it is whoever made it's.
311
+ */
312
+ dispose(release) {
313
+ this.disposed = true;
314
+ this.item.sync(false);
315
+ this.seen.dispose();
316
+ for (const prepared of this.ready.values())
317
+ prepared.discard();
318
+ this.ready.clear();
319
+ const free = () => {
320
+ release();
321
+ for (const letGo of this.releases)
322
+ letGo();
323
+ };
324
+ const finish = () => {
325
+ const unsettled = [...this.loads.values()].flatMap((entry) => (!entry.object && !entry.error ? [entry.promise] : []));
326
+ // A mesh decode can begin its source-material dependency after disposal starts.
327
+ if (unsettled.length)
328
+ void Promise.allSettled(unsettled).then(free);
329
+ else
330
+ free();
331
+ };
332
+ const tasks = [...this.arriving.values(), ...this.compiles.tasks()];
333
+ if (tasks.length > 0)
334
+ void Promise.all(tasks).then(finish);
335
+ else
336
+ finish();
337
+ }
338
+ }
339
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/levels/manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,GAAG,EAAmB,MAAM,WAAW,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC;AAyB9B;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,mBAAmB;IA0CX;IACA;IAEA;IAEA;IAGA;IAEA;IAnDnB,2GAA2G;IAC3G,MAAM,GAAG,CAAC,CAAC;IACX,kEAAkE;IAClE,MAAM,GAAG,CAAC,CAAC;IACX,mDAAmD;IACnD,KAAK,CAAoB;IACzB,sFAAsF;IACtF,OAAO,GAAG,KAAK,CAAC;IAChB,iDAAiD;IACxC,QAAQ,CAAW;IAC5B,8DAA8D;IACrD,QAAQ,CAAiB;IAClC,oCAAoC;IAC3B,IAAI,CAAc;IAE3B;;;OAGG;IACc,KAAK,CAAS;IACd,QAAQ,CAAS;IACjB,KAAK,CAAW;IACjC,qCAAqC;IAC7B,OAAO,CAAqB;IACpC,gEAAgE;IAC/C,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC1D,kEAAkE;IACjD,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC7D,oEAAoE;IACnD,QAAQ,CAAkB;IAC3C,wCAAwC;IACvB,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;IACpD,0DAA0D;IACzC,IAAI,GAAG,IAAI,aAAa,EAAE,CAAC;IACpC,QAAQ,GAAG,KAAK,CAAC;IACzB,2EAA2E;IAC1D,QAAQ,CAAiB;IAC1C,4GAA4G;IAC3F,IAAI,CAAmB;IAExC,YACmB,GAA0B,EAC1B,GAAW;IAC5B,2FAA2F;IAC1E,IAAY;IAC7B,sGAAsG;IACrF,MAA2B;IAC5C,mHAAmH;IACnH,EAAE,KAAK,EAAE,QAAQ,EAA8B,EAC9B,OAA2D;IAC5E,mFAAmF;IAClE,OAA+C;IAChE,8GAA8G;IAC9G,UAA2C;QAZ1B,QAAG,GAAH,GAAG,CAAuB;QAC1B,QAAG,GAAH,GAAG,CAAQ;QAEX,SAAI,GAAJ,IAAI,CAAQ;QAEZ,WAAM,GAAN,MAAM,CAAqB;QAG3B,YAAO,GAAP,OAAO,CAAoD;QAE3D,YAAO,GAAP,OAAO,CAAwC;QAIhE,IAAI,GAAG,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1G,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC;QAC1H,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QACvG,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAe,CACjC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,EACpD,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAC9B,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,IAAI,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI;YACP,UAAU;gBACV,IAAI,SAAS,CACX,UAAU,EACV,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EACjB,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAC9B,CAAC;IACN,CAAC;IAED,yEAAyE;IACzE,IAAI,QAAQ;QACV,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,OAAO;QACT,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QAC9C,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAChH,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,MAAc,EAAE,MAAc,EAAE,MAAe;QACrD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC;QACpD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,4DAA4D,CAAC,CAAC;YAC7H,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/D,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACH,aAAa;QACX,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,IAAI,CAAC,IAAI,wBAAwB,CAAC,CAAC;QAC5G,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,MAAc,EAAE,MAAe;QACtC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC3D,CAAC;IAED,gGAAgG;IACxF,UAAU,CAAC,OAAiB;QAClC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;IACzG,CAAC;IAED;;;;OAIG;IACK,IAAI,CAAC,MAAc,EAAE,MAAe,EAAE,KAAoB;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QACtC,MAAM,cAAc,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,SAAS,CAAC;QAChH,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,cAAc,IAAI,KAAK,KAAK,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YACpH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC1B,CAAC;QACD,gHAAgH;QAChH,kHAAkH;QAClH,+BAA+B;QAC/B,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,KAAK,KAAK;YAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAChE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAClG,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;QACtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/B,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC1H,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,+DAA+D;IACvD,KAAK,CAAC,KAAa,EAAE,IAA6B;QACxD,MAAM,KAAK,GAAY;YACrB,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;iBACvB,IAAI,CAAC,IAAI,CAAC;iBACV,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;gBACf,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,WAAW,KAAK,iCAAiC,CAAC,CAAC;gBACxG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;gBACtB,OAAO,MAAM,CAAC;YAChB,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;gBACxB,KAAK,CAAC,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,WAAW,KAAK,iBAAiB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC1H,MAAM,KAAK,CAAC,KAAK,CAAC;YACpB,CAAC,CAAC;SACL,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC7B,KAAK,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACnE,CAAC;IAEO,OAAO,CAAC,KAAa;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,cAAc,KAAK,EAAE,CAAC,CAAC;QAC/D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,qGAAqG;IAC7F,KAAK,CAAC,aAAa,CAAC,OAAsB,EAAE,IAAY;QAC9D,+FAA+F;QAC/F,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YAAE,OAAO;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QACvG,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5D,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IAC1G,CAAC;IAED;;;;OAIG;IACK,MAAM,CAAC,KAAa,EAAE,OAAsB;QAClD,qEAAqE;QACrE,MAAM,IAAI,GAAG,QAAQ,EAAE;aACpB,IAAI,CAAC,KAAK,IAAI,EAAE;YACf,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAC7C,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC;gBAAE,OAAO;YAC5E,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YACxC,8GAA8G;YAC9G,uDAAuD;YACvD,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAC1F,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzE,KAAK,MAAM,KAAK,IAAI,QAAQ;gBAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC;YACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC7C,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBAC5C,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;YACtH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACnB,MAAM,KAAK,CAAC;YACd,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ;gBAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC7C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAClC,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;aAC7C,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,CAAC,CAAC,CAAC;QACL,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,mHAAmH;IAC3G,IAAI;QACV,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC;YAAE,OAAO;QACxE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3C,QAAQ,CAAC,IAAI,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACjC,cAAc,CAAC,GAAG,EAAE;YAClB,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACK,IAAI;QACV,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;IACpI,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,KAAc;QACnB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO;QACxC,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,mBAAmB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACjH,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACjB,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,4FAA4F;IAC5F,KAAK,CAAC,MAAkB;QACtB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC;QACX,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,OAAmB;QACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACpB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC/D,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,OAAO,EAAE,CAAC;YACV,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ;gBAAE,KAAK,EAAE,CAAC;QAC7C,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACtH,gFAAgF;YAChF,IAAI,SAAS,CAAC,MAAM;gBAAE,KAAK,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;gBAC/D,IAAI,EAAE,CAAC;QACd,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;QACpE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;;YACtD,MAAM,EAAE,CAAC;IAChB,CAAC;CACF"}
@@ -1,8 +1,9 @@
1
1
  import { Fn, output, positionLocal, vec4 } from "three/tsl";
2
2
  import { castPosition, keepsPixel, placeInstances, tint } from "./fade.js";
3
- import { toNodeMaterial } from "./three.js";
4
- import { isNodeOf } from "./tsl.js";
5
- import { sway } from "./wind/sway.js";
3
+ import { toNodeMaterial } from "../three.js";
4
+ import { isNodeOf } from "../tsl.js";
5
+ import { sway } from "../wind/sway.js";
6
+ // Side tables, as three's Material has no typed place for a package's state (userData is the app's).
6
7
  /** Copy → the material it copies. */
7
8
  const originals = new WeakMap();
8
9
  /** Original → its copies, still and swaying. */
@@ -0,0 +1 @@
1
+ {"version":3,"file":"material.js","sourceRoot":"","sources":["../../src/levels/material.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { LoadingManager, Object3D, Renderer } from "three/webgpu";
2
+ /** A Lod or an InstancedLod: what has a LoadingManager, which items for its levels go to. */
3
+ export declare const hasLoadingManager: (node: Object3D) => node is Object3D & {
4
+ readonly manager: LoadingManager;
5
+ };
6
+ /**
7
+ * How deep in renders `renderer` is: -1 outside them, 0 in a render of its own, 1 in one it draws inside another, as it
8
+ * draws shadow maps and post-processing. Read from r186's `_callDepth`: three keeps a draw's built shader per depth,
9
+ * and no public API tells which.
10
+ */
11
+ export declare function callDepth(renderer: Renderer): number;
12
+ /**
13
+ * Whether `renderer` is rendering or compiling now, as it is while it updates what it draws; not while an app calls
14
+ * `update` itself or another renderer draws. A compile is told by r186's `_compilationPromises`, which no public API
15
+ * shows.
16
+ */
17
+ export declare const busy: (renderer: Renderer) => boolean;
18
+ /**
19
+ * Whether the scene `node` is in is being drawn into a shadow map: three's shadow map render
20
+ * draws it with its own override material, and calls `update` on every LOD with the
21
+ * light's camera, which must not switch the levels the scene's camera chose.
22
+ */
23
+ export declare function inShadowMap(node: Object3D): boolean;
24
+ /**
25
+ * Whether `target` is the framebuffer target r186 draws the canvas (or output target) through when tone mapping or
26
+ * the output colour space needs a final pass. A draw meant for the output sees it as the active target; a compile for
27
+ * the output leaves the target unset and lets three resolve it.
28
+ */
29
+ export declare const isOutputPass: (target: unknown) => boolean;
@@ -0,0 +1,41 @@
1
+ import { isLOD, isScene, isShadowPass } from "../three.js";
2
+ // What a Lod learns of the renderer drawing it, and when. three r186 shows much of it through no public API: each
3
+ // read of one of its private fields below says why none serves.
4
+ /** A Lod or an InstancedLod: what has a LoadingManager, which items for its levels go to. */
5
+ export const hasLoadingManager = (node) => isLOD(node) && "manager" in node && isLoadingManager(node.manager);
6
+ const isLoadingManager = (value) => typeof value === "object" && value !== null && "itemStart" in value && "itemEnd" in value;
7
+ /**
8
+ * How deep in renders `renderer` is: -1 outside them, 0 in a render of its own, 1 in one it draws inside another, as it
9
+ * draws shadow maps and post-processing. Read from r186's `_callDepth`: three keeps a draw's built shader per depth,
10
+ * and no public API tells which.
11
+ */
12
+ export function callDepth(renderer) {
13
+ const depth = Reflect.get(renderer, "_callDepth");
14
+ if (typeof depth !== "number")
15
+ throw new Error("Lod: three's renderer keeps no call depth (lod mirrors three r186)");
16
+ return depth;
17
+ }
18
+ /**
19
+ * Whether `renderer` is rendering or compiling now, as it is while it updates what it draws; not while an app calls
20
+ * `update` itself or another renderer draws. A compile is told by r186's `_compilationPromises`, which no public API
21
+ * shows.
22
+ */
23
+ export const busy = (renderer) => callDepth(renderer) >= 0 || Reflect.get(renderer, "_compilationPromises") != null;
24
+ /**
25
+ * Whether the scene `node` is in is being drawn into a shadow map: three's shadow map render
26
+ * draws it with its own override material, and calls `update` on every LOD with the
27
+ * light's camera, which must not switch the levels the scene's camera chose.
28
+ */
29
+ export function inShadowMap(node) {
30
+ for (let scene = node; scene; scene = scene.parent)
31
+ if (isScene(scene) && isShadowPass(scene.overrideMaterial))
32
+ return true;
33
+ return false;
34
+ }
35
+ /**
36
+ * Whether `target` is the framebuffer target r186 draws the canvas (or output target) through when tone mapping or
37
+ * the output colour space needs a final pass. A draw meant for the output sees it as the active target; a compile for
38
+ * the output leaves the target unset and lets three resolve it.
39
+ */
40
+ export const isOutputPass = (target) => typeof target === "object" && target !== null && Reflect.get(target, "isPostProcessingRenderTarget") === true;
41
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../src/levels/renderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3D,kHAAkH;AAClH,gEAAgE;AAEhE,6FAA6F;AAC7F,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAc,EAA2D,EAAE,CAC3G,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,IAAI,IAAI,IAAI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACrE,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAA2B,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,WAAW,IAAI,KAAK,IAAI,SAAS,IAAI,KAAK,CAAC;AAEhK;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,QAAkB;IAC1C,MAAM,KAAK,GAAY,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACrH,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,QAAkB,EAAW,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,sBAAsB,CAAC,IAAI,IAAI,CAAC;AAEvI;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,KAAK,IAAI,KAAK,GAAoB,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM;QAAE,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,gBAAgB,CAAC;YAAE,OAAO,IAAI,CAAC;IAC7I,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAe,EAAW,EAAE,CACvD,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,8BAA8B,CAAC,KAAK,IAAI,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { Camera, Renderer, Scene } from "three/webgpu";
2
+ import type { CameraRenders } from "./cameras.js";
3
+ /**
4
+ * What the cameras rendering a Lod asked of it: per camera the levels it wants, and whether it still renders the Lod.
5
+ * The renderer's updates of the Lod are counted in rounds: a round ends when a camera updates it a second time, so a
6
+ * round holds one update by each camera that renders it once a frame, whatever their order. Shadow maps do not count.
7
+ */
8
+ export declare class CameraRequests {
9
+ private readonly renderer;
10
+ /** What renders told of the cameras that drew the Lod. */
11
+ private readonly seen;
12
+ /** The frame a camera, not a shadow map's, last updated the Lod in. */
13
+ cameraFrame: number | null;
14
+ /** The cameras still rendering the Lod (see `fresh`), and what they asked for. */
15
+ private readonly requests;
16
+ private round;
17
+ /** The cameras that updated the Lod in the round under way. */
18
+ private readonly inRound;
19
+ constructor(renderer: Renderer,
20
+ /** What renders told of the cameras that drew the Lod. */
21
+ seen: CameraRenders);
22
+ /**
23
+ * `camera`, a shadow map's when `shadow`, rendering `scene`, wants the levels of the bits `wanted`: note it, drop the
24
+ * cameras that stopped rendering the Lod, and answer the renderer's frame.
25
+ */
26
+ set(scene: Scene, camera: Camera, wanted: number, shadow: boolean): number;
27
+ /** Note what a render of `scene` with `camera` tells: nothing outside the renderer's renders. */
28
+ private see;
29
+ /** The cameras still rendering the Lod. */
30
+ cameras(): Camera[];
31
+ /**
32
+ * The bits of the levels wanted by the cameras still rendering the Lod (see `rendering`): each camera that renders
33
+ * the scene once a frame counts, whatever their order, and one that stopped rendering it drops out.
34
+ */
35
+ needed(): number;
36
+ /**
37
+ * Whether `camera` still renders the Lod: it updated it in the current or last round, or it is a shadow map's whose
38
+ * target is not disposed (see `fresh`).
39
+ */
40
+ rendering(camera: Camera): boolean;
41
+ /**
42
+ * Whether `camera`'s `request` still counts: made in the current or last round, or a shadow map's while its map's
43
+ * target is not disposed, as the scene's cameras draw what its last update filled however seldom it is redrawn
44
+ * (three redraws a map whose `autoUpdate` is off only when asked). A shadow map's made this frame counts too, before
45
+ * a render notes its target: three draws a map at most once a frame, so a camera rendered again in the frame draws
46
+ * the map the update filled.
47
+ */
48
+ private fresh;
49
+ }
@@ -0,0 +1,95 @@
1
+ import { busy, inShadowMap } from "./renderer.js";
2
+ /**
3
+ * What the cameras rendering a Lod asked of it: per camera the levels it wants, and whether it still renders the Lod.
4
+ * The renderer's updates of the Lod are counted in rounds: a round ends when a camera updates it a second time, so a
5
+ * round holds one update by each camera that renders it once a frame, whatever their order. Shadow maps do not count.
6
+ */
7
+ export class CameraRequests {
8
+ renderer;
9
+ seen;
10
+ /** The frame a camera, not a shadow map's, last updated the Lod in. */
11
+ cameraFrame = null;
12
+ /** The cameras still rendering the Lod (see `fresh`), and what they asked for. */
13
+ requests = new Map();
14
+ round = 0;
15
+ /** The cameras that updated the Lod in the round under way. */
16
+ inRound = new Set();
17
+ constructor(renderer,
18
+ /** What renders told of the cameras that drew the Lod. */
19
+ seen) {
20
+ this.renderer = renderer;
21
+ this.seen = seen;
22
+ }
23
+ /**
24
+ * `camera`, a shadow map's when `shadow`, rendering `scene`, wants the levels of the bits `wanted`: note it, drop the
25
+ * cameras that stopped rendering the Lod, and answer the renderer's frame.
26
+ */
27
+ set(scene, camera, wanted, shadow) {
28
+ this.see(scene, camera);
29
+ for (const [other, request] of this.requests)
30
+ if (!this.fresh(other, request))
31
+ this.requests.delete(other);
32
+ let request = this.requests.get(camera);
33
+ if (!request)
34
+ this.requests.set(camera, (request = { levels: 0, round: this.round, frame: null }));
35
+ request.round = this.round;
36
+ const frame = this.renderer.info.frame;
37
+ request.frame = shadow ? frame : null;
38
+ if (!shadow)
39
+ this.cameraFrame = frame;
40
+ request.levels = wanted;
41
+ return frame;
42
+ }
43
+ /** Note what a render of `scene` with `camera` tells: nothing outside the renderer's renders. */
44
+ see(scene, camera) {
45
+ const { renderer } = this;
46
+ if (!busy(renderer))
47
+ return;
48
+ this.seen.note(renderer, scene, camera);
49
+ if (inShadowMap(scene))
50
+ return;
51
+ if (this.inRound.has(camera)) {
52
+ this.round++;
53
+ this.inRound.clear();
54
+ }
55
+ this.inRound.add(camera);
56
+ }
57
+ /** The cameras still rendering the Lod. */
58
+ cameras() {
59
+ return [...this.requests].flatMap(([camera, request]) => (this.fresh(camera, request) ? [camera] : []));
60
+ }
61
+ /**
62
+ * The bits of the levels wanted by the cameras still rendering the Lod (see `rendering`): each camera that renders
63
+ * the scene once a frame counts, whatever their order, and one that stopped rendering it drops out.
64
+ */
65
+ needed() {
66
+ let bits = 0;
67
+ for (const [camera, request] of this.requests)
68
+ if (this.fresh(camera, request))
69
+ bits |= request.levels;
70
+ return bits;
71
+ }
72
+ /**
73
+ * Whether `camera` still renders the Lod: it updated it in the current or last round, or it is a shadow map's whose
74
+ * target is not disposed (see `fresh`).
75
+ */
76
+ rendering(camera) {
77
+ const request = this.requests.get(camera);
78
+ return request !== undefined && this.fresh(camera, request);
79
+ }
80
+ /**
81
+ * Whether `camera`'s `request` still counts: made in the current or last round, or a shadow map's while its map's
82
+ * target is not disposed, as the scene's cameras draw what its last update filled however seldom it is redrawn
83
+ * (three redraws a map whose `autoUpdate` is off only when asked). A shadow map's made this frame counts too, before
84
+ * a render notes its target: three draws a map at most once a frame, so a camera rendered again in the frame draws
85
+ * the map the update filled.
86
+ */
87
+ fresh(camera, request) {
88
+ if (request.round >= this.round - 1)
89
+ return true;
90
+ if (request.frame === null)
91
+ return false;
92
+ return request.frame === this.renderer.info.frame || this.seen.drawsShadowMap(camera);
93
+ }
94
+ }
95
+ //# sourceMappingURL=requests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.js","sourceRoot":"","sources":["../../src/levels/requests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Vector3, type Camera, type Matrix4, type Sphere } from "three/webgpu";
2
+ /** How a camera measures heights: from where, and pixels per unit of subtense (perspective) or of size (orthographic). */
3
+ export interface Screen {
4
+ readonly eye: Vector3;
5
+ ortho: boolean;
6
+ scale: number;
7
+ }
8
+ /** `camera`'s screen at `height`, the one it draws at, into `out`. */
9
+ export declare function screenOf(camera: Camera, height: number, out?: Screen): Screen;
10
+ /**
11
+ * The height on `screen` of `sphere`, given in the space `root` maps to world: its diameter, scaled by the largest axis
12
+ * scale of `root`, over its distance (small-angle), or its diameter alone in an orthographic camera.
13
+ */
14
+ export declare function screenHeight(sphere: Sphere, root: Matrix4, screen: Screen): number;
@@ -0,0 +1,21 @@
1
+ import { Vector3 } from "three/webgpu";
2
+ /** `camera`'s screen at `height`, the one it draws at, into `out`. */
3
+ export function screenOf(camera, height, out = { eye: new Vector3(), ortho: false, scale: 0 }) {
4
+ const projection = camera.projectionMatrix.elements;
5
+ out.ortho = projection[15] === 1;
6
+ out.scale = ((projection[5] ?? 0) * height) / 2;
7
+ out.eye.setFromMatrixPosition(camera.matrixWorld);
8
+ return out;
9
+ }
10
+ const centre = new Vector3();
11
+ /**
12
+ * The height on `screen` of `sphere`, given in the space `root` maps to world: its diameter, scaled by the largest axis
13
+ * scale of `root`, over its distance (small-angle), or its diameter alone in an orthographic camera.
14
+ */
15
+ export function screenHeight(sphere, root, screen) {
16
+ const size = 2 * sphere.radius * root.getMaxScaleOnAxis();
17
+ if (screen.ortho)
18
+ return size * screen.scale;
19
+ return (size * screen.scale) / Math.max(screen.eye.distanceTo(centre.copy(sphere.center).applyMatrix4(root)), 1e-6);
20
+ }
21
+ //# sourceMappingURL=screen.js.map