@drawcall/lod 0.2.0 → 0.4.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 (355) hide show
  1. package/README.md +6 -7
  2. package/dist/bake.d.ts +36 -0
  3. package/dist/bake.js +176 -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 +14 -8
  15. package/dist/baked/index.js +24 -22
  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 +16 -11
  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.d.ts +1 -1
  24. package/dist/baked/interior/rooms.js +2 -2
  25. package/dist/baked/interior/rooms.js.map +1 -1
  26. package/dist/baked/low.js +5 -4
  27. package/dist/baked/low.js.map +1 -1
  28. package/dist/baked/raster.js +6 -6
  29. package/dist/baked/raster.js.map +1 -1
  30. package/dist/baked/textures.d.ts +17 -0
  31. package/dist/baked/textures.js +95 -0
  32. package/dist/baked/textures.js.map +1 -0
  33. package/dist/baked/transfer.js +19 -18
  34. package/dist/baked/transfer.js.map +1 -1
  35. package/dist/baked/unwrap.js +4 -3
  36. package/dist/baked/unwrap.js.map +1 -1
  37. package/dist/baked/xatlas.js.map +1 -1
  38. package/dist/codec/container.d.ts +8 -0
  39. package/dist/codec/container.js +63 -0
  40. package/dist/codec/container.js.map +1 -0
  41. package/dist/codec/mesh.d.ts +8 -0
  42. package/dist/{mesh/codec.js → codec/mesh.js} +80 -52
  43. package/dist/codec/mesh.js.map +1 -0
  44. package/dist/dispose.d.ts +8 -5
  45. package/dist/dispose.js +22 -24
  46. package/dist/dispose.js.map +1 -1
  47. package/dist/foliage.d.ts +32 -0
  48. package/dist/foliage.js +137 -0
  49. package/dist/foliage.js.map +1 -0
  50. package/dist/impostor/bake/atlas.d.ts +4 -4
  51. package/dist/impostor/bake/atlas.js +12 -12
  52. package/dist/impostor/bake/atlas.js.map +1 -1
  53. package/dist/impostor/bake/fit.d.ts +8 -0
  54. package/dist/impostor/bake/fit.js +28 -0
  55. package/dist/impostor/bake/fit.js.map +1 -0
  56. package/dist/impostor/bake/index.d.ts +22 -14
  57. package/dist/impostor/bake/index.js +50 -134
  58. package/dist/impostor/bake/index.js.map +1 -1
  59. package/dist/impostor/bake/materials.d.ts +3 -3
  60. package/dist/impostor/bake/materials.js +51 -13
  61. package/dist/impostor/bake/materials.js.map +1 -1
  62. package/dist/impostor/bake/sheet.d.ts +8 -0
  63. package/dist/impostor/bake/sheet.js +90 -0
  64. package/dist/impostor/bake/sheet.js.map +1 -0
  65. package/dist/impostor/bake/source.d.ts +3 -2
  66. package/dist/impostor/bake/source.js +9 -20
  67. package/dist/impostor/bake/source.js.map +1 -1
  68. package/dist/impostor/codec.d.ts +4 -5
  69. package/dist/impostor/codec.js +36 -109
  70. package/dist/impostor/codec.js.map +1 -1
  71. package/dist/impostor/impostor.d.ts +31 -7
  72. package/dist/impostor/impostor.js +21 -6
  73. package/dist/impostor/impostor.js.map +1 -1
  74. package/dist/impostor/ktx2/encode.d.ts +26 -0
  75. package/dist/impostor/ktx2/encode.js +120 -0
  76. package/dist/impostor/ktx2/encode.js.map +1 -0
  77. package/dist/impostor/ktx2/transcode.d.ts +3 -0
  78. package/dist/impostor/ktx2/transcode.js +99 -0
  79. package/dist/impostor/ktx2/transcode.js.map +1 -0
  80. package/dist/impostor/ktx2/uastc.d.ts +7 -0
  81. package/dist/impostor/ktx2/uastc.js +65 -0
  82. package/dist/impostor/ktx2/uastc.js.map +1 -0
  83. package/dist/impostor/ktx2/wasm/encoder.d.ts +4 -0
  84. package/dist/impostor/ktx2/wasm/encoder.js +10 -0
  85. package/dist/impostor/ktx2/wasm/encoder.js.map +1 -0
  86. package/dist/impostor/ktx2/wasm/transcoder.d.ts +3 -0
  87. package/dist/impostor/ktx2/wasm/transcoder.js +9 -0
  88. package/dist/impostor/ktx2/wasm/transcoder.js.map +1 -0
  89. package/dist/impostor/ktx2/worker.d.ts +1 -0
  90. package/dist/impostor/ktx2/worker.js +10 -0
  91. package/dist/impostor/ktx2/worker.js.map +1 -0
  92. package/dist/impostor/mesh/card.d.ts +4 -4
  93. package/dist/impostor/mesh/card.js +7 -7
  94. package/dist/impostor/mesh/card.js.map +1 -1
  95. package/dist/impostor/mesh/index.d.ts +7 -6
  96. package/dist/impostor/mesh/index.js +10 -11
  97. package/dist/impostor/mesh/index.js.map +1 -1
  98. package/dist/impostor/mesh/material.d.ts +18 -9
  99. package/dist/impostor/mesh/material.js +40 -27
  100. package/dist/impostor/mesh/material.js.map +1 -1
  101. package/dist/impostor/mesh/surface.d.ts +1 -1
  102. package/dist/impostor/mesh/surface.js +13 -9
  103. package/dist/impostor/mesh/surface.js.map +1 -1
  104. package/dist/impostor/mesh/textures.d.ts +3 -3
  105. package/dist/impostor/mesh/textures.js +24 -34
  106. package/dist/impostor/mesh/textures.js.map +1 -1
  107. package/dist/index.d.ts +13 -11
  108. package/dist/index.js +12 -10
  109. package/dist/index.js.map +1 -1
  110. package/dist/instanced/camera.d.ts +34 -0
  111. package/dist/instanced/camera.js +45 -0
  112. package/dist/instanced/camera.js.map +1 -0
  113. package/dist/instanced/clusters.d.ts +54 -0
  114. package/dist/instanced/clusters.js +151 -0
  115. package/dist/instanced/clusters.js.map +1 -0
  116. package/dist/instanced/cull.d.ts +28 -0
  117. package/dist/instanced/cull.js +22 -0
  118. package/dist/instanced/cull.js.map +1 -0
  119. package/dist/instanced/instances.d.ts +39 -0
  120. package/dist/instanced/instances.js +104 -0
  121. package/dist/instanced/instances.js.map +1 -0
  122. package/dist/instanced/key.d.ts +19 -0
  123. package/dist/instanced/key.js +45 -0
  124. package/dist/instanced/key.js.map +1 -0
  125. package/dist/instanced/levels.d.ts +60 -0
  126. package/dist/instanced/levels.js +131 -0
  127. package/dist/instanced/levels.js.map +1 -0
  128. package/dist/instanced/lists.d.ts +57 -0
  129. package/dist/instanced/lists.js +114 -0
  130. package/dist/instanced/lists.js.map +1 -0
  131. package/dist/instanced/measure.d.ts +28 -0
  132. package/dist/instanced/measure.js +203 -0
  133. package/dist/instanced/measure.js.map +1 -0
  134. package/dist/instanced/meshes.d.ts +44 -51
  135. package/dist/instanced/meshes.js +167 -179
  136. package/dist/instanced/meshes.js.map +1 -1
  137. package/dist/instanced/mirror.d.ts +24 -0
  138. package/dist/instanced/mirror.js +76 -0
  139. package/dist/instanced/mirror.js.map +1 -0
  140. package/dist/instanced/raycast.d.ts +10 -11
  141. package/dist/instanced/raycast.js +31 -41
  142. package/dist/instanced/raycast.js.map +1 -1
  143. package/dist/instanced/rows.d.ts +50 -0
  144. package/dist/instanced/rows.js +36 -0
  145. package/dist/instanced/rows.js.map +1 -0
  146. package/dist/instanced/shape.d.ts +27 -0
  147. package/dist/instanced/shape.js +54 -0
  148. package/dist/instanced/shape.js.map +1 -0
  149. package/dist/instanced/sort.d.ts +61 -0
  150. package/dist/instanced/sort.js +192 -0
  151. package/dist/instanced/sort.js.map +1 -0
  152. package/dist/instanced/update.d.ts +34 -0
  153. package/dist/instanced/update.js +180 -0
  154. package/dist/instanced/update.js.map +1 -0
  155. package/dist/levels/bounds.d.ts +21 -0
  156. package/dist/levels/bounds.js +42 -0
  157. package/dist/levels/bounds.js.map +1 -0
  158. package/dist/levels/cameras.d.ts +48 -0
  159. package/dist/levels/cameras.js +122 -0
  160. package/dist/levels/cameras.js.map +1 -0
  161. package/dist/levels/compile/contexts.d.ts +30 -0
  162. package/dist/levels/compile/contexts.js +18 -0
  163. package/dist/levels/compile/contexts.js.map +1 -0
  164. package/dist/levels/compile/index.d.ts +41 -0
  165. package/dist/levels/compile/index.js +193 -0
  166. package/dist/levels/compile/index.js.map +1 -0
  167. package/dist/levels/compile/pipelines.d.ts +26 -0
  168. package/dist/levels/compile/pipelines.js +172 -0
  169. package/dist/levels/compile/pipelines.js.map +1 -0
  170. package/dist/levels/compiles.d.ts +29 -0
  171. package/dist/levels/compiles.js +50 -0
  172. package/dist/levels/compiles.js.map +1 -0
  173. package/dist/levels/draw.d.ts +102 -0
  174. package/dist/levels/draw.js +401 -0
  175. package/dist/levels/draw.js.map +1 -0
  176. package/dist/levels/fade.d.ts +60 -0
  177. package/dist/levels/fade.js +129 -0
  178. package/dist/levels/fade.js.map +1 -0
  179. package/dist/levels/index.d.ts +99 -0
  180. package/dist/levels/index.js +155 -0
  181. package/dist/levels/index.js.map +1 -0
  182. package/dist/levels/item.d.ts +38 -0
  183. package/dist/levels/item.js +89 -0
  184. package/dist/levels/item.js.map +1 -0
  185. package/dist/levels/load.d.ts +31 -0
  186. package/dist/levels/load.js +144 -0
  187. package/dist/levels/load.js.map +1 -0
  188. package/dist/levels/manager.d.ts +158 -0
  189. package/dist/levels/manager.js +352 -0
  190. package/dist/levels/manager.js.map +1 -0
  191. package/dist/{material.d.ts → levels/material.d.ts} +2 -2
  192. package/dist/{material.js → levels/material.js} +6 -5
  193. package/dist/levels/material.js.map +1 -0
  194. package/dist/levels/renderer.d.ts +32 -0
  195. package/dist/levels/renderer.js +57 -0
  196. package/dist/levels/renderer.js.map +1 -0
  197. package/dist/levels/requests.d.ts +52 -0
  198. package/dist/levels/requests.js +97 -0
  199. package/dist/levels/requests.js.map +1 -0
  200. package/dist/levels/screen.d.ts +14 -0
  201. package/dist/levels/screen.js +21 -0
  202. package/dist/levels/screen.js.map +1 -0
  203. package/dist/loader/build.d.ts +10 -0
  204. package/dist/loader/build.js +28 -0
  205. package/dist/loader/build.js.map +1 -0
  206. package/dist/loader/context.d.ts +44 -0
  207. package/dist/loader/context.js +96 -0
  208. package/dist/loader/context.js.map +1 -0
  209. package/dist/loader/entry.d.ts +4 -0
  210. package/dist/loader/entry.js +43 -0
  211. package/dist/loader/entry.js.map +1 -0
  212. package/dist/loader/index.d.ts +76 -0
  213. package/dist/loader/index.js +272 -0
  214. package/dist/loader/index.js.map +1 -0
  215. package/dist/loader/level.d.ts +41 -0
  216. package/dist/loader/level.js +140 -0
  217. package/dist/loader/level.js.map +1 -0
  218. package/dist/loader/node.d.ts +26 -0
  219. package/dist/loader/node.js +199 -0
  220. package/dist/loader/node.js.map +1 -0
  221. package/dist/loader/request.d.ts +54 -0
  222. package/dist/loader/request.js +19 -0
  223. package/dist/loader/request.js.map +1 -0
  224. package/dist/loader/url.d.ts +10 -6
  225. package/dist/loader/url.js +22 -14
  226. package/dist/loader/url.js.map +1 -1
  227. package/dist/lod.d.ts +144 -43
  228. package/dist/lod.js +354 -163
  229. package/dist/lod.js.map +1 -1
  230. package/dist/meshopt.d.ts +6 -0
  231. package/dist/meshopt.js +20 -0
  232. package/dist/meshopt.js.map +1 -0
  233. package/dist/node-process.d.ts +5 -0
  234. package/dist/node-process.js +6 -0
  235. package/dist/node-process.js.map +1 -0
  236. package/dist/node.d.ts +2 -0
  237. package/dist/node.js +5 -0
  238. package/dist/node.js.map +1 -0
  239. package/dist/simplify/cards.d.ts +14 -0
  240. package/dist/simplify/cards.js +128 -0
  241. package/dist/simplify/cards.js.map +1 -0
  242. package/dist/{simplify.d.ts → simplify/index.d.ts} +8 -5
  243. package/dist/{simplify.js → simplify/index.js} +45 -27
  244. package/dist/simplify/index.js.map +1 -0
  245. package/dist/{bounds.d.ts → source/detail.d.ts} +9 -23
  246. package/dist/{bounds.js → source/detail.js} +28 -58
  247. package/dist/source/detail.js.map +1 -0
  248. package/dist/source/deviation.js +6 -6
  249. package/dist/source/deviation.js.map +1 -1
  250. package/dist/source/{shading.d.ts → evaluator.d.ts} +10 -10
  251. package/dist/source/{shading.js → evaluator.js} +5 -5
  252. package/dist/source/evaluator.js.map +1 -0
  253. package/dist/source/{trace.d.ts → raycaster.d.ts} +6 -6
  254. package/dist/source/{trace.js → raycaster.js} +8 -8
  255. package/dist/source/raycaster.js.map +1 -0
  256. package/dist/source/{texels.d.ts → sampler.d.ts} +1 -1
  257. package/dist/source/{texels.js → sampler.js} +8 -5
  258. package/dist/source/sampler.js.map +1 -0
  259. package/dist/source/source.d.ts +1 -1
  260. package/dist/source/source.js +1 -1
  261. package/dist/source/source.js.map +1 -1
  262. package/dist/source/surface.js +1 -1
  263. package/dist/source/surface.js.map +1 -1
  264. package/dist/task.d.ts +6 -0
  265. package/dist/{pause.js → task.js} +5 -5
  266. package/dist/task.js.map +1 -0
  267. package/dist/three.d.ts +19 -30
  268. package/dist/three.js +30 -57
  269. package/dist/three.js.map +1 -1
  270. package/dist/tsl.d.ts +8 -12
  271. package/dist/tsl.js +11 -39
  272. package/dist/tsl.js.map +1 -1
  273. package/dist/typegpu.d.ts +37 -0
  274. package/dist/typegpu.js +37 -0
  275. package/dist/typegpu.js.map +1 -0
  276. package/dist/wind/bounds.js +3 -3
  277. package/dist/wind/bounds.js.map +1 -1
  278. package/dist/wind/hooks.d.ts +7 -4
  279. package/dist/wind/hooks.js +5 -2
  280. package/dist/wind/hooks.js.map +1 -1
  281. package/dist/wind/index.d.ts +4 -4
  282. package/dist/wind/index.js +25 -23
  283. package/dist/wind/index.js.map +1 -1
  284. package/dist/wind/sway.d.ts +2 -0
  285. package/dist/wind/sway.js +4 -1
  286. package/dist/wind/sway.js.map +1 -1
  287. package/package.json +24 -10
  288. package/skills/lod/SKILL.md +120 -32
  289. package/dist/bounds.js.map +0 -1
  290. package/dist/compile.d.ts +0 -4
  291. package/dist/compile.js +0 -100
  292. package/dist/compile.js.map +0 -1
  293. package/dist/deferred.d.ts +0 -12
  294. package/dist/deferred.js +0 -27
  295. package/dist/deferred.js.map +0 -1
  296. package/dist/fade.d.ts +0 -36
  297. package/dist/fade.js +0 -112
  298. package/dist/fade.js.map +0 -1
  299. package/dist/instanced/args.d.ts +0 -20
  300. package/dist/instanced/args.js +0 -77
  301. package/dist/instanced/args.js.map +0 -1
  302. package/dist/instanced/blocks.d.ts +0 -66
  303. package/dist/instanced/blocks.js +0 -294
  304. package/dist/instanced/blocks.js.map +0 -1
  305. package/dist/instanced/dirty.d.ts +0 -15
  306. package/dist/instanced/dirty.js +0 -96
  307. package/dist/instanced/dirty.js.map +0 -1
  308. package/dist/instanced/index.d.ts +0 -90
  309. package/dist/instanced/index.js +0 -349
  310. package/dist/instanced/index.js.map +0 -1
  311. package/dist/instanced/parts.d.ts +0 -14
  312. package/dist/instanced/parts.js +0 -79
  313. package/dist/instanced/parts.js.map +0 -1
  314. package/dist/instanced/select.d.ts +0 -92
  315. package/dist/instanced/select.js +0 -315
  316. package/dist/instanced/select.js.map +0 -1
  317. package/dist/instanced/store.d.ts +0 -31
  318. package/dist/instanced/store.js +0 -96
  319. package/dist/instanced/store.js.map +0 -1
  320. package/dist/levels.d.ts +0 -95
  321. package/dist/levels.js +0 -171
  322. package/dist/levels.js.map +0 -1
  323. package/dist/loader/bundle.d.ts +0 -25
  324. package/dist/loader/bundle.js +0 -241
  325. package/dist/loader/bundle.js.map +0 -1
  326. package/dist/loader/cache.d.ts +0 -15
  327. package/dist/loader/cache.js +0 -75
  328. package/dist/loader/cache.js.map +0 -1
  329. package/dist/loader/provenance.d.ts +0 -30
  330. package/dist/loader/provenance.js +0 -105
  331. package/dist/loader/provenance.js.map +0 -1
  332. package/dist/loader.d.ts +0 -55
  333. package/dist/loader.js +0 -239
  334. package/dist/loader.js.map +0 -1
  335. package/dist/material.js.map +0 -1
  336. package/dist/mesh/codec.d.ts +0 -4
  337. package/dist/mesh/codec.js.map +0 -1
  338. package/dist/pause.d.ts +0 -6
  339. package/dist/pause.js.map +0 -1
  340. package/dist/queue.d.ts +0 -2
  341. package/dist/queue.js +0 -33
  342. package/dist/queue.js.map +0 -1
  343. package/dist/renderer.d.ts +0 -21
  344. package/dist/renderer.js +0 -83
  345. package/dist/renderer.js.map +0 -1
  346. package/dist/residency.d.ts +0 -44
  347. package/dist/residency.js +0 -205
  348. package/dist/residency.js.map +0 -1
  349. package/dist/simplify.js.map +0 -1
  350. package/dist/source/shading.js.map +0 -1
  351. package/dist/source/texels.js.map +0 -1
  352. package/dist/source/trace.js.map +0 -1
  353. package/dist/view.d.ts +0 -45
  354. package/dist/view.js +0 -131
  355. package/dist/view.js.map +0 -1
