@drawcall/lod 0.1.2 → 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 (358) hide show
  1. package/README.md +13 -70
  2. package/dist/at.d.ts +2 -0
  3. package/dist/at.js +8 -0
  4. package/dist/at.js.map +1 -0
  5. package/dist/bake.d.ts +22 -0
  6. package/dist/bake.js +88 -0
  7. package/dist/bake.js.map +1 -0
  8. package/dist/baked/codec.d.ts +5 -5
  9. package/dist/baked/codec.js +58 -158
  10. package/dist/baked/codec.js.map +1 -1
  11. package/dist/baked/coverage.d.ts +6 -3
  12. package/dist/baked/coverage.js +6 -3
  13. package/dist/baked/coverage.js.map +1 -1
  14. package/dist/baked/fields.d.ts +9 -0
  15. package/dist/baked/fields.js +22 -0
  16. package/dist/baked/fields.js.map +1 -0
  17. package/dist/baked/index.d.ts +16 -6
  18. package/dist/baked/index.js +23 -21
  19. package/dist/baked/index.js.map +1 -1
  20. package/dist/baked/interior/faces.d.ts +4 -3
  21. package/dist/baked/interior/faces.js +13 -10
  22. package/dist/baked/interior/faces.js.map +1 -1
  23. package/dist/baked/interior/material.d.ts +7 -10
  24. package/dist/baked/interior/material.js +29 -36
  25. package/dist/baked/interior/material.js.map +1 -1
  26. package/dist/baked/interior/rooms.js +1 -1
  27. package/dist/baked/interior/rooms.js.map +1 -1
  28. package/dist/baked/low.d.ts +2 -2
  29. package/dist/baked/low.js +9 -8
  30. package/dist/baked/low.js.map +1 -1
  31. package/dist/baked/raster.js +6 -6
  32. package/dist/baked/raster.js.map +1 -1
  33. package/dist/baked/textures.d.ts +17 -0
  34. package/dist/baked/textures.js +95 -0
  35. package/dist/baked/textures.js.map +1 -0
  36. package/dist/baked/transfer.js +19 -18
  37. package/dist/baked/transfer.js.map +1 -1
  38. package/dist/baked/unwrap.js +4 -3
  39. package/dist/baked/unwrap.js.map +1 -1
  40. package/dist/baked/xatlas.js.map +1 -1
  41. package/dist/codec/container.d.ts +8 -0
  42. package/dist/codec/container.js +63 -0
  43. package/dist/codec/container.js.map +1 -0
  44. package/dist/codec/mesh.d.ts +8 -0
  45. package/dist/codec/mesh.js +220 -0
  46. package/dist/codec/mesh.js.map +1 -0
  47. package/dist/dispose.d.ts +11 -4
  48. package/dist/dispose.js +39 -12
  49. package/dist/dispose.js.map +1 -1
  50. package/dist/gpu.d.ts +39 -0
  51. package/dist/gpu.js +41 -0
  52. package/dist/gpu.js.map +1 -0
  53. package/dist/impostor/bake/atlas.d.ts +4 -4
  54. package/dist/impostor/bake/atlas.js +12 -12
  55. package/dist/impostor/bake/atlas.js.map +1 -1
  56. package/dist/impostor/bake/fit.d.ts +8 -0
  57. package/dist/impostor/bake/fit.js +28 -0
  58. package/dist/impostor/bake/fit.js.map +1 -0
  59. package/dist/impostor/bake/index.d.ts +23 -14
  60. package/dist/impostor/bake/index.js +42 -134
  61. package/dist/impostor/bake/index.js.map +1 -1
  62. package/dist/impostor/bake/materials.d.ts +3 -3
  63. package/dist/impostor/bake/materials.js +60 -12
  64. package/dist/impostor/bake/materials.js.map +1 -1
  65. package/dist/impostor/bake/sheet.d.ts +8 -0
  66. package/dist/impostor/bake/sheet.js +90 -0
  67. package/dist/impostor/bake/sheet.js.map +1 -0
  68. package/dist/impostor/bake/source.d.ts +2 -2
  69. package/dist/impostor/bake/source.js +8 -19
  70. package/dist/impostor/bake/source.js.map +1 -1
  71. package/dist/impostor/codec.d.ts +5 -11
  72. package/dist/impostor/codec.js +37 -121
  73. package/dist/impostor/codec.js.map +1 -1
  74. package/dist/impostor/impostor.d.ts +31 -7
  75. package/dist/impostor/impostor.js +21 -6
  76. package/dist/impostor/impostor.js.map +1 -1
  77. package/dist/impostor/ktx2/encode.d.ts +26 -0
  78. package/dist/impostor/ktx2/encode.js +117 -0
  79. package/dist/impostor/ktx2/encode.js.map +1 -0
  80. package/dist/impostor/ktx2/transcode.d.ts +3 -0
  81. package/dist/impostor/ktx2/transcode.js +99 -0
  82. package/dist/impostor/ktx2/transcode.js.map +1 -0
  83. package/dist/impostor/ktx2/uastc.d.ts +7 -0
  84. package/dist/impostor/ktx2/uastc.js +64 -0
  85. package/dist/impostor/ktx2/uastc.js.map +1 -0
  86. package/dist/impostor/ktx2/wasm/encoder.d.ts +4 -0
  87. package/dist/impostor/ktx2/wasm/encoder.js +10 -0
  88. package/dist/impostor/ktx2/wasm/encoder.js.map +1 -0
  89. package/dist/impostor/ktx2/wasm/transcoder.d.ts +3 -0
  90. package/dist/impostor/ktx2/wasm/transcoder.js +9 -0
  91. package/dist/impostor/ktx2/wasm/transcoder.js.map +1 -0
  92. package/dist/impostor/ktx2/worker.d.ts +1 -0
  93. package/dist/impostor/ktx2/worker.js +12 -0
  94. package/dist/impostor/ktx2/worker.js.map +1 -0
  95. package/dist/impostor/mesh/card.d.ts +3 -3
  96. package/dist/impostor/mesh/card.js +11 -8
  97. package/dist/impostor/mesh/card.js.map +1 -1
  98. package/dist/impostor/mesh/index.d.ts +10 -7
  99. package/dist/impostor/mesh/index.js +15 -18
  100. package/dist/impostor/mesh/index.js.map +1 -1
  101. package/dist/impostor/mesh/material.d.ts +24 -13
  102. package/dist/impostor/mesh/material.js +67 -51
  103. package/dist/impostor/mesh/material.js.map +1 -1
  104. package/dist/impostor/mesh/surface.d.ts +20 -16
  105. package/dist/impostor/mesh/surface.js +81 -58
  106. package/dist/impostor/mesh/surface.js.map +1 -1
  107. package/dist/impostor/mesh/textures.d.ts +3 -3
  108. package/dist/impostor/mesh/textures.js +24 -34
  109. package/dist/impostor/mesh/textures.js.map +1 -1
  110. package/dist/impostor/octahedral.d.ts +1 -8
  111. package/dist/impostor/octahedral.js +3 -18
  112. package/dist/impostor/octahedral.js.map +1 -1
  113. package/dist/index.d.ts +16 -10
  114. package/dist/index.js +14 -8
  115. package/dist/index.js.map +1 -1
  116. package/dist/instanced/camera.d.ts +46 -0
  117. package/dist/instanced/camera.js +70 -0
  118. package/dist/instanced/camera.js.map +1 -0
  119. package/dist/instanced/chunk.d.ts +97 -0
  120. package/dist/instanced/chunk.js +156 -0
  121. package/dist/instanced/chunk.js.map +1 -0
  122. package/dist/instanced/chunks.d.ts +60 -0
  123. package/dist/instanced/chunks.js +208 -0
  124. package/dist/instanced/chunks.js.map +1 -0
  125. package/dist/instanced/cull.d.ts +28 -0
  126. package/dist/instanced/cull.js +22 -0
  127. package/dist/instanced/cull.js.map +1 -0
  128. package/dist/instanced/index.d.ts +96 -92
  129. package/dist/instanced/index.js +229 -512
  130. package/dist/instanced/index.js.map +1 -1
  131. package/dist/instanced/key.d.ts +19 -0
  132. package/dist/instanced/key.js +45 -0
  133. package/dist/instanced/key.js.map +1 -0
  134. package/dist/instanced/levels.d.ts +60 -0
  135. package/dist/instanced/levels.js +130 -0
  136. package/dist/instanced/levels.js.map +1 -0
  137. package/dist/instanced/lists.d.ts +70 -0
  138. package/dist/instanced/lists.js +133 -0
  139. package/dist/instanced/lists.js.map +1 -0
  140. package/dist/instanced/measure.d.ts +28 -0
  141. package/dist/instanced/measure.js +203 -0
  142. package/dist/instanced/measure.js.map +1 -0
  143. package/dist/instanced/meshes.d.ts +46 -14
  144. package/dist/instanced/meshes.js +137 -22
  145. package/dist/instanced/meshes.js.map +1 -1
  146. package/dist/instanced/mirror.d.ts +20 -0
  147. package/dist/instanced/mirror.js +37 -0
  148. package/dist/instanced/mirror.js.map +1 -0
  149. package/dist/instanced/pages/buffers.d.ts +37 -0
  150. package/dist/instanced/pages/buffers.js +15 -0
  151. package/dist/instanced/pages/buffers.js.map +1 -0
  152. package/dist/instanced/pages/chunk.d.ts +51 -0
  153. package/dist/instanced/pages/chunk.js +81 -0
  154. package/dist/instanced/pages/chunk.js.map +1 -0
  155. package/dist/instanced/pages/index.d.ts +74 -0
  156. package/dist/instanced/pages/index.js +269 -0
  157. package/dist/instanced/pages/index.js.map +1 -0
  158. package/dist/instanced/pages/passes.d.ts +21 -0
  159. package/dist/instanced/pages/passes.js +52 -0
  160. package/dist/instanced/pages/passes.js.map +1 -0
  161. package/dist/instanced/pages/slots.d.ts +11 -0
  162. package/dist/instanced/pages/slots.js +90 -0
  163. package/dist/instanced/pages/slots.js.map +1 -0
  164. package/dist/instanced/pages/workgroup.d.ts +14 -0
  165. package/dist/instanced/pages/workgroup.js +38 -0
  166. package/dist/instanced/pages/workgroup.js.map +1 -0
  167. package/dist/instanced/raycast.d.ts +15 -0
  168. package/dist/instanced/raycast.js +46 -0
  169. package/dist/instanced/raycast.js.map +1 -0
  170. package/dist/instanced/rows.d.ts +108 -0
  171. package/dist/instanced/rows.js +209 -0
  172. package/dist/instanced/rows.js.map +1 -0
  173. package/dist/instanced/shape.d.ts +25 -0
  174. package/dist/instanced/shape.js +51 -0
  175. package/dist/instanced/shape.js.map +1 -0
  176. package/dist/instanced/sort.d.ts +63 -0
  177. package/dist/instanced/sort.js +162 -0
  178. package/dist/instanced/sort.js.map +1 -0
  179. package/dist/instanced/update.d.ts +30 -0
  180. package/dist/instanced/update.js +207 -0
  181. package/dist/instanced/update.js.map +1 -0
  182. package/dist/levels/bounds.d.ts +21 -0
  183. package/dist/levels/bounds.js +42 -0
  184. package/dist/levels/bounds.js.map +1 -0
  185. package/dist/levels/cameras.d.ts +48 -0
  186. package/dist/levels/cameras.js +122 -0
  187. package/dist/levels/cameras.js.map +1 -0
  188. package/dist/levels/compile/contexts.d.ts +30 -0
  189. package/dist/levels/compile/contexts.js +18 -0
  190. package/dist/levels/compile/contexts.js.map +1 -0
  191. package/dist/levels/compile/index.d.ts +39 -0
  192. package/dist/levels/compile/index.js +185 -0
  193. package/dist/levels/compile/index.js.map +1 -0
  194. package/dist/levels/compile/pipelines.d.ts +26 -0
  195. package/dist/levels/compile/pipelines.js +177 -0
  196. package/dist/levels/compile/pipelines.js.map +1 -0
  197. package/dist/levels/compiles.d.ts +29 -0
  198. package/dist/levels/compiles.js +50 -0
  199. package/dist/levels/compiles.js.map +1 -0
  200. package/dist/levels/draw.d.ts +102 -0
  201. package/dist/levels/draw.js +401 -0
  202. package/dist/levels/draw.js.map +1 -0
  203. package/dist/levels/fade.d.ts +69 -0
  204. package/dist/levels/fade.js +150 -0
  205. package/dist/levels/fade.js.map +1 -0
  206. package/dist/levels/index.d.ts +99 -0
  207. package/dist/levels/index.js +155 -0
  208. package/dist/levels/index.js.map +1 -0
  209. package/dist/levels/item.d.ts +38 -0
  210. package/dist/levels/item.js +97 -0
  211. package/dist/levels/item.js.map +1 -0
  212. package/dist/levels/load.d.ts +31 -0
  213. package/dist/levels/load.js +142 -0
  214. package/dist/levels/load.js.map +1 -0
  215. package/dist/levels/manager.d.ts +159 -0
  216. package/dist/levels/manager.js +339 -0
  217. package/dist/levels/manager.js.map +1 -0
  218. package/dist/{material.js → levels/material.js} +13 -7
  219. package/dist/levels/material.js.map +1 -0
  220. package/dist/levels/renderer.d.ts +29 -0
  221. package/dist/levels/renderer.js +41 -0
  222. package/dist/levels/renderer.js.map +1 -0
  223. package/dist/levels/requests.d.ts +49 -0
  224. package/dist/levels/requests.js +95 -0
  225. package/dist/levels/requests.js.map +1 -0
  226. package/dist/levels/screen.d.ts +14 -0
  227. package/dist/levels/screen.js +21 -0
  228. package/dist/levels/screen.js.map +1 -0
  229. package/dist/levels/wait.d.ts +27 -0
  230. package/dist/levels/wait.js +61 -0
  231. package/dist/levels/wait.js.map +1 -0
  232. package/dist/loader/build.d.ts +10 -0
  233. package/dist/loader/build.js +28 -0
  234. package/dist/loader/build.js.map +1 -0
  235. package/dist/loader/cache.d.ts +12 -15
  236. package/dist/loader/cache.js +64 -33
  237. package/dist/loader/cache.js.map +1 -1
  238. package/dist/loader/context.d.ts +46 -0
  239. package/dist/loader/context.js +91 -0
  240. package/dist/loader/context.js.map +1 -0
  241. package/dist/loader/dependencies.d.ts +32 -0
  242. package/dist/loader/dependencies.js +113 -0
  243. package/dist/loader/dependencies.js.map +1 -0
  244. package/dist/loader/index.d.ts +62 -0
  245. package/dist/loader/index.js +284 -0
  246. package/dist/loader/index.js.map +1 -0
  247. package/dist/loader/level.d.ts +41 -0
  248. package/dist/loader/level.js +140 -0
  249. package/dist/loader/level.js.map +1 -0
  250. package/dist/loader/request.d.ts +87 -0
  251. package/dist/loader/request.js +59 -0
  252. package/dist/loader/request.js.map +1 -0
  253. package/dist/loader/url.d.ts +16 -0
  254. package/dist/loader/url.js +35 -0
  255. package/dist/loader/url.js.map +1 -0
  256. package/dist/lod.d.ts +79 -49
  257. package/dist/lod.js +209 -153
  258. package/dist/lod.js.map +1 -1
  259. package/dist/meshopt.d.ts +6 -0
  260. package/dist/meshopt.js +19 -0
  261. package/dist/meshopt.js.map +1 -0
  262. package/dist/simplify/cards.d.ts +14 -0
  263. package/dist/simplify/cards.js +128 -0
  264. package/dist/simplify/cards.js.map +1 -0
  265. package/dist/{simplify.d.ts → simplify/index.d.ts} +7 -4
  266. package/dist/{simplify.js → simplify/index.js} +42 -22
  267. package/dist/simplify/index.js.map +1 -0
  268. package/dist/{bounds.d.ts → source/detail.d.ts} +4 -13
  269. package/dist/{bounds.js → source/detail.js} +62 -32
  270. package/dist/source/detail.js.map +1 -0
  271. package/dist/source/{error.d.ts → deviation.d.ts} +3 -3
  272. package/dist/source/{error.js → deviation.js} +12 -12
  273. package/dist/source/deviation.js.map +1 -0
  274. package/dist/source/{shading.d.ts → evaluator.d.ts} +10 -10
  275. package/dist/source/{shading.js → evaluator.js} +5 -5
  276. package/dist/source/evaluator.js.map +1 -0
  277. package/dist/source/{trace.d.ts → raycaster.d.ts} +6 -6
  278. package/dist/source/{trace.js → raycaster.js} +8 -8
  279. package/dist/source/raycaster.js.map +1 -0
  280. package/dist/source/{texels.d.ts → sampler.d.ts} +1 -1
  281. package/dist/source/{texels.js → sampler.js} +3 -3
  282. package/dist/source/sampler.js.map +1 -0
  283. package/dist/source/source.d.ts +2 -2
  284. package/dist/source/source.js +2 -2
  285. package/dist/source/source.js.map +1 -1
  286. package/dist/source/surface.js +1 -1
  287. package/dist/source/surface.js.map +1 -1
  288. package/dist/task.d.ts +6 -0
  289. package/dist/{pause.js → task.js} +5 -5
  290. package/dist/task.js.map +1 -0
  291. package/dist/three.d.ts +20 -19
  292. package/dist/three.js +29 -35
  293. package/dist/three.js.map +1 -1
  294. package/dist/tsl.d.ts +10 -14
  295. package/dist/tsl.js +12 -47
  296. package/dist/tsl.js.map +1 -1
  297. package/dist/typegpu.d.ts +37 -0
  298. package/dist/typegpu.js +37 -0
  299. package/dist/typegpu.js.map +1 -0
  300. package/dist/wind/bounds.js +2 -2
  301. package/dist/wind/bounds.js.map +1 -1
  302. package/dist/wind/hooks.d.ts +7 -4
  303. package/dist/wind/hooks.js +5 -2
  304. package/dist/wind/hooks.js.map +1 -1
  305. package/dist/wind/index.d.ts +4 -4
  306. package/dist/wind/index.js +43 -40
  307. package/dist/wind/index.js.map +1 -1
  308. package/dist/wind/sway.d.ts +4 -1
  309. package/dist/wind/sway.js +4 -1
  310. package/dist/wind/sway.js.map +1 -1
  311. package/package.json +24 -8
  312. package/skills/lod/SKILL.md +147 -108
  313. package/dist/bounds.js.map +0 -1
  314. package/dist/fade.d.ts +0 -44
  315. package/dist/fade.js +0 -78
  316. package/dist/fade.js.map +0 -1
  317. package/dist/impostor/cache.d.ts +0 -15
  318. package/dist/impostor/cache.js +0 -44
  319. package/dist/impostor/cache.js.map +0 -1
  320. package/dist/instanced/args.d.ts +0 -20
  321. package/dist/instanced/args.js +0 -77
  322. package/dist/instanced/args.js.map +0 -1
  323. package/dist/instanced/bounds.d.ts +0 -50
  324. package/dist/instanced/bounds.js +0 -271
  325. package/dist/instanced/bounds.js.map +0 -1
  326. package/dist/instanced/dirty.d.ts +0 -12
  327. package/dist/instanced/dirty.js +0 -61
  328. package/dist/instanced/dirty.js.map +0 -1
  329. package/dist/instanced/select.d.ts +0 -84
  330. package/dist/instanced/select.js +0 -264
  331. package/dist/instanced/select.js.map +0 -1
  332. package/dist/lazy.d.ts +0 -64
  333. package/dist/lazy.js +0 -187
  334. package/dist/lazy.js.map +0 -1
  335. package/dist/levels.d.ts +0 -72
  336. package/dist/levels.js +0 -146
  337. package/dist/levels.js.map +0 -1
  338. package/dist/loader/dispose.d.ts +0 -3
  339. package/dist/loader/dispose.js +0 -25
  340. package/dist/loader/dispose.js.map +0 -1
  341. package/dist/loader.d.ts +0 -99
  342. package/dist/loader.js +0 -234
  343. package/dist/loader.js.map +0 -1
  344. package/dist/material.js.map +0 -1
  345. package/dist/pause.d.ts +0 -6
  346. package/dist/pause.js.map +0 -1
  347. package/dist/renderer.d.ts +0 -21
  348. package/dist/renderer.js +0 -83
  349. package/dist/renderer.js.map +0 -1
  350. package/dist/simplify.js.map +0 -1
  351. package/dist/source/error.js.map +0 -1
  352. package/dist/source/shading.js.map +0 -1
  353. package/dist/source/texels.js.map +0 -1
  354. package/dist/source/trace.js.map +0 -1
  355. package/dist/view.d.ts +0 -30
  356. package/dist/view.js +0 -75
  357. package/dist/view.js.map +0 -1
  358. /package/dist/{material.d.ts → levels/material.d.ts} +0 -0
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.js","sourceRoot":"","sources":["../../src/levels/screen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA0C,MAAM,cAAc,CAAC;AAW/E,sEAAsE;AACtE,MAAM,UAAU,QAAQ,CAAC,MAAc,EAAE,MAAc,EAAE,MAAc,EAAE,GAAG,EAAE,IAAI,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE;IACnH,MAAM,UAAU,GAAG,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC;IACpD,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IACjC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAChD,GAAG,CAAC,GAAG,CAAC,qBAAqB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAClD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,IAAa,EAAE,MAAc;IACxE,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC1D,IAAI,MAAM,CAAC,KAAK;QAAE,OAAO,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC;IAC7C,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACtH,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Whether an InstancedLod's chunks wait to be shown taken in on the GPU: from a change until, a few renders later, a
3
+ * read of their status shows each taken in, so that its manager holds its item until a host sees them drawn.
4
+ */
5
+ export declare class ChunkWait {
6
+ /** Whether the GPU shows every chunk taken in, read back; it throws if a chunk lacks room. */
7
+ private readonly read;
8
+ /** Called once a read shows every chunk taken in. */
9
+ private readonly taken;
10
+ /** Called with what a read throws. */
11
+ private readonly failed;
12
+ /** While chunks wait, the renders left before their status is read, and whether a read is under way. */
13
+ private rest;
14
+ constructor(
15
+ /** Whether the GPU shows every chunk taken in, read back; it throws if a chunk lacks room. */
16
+ read: () => Promise<boolean>,
17
+ /** Called once a read shows every chunk taken in. */
18
+ taken: () => void,
19
+ /** Called with what a read throws. */
20
+ failed: (error: unknown) => void);
21
+ /** Whether chunks wait to be shown taken in. */
22
+ get waiting(): boolean;
23
+ /** The chunks were added or removed: wait for them again. */
24
+ changed(): void;
25
+ /** A render updated the InstancedLod: read the chunks' status once their change has rested. */
26
+ render(): void;
27
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Renders a change of an InstancedLod's chunks rests for before their status is read back (see `ChunkWait`): chunks
3
+ * change for many frames while an app loads them in, and every read is a submission of its own.
4
+ */
5
+ const CHUNK_REST = 4;
6
+ /**
7
+ * Whether an InstancedLod's chunks wait to be shown taken in on the GPU: from a change until, a few renders later, a
8
+ * read of their status shows each taken in, so that its manager holds its item until a host sees them drawn.
9
+ */
10
+ export class ChunkWait {
11
+ read;
12
+ taken;
13
+ failed;
14
+ /** While chunks wait, the renders left before their status is read, and whether a read is under way. */
15
+ rest = null;
16
+ constructor(
17
+ /** Whether the GPU shows every chunk taken in, read back; it throws if a chunk lacks room. */
18
+ read,
19
+ /** Called once a read shows every chunk taken in. */
20
+ taken,
21
+ /** Called with what a read throws. */
22
+ failed) {
23
+ this.read = read;
24
+ this.taken = taken;
25
+ this.failed = failed;
26
+ }
27
+ /** Whether chunks wait to be shown taken in. */
28
+ get waiting() {
29
+ return this.rest !== null;
30
+ }
31
+ /** The chunks were added or removed: wait for them again. */
32
+ changed() {
33
+ if (this.rest)
34
+ this.rest.renders = CHUNK_REST;
35
+ else
36
+ this.rest = { renders: CHUNK_REST, reading: false };
37
+ }
38
+ /** A render updated the InstancedLod: read the chunks' status once their change has rested. */
39
+ render() {
40
+ const { rest } = this;
41
+ if (!rest || rest.reading)
42
+ return;
43
+ if (rest.renders > 0) {
44
+ rest.renders--;
45
+ return;
46
+ }
47
+ rest.reading = true;
48
+ this.read().then((taken) => {
49
+ rest.reading = false;
50
+ if (this.rest !== rest)
51
+ return;
52
+ if (!taken || rest.renders > 0) {
53
+ rest.renders = CHUNK_REST;
54
+ return;
55
+ }
56
+ this.rest = null;
57
+ this.taken();
58
+ }, (error) => this.failed(error));
59
+ }
60
+ }
61
+ //# sourceMappingURL=wait.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait.js","sourceRoot":"","sources":["../../src/levels/wait.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,GAAG,CAAC,CAAC;AAErB;;;GAGG;AACH,MAAM,OAAO,SAAS;IAMD;IAEA;IAEA;IATnB,wGAAwG;IAChG,IAAI,GAAiD,IAAI,CAAC;IAElE;IACE,8FAA8F;IAC7E,IAA4B;IAC7C,qDAAqD;IACpC,KAAiB;IAClC,sCAAsC;IACrB,MAAgC;QAJhC,SAAI,GAAJ,IAAI,CAAwB;QAE5B,UAAK,GAAL,KAAK,CAAY;QAEjB,WAAM,GAAN,MAAM,CAA0B;IAChD,CAAC;IAEJ,gDAAgD;IAChD,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC;IAC5B,CAAC;IAED,6DAA6D;IAC7D,OAAO;QACL,IAAI,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC;;YACzC,IAAI,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC3D,CAAC;IAED,+FAA+F;IAC/F,MAAM;QACJ,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QAClC,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CACd,CAAC,KAAK,EAAE,EAAE;YACR,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;gBAAE,OAAO;YAC/B,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC;gBAC1B,OAAO;YACT,CAAC;YACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC,EACD,CAAC,KAAc,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CACvC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import type { Object3D, Renderer } from "three/webgpu";
2
+ import type { Derived } from "./level.js";
3
+ /**
4
+ * Build the level `request` asks for from `source`, with the baked level's `low` shell and `interior` rooms if it names
5
+ * them. `renderer` answers the renderer to bake with, asked for only by a bake that draws.
6
+ */
7
+ export declare function buildLevel(source: Object3D, request: Derived, { low, interior }: {
8
+ low: Object3D | undefined;
9
+ interior: Object3D | undefined;
10
+ }, renderer: () => Promise<Renderer>): Promise<Object3D>;
@@ -0,0 +1,28 @@
1
+ import { bakeMesh } from "../baked/index.js";
2
+ import { bakeImpostor } from "../impostor/bake/index.js";
3
+ import { ImpostorMesh } from "../impostor/mesh/index.js";
4
+ import { simplify } from "../simplify/index.js";
5
+ import { placeLike } from "../three.js";
6
+ /**
7
+ * Build the level `request` asks for from `source`, with the baked level's `low` shell and `interior` rooms if it names
8
+ * them. `renderer` answers the renderer to bake with, asked for only by a bake that draws.
9
+ */
10
+ export async function buildLevel(source, request, { low, interior }, renderer) {
11
+ switch (request.type) {
12
+ case "simplify":
13
+ return simplify(source, { ratio: request.ratio });
14
+ case "impostor": {
15
+ const { type: _, draw: __, ...options } = request;
16
+ const object = new ImpostorMesh(await bakeImpostor(source, await renderer(), options));
17
+ object.name = `${source.name || "object"} impostor`;
18
+ placeLike(object, source);
19
+ return object;
20
+ }
21
+ case "baked": {
22
+ const shell = low ? { low } : { ratio: request.ratio };
23
+ const rooms = interior ? { interior, renderer: await renderer() } : {};
24
+ return bakeMesh(source, { textureSize: request.textureSize, ...shell, ...rooms });
25
+ }
26
+ }
27
+ }
28
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/loader/build.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAgB,EAChB,OAAgB,EAChB,EAAE,GAAG,EAAE,QAAQ,EAAiE,EAChF,QAAiC;IAEjC,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,UAAU;YACb,OAAO,QAAQ,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACpD,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC;YAClD,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,YAAY,CAAC,MAAM,EAAE,MAAM,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;YACvF,MAAM,CAAC,IAAI,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,QAAQ,WAAW,CAAC;YACpD,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC1B,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;YACvD,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,OAAO,QAAQ,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -1,15 +1,12 @@
1
- import type { GLTSSource } from "@drawcall/glts";
2
- import type { Object3D } from "three/webgpu";
3
- import type { Dependencies } from "vitecache";
4
- import { type BakeImpostorOptions } from "../impostor/bake/index.js";
5
- import { type ImpostorCacheOptions } from "../impostor/cache.js";
6
- import type { Impostor } from "../impostor/impostor.js";
7
- /** Cache location and additional inputs that GLTS does not track, such as generator packages. */
8
- export interface LodCacheOptions extends ImpostorCacheOptions {
9
- /** Extra vitecache dependencies. Names beginning with glts: or lod: are reserved. */
10
- dependencies?: Dependencies;
11
- }
12
- /** Loaded GLTS scenes expose their run's source even outside an active script. */
13
- export declare function originOf(object: Object3D): GLTSSource | undefined;
14
- /** Capture dependencies when the bake starts, including files loaded since its request. */
15
- export declare function impostor(source: Object3D, options: BakeImpostorOptions, origin?: GLTSSource, excluded?: readonly Object3D[], cacheOptions?: LodCacheOptions): Promise<Impostor>;
1
+ import { CacheEntry, type CacheEntryOptions, type Dependencies } from "vitecache";
2
+ import type { Derived } from "./level.js";
3
+ /** Persistent cache location. Generator packages are discovered from GLTS source provenance. */
4
+ export type LodCacheOptions = Pick<CacheEntryOptions, "basePath" | "root">;
5
+ /**
6
+ * One derived level, or the source's shape: keyed by the URLs it is built from, its request and their bundled modules,
7
+ * and saved with what loading them revealed, so vitecache rechecks those without loading the sources. Each level has
8
+ * its own entry, so a level is built and saved only when it is first needed; the shape's describes the ladder before
9
+ * any level is.
10
+ */
11
+ export declare function ladderEntry(inputs: Dependencies, of: Derived | "shape", modules: Readonly<Record<string, string>>, options?: LodCacheOptions): CacheEntry;
12
+ export declare function sha256(bytes: Uint8Array): Promise<string>;
@@ -1,37 +1,68 @@
1
- import { bake, bakeImpostor } from "../impostor/bake/index.js";
2
- import { cached } from "../impostor/cache.js";
3
- /** Loaded GLTS scenes expose their run's source even outside an active script. */
4
- export function originOf(object) {
5
- const source = Reflect.get(object, "source");
6
- if (source === undefined)
7
- return undefined;
8
- if (!isSource(source))
9
- throw new Error("LodLoader: invalid GLTS source metadata");
10
- return source;
1
+ import { CacheEntry } from "vitecache";
2
+ import { urlQuery } from "./url.js";
3
+ /**
4
+ * What builds and lays out a cached level, and so what identifies it beside its inputs: bump it with any change to
5
+ * the bytes a level or shape entry holds. Not this package's files, which change with every rebuild, whether a level
6
+ * would or not.
7
+ */
8
+ const version = "lod-level@23";
9
+ /**
10
+ * One derived level, or the source's shape: keyed by the URLs it is built from, its request and their bundled modules,
11
+ * and saved with what loading them revealed, so vitecache rechecks those without loading the sources. Each level has
12
+ * its own entry, so a level is built and saved only when it is first needed; the shape's describes the ladder before
13
+ * any level is.
14
+ */
15
+ export function ladderEntry(inputs, of, modules, options) {
16
+ // vitecache resolves URLs to file paths; generation parameters go in the key.
17
+ const queries = {};
18
+ for (const [name, dependency] of Object.entries(inputs)) {
19
+ const query = dependency.url === undefined ? "" : urlQuery(dependency.url);
20
+ if (query)
21
+ queries[name] = query;
22
+ }
23
+ return new CacheEntry({
24
+ basePath: options?.basePath,
25
+ root: options?.root,
26
+ version,
27
+ dependencies: {
28
+ ...inputs,
29
+ "lod:level": { value: of === "shape" ? { type: of } : parameters(of) },
30
+ "lod:modules": { value: modules },
31
+ "lod:queries": { value: queries },
32
+ // Only packages the app installs resolve from its root; this package's own dependencies are covered by `version` above.
33
+ "lod:three": { package: "three" },
34
+ },
35
+ });
11
36
  }
12
- function isSource(source) {
13
- if (typeof source !== "object" || source === null)
14
- return false;
15
- const url = Reflect.get(source, "url");
16
- const dependencies = Reflect.get(source, "dependencyUrls");
17
- return typeof url === "string" && Array.isArray(dependencies) && dependencies.every((url) => typeof url === "string");
37
+ export async function sha256(bytes) {
38
+ const hash = await crypto.subtle.digest("SHA-256", new Uint8Array(bytes));
39
+ return Array.from(new Uint8Array(hash), (byte) => byte.toString(16).padStart(2, "0")).join("");
18
40
  }
19
- /** Capture dependencies when the bake starts, including files loaded since its request. */
20
- export async function impostor(source, options, origin, excluded = [], cacheOptions) {
21
- const make = (settings) => (excluded.length > 0 ? bake(source, settings, excluded) : bakeImpostor(source, settings));
22
- if (!origin)
23
- return make(options);
24
- const urls = origin.dependencyUrls;
25
- const { dependencies = {}, ...location } = cacheOptions ?? {};
26
- if (Object.keys(dependencies).some((name) => name.startsWith("glts:")))
27
- throw new Error("LodLoader: dependency names beginning with glts: are reserved");
28
- return cached(options, {
29
- ...dependencies,
30
- "glts:source": { url: origin.url },
31
- // URL resolution tracks the file; retain its query parameters as inputs too.
32
- "glts:query": { value: new URL(origin.url).search },
33
- ...Object.fromEntries(urls.map((url, index) => [`glts:dependency:${index}`, { url }])),
34
- "glts:dependencyQueries": { value: urls.map((url) => new URL(url).search) },
35
- }, make, location);
41
+ /** What derives a level's content. Switch thresholds and impostor draw options apply at decode, so changing one reuses the cache. */
42
+ function parameters(level) {
43
+ switch (level.type) {
44
+ case "simplify":
45
+ // Alpha-tested cards are thinned whole since lod-level@23; keyed here so other kinds' levels stay cached.
46
+ return { type: level.type, ratio: level.ratio ?? null, cards: "thin" };
47
+ case "baked":
48
+ return {
49
+ type: level.type,
50
+ ratio: level.ratio ?? null,
51
+ textureSize: level.textureSize ?? null,
52
+ low: level.low ?? null,
53
+ interior: level.interior ?? null,
54
+ };
55
+ case "impostor":
56
+ return {
57
+ type: level.type,
58
+ // The impostor bakes its top mip for this height too.
59
+ maxPixels: level.maxPixels ?? null,
60
+ layout: level.layout ?? null,
61
+ frames: level.frames ?? null,
62
+ resolution: level.resolution ?? null,
63
+ emissive: level.emissive ?? null,
64
+ supersample: level.supersample ?? null,
65
+ };
66
+ }
36
67
  }
37
68
  //# sourceMappingURL=cache.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/loader/cache.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,YAAY,EAA4B,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,MAAM,EAA6B,MAAM,sBAAsB,CAAC;AASzE,kFAAkF;AAClF,MAAM,UAAU,QAAQ,CAAC,MAAgB;IACvC,MAAM,MAAM,GAAY,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAClF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,QAAQ,CAAC,MAAe;IAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAChE,MAAM,GAAG,GAAY,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAChD,MAAM,YAAY,GAAY,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACpE,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC;AACjI,CAAC;AAED,2FAA2F;AAC3F,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAgB,EAChB,OAA4B,EAC5B,MAAmB,EACnB,WAAgC,EAAE,EAClC,YAA8B;IAE9B,MAAM,IAAI,GAAG,CAAC,QAA6B,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1I,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,MAAM,CAAC,cAAc,CAAC;IACnC,MAAM,EAAE,YAAY,GAAG,EAAE,EAAE,GAAG,QAAQ,EAAE,GAAG,YAAY,IAAI,EAAE,CAAC;IAC9D,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACzJ,OAAO,MAAM,CACX,OAAO,EACP;QACE,GAAG,YAAY;QACf,aAAa,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE;QAClC,6EAA6E;QAC7E,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE;QACnD,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,mBAAmB,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACtF,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE;KAC5E,EACD,IAAI,EACJ,QAAQ,CACT,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/loader/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { Object3D } from "three/webgpu";
2
+ import { type DisposeOptions } from "../dispose.js";
3
+ import type { AssetDependencies } from "./dependencies.js";
4
+ /**
5
+ * What one ladder's loads share: the source loaded to measure or build the ladder with, handed to the first level load
6
+ * (the source level draws it, a build uses it, a cached level disposes it; onLevel has not changed it), the levels built
7
+ * with the ladder, each handed to its first load, and every level object loaded. Those are freed if describing the
8
+ * ladder fails, else when the last Lod holding the levels is disposed (see `hold`), which spends them.
9
+ */
10
+ export declare class LodLoadContext {
11
+ private readonly load;
12
+ private readonly onLevel;
13
+ /** Level bytes built while describing the ladder, by index: a cached level is read again when it loads. */
14
+ private readonly built;
15
+ private spare;
16
+ /** Every level object loaded, and what freeing it frees: a simplified level draws with its source's materials. */
17
+ private readonly loaded;
18
+ /** How many Lods hold the levels, and whether the last has let go, which freed them. */
19
+ private holders;
20
+ private spent;
21
+ constructor(load: () => Promise<Loaded>, onLevel: ((object: Object3D, index: number) => void | Promise<void>) | undefined);
22
+ /** The spare source, loaded once. */
23
+ source(): Promise<Loaded>;
24
+ /** The spare source, for the first level load to take. */
25
+ take(): Loaded | undefined;
26
+ /** Hold the bytes of level `index`, built while describing the ladder, for its first load to take. */
27
+ setBuilt(index: number, bytes: Uint8Array): void;
28
+ /** The bytes of level `index` built while describing the ladder, once: undefined if none were, or once taken. */
29
+ takeBuilt(index: number): Uint8Array | undefined;
30
+ /** Apply onLevel to a level's arriving object, freeing it as `options` say if that fails. */
31
+ arrive(object: Object3D, index: number, options: DisposeOptions): Promise<Object3D>;
32
+ /** Describing the ladder failed: free what it loaded. */
33
+ fail(): void;
34
+ /**
35
+ * A Lod made from the levels holds them; the release it answers lets go, and the last frees what was loaded. Levels
36
+ * no Lod ever held are never freed. Freed levels are spent: a Lod made from them later throws.
37
+ */
38
+ readonly hold: () => (() => void);
39
+ /** Free the spare source and every level object loaded with `dispose`. */
40
+ private free;
41
+ }
42
+ /** A loaded source and what loading it read. */
43
+ export interface Loaded {
44
+ source: Object3D;
45
+ dependencies: AssetDependencies;
46
+ }
@@ -0,0 +1,91 @@
1
+ import { disposeRejected, disposeTree } from "../dispose.js";
2
+ /**
3
+ * What one ladder's loads share: the source loaded to measure or build the ladder with, handed to the first level load
4
+ * (the source level draws it, a build uses it, a cached level disposes it; onLevel has not changed it), the levels built
5
+ * with the ladder, each handed to its first load, and every level object loaded. Those are freed if describing the
6
+ * ladder fails, else when the last Lod holding the levels is disposed (see `hold`), which spends them.
7
+ */
8
+ export class LodLoadContext {
9
+ load;
10
+ onLevel;
11
+ /** Level bytes built while describing the ladder, by index: a cached level is read again when it loads. */
12
+ built = new Map();
13
+ spare;
14
+ /** Every level object loaded, and what freeing it frees: a simplified level draws with its source's materials. */
15
+ loaded = new Map();
16
+ /** How many Lods hold the levels, and whether the last has let go, which freed them. */
17
+ holders = 0;
18
+ spent = false;
19
+ constructor(load, onLevel) {
20
+ this.load = load;
21
+ this.onLevel = onLevel;
22
+ }
23
+ /** The spare source, loaded once. */
24
+ async source() {
25
+ this.spare ??= await this.load();
26
+ return this.spare;
27
+ }
28
+ /** The spare source, for the first level load to take. */
29
+ take() {
30
+ const taken = this.spare;
31
+ this.spare = undefined;
32
+ return taken;
33
+ }
34
+ /** Hold the bytes of level `index`, built while describing the ladder, for its first load to take. */
35
+ setBuilt(index, bytes) {
36
+ this.built.set(index, bytes);
37
+ }
38
+ /** The bytes of level `index` built while describing the ladder, once: undefined if none were, or once taken. */
39
+ takeBuilt(index) {
40
+ const bytes = this.built.get(index);
41
+ this.built.delete(index);
42
+ return bytes;
43
+ }
44
+ /** Apply onLevel to a level's arriving object, freeing it as `options` say if that fails. */
45
+ async arrive(object, index, options) {
46
+ try {
47
+ this.loaded.set(object, options);
48
+ await this.onLevel?.(object, index);
49
+ return object;
50
+ }
51
+ catch (error) {
52
+ this.loaded.delete(object);
53
+ disposeRejected(object, options);
54
+ throw error;
55
+ }
56
+ }
57
+ /** Describing the ladder failed: free what it loaded. */
58
+ fail() {
59
+ this.free(disposeRejected);
60
+ }
61
+ /**
62
+ * A Lod made from the levels holds them; the release it answers lets go, and the last frees what was loaded. Levels
63
+ * no Lod ever held are never freed. Freed levels are spent: a Lod made from them later throws.
64
+ */
65
+ hold = () => {
66
+ if (this.spent)
67
+ throw new Error("LodLoader: these levels were freed with the last Lod that held them; call loadAsync again");
68
+ this.holders++;
69
+ let held = true;
70
+ return () => {
71
+ if (!held)
72
+ return;
73
+ held = false;
74
+ if (--this.holders > 0)
75
+ return;
76
+ this.spent = true;
77
+ this.free(disposeTree);
78
+ };
79
+ };
80
+ /** Free the spare source and every level object loaded with `dispose`. */
81
+ free(dispose) {
82
+ const taken = this.take();
83
+ if (taken)
84
+ dispose(taken.source, { materials: true });
85
+ for (const [object, options] of this.loaded)
86
+ dispose(object, options);
87
+ this.loaded.clear();
88
+ this.built.clear();
89
+ }
90
+ }
91
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/loader/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { LoadingManager, Object3D } from "three/webgpu";
2
+ import type { Dependencies, SavedDependencies } from "vitecache";
3
+ /** The requested assets, and the files and packages loading them revealed, for saving with the index built from them. */
4
+ export declare class AssetDependencies {
5
+ private readonly manager;
6
+ readonly inputs: Dependencies;
7
+ private readonly resources;
8
+ /** Whole: a GLTS source reports what it has observed so far, so it is read when saving. */
9
+ private readonly scripts;
10
+ constructor(urls: Readonly<Record<string, string>>, manager: LoadingManager);
11
+ capture(url: string, object: Object3D, result: unknown): void;
12
+ /** Also hold what `other`'s loads read. */
13
+ include(other: AssetDependencies): this;
14
+ /** The requested URLs, resolved as `inputs` holds them. */
15
+ get requested(): string[];
16
+ /**
17
+ * What the captured assets were built from so far, beyond the requested URLs, or why that cannot be validated later:
18
+ * a CDN module fetched at runtime, which bundled moduleSources cannot vouch for, or a cross-origin resource, which
19
+ * vitecache cannot hash.
20
+ */
21
+ saved(): {
22
+ dependencies: SavedDependencies;
23
+ } | {
24
+ reason: string;
25
+ };
26
+ }
27
+ /**
28
+ * Digests of the bundled modules each input script's GLTS loader links, by input name. They are known before a source runs,
29
+ * so they key its levels: a source's bundled module hashes come from these moduleSources. Any change to them, such as a new
30
+ * bare import in any .glts, therefore invalidates every GLTS-derived level.
31
+ */
32
+ export declare function bundledModules(urls: Readonly<Record<string, string>>, manager: LoadingManager): Promise<Record<string, string>>;
@@ -0,0 +1,113 @@
1
+ import { isGLTSLoader, isGLTSScene } from "../three.js";
2
+ import { sha256 } from "./cache.js";
3
+ import { assetPath, isLocal, localURL, sourceRelativeURL, urlPath } from "./url.js";
4
+ /** The requested assets, and the files and packages loading them revealed, for saving with the index built from them. */
5
+ export class AssetDependencies {
6
+ manager;
7
+ inputs;
8
+ resources = new Set();
9
+ /** Whole: a GLTS source reports what it has observed so far, so it is read when saving. */
10
+ scripts = [];
11
+ constructor(urls, manager) {
12
+ this.manager = manager;
13
+ this.inputs = Object.fromEntries(Object.entries(urls).map(([name, url]) => [name, { url: localURL(manager.resolveURL(url)) }]));
14
+ }
15
+ capture(url, object, result) {
16
+ if (assetPath(url).extension !== "glts") {
17
+ for (const uri of gltfUrls(result, url))
18
+ this.resources.add(localURL(this.manager.resolveURL(uri)));
19
+ return;
20
+ }
21
+ if (!isGLTSScene(object))
22
+ throw new Error(`LodLoader: "${url}" did not load as a GLTS scene`);
23
+ this.scripts.push(object.source);
24
+ }
25
+ /** Also hold what `other`'s loads read. */
26
+ include(other) {
27
+ for (const resource of other.resources)
28
+ this.resources.add(resource);
29
+ this.scripts.push(...other.scripts);
30
+ return this;
31
+ }
32
+ /** The requested URLs, resolved as `inputs` holds them. */
33
+ get requested() {
34
+ return Object.values(this.inputs).flatMap(({ url }) => (url === undefined ? [] : [url]));
35
+ }
36
+ /**
37
+ * What the captured assets were built from so far, beyond the requested URLs, or why that cannot be validated later:
38
+ * a CDN module fetched at runtime, which bundled moduleSources cannot vouch for, or a cross-origin resource, which
39
+ * vitecache cannot hash.
40
+ */
41
+ saved() {
42
+ if (this.scripts.some((source) => source.runtimeModules.length))
43
+ return { reason: "it imports CDN modules at runtime" };
44
+ const found = new Set(this.resources);
45
+ for (const source of this.scripts)
46
+ for (const url of [source.url, ...source.dependencyUrls])
47
+ found.add(localURL(url));
48
+ const inputs = this.requested;
49
+ // A script's provenance URL carries its execution's query, so any query of an input script is that input.
50
+ const scripts = new Set(inputs.filter((url) => assetPath(url).extension === "glts").map(urlPath));
51
+ const urls = [...found].filter((url) => !inputs.includes(url) && !scripts.has(urlPath(url))).sort();
52
+ const remote = urls.find((url) => !isLocal(url));
53
+ if (remote)
54
+ return { reason: `it loads the cross-origin resource "${remote}"` };
55
+ const packages = [...new Set(this.scripts.flatMap((source) => source.packages))].sort();
56
+ return {
57
+ dependencies: {
58
+ ...Object.fromEntries(urls.map((url, index) => [`resource:${index}`, { url }])),
59
+ ...Object.fromEntries(packages.map((name) => [`package:${name}`, { package: name }])),
60
+ },
61
+ };
62
+ }
63
+ }
64
+ /** Each GLTS loader's moduleSources digest, hashed once: a side table keyed by the loaders' moduleSources, which the app owns. */
65
+ const digests = new WeakMap();
66
+ /**
67
+ * Digests of the bundled modules each input script's GLTS loader links, by input name. They are known before a source runs,
68
+ * so they key its levels: a source's bundled module hashes come from these moduleSources. Any change to them, such as a new
69
+ * bare import in any .glts, therefore invalidates every GLTS-derived level.
70
+ */
71
+ export async function bundledModules(urls, manager) {
72
+ const found = {};
73
+ for (const [name, url] of Object.entries(urls)) {
74
+ const handler = manager.getHandler(urlPath(url));
75
+ if (!handler || !isGLTSLoader(handler))
76
+ continue;
77
+ let digest = digests.get(handler.moduleSources);
78
+ if (!digest) {
79
+ // Include namespace bindings: an unused namespace can retain an old module URL.
80
+ digest = sha256(new TextEncoder().encode(JSON.stringify(handler.moduleSources)));
81
+ digests.set(handler.moduleSources, digest);
82
+ }
83
+ found[name] = await digest;
84
+ }
85
+ return found;
86
+ }
87
+ function field(value, name) {
88
+ return typeof value === "object" && value !== null ? Reflect.get(value, name) : undefined;
89
+ }
90
+ function gltfUrls(result, url) {
91
+ const parser = field(result, "parser");
92
+ if (parser === undefined)
93
+ return [];
94
+ const json = field(parser, "json");
95
+ if (typeof json !== "object" || json === null)
96
+ throw new Error("LodLoader: glTF parser.json must provide source metadata");
97
+ return ["buffers", "images"].flatMap((name) => {
98
+ const resources = field(json, name);
99
+ if (resources === undefined)
100
+ return [];
101
+ if (!Array.isArray(resources))
102
+ throw new Error(`LodLoader: glTF ${name} must be an array`);
103
+ return resources.flatMap((resource) => {
104
+ const uri = field(resource, "uri");
105
+ if (uri === undefined)
106
+ return [];
107
+ if (typeof uri !== "string")
108
+ throw new Error("LodLoader: glTF resource URIs must be strings");
109
+ return /^data:/i.test(uri) ? [] : [sourceRelativeURL(uri, url)];
110
+ });
111
+ });
112
+ }
113
+ //# sourceMappingURL=dependencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../src/loader/dependencies.ts"],"names":[],"mappings":"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"}