@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
@@ -1,23 +1,12 @@
1
1
  import { clone } from "three/addons/utils/SkeletonUtils.js";
2
- import { forEachMesh } from "../../bounds.js";
2
+ import { forEachMesh } from "../../source/detail.js";
3
3
  import { isImpostorMesh } from "../../three.js";
4
- /** Snapshot before validation/bounds, without copying loader-added rooms or their resources. */
5
- export function sourceForBake(object, excluded = []) {
6
- const children = object.children;
7
- try {
8
- // SkeletonUtils has no exclusion hook. This synchronous view emits no events and
9
- // is restored before any await, even if validation or a custom clone throws.
10
- // Cloning then removing rooms would allocate excluded nested LOD resources.
11
- if (excluded.length > 0)
12
- object.children = children.filter((child) => !excluded.includes(child));
13
- forEachMesh(object, (mesh) => {
14
- if (isImpostorMesh(mesh))
15
- throw new Error(`bakeImpostor: cannot bake an ImpostorMesh ("${mesh.name}"); bake from its source instead`);
16
- });
17
- return clone(object);
18
- }
19
- finally {
20
- object.children = children;
21
- }
4
+ /** A copy of `object` to bake, which the bake may move and change; ImpostorMeshes are refused. */
5
+ export function sourceForBake(object) {
6
+ forEachMesh(object, (mesh) => {
7
+ if (isImpostorMesh(mesh))
8
+ throw new Error(`bakeImpostor: cannot bake an ImpostorMesh ("${mesh.name}"); bake from its source instead`);
9
+ });
10
+ return clone(object);
22
11
  }
23
12
  //# sourceMappingURL=source.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"source.js","sourceRoot":"","sources":["../../../src/impostor/bake/source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,gGAAgG;AAChG,MAAM,UAAU,aAAa,CAAC,MAAgB,EAAE,WAAgC,EAAE;IAChF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,IAAI,CAAC;QACH,iFAAiF;QACjF,6EAA6E;QAC7E,4EAA4E;QAC5E,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACjG,WAAW,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC3B,IAAI,cAAc,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,IAAI,CAAC,IAAI,kCAAkC,CAAC,CAAC;QACxI,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../../../src/impostor/bake/source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,kGAAkG;AAClG,MAAM,UAAU,aAAa,CAAC,MAAgB;IAC5C,WAAW,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QAC3B,IAAI,cAAc,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,IAAI,CAAC,IAAI,kCAAkC,CAAC,CAAC;IACxI,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC;AACvB,CAAC"}
@@ -1,9 +1,8 @@
1
1
  import { type Impostor } from "./impostor.js";
2
2
  /**
3
- * Serializes `impostor` to a KTX2 file: one RGBA8 UNORM 2D array texture with a layer per
4
- * map and its baked mip levels, zlib-supercompressed, plus the metadata as JSON under the
5
- * "impostor" key.
3
+ * Serializes a baked `impostor`: every field but the layers as JSON, then one KTX2 file per map of GPU-compressible
4
+ * Basis UASTC, encoded in workers. A few seconds for a 1024 atlas.
6
5
  */
7
- export declare function encodeImpostor(impostor: Impostor): Uint8Array;
8
- /** Parses a file written by `encodeImpostor`, inflating its mips off the main thread. */
6
+ export declare function encodeImpostorAsync(impostor: Impostor): Promise<Uint8Array>;
7
+ /** Parses a file written by `encodeImpostorAsync`, transcoding its maps off the main thread to a format the GPU takes. */
9
8
  export declare function decodeImpostorAsync(bytes: Uint8Array): Promise<Impostor>;
@@ -1,126 +1,53 @@
1
- import { unzlib, zlibSync } from "fflate";
2
- import { KHR_DF_CHANNEL_RGBSDA_ALPHA, KHR_DF_CHANNEL_RGBSDA_BLUE, KHR_DF_CHANNEL_RGBSDA_GREEN, KHR_DF_CHANNEL_RGBSDA_RED, KHR_DF_MODEL_RGBSDA, KHR_DF_TRANSFER_LINEAR, KHR_SUPERCOMPRESSION_ZLIB, VK_FORMAT_R8G8B8A8_UNORM, createDefaultContainer, read, write, } from "ktx-parse";
1
+ import { read } from "ktx-parse";
2
+ import { RGBAFormat } from "three/webgpu";
3
+ import { pack, unpack } from "../codec/container.js";
3
4
  import { validateImpostor } from "./impostor.js";
4
- /** Key/value entry holding every non-pixel field as JSON. */
5
- const KEY = "impostor";
5
+ import { encodeLayer } from "./ktx2/encode.js";
6
+ import { transcode } from "./ktx2/transcode.js";
7
+ const srgb = (map) => map === "base" || map === "emissive";
6
8
  /**
7
- * Serializes `impostor` to a KTX2 file: one RGBA8 UNORM 2D array texture with a layer per
8
- * map and its baked mip levels, zlib-supercompressed, plus the metadata as JSON under the
9
- * "impostor" key.
9
+ * Serializes a baked `impostor`: every field but the layers as JSON, then one KTX2 file per map of GPU-compressible
10
+ * Basis UASTC, encoded in workers. A few seconds for a 1024 atlas.
10
11
  */
11
- export function encodeImpostor(impostor) {
12
+ export async function encodeImpostorAsync(impostor) {
12
13
  validateImpostor(impostor);
13
14
  const { layers, ...meta } = impostor;
14
- const levelCount = layers[0]?.length ?? 0;
15
- // KTX2 stores each mip level with all its array layers, layer-major.
16
- const levels = Array.from({ length: levelCount }, (_, m) => {
17
- const bytes = (meta.size >> m) ** 2 * 4;
18
- const raw = new Uint8Array(layers.length * bytes);
19
- layers.forEach((layer, i) => raw.set(layer[m] ?? fail(`layer ${i} has no level ${m}`), i * bytes));
20
- return { levelData: zlibSync(raw, { level: 6 }), uncompressedByteLength: raw.length };
21
- });
22
- const ktx = createDefaultContainer();
23
- ktx.vkFormat = VK_FORMAT_R8G8B8A8_UNORM;
24
- ktx.typeSize = 1;
25
- ktx.pixelWidth = meta.size;
26
- ktx.pixelHeight = meta.size;
27
- ktx.layerCount = layers.length;
28
- ktx.levelCount = levels.length;
29
- ktx.supercompressionScheme = KHR_SUPERCOMPRESSION_ZLIB;
30
- ktx.levels = levels;
31
- // UNORM data must declare a linear transfer; base/emissive are sRGB-encoded but the
32
- // renderer decodes them itself, as it does with the linear normal/orm layers.
33
- const channels = [KHR_DF_CHANNEL_RGBSDA_RED, KHR_DF_CHANNEL_RGBSDA_GREEN, KHR_DF_CHANNEL_RGBSDA_BLUE, KHR_DF_CHANNEL_RGBSDA_ALPHA];
34
- for (const dfd of ktx.dataFormatDescriptor) {
35
- dfd.colorModel = KHR_DF_MODEL_RGBSDA;
36
- dfd.transferFunction = KHR_DF_TRANSFER_LINEAR;
37
- dfd.bytesPlane = [4, 0, 0, 0, 0, 0, 0, 0];
38
- dfd.samples = channels.map((channelType, i) => ({
39
- bitOffset: i * 8,
40
- bitLength: 7, // stored as bits - 1
41
- channelType,
42
- samplePosition: [0, 0, 0, 0],
43
- sampleLower: 0,
44
- sampleUpper: 255,
45
- }));
46
- }
47
- ktx.keyValue[KEY] = JSON.stringify(meta);
48
- return write(ktx);
15
+ const files = await Promise.all(layers.map((layer, i) => {
16
+ const map = impostor.maps[i];
17
+ if (!map || layer.format !== RGBAFormat)
18
+ throw new Error("encodeImpostorAsync: encode a baked impostor; this one holds compressed blocks");
19
+ return encodeLayer({ levels: layer.mipmaps, size: impostor.size, srgb: srgb(map) });
20
+ }));
21
+ return pack(meta, files);
49
22
  }
50
- /** Parses a file written by `encodeImpostor`, inflating its mips off the main thread. */
23
+ /** Parses a file written by `encodeImpostorAsync`, transcoding its maps off the main thread to a format the GPU takes. */
51
24
  export async function decodeImpostorAsync(bytes) {
52
- const file = parse(bytes);
53
- const levels = await Promise.all(file.levels.map(async ({ data, length }, m) => {
25
+ const { header, files } = await unpack(bytes, fail);
26
+ if (typeof header !== "object" || header === null)
27
+ fail("metadata is not an object");
28
+ const size = Reflect.get(header, "size");
29
+ const layers = await Promise.all(files.map(async (file, i) => {
30
+ let ktx;
31
+ try {
32
+ ktx = read(file);
33
+ }
34
+ catch (error) {
35
+ fail(`map ${i} is not a KTX2 file`, error);
36
+ }
37
+ if (ktx.pixelWidth !== size || ktx.pixelHeight !== size)
38
+ fail(`map ${i} is ${ktx.pixelWidth}x${ktx.pixelHeight}, not the atlas size`);
54
39
  try {
55
- // Move large mips off the main thread; small mips avoid worker startup cost.
56
- if (length >= 8 * 1024 * 1024)
57
- return await new Promise((resolve, reject) => {
58
- unzlib(data.slice(), { consume: true }, (error, raw) => {
59
- if (error)
60
- reject(error);
61
- else
62
- resolve(raw);
63
- });
64
- });
65
- const stream = new Blob([data.slice()]).stream().pipeThrough(new DecompressionStream("deflate"));
66
- return new Uint8Array(await new Response(stream).arrayBuffer());
40
+ return await transcode(file);
67
41
  }
68
42
  catch (error) {
69
- throw invalid(`level ${m} does not inflate`, error);
43
+ fail(`map ${i} does not transcode`, error);
70
44
  }
71
45
  }));
72
- return decoded(file, levels);
73
- }
74
- function parse(bytes) {
75
- // ktx-parse reads through `bytes.buffer` without checking the view's end, so a truncated
76
- // view would read past it; give it a buffer of exactly the file instead.
77
- const file = bytes.byteLength === bytes.buffer.byteLength ? bytes : bytes.slice();
78
- const ktx = attempt("not a KTX2 container", () => read(file));
79
- if (ktx.vkFormat !== VK_FORMAT_R8G8B8A8_UNORM)
80
- fail(`vkFormat ${ktx.vkFormat} is not R8G8B8A8_UNORM`);
81
- if (ktx.supercompressionScheme !== KHR_SUPERCOMPRESSION_ZLIB)
82
- fail(`supercompression ${ktx.supercompressionScheme} is not zlib`);
83
- if (ktx.pixelWidth !== ktx.pixelHeight)
84
- fail(`atlas is ${ktx.pixelWidth}x${ktx.pixelHeight}, not square`);
85
- const json = ktx.keyValue[KEY];
86
- if (!(json instanceof Uint8Array))
87
- fail(`missing "${KEY}" metadata`);
88
- // ktx-parse returns values of keys not starting with "KTX" as raw bytes, NUL included.
89
- const meta = attempt("metadata is not JSON", () => JSON.parse(new TextDecoder().decode(json).replace(/\0$/, "")));
90
- if (typeof meta !== "object" || meta === null)
91
- fail("metadata is not an object");
92
- const levels = ktx.levels.map((level, m) => {
93
- const bytes = (ktx.pixelWidth >> m) ** 2 * 4;
94
- if (level.uncompressedByteLength !== bytes * ktx.layerCount)
95
- fail(`level ${m} size does not match the atlas`);
96
- return { data: level.levelData, length: level.uncompressedByteLength };
97
- });
98
- return { meta, layerCount: ktx.layerCount, levels };
99
- }
100
- function decoded(file, levels) {
101
- levels.forEach((raw, m) => {
102
- if (raw.length !== file.levels[m]?.length)
103
- fail(`level ${m} inflates to the wrong size`);
104
- });
105
- // Layers share one inflated buffer per mip, in KTX2's layer-major order.
106
- const layers = Array.from({ length: file.layerCount }, (_, i) => levels.map((raw) => raw.subarray((i * raw.length) / file.layerCount, ((i + 1) * raw.length) / file.layerCount)));
107
- const impostor = { ...file.meta, layers };
46
+ const impostor = { ...header, layers };
108
47
  validateImpostor(impostor);
109
48
  return impostor;
110
49
  }
111
- function fail(why) {
112
- throw new Error(`Invalid impostor file: ${why}`);
113
- }
114
- /** Runs `run`, turning any throw into an "Invalid impostor file" error. */
115
- function attempt(why, run) {
116
- try {
117
- return run();
118
- }
119
- catch (error) {
120
- throw invalid(why, error);
121
- }
122
- }
123
- function invalid(why, error) {
124
- return new Error(`Invalid impostor file: ${why} (${error instanceof Error ? error.message : String(error)})`, { cause: error });
50
+ function fail(why, cause) {
51
+ throw new Error(`Invalid impostor file: ${why}`, { cause });
125
52
  }
126
53
  //# sourceMappingURL=codec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"codec.js","sourceRoot":"","sources":["../../src/impostor/codec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codec.js","sourceRoot":"","sources":["../../src/impostor/codec.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
+ import { RGBAFormat, type CompressedPixelFormat } from "three/webgpu";
1
2
  /** Which part of the view sphere the atlas covers. */
2
3
  export type ImpostorLayout = "hemi" | "full";
3
4
  /**
4
- * The atlas maps, in the order they are stored. Each is one RGBA8 layer:
5
+ * The atlas maps, in the order they are stored. Each is one RGBA layer:
5
6
  *
6
7
  * - `base`: base colour (sRGB) in RGB, coverage in A.
7
8
  * - `normalDepth`: an object-space normal n in RGB (`n * 0.5 + 0.5`), depth in A. The
@@ -13,6 +14,18 @@ export type ImpostorLayout = "hemi" | "full";
13
14
  */
14
15
  export declare const MAPS: readonly ["base", "normalDepth", "orm", "emissive"];
15
16
  export type ImpostorMap = (typeof MAPS)[number];
17
+ /**
18
+ * One map's mip chain, `size >> level` square, from `size` down to one texel per frame (`frames` square). The levels
19
+ * are baked, not filtered from level 0.
20
+ */
21
+ export interface ImpostorLayer {
22
+ /**
23
+ * RGBAFormat: 4 bytes a texel, as baked. A decoded impostor holds the block-compressed format its decoder transcoded
24
+ * to for the GPU, or RGBAFormat where the GPU takes none.
25
+ */
26
+ format: typeof RGBAFormat | CompressedPixelFormat;
27
+ mipmaps: Uint8Array[];
28
+ }
16
29
  /**
17
30
  * A baked octahedral impostor: plain data, no GPU resources.
18
31
  *
@@ -25,7 +38,7 @@ export type ImpostorMap = (typeof MAPS)[number];
25
38
  * toward the camera that baked the frame and 0 is away from it.
26
39
  */
27
40
  export interface Impostor {
28
- version: 3;
41
+ version: 4;
29
42
  layout: ImpostorLayout;
30
43
  /** frames per atlas side */
31
44
  frames: number;
@@ -45,22 +58,33 @@ export interface Impostor {
45
58
  */
46
59
  specular?: [number, number, number, number];
47
60
  /**
48
- * One per entry in `maps`: its mip chain of RGBA8 arrays, `size >> level` square, from
49
- * `size` down to one texel per frame (`frames` square). The levels are baked, not
50
- * filtered from level 0. An ImpostorMesh's textures share these arrays, so they stay in
51
- * memory while the impostor is referenced, ready for `encodeImpostor`.
61
+ * One per entry in `maps`. An ImpostorMesh's textures share these arrays, so they stay in memory while the impostor is
62
+ * referenced, ready for `encodeImpostorAsync` when they are RGBAFormat.
52
63
  */
53
- layers: Uint8Array[][];
64
+ layers: ImpostorLayer[];
54
65
  }
55
66
  export declare function boxCentre(b: Impostor["box"]): [number, number, number];
56
67
  /** Half the box's edges. */
57
68
  export declare function boxExtent(b: Impostor["box"]): [number, number, number];
58
69
  /** Radius of the sphere around the box: the depth channel's unit. */
59
70
  export declare function boundingRadius(b: Impostor["box"]): number;
71
+ /**
72
+ * Empty border around the object in every frame, as a fraction of the frame's half
73
+ * size. It keeps mip levels from blending a frame's silhouette into its neighbour.
74
+ */
75
+ export declare const PAD = 0.06;
76
+ /**
77
+ * `texelPixels` of any impostor baked at `resolution`, at least: a frame fitted to the source's bounding sphere, the
78
+ * widest it can be. The default `maxPixels` of an impostor level a loader describes before building it.
79
+ */
80
+ export declare const framePixels: (resolution?: number) => number;
60
81
  /**
61
82
  * On-screen height of the object at which two atlas texels span one pixel: the default
62
83
  * `LodLevel.maxPixels` of an impostor. An impostor blends filtered reads of several
63
84
  * views, so it keeps the source's colour detail only down to about two texels per pixel.
85
+ * A LodLoader describes its levels before baking them, so its impostor levels default to
86
+ * `framePixels` instead: this height for a frame fitted to the bounding sphere, up to about
87
+ * 1.5 times lower than for the frame the bake fits.
64
88
  */
65
89
  export declare function texelPixels(impostor: Pick<Impostor, "size" | "frames" | "box" | "halfSize">): number;
66
90
  /** Throws unless `value` is a usable impostor. */
@@ -1,5 +1,6 @@
1
+ import { RGBAFormat } from "three/webgpu";
1
2
  /**
2
- * The atlas maps, in the order they are stored. Each is one RGBA8 layer:
3
+ * The atlas maps, in the order they are stored. Each is one RGBA layer:
3
4
  *
4
5
  * - `base`: base colour (sRGB) in RGB, coverage in A.
5
6
  * - `normalDepth`: an object-space normal n in RGB (`n * 0.5 + 0.5`), depth in A. The
@@ -21,10 +22,23 @@ export function boxExtent(b) {
21
22
  export function boundingRadius(b) {
22
23
  return Math.hypot(b[3] - b[0], b[4] - b[1], b[5] - b[2]) / 2;
23
24
  }
25
+ /**
26
+ * Empty border around the object in every frame, as a fraction of the frame's half
27
+ * size. It keeps mip levels from blending a frame's silhouette into its neighbour.
28
+ */
29
+ export const PAD = 0.06;
30
+ /**
31
+ * `texelPixels` of any impostor baked at `resolution`, at least: a frame fitted to the source's bounding sphere, the
32
+ * widest it can be. The default `maxPixels` of an impostor level a loader describes before building it.
33
+ */
34
+ export const framePixels = (resolution = 128) => 2 ** Math.floor(Math.log2(resolution)) / (2 * (1 + PAD));
24
35
  /**
25
36
  * On-screen height of the object at which two atlas texels span one pixel: the default
26
37
  * `LodLevel.maxPixels` of an impostor. An impostor blends filtered reads of several
27
38
  * views, so it keeps the source's colour detail only down to about two texels per pixel.
39
+ * A LodLoader describes its levels before baking them, so its impostor levels default to
40
+ * `framePixels` instead: this height for a frame fitted to the bounding sphere, up to about
41
+ * 1.5 times lower than for the frame the bake fits.
28
42
  */
29
43
  export function texelPixels(impostor) {
30
44
  const cell = impostor.size / impostor.frames;
@@ -42,7 +56,7 @@ export function validateImpostor(value) {
42
56
  fail("not an object");
43
57
  const fields = value;
44
58
  const { version, layout, frames, size, box, halfSize, maps, specular, layers } = fields;
45
- if (version !== 3)
59
+ if (version !== 4)
46
60
  fail(`unsupported version ${String(version)}; bake it again`);
47
61
  if (layout !== "hemi" && layout !== "full")
48
62
  fail(`unknown layout "${String(layout)}"`);
@@ -67,12 +81,13 @@ export function validateImpostor(value) {
67
81
  fail(`frame size ${cell} is not a power of two`);
68
82
  const levels = Math.log2(cell) + 1;
69
83
  for (const layer of layers) {
70
- if (!Array.isArray(layer) || layer.length !== levels)
84
+ if (typeof layer !== "object" || layer === null || !Array.isArray(layer.mipmaps) || layer.mipmaps.length !== levels)
71
85
  fail(`every layer must be a mip chain of ${levels} levels`);
72
- layer.forEach((level, m) => {
86
+ const rgba = layer.format === RGBAFormat;
87
+ layer.mipmaps.forEach((level, m) => {
73
88
  const bytes = (size >> m) ** 2 * 4;
74
- if (!(level instanceof Uint8Array) || level.length !== bytes)
75
- fail(`mip level ${m} must be a Uint8Array of ${bytes} bytes`);
89
+ if (!(level instanceof Uint8Array) || (rgba ? level.length !== bytes : !level.length))
90
+ fail(`mip level ${m} must be a Uint8Array${rgba ? ` of ${bytes} bytes` : ""}`);
76
91
  });
77
92
  }
78
93
  }
@@ -1 +1 @@
1
- {"version":3,"file":"impostor.js","sourceRoot":"","sources":["../../src/impostor/impostor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"impostor.js","sourceRoot":"","sources":["../../src/impostor/impostor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /** One map's RGBA8 mip levels, `size >> level` square. */
2
+ export interface Layer {
3
+ levels: Uint8Array[];
4
+ size: number;
5
+ /** Whether the texels are sRGB-encoded colour; otherwise linear data. */
6
+ srgb: boolean;
7
+ }
8
+ /** What the worker encodes: RGBA8 rows of a mip level, `width` wide and `height` high. */
9
+ export interface Job {
10
+ data: Uint8Array;
11
+ width: number;
12
+ height: number;
13
+ srgb: boolean;
14
+ }
15
+ /** What the worker answers a job with. */
16
+ export type Reply = {
17
+ file: Uint8Array;
18
+ } | {
19
+ error: string;
20
+ };
21
+ /**
22
+ * One map as a KTX2 file of Basis UASTC. Each level encodes as `parts` strips of rows, by default one per worker, so
23
+ * that a map's top level, which holds three quarters of its texels, takes all workers; the strips' and levels' files
24
+ * are then joined. Takes about a second per million texels and worker.
25
+ */
26
+ export declare function encodeLayer({ levels, size, srgb }: Layer, parts?: number): Promise<Uint8Array>;
@@ -0,0 +1,117 @@
1
+ import { read, write } from "ktx-parse";
2
+ // Read when the module loads, which also happens in Node, as for a .glts warmup; Node before 21 has no navigator.
3
+ const cores = globalThis.navigator?.hardwareConcurrency ?? 4;
4
+ /**
5
+ * A worker per core but one, since a cold ladder's encodes take far longer than its bakes; at most 8, since each holds
6
+ * 100 to 250 MB of WebAssembly memory.
7
+ */
8
+ const LIMIT = Math.max(1, Math.min(8, cores - 1));
9
+ /** Largest job first, so that the smaller ones fill the other workers meanwhile. */
10
+ const queue = [];
11
+ /** How many encoder workers run: a process-wide pool, as each holds its own WASM memory and LIMIT bounds them all. */
12
+ let workers = 0;
13
+ /**
14
+ * One map as a KTX2 file of Basis UASTC. Each level encodes as `parts` strips of rows, by default one per worker, so
15
+ * that a map's top level, which holds three quarters of its texels, takes all workers; the strips' and levels' files
16
+ * are then joined. Takes about a second per million texels and worker.
17
+ */
18
+ export async function encodeLayer({ levels, size, srgb }, parts = LIMIT) {
19
+ const files = await Promise.all(levels.map((data, m) => Promise.all(strips(data, size >> m, srgb, parts).map((job) => encodeJob(job).then(read)))));
20
+ const first = files[0]?.[0];
21
+ if (!first)
22
+ throw new Error("encodeImpostorAsync: a map has no mip levels");
23
+ // UASTC encodes each 4x4 block on its own, and a level's Zstandard data may be several frames, which decode as one:
24
+ // a level's strips, each a multiple of four rows high but the last, concatenate to data that decodes as the whole level's.
25
+ first.levels = files.map((parts) => {
26
+ const levels = parts.map((file) => {
27
+ const [level] = file.levels;
28
+ if (!level)
29
+ throw new Error("encodeImpostorAsync: the encoder wrote a file without levels");
30
+ return level;
31
+ });
32
+ const levelData = new Uint8Array(levels.reduce((sum, level) => sum + level.levelData.length, 0));
33
+ let offset = 0;
34
+ for (const level of levels) {
35
+ levelData.set(level.levelData, offset);
36
+ offset += level.levelData.length;
37
+ }
38
+ return { levelData, uncompressedByteLength: levels.reduce((sum, level) => sum + level.uncompressedByteLength, 0) };
39
+ });
40
+ first.pixelHeight = size;
41
+ first.levelCount = files.length;
42
+ return write(first);
43
+ }
44
+ /** A `size`² level's strips: at most `parts`, each a multiple of four rows high but perhaps the last. */
45
+ function strips(data, size, srgb, parts) {
46
+ const rows = 4 * Math.ceil(size / parts / 4);
47
+ const jobs = [];
48
+ // Sliced: each job owns its buffer, which moves to its worker.
49
+ for (let y = 0; y < size; y += rows) {
50
+ const height = Math.min(rows, size - y);
51
+ jobs.push({ data: data.slice(4 * size * y, 4 * size * (y + height)), width: size, height, srgb });
52
+ }
53
+ return jobs;
54
+ }
55
+ function encodeJob(job) {
56
+ return new Promise((resolve, reject) => {
57
+ queue.push({ job, resolve, reject });
58
+ queue.sort((a, b) => b.job.width * b.job.height - a.job.width * a.job.height);
59
+ if (workers < LIMIT)
60
+ void work();
61
+ });
62
+ }
63
+ /** One worker, with its own encoder instance, that takes queued jobs until none is left and then ends. */
64
+ async function work() {
65
+ workers++;
66
+ let worker;
67
+ try {
68
+ for (let task = queue.shift(); task; task = queue.shift()) {
69
+ try {
70
+ worker ??= await start();
71
+ const reply = await run(worker, task.job);
72
+ if ("file" in reply)
73
+ task.resolve(reply.file);
74
+ else
75
+ task.reject(new Error(`encodeImpostorAsync: ${reply.error}`));
76
+ }
77
+ catch (error) {
78
+ // The worker failed to load or crashed; the next job gets a fresh one.
79
+ task.reject(error);
80
+ worker?.terminate();
81
+ worker = undefined;
82
+ }
83
+ }
84
+ }
85
+ finally {
86
+ worker?.terminate();
87
+ workers--;
88
+ }
89
+ }
90
+ async function start() {
91
+ const { url } = await import("./worker.js");
92
+ return new Worker(url, { type: "module" });
93
+ }
94
+ /** `job` on `worker`; rejects when the worker fails rather than answers, as one that does not load does. */
95
+ function run(worker, job) {
96
+ return new Promise((resolve, reject) => {
97
+ const settle = () => {
98
+ worker.removeEventListener("message", message);
99
+ worker.removeEventListener("error", error);
100
+ worker.removeEventListener("messageerror", error);
101
+ };
102
+ const message = (event) => {
103
+ settle();
104
+ resolve(event.data);
105
+ };
106
+ const error = (event) => {
107
+ settle();
108
+ const why = event instanceof ErrorEvent ? event.message : `${event.type} event`;
109
+ reject(new Error(`encodeImpostorAsync: the encoder worker failed (${why})`));
110
+ };
111
+ worker.addEventListener("message", message);
112
+ worker.addEventListener("error", error);
113
+ worker.addEventListener("messageerror", error);
114
+ worker.postMessage(job, [job.data.buffer]);
115
+ });
116
+ }
117
+ //# sourceMappingURL=encode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.js","sourceRoot":"","sources":["../../../src/impostor/ktx2/encode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ImpostorLayer } from "../impostor.js";
2
+ /** A map's KTX2 file as the blocks of a GPU format, transcoded in three's workers. */
3
+ export declare function transcode(file: Uint8Array): Promise<ImpostorLayer>;