@@ -0,0 +1,39 @@
1
+ import { Box3, type InstancedBufferAttribute, type StorageInstancedBufferAttribute } from "three/webgpu";
2
+ /** A Lod's instancing data, as an InstancedMesh holds it. */
3
+ export interface InstanceAttributes {
4
+ readonly instanceMatrix: InstancedBufferAttribute;
5
+ readonly instanceColor: InstancedBufferAttribute | null;
6
+ readonly count: number;
7
+ }
8
+ /** Of a CPU instanceMatrix's first `count` instances at a scale above 0: their origins' box and scales. */
9
+ export interface Measured {
10
+ readonly originBox: Box3;
11
+ /** No matrix scales its longest axis less. */
12
+ minScale: number;
13
+ /** No matrix stretches any direction more. */
14
+ maxScale: number;
15
+ }
16
+ /** A Lod's instances as storage. */
17
+ export declare class Instances {
18
+ /** Bumped whenever what the storage holds, or how many instances there are, may have changed. */
19
+ version: number;
20
+ /** Measured from a CPU instanceMatrix as it changes; null for a storage one, which the CPU cannot read. */
21
+ measured: Measured | null;
22
+ private matrices;
23
+ private colors;
24
+ private count;
25
+ /** The matrices as the GPU reads them, once taken in. */
26
+ get matrixStorage(): StorageInstancedBufferAttribute;
27
+ /** The colours as the GPU reads them, RGB and a pad: white without. */
28
+ get colorStorage(): StorageInstancedBufferAttribute;
29
+ /**
30
+ * Take in `attributes` as they are: an attribute assigned anew, edits marked by `needsUpdate` (within their update
31
+ * ranges), a new count. A storage instanceMatrix, which the app's GPU passes may write any time, counts as changed
32
+ * at every update. Throws unless they can be drawn.
33
+ */
34
+ refresh({ instanceMatrix, instanceColor, count }: InstanceAttributes): void;
35
+ /** Release the mirrors; the attributes are the app's. */
36
+ dispose(): void;
37
+ }
38
+ /** Measure the first `count` instances of `instanceMatrix` at a scale above 0 into `into`, or a new Measured. */
39
+ export declare function measure(instanceMatrix: InstancedBufferAttribute, count: number, into: Measured | null): Measured;
@@ -0,0 +1,104 @@
1
+ import { Box3, Matrix4, Vector3 } from "three/webgpu";
2
+ import { white } from "../levels/fade.js";
3
+ import { isStorageInstanced, stretch } from "../three.js";
4
+ import { ColorMirror, Mirror } from "./mirror.js";
5
+ const matrix = new Matrix4();
6
+ const origin = new Vector3();
7
+ /** A Lod's instances as storage. */
8
+ export class Instances {
9
+ /** Bumped whenever what the storage holds, or how many instances there are, may have changed. */
10
+ version = 0;
11
+ /** Measured from a CPU instanceMatrix as it changes; null for a storage one, which the CPU cannot read. */
12
+ measured = null;
13
+ matrices = null;
14
+ colors = null;
15
+ count = -1;
16
+ /** The matrices as the GPU reads them, once taken in. */
17
+ get matrixStorage() {
18
+ const found = this.matrices;
19
+ if (!found)
20
+ throw new Error("Lod: its instances are read before they were taken in");
21
+ return found.mirror?.attribute ?? storageOf(found.source);
22
+ }
23
+ /** The colours as the GPU reads them, RGB and a pad: white without. */
24
+ get colorStorage() {
25
+ const found = this.colors;
26
+ return found ? (found.mirror?.attribute ?? storageOf(found.source)) : white;
27
+ }
28
+ /**
29
+ * Take in `attributes` as they are: an attribute assigned anew, edits marked by `needsUpdate` (within their update
30
+ * ranges), a new count. A storage instanceMatrix, which the app's GPU passes may write any time, counts as changed
31
+ * at every update. Throws unless they can be drawn.
32
+ */
33
+ refresh({ instanceMatrix, instanceColor, count }) {
34
+ check(instanceMatrix, instanceColor, count);
35
+ let replaced = false;
36
+ if (this.matrices?.source !== instanceMatrix) {
37
+ this.matrices?.mirror?.dispose();
38
+ this.matrices = { source: instanceMatrix, mirror: isStorageInstanced(instanceMatrix) ? null : new Mirror(instanceMatrix) };
39
+ this.measured = null;
40
+ replaced = true;
41
+ }
42
+ if (this.colors?.source !== (instanceColor ?? undefined)) {
43
+ this.colors?.mirror?.dispose();
44
+ this.colors = instanceColor && { source: instanceColor, mirror: isStorageInstanced(instanceColor) ? null : new ColorMirror(instanceColor) };
45
+ replaced = true;
46
+ }
47
+ const { mirror } = this.matrices;
48
+ const moved = mirror ? mirror.refresh() : true;
49
+ const recoloured = this.colors?.mirror?.refresh() ?? false;
50
+ if (mirror && (moved || replaced || count !== this.count || !this.measured))
51
+ this.measured = measure(instanceMatrix, count, this.measured);
52
+ if (replaced || moved || recoloured || count !== this.count)
53
+ this.version++;
54
+ this.count = count;
55
+ }
56
+ /** Release the mirrors; the attributes are the app's. */
57
+ dispose() {
58
+ this.matrices?.mirror?.dispose();
59
+ this.colors?.mirror?.dispose();
60
+ this.matrices = null;
61
+ this.colors = null;
62
+ }
63
+ }
64
+ /** `attribute`, which `refresh` found a storage attribute. */
65
+ function storageOf(attribute) {
66
+ if (!isStorageInstanced(attribute))
67
+ throw new TypeError("Lod: an attribute read in place is not a storage attribute");
68
+ return attribute;
69
+ }
70
+ /** Throws unless the attributes hold `count` instances as an InstancedMesh's do; a storage colour pads RGB to four floats. */
71
+ function check(instanceMatrix, instanceColor, count) {
72
+ if (instanceMatrix.itemSize !== 16 || !(instanceMatrix.array instanceof Float32Array) || instanceMatrix.normalized)
73
+ throw new TypeError(`Lod: instanceMatrix holds 16 floats per instance, not ${instanceMatrix.itemSize}${instanceMatrix.normalized ? " normalized" : ""}`);
74
+ if (!Number.isInteger(count) || count < 0 || count > instanceMatrix.count)
75
+ throw new RangeError(`Lod: count must be an integer from 0 to instanceMatrix.count, ${instanceMatrix.count}, not ${count}`);
76
+ if (!instanceColor)
77
+ return;
78
+ const size = isStorageInstanced(instanceColor) ? 4 : 3;
79
+ if (instanceColor.itemSize !== size || !(instanceColor.array instanceof Float32Array) || instanceColor.normalized)
80
+ throw new TypeError(`Lod: instanceColor holds ${size} floats per instance${size === 4 ? " in storage" : ""}, not ${instanceColor.itemSize}`);
81
+ if (instanceColor.count < count)
82
+ throw new RangeError(`Lod: instanceColor holds ${instanceColor.count} instances, fewer than count, ${count}`);
83
+ }
84
+ /** Measure the first `count` instances of `instanceMatrix` at a scale above 0 into `into`, or a new Measured. */
85
+ export function measure(instanceMatrix, count, into) {
86
+ const measured = into ?? { originBox: new Box3(), minScale: 0, maxScale: 0 };
87
+ const { array } = instanceMatrix;
88
+ measured.originBox.makeEmpty();
89
+ measured.minScale = Infinity;
90
+ measured.maxScale = 0;
91
+ for (let i = 0; i < count; i++) {
92
+ matrix.fromArray(array, i * 16);
93
+ const scale = matrix.getMaxScaleOnAxis();
94
+ if (scale === 0)
95
+ continue;
96
+ measured.originBox.expandByPoint(origin.setFromMatrixPosition(matrix));
97
+ measured.minScale = Math.min(measured.minScale, scale);
98
+ measured.maxScale = Math.max(measured.maxScale, stretch(matrix));
99
+ }
100
+ if (measured.originBox.isEmpty())
101
+ measured.minScale = measured.maxScale = 0;
102
+ return measured;
103
+ }
104
+ //# sourceMappingURL=instances.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instances.js","sourceRoot":"","sources":["../../src/instanced/instances.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Sphere, Vector3 } from "three/webgpu";
2
+ import type { d } from "typegpu";
3
+ import type { DrawLevels } from "../levels/draw.js";
4
+ import type { Cull } from "./cull.js";
5
+ /** The values something last ran with, written again in place each time it may run, telling whether any differs. */
6
+ export declare class Key {
7
+ private readonly values;
8
+ private length;
9
+ private changed;
10
+ /** Starts writing the values anew. */
11
+ start(): this;
12
+ put(value: number): this;
13
+ /** Whether the values written since start differ from the last ones. */
14
+ end(): boolean;
15
+ /** A camera's inputs, everything in the Lod's space: what sorting for it reads. */
16
+ camera(eye: Vector3, scale: number, ortho: boolean, levels: d.Infer<typeof DrawLevels>, cull: Cull | null, source: Sphere): this;
17
+ /** A camera's inputs but where it looks from: all an orthographic camera measures heights by. */
18
+ screen(scale: number, ortho: boolean, levels: d.Infer<typeof DrawLevels>, cull: Cull | null, source: Sphere): this;
19
+ }
@@ -0,0 +1,45 @@
1
+ // What a camera's sort or loading last ran with, so that it is skipped while nothing it reads changed.
2
+ /** The values something last ran with, written again in place each time it may run, telling whether any differs. */
3
+ export class Key {
4
+ values = [];
5
+ length = 0;
6
+ changed = false;
7
+ /** Starts writing the values anew. */
8
+ start() {
9
+ this.length = 0;
10
+ this.changed = false;
11
+ return this;
12
+ }
13
+ put(value) {
14
+ if (this.values[this.length] !== value) {
15
+ this.values[this.length] = value;
16
+ this.changed = true;
17
+ }
18
+ this.length++;
19
+ return this;
20
+ }
21
+ /** Whether the values written since start differ from the last ones. */
22
+ end() {
23
+ if (this.values.length !== this.length) {
24
+ this.values.length = this.length;
25
+ this.changed = true;
26
+ }
27
+ return this.changed;
28
+ }
29
+ /** A camera's inputs, everything in the Lod's space: what sorting for it reads. */
30
+ camera(eye, scale, ortho, levels, cull, source) {
31
+ return this.put(eye.x).put(eye.y).put(eye.z).screen(scale, ortho, levels, cull, source);
32
+ }
33
+ /** A camera's inputs but where it looks from: all an orthographic camera measures heights by. */
34
+ screen(scale, ortho, levels, cull, source) {
35
+ this.put(scale).put(Number(ortho));
36
+ this.put(levels.count).put(levels.empty).put(levels.coarsest).put(levels.forced).put(levels.fades);
37
+ for (const pixels of levels.maxPixels)
38
+ this.put(pixels);
39
+ this.put(Number(cull !== null));
40
+ if (cull)
41
+ this.put(cull.eye.x).put(cull.eye.y).put(cull.eye.z).put(cull.near).put(cull.far).put(Number(cull.survivors));
42
+ return this.put(source.center.x).put(source.center.y).put(source.center.z).put(source.radius);
43
+ }
44
+ }
45
+ //# sourceMappingURL=key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key.js","sourceRoot":"","sources":["../../src/instanced/key.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { Object3D, type Box3, type Camera, type Mesh, type Sphere } from "three/webgpu";
2
+ import { type ThresholdedLevel } from "../levels/index.js";
3
+ import type { DrawnInstances } from "../levels/fade.js";
4
+ import type { PreparedLevel } from "../levels/manager.js";
5
+ import type { InstanceLists } from "./lists.js";
6
+ import { type Part } from "./meshes.js";
7
+ import type { InstanceShape } from "./shape.js";
8
+ /** What a Lod's level meshes draw with: its shape, lists and the instances they draw. */
9
+ export interface Drawing {
10
+ readonly shape: InstanceShape;
11
+ readonly lists: InstanceLists;
12
+ /** What the level meshes draw: the Lod's instances, or while survivors scale, their scaled matrices. */
13
+ readonly drawn: DrawnInstances;
14
+ }
15
+ /**
16
+ * A Lod's level meshes: per level, the meshes drawing it with its debug tint, made from the level's object once there
17
+ * is one and added to the Lod, and the source level's parts, which a raycast hits.
18
+ */
19
+ export declare class MeshesByLevel {
20
+ /** The Lod, which holds the meshes. */
21
+ private readonly parent;
22
+ /** Its levels: a level that joins gets its object. */
23
+ private readonly levels;
24
+ private readonly drawing;
25
+ /** Around every instance, survivors grown: what every level mesh is culled and boxed by. */
26
+ private readonly bounds;
27
+ /** Sorts `camera`'s lists as `renderer` draws a mesh for it. */
28
+ private readonly drawFor;
29
+ private readonly tints;
30
+ private readonly byLevel;
31
+ private sourceParts;
32
+ constructor(
33
+ /** The Lod, which holds the meshes. */
34
+ parent: Object3D,
35
+ /** Its levels: a level that joins gets its object. */
36
+ levels: readonly ThresholdedLevel[], drawing: Drawing,
37
+ /** Around every instance, survivors grown: what every level mesh is culled and boxed by. */
38
+ bounds: {
39
+ readonly sphere: Sphere;
40
+ readonly box: Box3;
41
+ },
42
+ /** Sorts `camera`'s lists as `renderer` draws a mesh for it. */
43
+ drawFor: (renderer: unknown, camera: Camera) => void);
44
+ /** The source level's parts, which a raycast hits. */
45
+ get source(): readonly Part[];
46
+ /** The meshes drawing level `level`. */
47
+ of(level: number): readonly Mesh[];
48
+ /** Every level's meshes. */
49
+ all(): Mesh[];
50
+ /** Tint each level as Lod.debug, `debug`, has it. */
51
+ tint(debug: boolean): void;
52
+ /** Show the meshes of the levels of the bits `levels`, and hide the others. */
53
+ show(levels: number): void;
54
+ /** The meshes drawing `parts` of level `level` for the cameras of the lists. */
55
+ private meshesOf;
56
+ /** Level meshes of `loaded`, level `index`'s object, staged for wind and compiling. */
57
+ prepare(index: number, loaded: Object3D): PreparedLevel;
58
+ /** Take every mesh out of the Lod and free it. */
59
+ dispose(): void;
60
+ }
@@ -0,0 +1,131 @@
1
+ import { Color, Object3D } from "three/webgpu";
2
+ import { at } from "../at.js";
3
+ import { prepareBounds } from "../levels/bounds.js";
4
+ import { disposeCopies } from "../dispose.js";
5
+ import { tintOf } from "../levels/index.js";
6
+ import { has } from "../levels/draw.js";
7
+ import { refreshWind } from "../wind/index.js";
8
+ import { freeMesh, levelMeshes, partsOf } from "./meshes.js";
9
+ /**
10
+ * A Lod's level meshes: per level, the meshes drawing it with its debug tint, made from the level's object once there
11
+ * is one and added to the Lod, and the source level's parts, which a raycast hits.
12
+ */
13
+ export class MeshesByLevel {
14
+ parent;
15
+ levels;
16
+ drawing;
17
+ bounds;
18
+ drawFor;
19
+ tints;
20
+ byLevel = [];
21
+ sourceParts = [];
22
+ constructor(
23
+ /** The Lod, which holds the meshes. */
24
+ parent,
25
+ /** Its levels: a level that joins gets its object. */
26
+ levels, drawing,
27
+ /** Around every instance, survivors grown: what every level mesh is culled and boxed by. */
28
+ bounds,
29
+ /** Sorts `camera`'s lists as `renderer` draws a mesh for it. */
30
+ drawFor) {
31
+ this.parent = parent;
32
+ this.levels = levels;
33
+ this.drawing = drawing;
34
+ this.bounds = bounds;
35
+ this.drawFor = drawFor;
36
+ this.tints = levels.map(() => new Color(1, 1, 1));
37
+ levels.forEach(({ object }, i) => {
38
+ const parts = object ? partsOf(object, i) : [];
39
+ if (i === 0)
40
+ this.sourceParts = parts;
41
+ const made = this.meshesOf(parts, i);
42
+ drawInto(drawing.lists, made);
43
+ this.byLevel.push(made.meshes);
44
+ for (const mesh of made.meshes)
45
+ parent.add(mesh);
46
+ });
47
+ }
48
+ /** The source level's parts, which a raycast hits. */
49
+ get source() {
50
+ return this.sourceParts;
51
+ }
52
+ /** The meshes drawing level `level`. */
53
+ of(level) {
54
+ return at(this.byLevel, level);
55
+ }
56
+ /** Every level's meshes. */
57
+ all() {
58
+ return this.byLevel.flat();
59
+ }
60
+ /** Tint each level as Lod.debug, `debug`, has it. */
61
+ tint(debug) {
62
+ this.levels.forEach((_, i) => at(this.tints, i).copy(tintOf(i, debug)));
63
+ }
64
+ /** Show the meshes of the levels of the bits `levels`, and hide the others. */
65
+ show(levels) {
66
+ this.byLevel.forEach((meshes, level) => {
67
+ for (const mesh of meshes)
68
+ mesh.visible = has(levels, level);
69
+ });
70
+ }
71
+ /** The meshes drawing `parts` of level `level` for the cameras of the lists. */
72
+ meshesOf(parts, level) {
73
+ const { lists, drawn, shape } = this.drawing;
74
+ return levelMeshes(parts, at(this.tints, level), {
75
+ instances: drawn,
76
+ bounds: this.bounds.sphere,
77
+ box: this.bounds.box,
78
+ slots: (camera) => lists.slots(camera),
79
+ radius: shape.fadeRadius,
80
+ layers: this.parent.layers,
81
+ drawFor: (renderer, camera) => {
82
+ this.drawFor(renderer, camera);
83
+ return lists.slots(camera)?.args ?? null;
84
+ },
85
+ });
86
+ }
87
+ /** Level meshes of `loaded`, level `index`'s object, staged for wind and compiling. */
88
+ prepare(index, loaded) {
89
+ const level = at(this.levels, index);
90
+ const object = loaded.clone();
91
+ if (level.box)
92
+ prepareBounds(object, level.box);
93
+ const parts = partsOf(object, index);
94
+ const made = this.meshesOf(parts, index);
95
+ const staged = new Object3D();
96
+ for (const mesh of made.meshes)
97
+ staged.add(mesh);
98
+ refreshWind(this.parent, staged);
99
+ return {
100
+ object: staged,
101
+ join: () => {
102
+ level.object = object;
103
+ drawInto(this.drawing.lists, made);
104
+ this.byLevel[index] = made.meshes;
105
+ if (index === 0)
106
+ this.sourceParts = parts;
107
+ for (const mesh of made.meshes)
108
+ this.parent.add(mesh);
109
+ },
110
+ discard: () => {
111
+ for (const mesh of made.meshes)
112
+ freeMesh(mesh);
113
+ disposeCopies(object);
114
+ },
115
+ };
116
+ }
117
+ /** Take every mesh out of the Lod and free it. */
118
+ dispose() {
119
+ for (const mesh of this.byLevel.flat()) {
120
+ mesh.removeFromParent();
121
+ freeMesh(mesh);
122
+ }
123
+ this.byLevel.length = 0;
124
+ }
125
+ }
126
+ /** Let `made` draw for the cameras of `lists`, its draws appended to theirs. */
127
+ function drawInto(lists, made) {
128
+ if (made.draws.length > 0)
129
+ made.drawFrom(lists.appendDraws(made.draws));
130
+ }
131
+ //# sourceMappingURL=levels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"levels.js","sourceRoot":"","sources":["../../src/instanced/levels.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { Frustum, Matrix4, type Camera, type Renderer, type StorageInstancedBufferAttribute } from "three/webgpu";
2
+ import type { InstanceSlots } from "../levels/fade.js";
3
+ import { type LodLevel } from "../levels/index.js";
4
+ import { Key } from "./key.js";
5
+ import { type RowValues } from "./sort.js";
6
+ import type { IndirectDraw } from "./rows.js";
7
+ /** What one camera's sort reads besides its lists, everything in the Lod's space. */
8
+ export interface SortInputs extends Omit<RowValues, "frustum"> {
9
+ /** The instances the camera sees, as start and count, flat (see clusters.ts), and how many in all. */
10
+ ranges: readonly number[];
11
+ instances: number;
12
+ /** Whether every range it sees lies wholly inside its frustum. */
13
+ inside: boolean;
14
+ /**
15
+ * The bit of the one level each instance draws, without a fade, at any height its range's instances can have, with
16
+ * no cullDistance and no arrival under way; else 0. Inside the camera's frustum, its lists then hold every instance
17
+ * at that level however the camera moves.
18
+ */
19
+ onlyLevel: number;
20
+ /** Bumped whenever what the instances' storage holds changed. */
21
+ version: number;
22
+ }
23
+ /** One camera's lists: what it last sorted with, which a sort is skipped for. */
24
+ export interface CameraLists {
25
+ /** The camera's frustum in the Lod's space, as its last update found it (see `frustumIn`). */
26
+ readonly frustum: Frustum;
27
+ /** Whether a sort was written for the camera: until then the level meshes draw nothing for it. */
28
+ written: boolean;
29
+ readonly sortKey: Key;
30
+ }
31
+ /** The lists of every camera drawing one Lod, and the sorts filling them. */
32
+ export declare class InstanceLists {
33
+ private readonly cameras;
34
+ private readonly sorter;
35
+ /** `listed` tells per level whether it has an instance list: whether it draws something. */
36
+ constructor(listed: readonly boolean[]);
37
+ /** `camera`'s lists, made the first time it asks. */
38
+ of(camera: Camera): CameraLists;
39
+ /** Where `camera`'s lists and indirect draws lie; null before a sort was written for it. */
40
+ slots(camera: Camera): InstanceSlots | null;
41
+ /** Every camera draws `draws` too, after the draws it has; where they start. */
42
+ appendDraws(draws: readonly IndirectDraw[]): number;
43
+ /** Survivors' scaled matrices for `capacity` instances. */
44
+ scaledMatrices(capacity: number): StorageInstancedBufferAttribute;
45
+ /** Sort for `camera` at its next draw, unless nothing it sorts by changed since its last sort; `limit` bounds its buffers. */
46
+ sort(camera: Camera, sort: SortInputs, limit: number): void;
47
+ /** Sort for `camera` on `renderer`, reading `matrices`, if due: before a level mesh draws for it. */
48
+ drawFor(renderer: Renderer, camera: Camera, matrices: StorageInstancedBufferAttribute): void;
49
+ /** Give back the lists of every camera other than `camera` that `rendering` says stopped drawing, as a clone made for one frame does. */
50
+ prune(camera: Camera, rendering: (camera: Camera) => boolean): void;
51
+ dispose(): void;
52
+ private forget;
53
+ }
54
+ /** Set `lists`' frustum to `camera`'s in the space of `space`, a world matrix, and return it. */
55
+ export declare function frustumIn(lists: CameraLists, camera: Camera, space: Matrix4): Frustum;
56
+ /** Per level of `inputs`, whether it has an instance list: whether it draws something. */
57
+ export declare function listedOf(inputs: readonly LodLevel[]): boolean[];
@@ -0,0 +1,114 @@
1
+ import { Frustum, Matrix4 } from "three/webgpu";
2
+ import { has } from "../levels/draw.js";
3
+ import { emptyLevels } from "../levels/index.js";
4
+ import { Key } from "./key.js";
5
+ import { Sorter } from "./sort.js";
6
+ const projection = new Matrix4();
7
+ /** What a camera's sort key starts with: how it lies to the instances it sees, which says what else the key holds. */
8
+ const MODE = {
9
+ /** It sees none: nothing draws, and no sort runs. */
10
+ hidden: 0,
11
+ /** The key holds everything the sort reads. */
12
+ seen: 1,
13
+ /** Every range wholly inside its frustum, each instance drawing one level without a fade and none culled: the key holds the level. */
14
+ oneLevel: 2,
15
+ /** Every range wholly inside an orthographic camera's frustum, none culled: heights are alike from anywhere, so no eye. */
16
+ orthoInside: 3,
17
+ };
18
+ /** The lists of every camera drawing one Lod, and the sorts filling them. */
19
+ export class InstanceLists {
20
+ cameras = new Map();
21
+ sorter;
22
+ /** `listed` tells per level whether it has an instance list: whether it draws something. */
23
+ constructor(listed) {
24
+ this.sorter = new Sorter(listed.reduce((mask, on, i) => (on ? mask | (1 << i) : mask), 0));
25
+ }
26
+ /** `camera`'s lists, made the first time it asks. */
27
+ of(camera) {
28
+ const found = this.cameras.get(camera);
29
+ if (found)
30
+ return found;
31
+ const lists = { frustum: new Frustum(), written: false, sortKey: new Key() };
32
+ this.cameras.set(camera, lists);
33
+ return lists;
34
+ }
35
+ /** Where `camera`'s lists and indirect draws lie; null before a sort was written for it. */
36
+ slots(camera) {
37
+ return this.sorter.slotsOf(camera);
38
+ }
39
+ /** Every camera draws `draws` too, after the draws it has; where they start. */
40
+ appendDraws(draws) {
41
+ return this.sorter.appendDraws(draws);
42
+ }
43
+ /** Survivors' scaled matrices for `capacity` instances. */
44
+ scaledMatrices(capacity) {
45
+ return this.sorter.scaledMatrices(capacity);
46
+ }
47
+ /** Sort for `camera` at its next draw, unless nothing it sorts by changed since its last sort; `limit` bounds its buffers. */
48
+ sort(camera, sort, limit) {
49
+ const lists = this.of(camera);
50
+ const { levels, eye, scale, ortho, cull, loaded, before, progress, source, reach, ranges } = sort;
51
+ const mode = modeOf(sort);
52
+ // No level mesh draws for the camera (see Lod.sort): its lists are not read. The key still holds what the last
53
+ // sort read, which a camera that looks back at the instances as it was matches: that sort's lists still hold.
54
+ if (mode === MODE.hidden)
55
+ return;
56
+ const key = lists.sortKey.start().put(mode).put(sort.version);
57
+ for (const value of ranges)
58
+ key.put(value);
59
+ if (mode === MODE.oneLevel)
60
+ key.put(sort.onlyLevel);
61
+ else if (mode === MODE.orthoInside)
62
+ key.screen(scale, ortho, levels, cull, source).put(loaded).put(before).put(progress).put(reach);
63
+ else if (mode === MODE.seen) {
64
+ for (const { normal, constant } of lists.frustum.planes)
65
+ key.put(normal.x).put(normal.y).put(normal.z).put(constant);
66
+ key.camera(eye, scale, ortho, levels, cull, source).put(loaded).put(before).put(progress).put(reach);
67
+ }
68
+ if (!key.end())
69
+ return;
70
+ this.sorter.write(camera, { levels, eye, scale, ortho, cull, loaded, before, progress, source, reach, frustum: lists.frustum }, ranges, sort.instances, limit);
71
+ lists.written = true;
72
+ }
73
+ /** Sort for `camera` on `renderer`, reading `matrices`, if due: before a level mesh draws for it. */
74
+ drawFor(renderer, camera, matrices) {
75
+ this.sorter.run(renderer, camera, matrices);
76
+ }
77
+ /** Give back the lists of every camera other than `camera` that `rendering` says stopped drawing, as a clone made for one frame does. */
78
+ prune(camera, rendering) {
79
+ for (const other of [...this.cameras.keys()])
80
+ if (other !== camera && !rendering(other))
81
+ this.forget(other);
82
+ }
83
+ dispose() {
84
+ this.cameras.clear();
85
+ this.sorter.dispose();
86
+ }
87
+ forget(camera) {
88
+ this.cameras.delete(camera);
89
+ this.sorter.release(camera);
90
+ }
91
+ }
92
+ /** Set `lists`' frustum to `camera`'s in the space of `space`, a world matrix, and return it. */
93
+ export function frustumIn(lists, camera, space) {
94
+ projection.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse).multiply(space);
95
+ return lists.frustum.setFromProjectionMatrix(projection, camera.coordinateSystem, camera.reversedDepth);
96
+ }
97
+ /**
98
+ * How the camera lies to `sort`'s instances (see MODE). Wholly inside its frustum, with no cullDistance, no instance is
99
+ * culled wherever the camera is: instances that all draw one level fill its list alike, and an orthographic camera
100
+ * measures their heights alike from anywhere.
101
+ */
102
+ function modeOf({ ranges, inside, cull, onlyLevel, ortho }) {
103
+ if (ranges.length === 0)
104
+ return MODE.hidden;
105
+ if (cull !== null || !inside)
106
+ return MODE.seen;
107
+ return onlyLevel !== 0 ? MODE.oneLevel : ortho ? MODE.orthoInside : MODE.seen;
108
+ }
109
+ /** Per level of `inputs`, whether it has an instance list: whether it draws something. */
110
+ export function listedOf(inputs) {
111
+ const empty = emptyLevels(inputs);
112
+ return inputs.map((_, i) => !has(empty, i));
113
+ }
114
+ //# sourceMappingURL=lists.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lists.js","sourceRoot":"","sources":["../../src/instanced/lists.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type Sphere } from "three/webgpu";
2
+ import { d } from "typegpu";
3
+ import type { LocalCamera } from "./camera.js";
4
+ import type { Cull } from "./cull.js";
5
+ /** The largest a survivor of `cullDistance` grows: what it reaches where 1/64 of the instances draw. */
6
+ export declare const MAX_SURVIVOR_SCALE = 8;
7
+ /**
8
+ * The bits of `origin`, an instance's translation, hashed into [0, 1): what thins it out (see `CullDistance`), the
9
+ * same on the CPU and the GPU.
10
+ */
11
+ export declare const originHash: import("typegpu").TgpuFn<(origin: d.Vec3f) => d.F32>;
12
+ /**
13
+ * How an instance at `origin`, `distance` from the cullDistance camera, draws (see `CullDistance`): 0 thinned out,
14
+ * else the scale it draws at: 1, or with `survivors` 1/√share, share the share of instances drawn at its distance.
15
+ */
16
+ export declare const cullScale: import("typegpu").TgpuFn<(origin: d.Vec3f, distance: d.F32, near: d.F32, far: d.F32, survivors: d.U32) => d.F32>;
17
+ /**
18
+ * Where an instance at `matrix` stands for a camera, `source` the source's sphere (centre, radius) grown by `grow`:
19
+ * the source's centre (xyz), and its height on screen (w) seen from `eye` with `scale` pixels per unit of subtense, or
20
+ * of size with `ortho` 1, as a Lod measures its own on the CPU (see screen.ts: 2 r q / d).
21
+ */
22
+ export declare const instanceOnScreen: import("typegpu").TgpuFn<(matrix: d.Mat4x4f, source: d.Vec4f, grow: d.F32, eye: d.Vec3f, scale: d.F32, ortho: d.U32) => d.Vec4f>;
23
+ /**
24
+ * The level the instance at `offset` of `matrices` draws most of its pixels with (see `Lod.getLevelAt`), thinned out
25
+ * by `cull` and seen by `camera`, both in the Lod's space, of the levels of `loaded`, `source` the
26
+ * source's sphere; null if it draws nothing.
27
+ */
28
+ export declare function instanceLevel(matrices: ArrayLike<number>, offset: number, cull: Cull | null, camera: LocalCamera, source: Sphere, loaded: number): number | null;