@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.
- package/README.md +6 -7
- package/dist/bake.d.ts +36 -0
- package/dist/bake.js +176 -0
- package/dist/bake.js.map +1 -0
- package/dist/baked/codec.d.ts +3 -6
- package/dist/baked/codec.js +48 -154
- package/dist/baked/codec.js.map +1 -1
- package/dist/baked/coverage.d.ts +6 -3
- package/dist/baked/coverage.js +6 -3
- package/dist/baked/coverage.js.map +1 -1
- package/dist/baked/fields.d.ts +9 -0
- package/dist/baked/fields.js +22 -0
- package/dist/baked/fields.js.map +1 -0
- package/dist/baked/index.d.ts +14 -8
- package/dist/baked/index.js +24 -22
- package/dist/baked/index.js.map +1 -1
- package/dist/baked/interior/faces.d.ts +4 -3
- package/dist/baked/interior/faces.js +16 -11
- package/dist/baked/interior/faces.js.map +1 -1
- package/dist/baked/interior/material.d.ts +7 -10
- package/dist/baked/interior/material.js +29 -36
- package/dist/baked/interior/material.js.map +1 -1
- package/dist/baked/interior/rooms.d.ts +1 -1
- package/dist/baked/interior/rooms.js +2 -2
- package/dist/baked/interior/rooms.js.map +1 -1
- package/dist/baked/low.js +5 -4
- package/dist/baked/low.js.map +1 -1
- package/dist/baked/raster.js +6 -6
- package/dist/baked/raster.js.map +1 -1
- package/dist/baked/textures.d.ts +17 -0
- package/dist/baked/textures.js +95 -0
- package/dist/baked/textures.js.map +1 -0
- package/dist/baked/transfer.js +19 -18
- package/dist/baked/transfer.js.map +1 -1
- package/dist/baked/unwrap.js +4 -3
- package/dist/baked/unwrap.js.map +1 -1
- package/dist/baked/xatlas.js.map +1 -1
- package/dist/codec/container.d.ts +8 -0
- package/dist/codec/container.js +63 -0
- package/dist/codec/container.js.map +1 -0
- package/dist/codec/mesh.d.ts +8 -0
- package/dist/{mesh/codec.js → codec/mesh.js} +80 -52
- package/dist/codec/mesh.js.map +1 -0
- package/dist/dispose.d.ts +8 -5
- package/dist/dispose.js +22 -24
- package/dist/dispose.js.map +1 -1
- package/dist/foliage.d.ts +32 -0
- package/dist/foliage.js +137 -0
- package/dist/foliage.js.map +1 -0
- package/dist/impostor/bake/atlas.d.ts +4 -4
- package/dist/impostor/bake/atlas.js +12 -12
- package/dist/impostor/bake/atlas.js.map +1 -1
- package/dist/impostor/bake/fit.d.ts +8 -0
- package/dist/impostor/bake/fit.js +28 -0
- package/dist/impostor/bake/fit.js.map +1 -0
- package/dist/impostor/bake/index.d.ts +22 -14
- package/dist/impostor/bake/index.js +50 -134
- package/dist/impostor/bake/index.js.map +1 -1
- package/dist/impostor/bake/materials.d.ts +3 -3
- package/dist/impostor/bake/materials.js +51 -13
- package/dist/impostor/bake/materials.js.map +1 -1
- package/dist/impostor/bake/sheet.d.ts +8 -0
- package/dist/impostor/bake/sheet.js +90 -0
- package/dist/impostor/bake/sheet.js.map +1 -0
- package/dist/impostor/bake/source.d.ts +3 -2
- package/dist/impostor/bake/source.js +9 -20
- package/dist/impostor/bake/source.js.map +1 -1
- package/dist/impostor/codec.d.ts +4 -5
- package/dist/impostor/codec.js +36 -109
- package/dist/impostor/codec.js.map +1 -1
- package/dist/impostor/impostor.d.ts +31 -7
- package/dist/impostor/impostor.js +21 -6
- package/dist/impostor/impostor.js.map +1 -1
- package/dist/impostor/ktx2/encode.d.ts +26 -0
- package/dist/impostor/ktx2/encode.js +120 -0
- package/dist/impostor/ktx2/encode.js.map +1 -0
- package/dist/impostor/ktx2/transcode.d.ts +3 -0
- package/dist/impostor/ktx2/transcode.js +99 -0
- package/dist/impostor/ktx2/transcode.js.map +1 -0
- package/dist/impostor/ktx2/uastc.d.ts +7 -0
- package/dist/impostor/ktx2/uastc.js +65 -0
- package/dist/impostor/ktx2/uastc.js.map +1 -0
- package/dist/impostor/ktx2/wasm/encoder.d.ts +4 -0
- package/dist/impostor/ktx2/wasm/encoder.js +10 -0
- package/dist/impostor/ktx2/wasm/encoder.js.map +1 -0
- package/dist/impostor/ktx2/wasm/transcoder.d.ts +3 -0
- package/dist/impostor/ktx2/wasm/transcoder.js +9 -0
- package/dist/impostor/ktx2/wasm/transcoder.js.map +1 -0
- package/dist/impostor/ktx2/worker.d.ts +1 -0
- package/dist/impostor/ktx2/worker.js +10 -0
- package/dist/impostor/ktx2/worker.js.map +1 -0
- package/dist/impostor/mesh/card.d.ts +4 -4
- package/dist/impostor/mesh/card.js +7 -7
- package/dist/impostor/mesh/card.js.map +1 -1
- package/dist/impostor/mesh/index.d.ts +7 -6
- package/dist/impostor/mesh/index.js +10 -11
- package/dist/impostor/mesh/index.js.map +1 -1
- package/dist/impostor/mesh/material.d.ts +18 -9
- package/dist/impostor/mesh/material.js +40 -27
- package/dist/impostor/mesh/material.js.map +1 -1
- package/dist/impostor/mesh/surface.d.ts +1 -1
- package/dist/impostor/mesh/surface.js +13 -9
- package/dist/impostor/mesh/surface.js.map +1 -1
- package/dist/impostor/mesh/textures.d.ts +3 -3
- package/dist/impostor/mesh/textures.js +24 -34
- package/dist/impostor/mesh/textures.js.map +1 -1
- package/dist/index.d.ts +13 -11
- package/dist/index.js +12 -10
- package/dist/index.js.map +1 -1
- package/dist/instanced/camera.d.ts +34 -0
- package/dist/instanced/camera.js +45 -0
- package/dist/instanced/camera.js.map +1 -0
- package/dist/instanced/clusters.d.ts +54 -0
- package/dist/instanced/clusters.js +151 -0
- package/dist/instanced/clusters.js.map +1 -0
- package/dist/instanced/cull.d.ts +28 -0
- package/dist/instanced/cull.js +22 -0
- package/dist/instanced/cull.js.map +1 -0
- package/dist/instanced/instances.d.ts +39 -0
- package/dist/instanced/instances.js +104 -0
- package/dist/instanced/instances.js.map +1 -0
- package/dist/instanced/key.d.ts +19 -0
- package/dist/instanced/key.js +45 -0
- package/dist/instanced/key.js.map +1 -0
- package/dist/instanced/levels.d.ts +60 -0
- package/dist/instanced/levels.js +131 -0
- package/dist/instanced/levels.js.map +1 -0
- package/dist/instanced/lists.d.ts +57 -0
- package/dist/instanced/lists.js +114 -0
- package/dist/instanced/lists.js.map +1 -0
- package/dist/instanced/measure.d.ts +28 -0
- package/dist/instanced/measure.js +203 -0
- package/dist/instanced/measure.js.map +1 -0
- package/dist/instanced/meshes.d.ts +44 -51
- package/dist/instanced/meshes.js +167 -179
- package/dist/instanced/meshes.js.map +1 -1
- package/dist/instanced/mirror.d.ts +24 -0
- package/dist/instanced/mirror.js +76 -0
- package/dist/instanced/mirror.js.map +1 -0
- package/dist/instanced/raycast.d.ts +10 -11
- package/dist/instanced/raycast.js +31 -41
- package/dist/instanced/raycast.js.map +1 -1
- package/dist/instanced/rows.d.ts +50 -0
- package/dist/instanced/rows.js +36 -0
- package/dist/instanced/rows.js.map +1 -0
- package/dist/instanced/shape.d.ts +27 -0
- package/dist/instanced/shape.js +54 -0
- package/dist/instanced/shape.js.map +1 -0
- package/dist/instanced/sort.d.ts +61 -0
- package/dist/instanced/sort.js +192 -0
- package/dist/instanced/sort.js.map +1 -0
- package/dist/instanced/update.d.ts +34 -0
- package/dist/instanced/update.js +180 -0
- package/dist/instanced/update.js.map +1 -0
- package/dist/levels/bounds.d.ts +21 -0
- package/dist/levels/bounds.js +42 -0
- package/dist/levels/bounds.js.map +1 -0
- package/dist/levels/cameras.d.ts +48 -0
- package/dist/levels/cameras.js +122 -0
- package/dist/levels/cameras.js.map +1 -0
- package/dist/levels/compile/contexts.d.ts +30 -0
- package/dist/levels/compile/contexts.js +18 -0
- package/dist/levels/compile/contexts.js.map +1 -0
- package/dist/levels/compile/index.d.ts +41 -0
- package/dist/levels/compile/index.js +193 -0
- package/dist/levels/compile/index.js.map +1 -0
- package/dist/levels/compile/pipelines.d.ts +26 -0
- package/dist/levels/compile/pipelines.js +172 -0
- package/dist/levels/compile/pipelines.js.map +1 -0
- package/dist/levels/compiles.d.ts +29 -0
- package/dist/levels/compiles.js +50 -0
- package/dist/levels/compiles.js.map +1 -0
- package/dist/levels/draw.d.ts +102 -0
- package/dist/levels/draw.js +401 -0
- package/dist/levels/draw.js.map +1 -0
- package/dist/levels/fade.d.ts +60 -0
- package/dist/levels/fade.js +129 -0
- package/dist/levels/fade.js.map +1 -0
- package/dist/levels/index.d.ts +99 -0
- package/dist/levels/index.js +155 -0
- package/dist/levels/index.js.map +1 -0
- package/dist/levels/item.d.ts +38 -0
- package/dist/levels/item.js +89 -0
- package/dist/levels/item.js.map +1 -0
- package/dist/levels/load.d.ts +31 -0
- package/dist/levels/load.js +144 -0
- package/dist/levels/load.js.map +1 -0
- package/dist/levels/manager.d.ts +158 -0
- package/dist/levels/manager.js +352 -0
- package/dist/levels/manager.js.map +1 -0
- package/dist/{material.d.ts → levels/material.d.ts} +2 -2
- package/dist/{material.js → levels/material.js} +6 -5
- package/dist/levels/material.js.map +1 -0
- package/dist/levels/renderer.d.ts +32 -0
- package/dist/levels/renderer.js +57 -0
- package/dist/levels/renderer.js.map +1 -0
- package/dist/levels/requests.d.ts +52 -0
- package/dist/levels/requests.js +97 -0
- package/dist/levels/requests.js.map +1 -0
- package/dist/levels/screen.d.ts +14 -0
- package/dist/levels/screen.js +21 -0
- package/dist/levels/screen.js.map +1 -0
- package/dist/loader/build.d.ts +10 -0
- package/dist/loader/build.js +28 -0
- package/dist/loader/build.js.map +1 -0
- package/dist/loader/context.d.ts +44 -0
- package/dist/loader/context.js +96 -0
- package/dist/loader/context.js.map +1 -0
- package/dist/loader/entry.d.ts +4 -0
- package/dist/loader/entry.js +43 -0
- package/dist/loader/entry.js.map +1 -0
- package/dist/loader/index.d.ts +76 -0
- package/dist/loader/index.js +272 -0
- package/dist/loader/index.js.map +1 -0
- package/dist/loader/level.d.ts +41 -0
- package/dist/loader/level.js +140 -0
- package/dist/loader/level.js.map +1 -0
- package/dist/loader/node.d.ts +26 -0
- package/dist/loader/node.js +199 -0
- package/dist/loader/node.js.map +1 -0
- package/dist/loader/request.d.ts +54 -0
- package/dist/loader/request.js +19 -0
- package/dist/loader/request.js.map +1 -0
- package/dist/loader/url.d.ts +10 -6
- package/dist/loader/url.js +22 -14
- package/dist/loader/url.js.map +1 -1
- package/dist/lod.d.ts +144 -43
- package/dist/lod.js +354 -163
- package/dist/lod.js.map +1 -1
- package/dist/meshopt.d.ts +6 -0
- package/dist/meshopt.js +20 -0
- package/dist/meshopt.js.map +1 -0
- package/dist/node-process.d.ts +5 -0
- package/dist/node-process.js +6 -0
- package/dist/node-process.js.map +1 -0
- package/dist/node.d.ts +2 -0
- package/dist/node.js +5 -0
- package/dist/node.js.map +1 -0
- package/dist/simplify/cards.d.ts +14 -0
- package/dist/simplify/cards.js +128 -0
- package/dist/simplify/cards.js.map +1 -0
- package/dist/{simplify.d.ts → simplify/index.d.ts} +8 -5
- package/dist/{simplify.js → simplify/index.js} +45 -27
- package/dist/simplify/index.js.map +1 -0
- package/dist/{bounds.d.ts → source/detail.d.ts} +9 -23
- package/dist/{bounds.js → source/detail.js} +28 -58
- package/dist/source/detail.js.map +1 -0
- package/dist/source/deviation.js +6 -6
- package/dist/source/deviation.js.map +1 -1
- package/dist/source/{shading.d.ts → evaluator.d.ts} +10 -10
- package/dist/source/{shading.js → evaluator.js} +5 -5
- package/dist/source/evaluator.js.map +1 -0
- package/dist/source/{trace.d.ts → raycaster.d.ts} +6 -6
- package/dist/source/{trace.js → raycaster.js} +8 -8
- package/dist/source/raycaster.js.map +1 -0
- package/dist/source/{texels.d.ts → sampler.d.ts} +1 -1
- package/dist/source/{texels.js → sampler.js} +8 -5
- package/dist/source/sampler.js.map +1 -0
- package/dist/source/source.d.ts +1 -1
- package/dist/source/source.js +1 -1
- package/dist/source/source.js.map +1 -1
- package/dist/source/surface.js +1 -1
- package/dist/source/surface.js.map +1 -1
- package/dist/task.d.ts +6 -0
- package/dist/{pause.js → task.js} +5 -5
- package/dist/task.js.map +1 -0
- package/dist/three.d.ts +19 -30
- package/dist/three.js +30 -57
- package/dist/three.js.map +1 -1
- package/dist/tsl.d.ts +8 -12
- package/dist/tsl.js +11 -39
- package/dist/tsl.js.map +1 -1
- package/dist/typegpu.d.ts +37 -0
- package/dist/typegpu.js +37 -0
- package/dist/typegpu.js.map +1 -0
- package/dist/wind/bounds.js +3 -3
- package/dist/wind/bounds.js.map +1 -1
- package/dist/wind/hooks.d.ts +7 -4
- package/dist/wind/hooks.js +5 -2
- package/dist/wind/hooks.js.map +1 -1
- package/dist/wind/index.d.ts +4 -4
- package/dist/wind/index.js +25 -23
- package/dist/wind/index.js.map +1 -1
- package/dist/wind/sway.d.ts +2 -0
- package/dist/wind/sway.js +4 -1
- package/dist/wind/sway.js.map +1 -1
- package/package.json +24 -10
- package/skills/lod/SKILL.md +120 -32
- package/dist/bounds.js.map +0 -1
- package/dist/compile.d.ts +0 -4
- package/dist/compile.js +0 -100
- package/dist/compile.js.map +0 -1
- package/dist/deferred.d.ts +0 -12
- package/dist/deferred.js +0 -27
- package/dist/deferred.js.map +0 -1
- package/dist/fade.d.ts +0 -36
- package/dist/fade.js +0 -112
- package/dist/fade.js.map +0 -1
- package/dist/instanced/args.d.ts +0 -20
- package/dist/instanced/args.js +0 -77
- package/dist/instanced/args.js.map +0 -1
- package/dist/instanced/blocks.d.ts +0 -66
- package/dist/instanced/blocks.js +0 -294
- package/dist/instanced/blocks.js.map +0 -1
- package/dist/instanced/dirty.d.ts +0 -15
- package/dist/instanced/dirty.js +0 -96
- package/dist/instanced/dirty.js.map +0 -1
- package/dist/instanced/index.d.ts +0 -90
- package/dist/instanced/index.js +0 -349
- package/dist/instanced/index.js.map +0 -1
- package/dist/instanced/parts.d.ts +0 -14
- package/dist/instanced/parts.js +0 -79
- package/dist/instanced/parts.js.map +0 -1
- package/dist/instanced/select.d.ts +0 -92
- package/dist/instanced/select.js +0 -315
- package/dist/instanced/select.js.map +0 -1
- package/dist/instanced/store.d.ts +0 -31
- package/dist/instanced/store.js +0 -96
- package/dist/instanced/store.js.map +0 -1
- package/dist/levels.d.ts +0 -95
- package/dist/levels.js +0 -171
- package/dist/levels.js.map +0 -1
- package/dist/loader/bundle.d.ts +0 -25
- package/dist/loader/bundle.js +0 -241
- package/dist/loader/bundle.js.map +0 -1
- package/dist/loader/cache.d.ts +0 -15
- package/dist/loader/cache.js +0 -75
- package/dist/loader/cache.js.map +0 -1
- package/dist/loader/provenance.d.ts +0 -30
- package/dist/loader/provenance.js +0 -105
- package/dist/loader/provenance.js.map +0 -1
- package/dist/loader.d.ts +0 -55
- package/dist/loader.js +0 -239
- package/dist/loader.js.map +0 -1
- package/dist/material.js.map +0 -1
- package/dist/mesh/codec.d.ts +0 -4
- package/dist/mesh/codec.js.map +0 -1
- package/dist/pause.d.ts +0 -6
- package/dist/pause.js.map +0 -1
- package/dist/queue.d.ts +0 -2
- package/dist/queue.js +0 -33
- package/dist/queue.js.map +0 -1
- package/dist/renderer.d.ts +0 -21
- package/dist/renderer.js +0 -83
- package/dist/renderer.js.map +0 -1
- package/dist/residency.d.ts +0 -44
- package/dist/residency.js +0 -205
- package/dist/residency.js.map +0 -1
- package/dist/simplify.js.map +0 -1
- package/dist/source/shading.js.map +0 -1
- package/dist/source/texels.js.map +0 -1
- package/dist/source/trace.js.map +0 -1
- package/dist/view.d.ts +0 -45
- package/dist/view.js +0 -131
- package/dist/view.js.map +0 -1
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { createCanvas } from "@drawcall/webgpu";
|
|
5
|
+
import { resolve as resolveImport } from "import-meta-resolve";
|
|
6
|
+
import { Loader, LoadingManager, WebGPURenderer } from "three/webgpu";
|
|
7
|
+
import { publicURL } from "vitecache";
|
|
8
|
+
import { setUpBakeRenderer } from "../bake.js";
|
|
9
|
+
import { CachedLodLoader as BrowserCachedLodLoader } from "./index.js";
|
|
10
|
+
import { loaderPathURL, placeholderOrigin } from "./url.js";
|
|
11
|
+
/** The session of each load, by its async context: the served fetch is global. */
|
|
12
|
+
const sessions = new AsyncLocalStorage();
|
|
13
|
+
/**
|
|
14
|
+
* CachedLodLoader in Node, as the vitecache plugin and the glts CLI run it: `loadAsync` builds and saves every level of
|
|
15
|
+
* the ladder, each with the public files the ladder's loads read and the installed versions of three and of the
|
|
16
|
+
* packages its .glts sources import. A load that reads anything else, such as a URL off the public directory or a module
|
|
17
|
+
* a .glts source imports from a CDN, fails, since no stored level could be checked against it. Served paths such as
|
|
18
|
+
* `/trees/oak.glts`, and `file:` URLs in the public directory, as a headless .glts script's manager resolves them to,
|
|
19
|
+
* load from vitecache's public directory (see `publicURL`), and `.glts` sources through a GLTSLoader of the load's own;
|
|
20
|
+
* bakes draw on a WebGPU device of @drawcall/webgpu. The manager only resolves the request's URL.
|
|
21
|
+
*
|
|
22
|
+
* Each `loadAsync` loads and bakes with what it makes for itself, which it frees before resolving, so loads may run
|
|
23
|
+
* concurrently. The levels it returns load their stored bytes as in browsers, and none holds the source: the source
|
|
24
|
+
* level, and a simplified level, which draws with the source's materials, load the source again when a camera needs
|
|
25
|
+
* them, as the glts CLI's renders of a .glts script that draws a Lod do.
|
|
26
|
+
*/
|
|
27
|
+
export class CachedLodLoader extends BrowserCachedLodLoader {
|
|
28
|
+
constructor(manager, options = {}) {
|
|
29
|
+
super(manager, options);
|
|
30
|
+
}
|
|
31
|
+
loadAsync(request) {
|
|
32
|
+
const input = typeof request === "string" ? { url: request } : request;
|
|
33
|
+
const url = this.publicPath(this.manager.resolveURL(loaderPathURL(input.url, this.path)));
|
|
34
|
+
return session({ read: new Set(), packages: new Set() }, async () => {
|
|
35
|
+
const loader = new SessionLoader(this.options);
|
|
36
|
+
try {
|
|
37
|
+
return await loader.loadAsync({ ...input, url });
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
await loader.dispose();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/** Nothing to free: each load frees what it made. */
|
|
45
|
+
async dispose() { }
|
|
46
|
+
/** A `file:` URL in the public directory as its served path; others as in browsers. */
|
|
47
|
+
publicPath(url) {
|
|
48
|
+
if (!url.startsWith("file:"))
|
|
49
|
+
return super.publicPath(url);
|
|
50
|
+
const base = publicURL("/");
|
|
51
|
+
if (!url.startsWith(base))
|
|
52
|
+
throw new Error(`CachedLodLoader: cannot precompute "${url}", which lies outside the public directory ${base}`);
|
|
53
|
+
return `/${url.slice(base.length)}`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** One `loadAsync` of the Node loader: builds every level, with a GLTSLoader and bake renderer of its own. */
|
|
57
|
+
class SessionLoader extends BrowserCachedLodLoader {
|
|
58
|
+
buildsAll = true;
|
|
59
|
+
scripts;
|
|
60
|
+
constructor(options) {
|
|
61
|
+
super(servingManager(), options);
|
|
62
|
+
// Packages resolve as the app's do.
|
|
63
|
+
this.scripts = new ScriptLoader(this.manager, publicURL("/"));
|
|
64
|
+
this.manager.addHandler(/\.glts$/i, this.scripts);
|
|
65
|
+
}
|
|
66
|
+
async dispose() {
|
|
67
|
+
await super.dispose();
|
|
68
|
+
await this.scripts.dispose();
|
|
69
|
+
}
|
|
70
|
+
/** Load `url` in the load's session, or, once `loadAsync` has resolved, in a session of its own. */
|
|
71
|
+
loadAsset(url) {
|
|
72
|
+
if (sessions.getStore())
|
|
73
|
+
return super.loadAsset(url);
|
|
74
|
+
return session({ read: new Set(), packages: new Set() }, () => super.loadAsset(url));
|
|
75
|
+
}
|
|
76
|
+
newBakeRenderer() {
|
|
77
|
+
// Three's DOM canvas types exclude native canvases; its constructor checks the actual API.
|
|
78
|
+
const renderer = Reflect.construct(WebGPURenderer, [{ canvas: canvas(), antialias: false }]);
|
|
79
|
+
if (!(renderer instanceof WebGPURenderer))
|
|
80
|
+
throw new Error("CachedLodLoader: three did not make a WebGPURenderer");
|
|
81
|
+
return setUpBakeRenderer(renderer);
|
|
82
|
+
}
|
|
83
|
+
inputs() {
|
|
84
|
+
const state = sessions.getStore();
|
|
85
|
+
if (!state)
|
|
86
|
+
throw new Error("CachedLodLoader: a level was built outside loadAsync");
|
|
87
|
+
// three builds every level, whatever its source imports.
|
|
88
|
+
const packages = [...new Set(["three", ...state.packages])].sort();
|
|
89
|
+
return [...[...state.read].sort().map((path) => ({ path })), ...packages.map((name) => ({ package: name }))];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/** A manager that serves root-relative paths from the public directory while a load runs. */
|
|
93
|
+
function servingManager() {
|
|
94
|
+
const manager = new LoadingManager();
|
|
95
|
+
manager.setURLModifier((url) => {
|
|
96
|
+
if (!url.startsWith("/") || url.startsWith("//"))
|
|
97
|
+
return url;
|
|
98
|
+
if (!sessions.getStore())
|
|
99
|
+
throw new Error(`CachedLodLoader: cannot load "${url}" once the load that asked for it has ended`);
|
|
100
|
+
return placeholderOrigin + url;
|
|
101
|
+
});
|
|
102
|
+
return manager;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Loads `.glts` sources with a GLTSLoader made at the first load, resolving their packages as the app at `root` does,
|
|
106
|
+
* and records the packages each imports.
|
|
107
|
+
*/
|
|
108
|
+
class ScriptLoader extends Loader {
|
|
109
|
+
root;
|
|
110
|
+
loader;
|
|
111
|
+
constructor(manager, root) {
|
|
112
|
+
super(manager);
|
|
113
|
+
this.root = root;
|
|
114
|
+
}
|
|
115
|
+
async loadAsync(url) {
|
|
116
|
+
this.loader ??= import("@drawcall/glts").then(({ GLTSLoader }) => new GLTSLoader(this.manager, { resolve: (specifier) => resolveImport(specifier, this.root) }));
|
|
117
|
+
const scene = await (await this.loader).loadAsync(url);
|
|
118
|
+
const { packages, runtimeModules } = scene.source;
|
|
119
|
+
if (runtimeModules.length > 0)
|
|
120
|
+
throw new Error(`CachedLodLoader: cannot precompute "${url}": it imports ${runtimeModules.join(", ")} from a CDN at runtime, which a stored level cannot be checked against`);
|
|
121
|
+
const state = sessions.getStore();
|
|
122
|
+
if (!state)
|
|
123
|
+
throw new Error(`CachedLodLoader: "${url}" loaded outside loadAsync`);
|
|
124
|
+
for (const name of packages)
|
|
125
|
+
state.packages.add(name);
|
|
126
|
+
return scene;
|
|
127
|
+
}
|
|
128
|
+
/** Free the GLTSLoader and the scenes it loaded, resolving once freed; the next load makes another. */
|
|
129
|
+
async dispose() {
|
|
130
|
+
const loader = this.loader;
|
|
131
|
+
this.loader = undefined;
|
|
132
|
+
// A GLTSLoader that failed to load failed the load that made it.
|
|
133
|
+
const made = await loader?.catch(() => undefined);
|
|
134
|
+
made?.dispose();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
let users = 0;
|
|
138
|
+
/** What sessions install while any runs: the canvas, and what restores the globals. */
|
|
139
|
+
let installed;
|
|
140
|
+
/**
|
|
141
|
+
* The restore of the last sessions to finish, which the next install waits for: @drawcall/webgpu saves and restores
|
|
142
|
+
* the globals it installs per canvas, so two canvases' lives must not overlap.
|
|
143
|
+
*/
|
|
144
|
+
let restored = Promise.resolve();
|
|
145
|
+
let current;
|
|
146
|
+
/** The canvas of the sessions running. */
|
|
147
|
+
function canvas() {
|
|
148
|
+
if (!current)
|
|
149
|
+
throw new Error("CachedLodLoader: baking outside loadAsync");
|
|
150
|
+
return current;
|
|
151
|
+
}
|
|
152
|
+
async function session(state, run) {
|
|
153
|
+
users++;
|
|
154
|
+
// A failed restore failed the session that ran it. Sessions running together share one install.
|
|
155
|
+
const shared = (installed ??= restored.catch(() => { }).then(install));
|
|
156
|
+
try {
|
|
157
|
+
current = (await shared).canvas;
|
|
158
|
+
return await sessions.run(state, run);
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
if (--users === 0) {
|
|
162
|
+
installed = current = undefined;
|
|
163
|
+
// A failed install failed the run above.
|
|
164
|
+
restored = shared.then(({ restore }) => restore(), () => { });
|
|
165
|
+
await restored;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/** A canvas of @drawcall/webgpu, which installs WebGPU, image decoding and workers while it lives, and the served fetch. */
|
|
170
|
+
async function install() {
|
|
171
|
+
const canvas = await createCanvas(1, 1);
|
|
172
|
+
const { fetch } = globalThis;
|
|
173
|
+
globalThis.fetch = (input, init) => serve(fetch, input, init);
|
|
174
|
+
const restore = async () => {
|
|
175
|
+
globalThis.fetch = fetch;
|
|
176
|
+
await canvas.dispose();
|
|
177
|
+
};
|
|
178
|
+
return { canvas, restore };
|
|
179
|
+
}
|
|
180
|
+
async function serve(fetch, input, init) {
|
|
181
|
+
const url = new URL(input instanceof Request ? input.url : input);
|
|
182
|
+
const state = sessions.getStore();
|
|
183
|
+
if (!state || url.protocol === "data:" || url.protocol === "blob:")
|
|
184
|
+
return fetch(input, init);
|
|
185
|
+
if (url.origin !== placeholderOrigin)
|
|
186
|
+
throw new Error(`CachedLodLoader: cannot precompute a load that fetches ${url.href}, which a stored level cannot be checked against`);
|
|
187
|
+
const file = publicURL(url.pathname);
|
|
188
|
+
try {
|
|
189
|
+
const bytes = await readFile(fileURLToPath(file));
|
|
190
|
+
state.read.add(file);
|
|
191
|
+
return new Response(bytes);
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
195
|
+
return new Response(null, { status: 404 });
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/loader/node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ImpostorMeshOptions } from "../impostor/mesh/index.js";
|
|
2
|
+
import type { BakeImpostorOptions } from "../impostor/bake/index.js";
|
|
3
|
+
import type { SimplifyOptions } from "../simplify/index.js";
|
|
4
|
+
import type { Derived } from "./level.js";
|
|
5
|
+
/**
|
|
6
|
+
* Levels derived from the source, finest first. In browsers each derived level is built when it first loads, except a
|
|
7
|
+
* simplified or baked level without `maxPixels`, which is built with the ladder since its default threshold is measured
|
|
8
|
+
* from its deviation; in Node every level is built with the ladder. An impostor's default is `framePixels` of its
|
|
9
|
+
* resolution: the threshold of a frame fitted to the source's bounding sphere, so the level before it draws smaller
|
|
10
|
+
* than it needs to. The frame the bake fits to the source is up to about 1.5 times tighter; give `maxPixels` to
|
|
11
|
+
* switch to the impostor sooner. Changing `maxPixels` or an impostor's `draw` reuses them, except an impostor's
|
|
12
|
+
* `maxPixels`, which also sizes its bake.
|
|
13
|
+
*/
|
|
14
|
+
export type LodLevelRequest = ({
|
|
15
|
+
type: "simplify";
|
|
16
|
+
maxPixels?: number;
|
|
17
|
+
} & SimplifyOptions) | ({
|
|
18
|
+
type: "baked";
|
|
19
|
+
maxPixels?: number;
|
|
20
|
+
textureSize?: number;
|
|
21
|
+
/** Room geometry for window baking, as an asset URL relative to the source. */
|
|
22
|
+
interior?: string;
|
|
23
|
+
} & ({
|
|
24
|
+
/** Authored low shell to bake onto, as an asset URL relative to the source. */
|
|
25
|
+
low: string;
|
|
26
|
+
ratio?: never;
|
|
27
|
+
} | {
|
|
28
|
+
low?: never;
|
|
29
|
+
ratio?: number;
|
|
30
|
+
})) | ({
|
|
31
|
+
type: "impostor";
|
|
32
|
+
draw?: ImpostorMeshOptions;
|
|
33
|
+
} & BakeImpostorOptions) | {
|
|
34
|
+
type: "empty";
|
|
35
|
+
maxPixels: number;
|
|
36
|
+
};
|
|
37
|
+
/** A .glb, .gltf or .glts asset URL. Source and simplified levels load the original asset on demand. */
|
|
38
|
+
export type LodRequest = string | {
|
|
39
|
+
url: string;
|
|
40
|
+
levels?: readonly LodLevelRequest[];
|
|
41
|
+
};
|
|
42
|
+
/** A normalized request. */
|
|
43
|
+
export type Ladder = ReturnType<typeof normalize>;
|
|
44
|
+
/**
|
|
45
|
+
* `request` with its source URL resolved against `path`, which loads it, and `key` of that, which its levels are stored
|
|
46
|
+
* under. A baked level's low and interior URLs stay relative to the source.
|
|
47
|
+
*/
|
|
48
|
+
export declare function normalize(request: LodRequest, path: string, key: (url: string) => string): {
|
|
49
|
+
url: string;
|
|
50
|
+
key: string;
|
|
51
|
+
levels: readonly LodLevelRequest[];
|
|
52
|
+
};
|
|
53
|
+
/** The request of ladder level `index`, which must be a derived level. */
|
|
54
|
+
export declare function derived(levels: readonly LodLevelRequest[], index: number): Derived;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { loaderPathURL } from "./url.js";
|
|
2
|
+
const DEFAULT_LEVELS = [{ type: "impostor" }];
|
|
3
|
+
/**
|
|
4
|
+
* `request` with its source URL resolved against `path`, which loads it, and `key` of that, which its levels are stored
|
|
5
|
+
* under. A baked level's low and interior URLs stay relative to the source.
|
|
6
|
+
*/
|
|
7
|
+
export function normalize(request, path, key) {
|
|
8
|
+
const input = typeof request === "string" ? { url: request } : request;
|
|
9
|
+
const url = loaderPathURL(input.url, path);
|
|
10
|
+
return { url, key: key(url), levels: structuredClone(input.levels ?? DEFAULT_LEVELS) };
|
|
11
|
+
}
|
|
12
|
+
/** The request of ladder level `index`, which must be a derived level. */
|
|
13
|
+
export function derived(levels, index) {
|
|
14
|
+
const level = levels[index - 1];
|
|
15
|
+
if (!level || level.type === "empty")
|
|
16
|
+
throw new Error(`CachedLodLoader: level ${index} is not derived`);
|
|
17
|
+
return level;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/loader/request.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAkCzC,MAAM,cAAc,GAA+B,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AAK1E;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,OAAmB,EAAE,IAAY,EAAE,GAA4B;IACvF,MAAM,KAAK,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACvE,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC3C,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,KAAK,CAAC,MAAM,IAAI,cAAc,CAAC,EAAE,CAAC;AACzF,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,OAAO,CAAC,MAAkC,EAAE,KAAa;IACvE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,iBAAiB,CAAC,CAAC;IACxG,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/loader/url.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An origin no URL has: paths parse against it where there is no document to resolve them against, and Node loads
|
|
3
|
+
* fetch the app's public files at it, as a page of the app fetches them from its own.
|
|
4
|
+
*/
|
|
5
|
+
export declare const placeholderOrigin = "https://lod.invalid";
|
|
1
6
|
/** Resolve a relative asset path without changing absolute URLs or root-relative paths. */
|
|
2
7
|
export declare function loaderPathURL(url: string, base: string): string;
|
|
3
|
-
|
|
4
|
-
|
|
8
|
+
/**
|
|
9
|
+
* `url` as a path below the app's base, such as `/tree/model.glts`, when the app serves it, so that what is stored for
|
|
10
|
+
* it does not depend on where the app is deployed; any other URL, absolute.
|
|
11
|
+
*/
|
|
12
|
+
export declare function publicPath(url: string, basePath: string): string;
|
|
5
13
|
export declare function assetPath(url: string): {
|
|
6
14
|
path: string;
|
|
7
15
|
extension: string;
|
|
8
16
|
};
|
|
9
17
|
export declare function sourceRelativeURL(value: string, source: string): string;
|
|
10
|
-
/** A same-origin path, as localURL leaves it: vitecache can resolve only these to project files. */
|
|
11
|
-
export declare const isLocal: (url: string) => boolean;
|
|
12
|
-
/** Keep same-origin dependencies portable between development and deployment. */
|
|
13
|
-
export declare function localURL(url: string): string;
|
package/dist/loader/url.js
CHANGED
|
@@ -1,31 +1,39 @@
|
|
|
1
1
|
import { LoaderUtils } from "three/webgpu";
|
|
2
2
|
const absolute = /^[a-z][a-z\d+.-]*:/i;
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* An origin no URL has: paths parse against it where there is no document to resolve them against, and Node loads
|
|
5
|
+
* fetch the app's public files at it, as a page of the app fetches them from its own.
|
|
6
|
+
*/
|
|
7
|
+
export const placeholderOrigin = "https://lod.invalid";
|
|
4
8
|
/** Resolve a relative asset path without changing absolute URLs or root-relative paths. */
|
|
5
9
|
export function loaderPathURL(url, base) {
|
|
6
10
|
return absolute.test(url) || url.startsWith("/") ? url : LoaderUtils.resolveURL(url, base);
|
|
7
11
|
}
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
/** What relative URLs resolve against: the page, else an origin no URL has. */
|
|
13
|
+
const page = () => (typeof document === "undefined" ? placeholderOrigin : document.baseURI);
|
|
14
|
+
/**
|
|
15
|
+
* `url` as a path below the app's base, such as `/tree/model.glts`, when the app serves it, so that what is stored for
|
|
16
|
+
* it does not depend on where the app is deployed; any other URL, absolute.
|
|
17
|
+
*/
|
|
18
|
+
export function publicPath(url, basePath) {
|
|
19
|
+
const resolved = new URL(url, page());
|
|
20
|
+
// The cache's URL includes the app's base.
|
|
21
|
+
const base = new URL("..", new URL(basePath, page()));
|
|
22
|
+
if (resolved.origin !== base.origin || !resolved.pathname.startsWith(base.pathname))
|
|
23
|
+
return resolved.href;
|
|
24
|
+
return `/${resolved.pathname.slice(base.pathname.length)}${resolved.search}`;
|
|
25
|
+
}
|
|
26
|
+
const urlPath = (url) => url.replace(/[?#].*$/s, "");
|
|
10
27
|
export function assetPath(url) {
|
|
11
28
|
const path = urlPath(url);
|
|
12
29
|
const extension = /\.(glb|gltf|glts)$/i.exec(path)?.[1]?.toLowerCase();
|
|
13
30
|
if (!extension)
|
|
14
|
-
throw new Error(`
|
|
31
|
+
throw new Error(`CachedLodLoader: cannot load "${url}": expected a .glb, .gltf or .glts file`);
|
|
15
32
|
return { path, extension };
|
|
16
33
|
}
|
|
17
34
|
export function sourceRelativeURL(value, source) {
|
|
18
|
-
const base = new URL(source, typeof document === "undefined" ?
|
|
35
|
+
const base = new URL(source, typeof document === "undefined" ? placeholderOrigin : document.baseURI);
|
|
19
36
|
const url = new URL(value, base);
|
|
20
37
|
return url.origin === base.origin && !absolute.test(source) ? url.pathname + url.search + url.hash : url.href;
|
|
21
38
|
}
|
|
22
|
-
/** A same-origin path, as localURL leaves it: vitecache can resolve only these to project files. */
|
|
23
|
-
export const isLocal = (url) => url.startsWith("/") && !url.startsWith("//");
|
|
24
|
-
/** Keep same-origin dependencies portable between development and deployment. */
|
|
25
|
-
export function localURL(url) {
|
|
26
|
-
if (typeof location === "undefined" || !/^https?:/i.test(url))
|
|
27
|
-
return url;
|
|
28
|
-
const parsed = new URL(url);
|
|
29
|
-
return parsed.origin === location.origin ? parsed.pathname + parsed.search + parsed.hash : url;
|
|
30
|
-
}
|
|
31
39
|
//# sourceMappingURL=url.js.map
|
package/dist/loader/url.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/loader/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,QAAQ,GAAG,qBAAqB,CAAC;AACvC,MAAM,
|
|
1
|
+
{"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/loader/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,QAAQ,GAAG,qBAAqB,CAAC;AACvC;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAEvD,2FAA2F;AAC3F,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,IAAY;IACrD,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC7F,CAAC;AAED,+EAA+E;AAC/E,MAAM,IAAI,GAAG,GAAW,EAAE,CAAC,CAAC,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAEpG;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,QAAgB;IACtD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,2CAA2C;IAC3C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACtD,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC,IAAI,CAAC;IAC1G,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC/E,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAErE,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,SAAS,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IACvE,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,yCAAyC,CAAC,CAAC;IAC/G,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,MAAc;IAC7D,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACrG,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjC,OAAO,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;AAChH,CAAC"}
|
package/dist/lod.d.ts
CHANGED
|
@@ -1,67 +1,168 @@
|
|
|
1
|
-
import { Object3D, type Camera, type Intersection, type Raycaster } from "three/webgpu";
|
|
2
|
-
import { type
|
|
3
|
-
import { type
|
|
4
|
-
import {
|
|
1
|
+
import { Box3, Color, InstancedBufferAttribute, Matrix4, Object3D, type Camera, type Intersection, type LoadingManager, type Raycaster } from "three/webgpu";
|
|
2
|
+
import { type LodLevel, type ThresholdedLevel } from "./levels/index.js";
|
|
3
|
+
import { type LodEventMap } from "./levels/manager.js";
|
|
4
|
+
import { WIND } from "./wind/hooks.js";
|
|
5
|
+
import { type LodCluster } from "./instanced/clusters.js";
|
|
6
|
+
import { type CullDistance } from "./instanced/cull.js";
|
|
7
|
+
/** How a Lod is made. */
|
|
8
|
+
export interface LodOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Gets an item while levels a camera needs load, compile or fade in, ended once they are complete; three's
|
|
11
|
+
* `DefaultLoadingManager` without one. Wait for a quiet frame, one in which no item started or ended, rendering (or
|
|
12
|
+
* compiling) the Scene that holds the Lod a frame apart meanwhile, to capture what a camera sees complete. A Lod its
|
|
13
|
+
* renderer rendered around for a frame without updating it ends its item, and its next update starts it again.
|
|
14
|
+
* Renders of other scenes in a separate task can end the item early, and the next update reopens it; a renderer that
|
|
15
|
+
* only compiles leaves a hidden Lod's item held.
|
|
16
|
+
*/
|
|
17
|
+
manager?: LoadingManager;
|
|
18
|
+
}
|
|
5
19
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
20
|
+
* Copies of one object at levels of detail, driven like a three InstancedMesh: `instanceMatrix`, `instanceColor`,
|
|
21
|
+
* `count` and `boundingBox`, and `clusters` to cull and choose levels by. Each copy draws the level levelsToDraw gives
|
|
22
|
+
* for its height on screen, switching with dithered fades; each camera's instances are sorted into indirect draws on
|
|
23
|
+
* the GPU. `new Lod(levels)` is one object at the Lod's own transform.
|
|
24
|
+
*
|
|
25
|
+
* The attributes are assignable. A CPU attribute's edits draw once its `needsUpdate` is set (within its update ranges,
|
|
26
|
+
* which the Lod takes and clears), as an InstancedMesh's do. A StorageInstancedBufferAttribute, such as one the app's
|
|
27
|
+
* compute pass writes, is read in place, every frame; a storage colour holds four floats per instance. A matrix of
|
|
28
|
+
* scale 0 draws nothing. Instance matrices may scale arbitrarily; the Lod's own transform and its parents should scale
|
|
29
|
+
* uniformly.
|
|
30
|
+
*
|
|
31
|
+
* Which levels load and which level meshes draw for a camera follow from the instances' bounds: per cluster, its box
|
|
32
|
+
* and scales; without clusters, `boundingBox` around the first `count` instances, else what the CPU measures of a CPU
|
|
33
|
+
* instanceMatrix. With clusters, only their instances draw. A storage instanceMatrix with neither loads every level
|
|
34
|
+
* (it warns once). Each camera draws only the instances in its frustum, and each shadow map is a camera of its own: it
|
|
35
|
+
* draws the casters in its frustum, each at the level its texels resolve, as an orthographic camera would (an instance
|
|
36
|
+
* smaller than a texel casts nothing). Thresholds, fades and loading follow `LodLevel`; `cullDistance` thins the
|
|
37
|
+
* instances out with distance. Nothing draws until the coarsest level that draws something has loaded, which loads
|
|
38
|
+
* first; a deferred level loads when a camera first needs it, and meanwhile the nearest loaded coarser level draws in
|
|
39
|
+
* its place. Arriving levels' texture uploads are paced to about one uncompressed 2048² RGBA texture's bytes per frame.
|
|
10
40
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
41
|
+
* It draws with WebGPU only (three's WebGPURenderer on its WebGPU backend, with `indirect-first-instance`), with the
|
|
42
|
+
* first renderer that draws it: it learns of it in that renderer's first frame, which draws nothing of it, and another
|
|
43
|
+
* renderer drawing it is its error. Sequential cameras are supported; a nested render with a camera that the outer
|
|
44
|
+
* render also draws with replaces that camera's instance lists, so exclude the Lod from it with camera layers.
|
|
14
45
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* refused; use static meshes with node materials
|
|
46
|
+
* Level templates are cloned, then their meshes are instanced, as children of the Lod on its layers; it sets each
|
|
47
|
+
* one's `visible` per camera, so hide the Lod itself, never its level meshes. Skinned meshes, InstancedMeshes (except ImpostorMesh),
|
|
48
|
+
* lines, points, sprites and LODs in levels are refused, as are ShaderMaterials; use static meshes with node materials
|
|
49
|
+
* or supported built-in materials. Build a new Lod after adding or moving meshes within a level: geometry is measured
|
|
50
|
+
* at construction or arrival. For external detail, leave level 0 empty and draw the instances that `getLevelAt`
|
|
51
|
+
* reports there.
|
|
18
52
|
*/
|
|
19
|
-
export declare class Lod extends Object3D<
|
|
53
|
+
export declare class Lod extends Object3D<LodEventMap> {
|
|
20
54
|
/** Multiplies every measured height: below 1, cheaper levels take over sooner. */
|
|
21
55
|
static quality: number;
|
|
22
56
|
/** Tint every level by its index, to see which level draws where. */
|
|
23
57
|
static debug: boolean;
|
|
24
|
-
/**
|
|
25
|
-
* Share of a level's range its fade spans: from `maxPixels × (1 - fade)` up to its
|
|
26
|
-
* `maxPixels`, the finer level draws too.
|
|
27
|
-
*/
|
|
58
|
+
/** Share of a level's range its fade spans: from `maxPixels × (1 - fade)` up to its `maxPixels`, the finer level draws too. */
|
|
28
59
|
static readonly fade = 0.1;
|
|
29
60
|
readonly isLOD = true;
|
|
61
|
+
readonly isLod = true;
|
|
30
62
|
/** Let the renderer call `update` with its camera every frame. */
|
|
31
63
|
autoUpdate: boolean;
|
|
32
|
-
/** Draw only this level, without fades. */
|
|
64
|
+
/** Draw only this level, without fades, once the coarsest level that draws something has loaded. */
|
|
33
65
|
forceLevel: number | null;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
|
|
40
|
-
|
|
66
|
+
/** The levels, each `object` the template its level meshes are made from, once there is one (never in the scene). */
|
|
67
|
+
readonly levels: ThresholdedLevel[];
|
|
68
|
+
/** Thins the instances out with distance from a camera, in every camera; null draws them at any distance. */
|
|
69
|
+
cullDistance: CullDistance | null;
|
|
70
|
+
/** 16 floats per instance: a CPU InstancedBufferAttribute (identities to start with) or a storage one. */
|
|
71
|
+
instanceMatrix: InstancedBufferAttribute;
|
|
72
|
+
/** RGB per instance, white without: three floats on the CPU, four in a storage attribute. */
|
|
73
|
+
instanceColor: InstancedBufferAttribute | null;
|
|
74
|
+
/** How many of `instanceMatrix`'s instances draw. */
|
|
75
|
+
count: number;
|
|
76
|
+
/** Bounds every instance at every level, in the Lod's space (see `computeBoundingBox`); measured when null. */
|
|
77
|
+
boundingBox: Box3 | null;
|
|
78
|
+
/** Disjoint ranges of instances, each inside its box, which cull and choose levels apart; clipped to `count`. */
|
|
79
|
+
clusters: LodCluster[] | undefined;
|
|
80
|
+
/** The levels as they were given, which a copy is made from. */
|
|
81
|
+
private inputs;
|
|
82
|
+
/** What it is made of for its levels, which a copy makes anew. */
|
|
83
|
+
private built;
|
|
41
84
|
private disposed;
|
|
42
|
-
private readonly
|
|
85
|
+
private readonly instances;
|
|
86
|
+
/** What the level meshes draw. */
|
|
87
|
+
private readonly drawn;
|
|
88
|
+
/** Around every instance, survivors grown: what every level mesh is culled and boxed by. */
|
|
89
|
+
private readonly bounds;
|
|
90
|
+
private readonly view;
|
|
91
|
+
/** The cluster ranges last checked to be disjoint. */
|
|
92
|
+
private readonly checked;
|
|
93
|
+
/** What `cullIn` writes cullDistance into, in this Lod's space. */
|
|
94
|
+
private readonly cull;
|
|
95
|
+
/**
|
|
96
|
+
* Drawn until a renderer has drawn the Lod, to learn which: three tells a mesh its renderer, but not a LOD. It bounds
|
|
97
|
+
* the instances for Box3.setFromObject, as the level meshes do once there are some.
|
|
98
|
+
*/
|
|
99
|
+
private readonly sentinel;
|
|
100
|
+
private warned;
|
|
101
|
+
/** `levels[0]` is the source; empty only as the target of `copy`. `count` instances, at the Lod's origin to start with. */
|
|
102
|
+
constructor(levels: readonly LodLevel[], count?: number, options?: LodOptions);
|
|
43
103
|
get pending(): boolean;
|
|
44
104
|
get error(): Error | undefined;
|
|
105
|
+
/** Where the item of levels a camera misses goes (see `LodOptions.manager`). */
|
|
106
|
+
get manager(): LoadingManager;
|
|
107
|
+
set manager(manager: LoadingManager | undefined);
|
|
108
|
+
setMatrixAt(index: number, matrix: Matrix4): this;
|
|
109
|
+
getMatrixAt(index: number, matrix: Matrix4): Matrix4;
|
|
110
|
+
/** Write instance `index`'s colour, making a white `instanceColor` for every instance first if there is none. */
|
|
111
|
+
setColorAt(index: number, color: Color): this;
|
|
112
|
+
/** Instance `index`'s colour: white without `instanceColor`. */
|
|
113
|
+
getColorAt(index: number, color: Color): Color;
|
|
45
114
|
/**
|
|
46
|
-
* `
|
|
47
|
-
*
|
|
48
|
-
* first level that draws something.
|
|
115
|
+
* Set `boundingBox` around the first `count` instances at every level and its sway, from a CPU instanceMatrix as it
|
|
116
|
+
* is now; the CPU cannot read a storage one.
|
|
49
117
|
*/
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
118
|
+
computeBoundingBox(): void;
|
|
119
|
+
/** What this Lod is made of for `inputs`: its levels, their meshes and their loading. */
|
|
120
|
+
private init;
|
|
121
|
+
/**
|
|
122
|
+
* The sentinel, drawn until a renderer has drawn the Lod (see `see`): no instances, on the Lod's layers, casting, and
|
|
123
|
+
* never hit by a raycast. Its box is the instances' bounds, and its vertices that box's corners (see `placeSentinel`),
|
|
124
|
+
* which precise Box3.setFromObject reads.
|
|
125
|
+
*/
|
|
126
|
+
private makeSentinel;
|
|
127
|
+
/** `renderer`, which three hands a mesh's draw, draws the Lod (see `LodLevelLoadManager.see`): it, once checked. */
|
|
128
|
+
private see;
|
|
129
|
+
[WIND](padding: number, slope: number, baseY: number): void;
|
|
130
|
+
/** Take in the instances as they are now, so that its level meshes bound them (see Box3.setFromObject), then update the world matrices. */
|
|
131
|
+
updateMatrixWorld(force?: boolean): void;
|
|
132
|
+
/** Sort the instances into level lists for `camera`, a camera's or a shadow map's, and load the levels they need. What fails is reported (see `error`). */
|
|
56
133
|
update(camera: Camera): void;
|
|
57
|
-
|
|
58
|
-
|
|
134
|
+
/** Take in the attributes, clusters and cullDistance as they are now, and bound the instances. */
|
|
135
|
+
private refresh;
|
|
136
|
+
/** Put the sentinel's vertices at the corners of the instances' bounds; at the origin while nothing bounds them. */
|
|
137
|
+
private placeSentinel;
|
|
138
|
+
/** Sort for `camera`, a shadow map's when `shadow`, drawn by `renderer`. */
|
|
139
|
+
private sort;
|
|
140
|
+
/** `camera` in this Lod's space, drawn by `renderer` (see `localCamera`). */
|
|
141
|
+
private localCamera;
|
|
142
|
+
/**
|
|
143
|
+
* The level that draws most of instance `index`'s pixels for `camera` from where it is now, with the levels loaded
|
|
144
|
+
* now and no arrival under way (see `drawnLevel`); null at scale 0, thinned out by `cullDistance`, or while no level
|
|
145
|
+
* it could draw is loaded. From the CPU instanceMatrix as it is, edits not yet drawn included; the CPU cannot read a
|
|
146
|
+
* storage one. It measures with the renderer drawing the Lod, so it throws before one has drawn it.
|
|
147
|
+
*/
|
|
148
|
+
getLevelAt(index: number, camera: Camera): number | null;
|
|
59
149
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
150
|
+
* Hits the first `count` instances on the source level, with `instanceId` set as on an InstancedMesh's hits; `object`
|
|
151
|
+
* is this Lod. Instances of a storage instanceMatrix, which the CPU cannot read, are not hit. Its level meshes, on its
|
|
152
|
+
* layers, are never hit themselves.
|
|
153
|
+
*/
|
|
154
|
+
raycast(raycaster: Raycaster, intersects: Intersection[]): void;
|
|
155
|
+
/**
|
|
156
|
+
* Copies `source`'s levels, instances and settings into this Lod without levels (it throws otherwise); the copy
|
|
157
|
+
* shares geometry and textures with `source`, and holds copies of its attributes and clusters. Storage attributes
|
|
158
|
+
* cannot be copied: their instances live on the GPU.
|
|
63
159
|
*/
|
|
64
160
|
copy(source: Lod): this;
|
|
65
|
-
|
|
161
|
+
clone(): this;
|
|
162
|
+
/**
|
|
163
|
+
* Release its buffers and what it made of its levels, once nothing it prepares or compiles still uses them. Objects
|
|
164
|
+
* you give or load, its attributes among them, are yours to dispose; CachedLodLoader's are freed when the last Lod
|
|
165
|
+
* holding them is disposed (see `LodLevel.hold`).
|
|
166
|
+
*/
|
|
66
167
|
dispose(): void;
|
|
67
168
|
}
|