@drawcall/lod 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/dist/bake.d.ts +22 -0
- package/dist/bake.js +88 -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 +12 -6
- package/dist/baked/index.js +22 -20
- package/dist/baked/index.js.map +1 -1
- package/dist/baked/interior/faces.d.ts +4 -3
- package/dist/baked/interior/faces.js +13 -10
- 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.js +1 -1
- 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 +7 -4
- package/dist/dispose.js +20 -22
- package/dist/dispose.js.map +1 -1
- package/dist/gpu.d.ts +39 -0
- package/dist/gpu.js +41 -0
- package/dist/gpu.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 +41 -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 +2 -2
- package/dist/impostor/bake/source.js +8 -19
- 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 +117 -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 +64 -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 +12 -0
- package/dist/impostor/ktx2/worker.js.map +1 -0
- package/dist/impostor/mesh/card.d.ts +3 -3
- package/dist/impostor/mesh/card.js +7 -7
- package/dist/impostor/mesh/card.js.map +1 -1
- package/dist/impostor/mesh/index.d.ts +5 -4
- package/dist/impostor/mesh/index.js +8 -9
- 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 +15 -10
- package/dist/index.js +13 -8
- package/dist/index.js.map +1 -1
- package/dist/instanced/camera.d.ts +46 -0
- package/dist/instanced/camera.js +70 -0
- package/dist/instanced/camera.js.map +1 -0
- package/dist/instanced/chunk.d.ts +97 -0
- package/dist/instanced/chunk.js +156 -0
- package/dist/instanced/chunk.js.map +1 -0
- package/dist/instanced/chunks.d.ts +60 -0
- package/dist/instanced/chunks.js +208 -0
- package/dist/instanced/chunks.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/index.d.ts +96 -66
- package/dist/instanced/index.js +229 -288
- package/dist/instanced/index.js.map +1 -1
- 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 +130 -0
- package/dist/instanced/levels.js.map +1 -0
- package/dist/instanced/lists.d.ts +70 -0
- package/dist/instanced/lists.js +133 -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 +42 -51
- package/dist/instanced/meshes.js +158 -180
- package/dist/instanced/meshes.js.map +1 -1
- package/dist/instanced/mirror.d.ts +20 -0
- package/dist/instanced/mirror.js +37 -0
- package/dist/instanced/mirror.js.map +1 -0
- package/dist/instanced/pages/buffers.d.ts +37 -0
- package/dist/instanced/pages/buffers.js +15 -0
- package/dist/instanced/pages/buffers.js.map +1 -0
- package/dist/instanced/pages/chunk.d.ts +51 -0
- package/dist/instanced/pages/chunk.js +81 -0
- package/dist/instanced/pages/chunk.js.map +1 -0
- package/dist/instanced/pages/index.d.ts +74 -0
- package/dist/instanced/pages/index.js +269 -0
- package/dist/instanced/pages/index.js.map +1 -0
- package/dist/instanced/pages/passes.d.ts +21 -0
- package/dist/instanced/pages/passes.js +52 -0
- package/dist/instanced/pages/passes.js.map +1 -0
- package/dist/instanced/pages/slots.d.ts +11 -0
- package/dist/instanced/pages/slots.js +90 -0
- package/dist/instanced/pages/slots.js.map +1 -0
- package/dist/instanced/pages/workgroup.d.ts +14 -0
- package/dist/instanced/pages/workgroup.js +38 -0
- package/dist/instanced/pages/workgroup.js.map +1 -0
- package/dist/instanced/raycast.d.ts +13 -11
- package/dist/instanced/raycast.js +33 -40
- package/dist/instanced/raycast.js.map +1 -1
- package/dist/instanced/rows.d.ts +108 -0
- package/dist/instanced/rows.js +209 -0
- package/dist/instanced/rows.js.map +1 -0
- package/dist/instanced/shape.d.ts +25 -0
- package/dist/instanced/shape.js +51 -0
- package/dist/instanced/shape.js.map +1 -0
- package/dist/instanced/sort.d.ts +63 -0
- package/dist/instanced/sort.js +162 -0
- package/dist/instanced/sort.js.map +1 -0
- package/dist/instanced/update.d.ts +30 -0
- package/dist/instanced/update.js +207 -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 +39 -0
- package/dist/levels/compile/index.js +185 -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 +177 -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 +69 -0
- package/dist/levels/fade.js +150 -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 +97 -0
- package/dist/levels/item.js.map +1 -0
- package/dist/levels/load.d.ts +31 -0
- package/dist/levels/load.js +142 -0
- package/dist/levels/load.js.map +1 -0
- package/dist/levels/manager.d.ts +159 -0
- package/dist/levels/manager.js +339 -0
- package/dist/levels/manager.js.map +1 -0
- package/dist/{material.js → levels/material.js} +4 -3
- package/dist/levels/material.js.map +1 -0
- package/dist/levels/renderer.d.ts +29 -0
- package/dist/levels/renderer.js +41 -0
- package/dist/levels/renderer.js.map +1 -0
- package/dist/levels/requests.d.ts +49 -0
- package/dist/levels/requests.js +95 -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/levels/wait.d.ts +27 -0
- package/dist/levels/wait.js +61 -0
- package/dist/levels/wait.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/cache.d.ts +6 -9
- package/dist/loader/cache.js +17 -24
- package/dist/loader/cache.js.map +1 -1
- package/dist/loader/context.d.ts +46 -0
- package/dist/loader/context.js +91 -0
- package/dist/loader/context.js.map +1 -0
- package/dist/loader/{provenance.d.ts → dependencies.d.ts} +5 -3
- package/dist/loader/{provenance.js → dependencies.js} +12 -4
- package/dist/loader/dependencies.js.map +1 -0
- package/dist/loader/index.d.ts +62 -0
- package/dist/loader/index.js +284 -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/request.d.ts +87 -0
- package/dist/loader/request.js +59 -0
- package/dist/loader/request.js.map +1 -0
- package/dist/loader/url.d.ts +5 -2
- package/dist/loader/url.js +10 -6
- package/dist/loader/url.js.map +1 -1
- package/dist/lod.d.ts +81 -40
- package/dist/lod.js +196 -149
- package/dist/lod.js.map +1 -1
- package/dist/meshopt.d.ts +6 -0
- package/dist/meshopt.js +19 -0
- package/dist/meshopt.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} +7 -4
- package/dist/{simplify.js → simplify/index.js} +41 -23
- package/dist/simplify/index.js.map +1 -0
- package/dist/{bounds.d.ts → source/detail.d.ts} +4 -23
- package/dist/{bounds.js → source/detail.js} +19 -51
- 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} +3 -3
- 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 +13 -24
- package/dist/three.js +26 -53
- 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 +2 -2
- 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 +2 -2
- package/dist/wind/index.js +15 -15
- 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 +18 -8
- package/skills/lod/SKILL.md +108 -31
- 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/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/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
- /package/dist/{material.d.ts → levels/material.d.ts} +0 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Vector2, Vector4 } from "three/webgpu";
|
|
2
|
+
import { at } from "../at.js";
|
|
3
|
+
import { busy } from "./renderer.js";
|
|
4
|
+
import { renderNow, sameContext } from "./compile/contexts.js";
|
|
5
|
+
// What renders tell a Lod of the cameras that draw it.
|
|
6
|
+
const viewport = new Vector4();
|
|
7
|
+
const canvas = new Vector2();
|
|
8
|
+
/**
|
|
9
|
+
* The height `renderer` draws at now, which levels are chosen at: CSS pixels on the canvas, so that a high-density
|
|
10
|
+
* screen picks the levels a standard one does and pays for its extra pixels only in fill; pixels in a render target,
|
|
11
|
+
* except one the canvas's size, which stands in for it (a post-processing target); in a shadow pass, the map's texels.
|
|
12
|
+
*/
|
|
13
|
+
export function drawingHeight(renderer, shadow) {
|
|
14
|
+
const active = renderer.getRenderTarget();
|
|
15
|
+
if (shadow)
|
|
16
|
+
return active ? active.height : null;
|
|
17
|
+
if (!active)
|
|
18
|
+
return renderer.getViewport(viewport).w;
|
|
19
|
+
const ratio = active.height === renderer.getDrawingBufferSize(canvas).y ? renderer.getPixelRatio() : 1;
|
|
20
|
+
return active.viewport.w / ratio;
|
|
21
|
+
}
|
|
22
|
+
/** The render contexts kept per camera: those of a camera that draws several scenes or targets each frame. */
|
|
23
|
+
const CONTEXTS = 8;
|
|
24
|
+
/**
|
|
25
|
+
* What a Lod's renders told of each camera that drew it: the height it draws at, where it rendered, and the shadow
|
|
26
|
+
* maps it drew. A context or shadow map whose target is disposed is passed over, so that no compile revives the target.
|
|
27
|
+
*/
|
|
28
|
+
export class CameraRenders {
|
|
29
|
+
/** Per camera: a side table, as three's Camera has no place for a package's state; a camera let go is let go here. */
|
|
30
|
+
cameras = new WeakMap();
|
|
31
|
+
/** The targets disposed since they were last drawn into. */
|
|
32
|
+
disposed = new WeakSet();
|
|
33
|
+
/** One listener on each target drawn into, until it is disposed or `dispose` is called. */
|
|
34
|
+
listeners = new Map();
|
|
35
|
+
/**
|
|
36
|
+
* The height `camera` draws at, measured from `renderer` while it renders (see `drawingHeight`), else the last it
|
|
37
|
+
* drew at; before it drew, the canvas's.
|
|
38
|
+
*/
|
|
39
|
+
heightOf(camera, renderer, shadow) {
|
|
40
|
+
const height = busy(renderer) ? drawingHeight(renderer, shadow) : null;
|
|
41
|
+
if (height !== null)
|
|
42
|
+
this.stateOf(camera).height = height;
|
|
43
|
+
return this.cameras.get(camera)?.height ?? renderer.getSize(canvas).y;
|
|
44
|
+
}
|
|
45
|
+
/** Where `camera` last rendered a scene holding the Lod, into a target not disposed. */
|
|
46
|
+
contextOf(camera) {
|
|
47
|
+
return this.cameras.get(camera)?.contexts.find((context) => !this.isDisposed(context.target));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Whether `context` is still one its camera renders in: not one whose target was disposed, nor one evicted by the
|
|
51
|
+
* cap on contexts per camera.
|
|
52
|
+
*/
|
|
53
|
+
holds(context) {
|
|
54
|
+
return !this.isDisposed(context.target) && (this.cameras.get(context.camera)?.contexts.includes(context) ?? false);
|
|
55
|
+
}
|
|
56
|
+
/** The shadow maps `cameras` drew, into targets not disposed. */
|
|
57
|
+
shadowsOf(cameras) {
|
|
58
|
+
return [...cameras].flatMap((camera) => this.cameras.get(camera)?.shadows ?? []).filter((map) => !this.isDisposed(map.target));
|
|
59
|
+
}
|
|
60
|
+
/** Whether `camera`, a light's shadow camera, drew a shadow map whose target is not disposed. */
|
|
61
|
+
drawsShadowMap(camera) {
|
|
62
|
+
return this.cameras.get(camera)?.shadows.some((map) => !this.isDisposed(map.target)) ?? false;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Whether `target` was disposed since it was last drawn into: what draws into it compiles nothing. The output never
|
|
66
|
+
* is.
|
|
67
|
+
*/
|
|
68
|
+
isDisposed(target) {
|
|
69
|
+
return target !== null && this.disposed.has(target);
|
|
70
|
+
}
|
|
71
|
+
/** Note what `renderer` rendering `scene` with `camera` tells: the camera's render context, or a shadow map. */
|
|
72
|
+
note(renderer, scene, camera) {
|
|
73
|
+
const now = renderNow(renderer, scene, camera);
|
|
74
|
+
if (!now)
|
|
75
|
+
return;
|
|
76
|
+
const state = this.stateOf(camera);
|
|
77
|
+
if ("shadow" in now) {
|
|
78
|
+
const { shadow } = now;
|
|
79
|
+
this.drawnInto(shadow.target);
|
|
80
|
+
const index = state.shadows.findIndex((map) => map.target === shadow.target);
|
|
81
|
+
if (index >= 0)
|
|
82
|
+
state.shadows[index] = shadow;
|
|
83
|
+
else
|
|
84
|
+
state.shadows.push(shadow);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const { contexts } = state;
|
|
88
|
+
const { target } = now.context;
|
|
89
|
+
if (target)
|
|
90
|
+
this.drawnInto(target);
|
|
91
|
+
const index = contexts.findIndex((context) => sameContext(context, now.context));
|
|
92
|
+
contexts.unshift(index >= 0 ? at(contexts.splice(index, 1), 0) : now.context);
|
|
93
|
+
if (contexts.length > CONTEXTS)
|
|
94
|
+
contexts.pop();
|
|
95
|
+
}
|
|
96
|
+
/** Stop listening to the targets drawn into. */
|
|
97
|
+
dispose() {
|
|
98
|
+
for (const [target, listener] of this.listeners)
|
|
99
|
+
target.removeEventListener("dispose", listener);
|
|
100
|
+
this.listeners.clear();
|
|
101
|
+
}
|
|
102
|
+
/** `target` is drawn into now: live again if it was disposed, and listened to for its disposal. */
|
|
103
|
+
drawnInto(target) {
|
|
104
|
+
this.disposed.delete(target);
|
|
105
|
+
if (this.listeners.has(target))
|
|
106
|
+
return;
|
|
107
|
+
const listener = () => {
|
|
108
|
+
this.disposed.add(target);
|
|
109
|
+
target.removeEventListener("dispose", listener);
|
|
110
|
+
this.listeners.delete(target);
|
|
111
|
+
};
|
|
112
|
+
this.listeners.set(target, listener);
|
|
113
|
+
target.addEventListener("dispose", listener);
|
|
114
|
+
}
|
|
115
|
+
stateOf(camera) {
|
|
116
|
+
let state = this.cameras.get(camera);
|
|
117
|
+
if (!state)
|
|
118
|
+
this.cameras.set(camera, (state = { height: null, contexts: [], shadows: [] }));
|
|
119
|
+
return state;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=cameras.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cameras.js","sourceRoot":"","sources":["../../src/levels/cameras.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Camera, Material, Renderer, Scene } from "three/webgpu";
|
|
2
|
+
export interface RenderContext {
|
|
3
|
+
camera: Camera;
|
|
4
|
+
scene: Scene;
|
|
5
|
+
/** The target the render was asked for: null for the output, also while three draws it through its output pass. */
|
|
6
|
+
target: ReturnType<Renderer["getRenderTarget"]>;
|
|
7
|
+
mrt: Parameters<Renderer["setMRT"]>[0];
|
|
8
|
+
cubeFace: number;
|
|
9
|
+
mipLevel: number;
|
|
10
|
+
/** How deep in renders it drew (see `callDepth`). */
|
|
11
|
+
depth: number;
|
|
12
|
+
}
|
|
13
|
+
/** A render target a camera or shadow map draws into. */
|
|
14
|
+
export type Target = NonNullable<RenderContext["target"]>;
|
|
15
|
+
/** A shadow map rendered for a scene, with the camera and override material three drew it with. */
|
|
16
|
+
export interface ShadowMap {
|
|
17
|
+
camera: Camera;
|
|
18
|
+
scene: Scene;
|
|
19
|
+
target: Target;
|
|
20
|
+
overrideMaterial: Material;
|
|
21
|
+
depth: number;
|
|
22
|
+
}
|
|
23
|
+
/** What `renderer` rendering `scene` with `camera` is now: a camera's render context, or a shadow map. */
|
|
24
|
+
export declare function renderNow(renderer: Renderer, scene: Scene, camera: Camera): {
|
|
25
|
+
context: RenderContext;
|
|
26
|
+
} | {
|
|
27
|
+
shadow: ShadowMap;
|
|
28
|
+
} | null;
|
|
29
|
+
/** Whether `a` and `b` describe the same render: what was compiled for one is compiled for the other. */
|
|
30
|
+
export declare const sameContext: (a: RenderContext, b: RenderContext) => boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { callDepth, inShadowMap, isOutputPass } from "../renderer.js";
|
|
2
|
+
/** What `renderer` rendering `scene` with `camera` is now: a camera's render context, or a shadow map. */
|
|
3
|
+
export function renderNow(renderer, scene, camera) {
|
|
4
|
+
const active = renderer.getRenderTarget();
|
|
5
|
+
// A compile, outside renders, prepares draws at depth 0.
|
|
6
|
+
const depth = Math.max(callDepth(renderer), 0);
|
|
7
|
+
if (inShadowMap(scene)) {
|
|
8
|
+
const material = scene.overrideMaterial;
|
|
9
|
+
return active && material ? { shadow: { camera, scene, target: active, overrideMaterial: material, depth } } : null;
|
|
10
|
+
}
|
|
11
|
+
const target = isOutputPass(active) ? null : active;
|
|
12
|
+
const cubeFace = renderer.getActiveCubeFace();
|
|
13
|
+
const mipLevel = renderer.getActiveMipmapLevel();
|
|
14
|
+
return { context: { camera, scene, target, mrt: renderer.getMRT(), cubeFace, mipLevel, depth } };
|
|
15
|
+
}
|
|
16
|
+
/** Whether `a` and `b` describe the same render: what was compiled for one is compiled for the other. */
|
|
17
|
+
export const sameContext = (a, b) => a.scene === b.scene && a.target === b.target && a.mrt === b.mrt && a.cubeFace === b.cubeFace && a.mipLevel === b.mipLevel && a.depth === b.depth;
|
|
18
|
+
//# sourceMappingURL=contexts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contexts.js","sourceRoot":"","sources":["../../../src/levels/compile/contexts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AA4BtE,0GAA0G;AAC1G,MAAM,UAAU,SAAS,CAAC,QAAkB,EAAE,KAAY,EAAE,MAAc;IACxE,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,EAAE,CAAC;IAC1C,yDAAyD;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/C,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,KAAK,CAAC,gBAAgB,CAAC;QACxC,OAAO,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACtH,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACpD,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,QAAQ,CAAC,oBAAoB,EAAE,CAAC;IACjD,OAAO,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC;AACnG,CAAC;AAED,yGAAyG;AACzG,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAgB,EAAE,CAAgB,EAAW,EAAE,CACzE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Object3D, Renderer } from "three/webgpu";
|
|
2
|
+
import type { RenderContext, ShadowMap, Target } from "./contexts.js";
|
|
3
|
+
/** What a compile is for besides its context: shadow maps, and which targets were disposed. */
|
|
4
|
+
export interface CompileFor {
|
|
5
|
+
/** The shadow maps the scene's level meshes draw into: each mesh that casts compiles for them too. */
|
|
6
|
+
shadows: readonly ShadowMap[];
|
|
7
|
+
/** Whether `target` was disposed: no draw compiles for it, as that would make its textures again. */
|
|
8
|
+
isDisposed(target: Target): boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* What a LodGpu's renderer prepares for the levels arriving: the levels share its queue's budget and its pipeline
|
|
12
|
+
* cache, which it shares the readiness of (see `sharePipelines`).
|
|
13
|
+
*/
|
|
14
|
+
export declare class Compiler {
|
|
15
|
+
private readonly renderer;
|
|
16
|
+
/** Uploaded since the last frame. */
|
|
17
|
+
private uploaded;
|
|
18
|
+
/** The last upload: uploads run in turn. */
|
|
19
|
+
private uploads;
|
|
20
|
+
/**
|
|
21
|
+
* The last draw compiled for each shader build: material, attributes, target, shadow map and nesting. three starts a
|
|
22
|
+
* build for each draw that misses its cache, even one another draw is building, so a draw that builds alike waits
|
|
23
|
+
* for the last one and finds its build cached.
|
|
24
|
+
*/
|
|
25
|
+
private readonly builds;
|
|
26
|
+
constructor(renderer: Renderer);
|
|
27
|
+
/**
|
|
28
|
+
* Prepare the same target and MRT as the camera's draw, even if normal rendering has since restored the canvas, and
|
|
29
|
+
* the shadow maps of `compileFor`, for each mesh that casts. r186 uploads a texture synchronously inside initTexture,
|
|
30
|
+
* and creates a pipeline it meets while rendering synchronously, so each texture and draw is prepared here first.
|
|
31
|
+
* Textures upload paced across frames (see `paced`); every draw then compiles at once, as do the draws of every
|
|
32
|
+
* other level the renderer prepares, so their pipelines are created side by side.
|
|
33
|
+
*/
|
|
34
|
+
compileAsync(object: Object3D, context: RenderContext, { shadows, isDisposed }: CompileFor): Promise<void>;
|
|
35
|
+
/** Run `upload`, which answers the bytes it uploaded, after the next frame if those since the last one reached `FRAME_UPLOAD`. */
|
|
36
|
+
private paced;
|
|
37
|
+
/** Compile the draw of `mesh`'s groups `part` for `target`. */
|
|
38
|
+
private compileDraw;
|
|
39
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { isMesh, isNode, isTexture } from "../../three.js";
|
|
2
|
+
import { compileMesh, frame, sharePipelines } from "./pipelines.js";
|
|
3
|
+
/**
|
|
4
|
+
* What a LodGpu's renderer prepares for the levels arriving: the levels share its queue's budget and its pipeline
|
|
5
|
+
* cache, which it shares the readiness of (see `sharePipelines`).
|
|
6
|
+
*/
|
|
7
|
+
export class Compiler {
|
|
8
|
+
renderer;
|
|
9
|
+
/** Uploaded since the last frame. */
|
|
10
|
+
uploaded = 0;
|
|
11
|
+
/** The last upload: uploads run in turn. */
|
|
12
|
+
uploads = Promise.resolve();
|
|
13
|
+
/**
|
|
14
|
+
* The last draw compiled for each shader build: material, attributes, target, shadow map and nesting. three starts a
|
|
15
|
+
* build for each draw that misses its cache, even one another draw is building, so a draw that builds alike waits
|
|
16
|
+
* for the last one and finds its build cached.
|
|
17
|
+
*/
|
|
18
|
+
builds = new Map();
|
|
19
|
+
constructor(renderer) {
|
|
20
|
+
this.renderer = renderer;
|
|
21
|
+
sharePipelines(renderer);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Prepare the same target and MRT as the camera's draw, even if normal rendering has since restored the canvas, and
|
|
25
|
+
* the shadow maps of `compileFor`, for each mesh that casts. r186 uploads a texture synchronously inside initTexture,
|
|
26
|
+
* and creates a pipeline it meets while rendering synchronously, so each texture and draw is prepared here first.
|
|
27
|
+
* Textures upload paced across frames (see `paced`); every draw then compiles at once, as do the draws of every
|
|
28
|
+
* other level the renderer prepares, so their pipelines are created side by side.
|
|
29
|
+
*/
|
|
30
|
+
async compileAsync(object, context, { shadows, isDisposed }) {
|
|
31
|
+
const { renderer } = this;
|
|
32
|
+
const { memory } = renderer.info;
|
|
33
|
+
for (const texture of textures(object))
|
|
34
|
+
await this.paced(() => {
|
|
35
|
+
const known = memory.textures;
|
|
36
|
+
renderer.initTexture(texture);
|
|
37
|
+
return memory.textures === known ? 0 : bytesOf(texture);
|
|
38
|
+
});
|
|
39
|
+
const meshes = [];
|
|
40
|
+
object.traverse((node) => {
|
|
41
|
+
if (isMesh(node))
|
|
42
|
+
meshes.push(node);
|
|
43
|
+
});
|
|
44
|
+
const draws = [];
|
|
45
|
+
for (const mesh of meshes) {
|
|
46
|
+
const targets = [{ context, overrideMaterial: null }];
|
|
47
|
+
if (mesh.castShadow)
|
|
48
|
+
for (const { camera, target, overrideMaterial, depth } of shadows.filter((map) => map.scene === context.scene))
|
|
49
|
+
targets.push({ context: { ...context, camera, target, mrt: null, cubeFace: 0, mipLevel: 0, depth }, overrideMaterial });
|
|
50
|
+
// r186 starts only the first material before yielding; isolate one draw so setup sees its captured target/MRT.
|
|
51
|
+
const parts = Array.isArray(mesh.material) ? mesh.geometry.groups.map((group) => [group]) : [mesh.geometry.groups];
|
|
52
|
+
for (const target of targets)
|
|
53
|
+
for (const part of parts)
|
|
54
|
+
draws.push(this.compileDraw(mesh, target, part, isDisposed));
|
|
55
|
+
}
|
|
56
|
+
await Promise.all(draws);
|
|
57
|
+
}
|
|
58
|
+
/** Run `upload`, which answers the bytes it uploaded, after the next frame if those since the last one reached `FRAME_UPLOAD`. */
|
|
59
|
+
paced(upload) {
|
|
60
|
+
const run = this.uploads.then(async () => {
|
|
61
|
+
if (this.uploaded >= FRAME_UPLOAD)
|
|
62
|
+
await frame();
|
|
63
|
+
const bytes = upload();
|
|
64
|
+
// The next frame empties the budget, whether or not an upload waits for it.
|
|
65
|
+
if (bytes > 0 && this.uploaded === 0)
|
|
66
|
+
void frame().then(() => void (this.uploaded = 0));
|
|
67
|
+
this.uploaded += bytes;
|
|
68
|
+
});
|
|
69
|
+
this.uploads = run.catch(() => { });
|
|
70
|
+
return run;
|
|
71
|
+
}
|
|
72
|
+
/** Compile the draw of `mesh`'s groups `part` for `target`. */
|
|
73
|
+
compileDraw(mesh, target, part, isDisposed) {
|
|
74
|
+
const { builds } = this;
|
|
75
|
+
const material = Array.isArray(mesh.material) ? mesh.material[part[0]?.materialIndex ?? 0] : mesh.material;
|
|
76
|
+
const key = [
|
|
77
|
+
material ? material.uuid : "none",
|
|
78
|
+
Object.keys(mesh.geometry.attributes).sort().join(),
|
|
79
|
+
target.context.target ? target.context.target.texture.id : "canvas",
|
|
80
|
+
target.overrideMaterial ? target.overrideMaterial.uuid : "camera",
|
|
81
|
+
target.context.depth,
|
|
82
|
+
].join(" ");
|
|
83
|
+
const start = () => {
|
|
84
|
+
// Uploads and alike builds may have taken frames: a target disposed meanwhile stays disposed.
|
|
85
|
+
const drawn = target.context.target;
|
|
86
|
+
if (drawn && isDisposed(drawn))
|
|
87
|
+
return Promise.resolve();
|
|
88
|
+
const groups = mesh.geometry.groups;
|
|
89
|
+
try {
|
|
90
|
+
mesh.geometry.groups = part;
|
|
91
|
+
return compileMesh(this.renderer, mesh, target);
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
94
|
+
mesh.geometry.groups = groups;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const alike = builds.get(key);
|
|
98
|
+
const own = alike ? alike.then(start) : start();
|
|
99
|
+
const settled = own.then(() => { }, () => { });
|
|
100
|
+
builds.set(key, settled);
|
|
101
|
+
void settled.then(() => {
|
|
102
|
+
if (builds.get(key) === settled)
|
|
103
|
+
builds.delete(key);
|
|
104
|
+
});
|
|
105
|
+
return own;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* What texture uploads may add in one frame, in bytes: a 2048² RGBA texture. Uploads run on the GPU's queue before the
|
|
110
|
+
* frame that follows them, which waits for them all. A draw's geometry is not paced: its buffers copy in far less
|
|
111
|
+
* time than a texture of the same size and its mipmaps.
|
|
112
|
+
*/
|
|
113
|
+
const FRAME_UPLOAD = 16 * 2 ** 20;
|
|
114
|
+
const sum = (values) => values.reduce((total, value) => total + value, 0);
|
|
115
|
+
/**
|
|
116
|
+
* The bytes `texture` uploads, as three 0.186.1 uploads it: its mip levels', or its image's and the mipmaps three
|
|
117
|
+
* generates from it. An uncompressed cube's image is its six faces, and its mip levels are those after the first, with
|
|
118
|
+
* six images each; a compressed cube's faces carry their own mip levels, unless it has some.
|
|
119
|
+
*/
|
|
120
|
+
function bytesOf(texture) {
|
|
121
|
+
const levels = texture.mipmaps ?? [];
|
|
122
|
+
const cube = Array.isArray(texture.image);
|
|
123
|
+
if (levels.length > 0 && (!cube || Reflect.get(texture, "isCompressedTexture") === true))
|
|
124
|
+
return bytesIn(levels);
|
|
125
|
+
const bytes = bytesIn(texture.image) + bytesIn(levels);
|
|
126
|
+
return texture.generateMipmaps && levels.length === 0 ? Math.ceil((bytes * 4) / 3) : bytes;
|
|
127
|
+
}
|
|
128
|
+
/** The bytes of an image, a mip level, a cube's face or a list of them: its data's, or four per texel. */
|
|
129
|
+
function bytesIn(image) {
|
|
130
|
+
if (Array.isArray(image))
|
|
131
|
+
return sum(image.map(bytesIn));
|
|
132
|
+
if (typeof image !== "object" || image === null)
|
|
133
|
+
return 0;
|
|
134
|
+
if (isTexture(image))
|
|
135
|
+
return bytesIn(image.mipmaps?.length ? image.mipmaps : image.image);
|
|
136
|
+
const images = Reflect.get(image, "images");
|
|
137
|
+
if (Array.isArray(images))
|
|
138
|
+
return bytesIn(images);
|
|
139
|
+
const data = Reflect.get(image, "data");
|
|
140
|
+
if (ArrayBuffer.isView(data))
|
|
141
|
+
return data.byteLength;
|
|
142
|
+
const dimension = (name) => {
|
|
143
|
+
const value = Reflect.get(image, name);
|
|
144
|
+
return typeof value === "number" ? value : 1;
|
|
145
|
+
};
|
|
146
|
+
return dimension("width") * dimension("height") * dimension("depth") * 4;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* The textures `object`'s meshes draw: their materials', those their nodes sample, and those a material keeps in plain
|
|
150
|
+
* objects and arrays for nodes it makes while it builds (an impostor's atlases, a baked mesh's rooms).
|
|
151
|
+
*/
|
|
152
|
+
function textures(object) {
|
|
153
|
+
const found = new Set();
|
|
154
|
+
const visited = new Set();
|
|
155
|
+
const visit = (value) => {
|
|
156
|
+
if (typeof value !== "object" || value === null || visited.has(value))
|
|
157
|
+
return;
|
|
158
|
+
visited.add(value);
|
|
159
|
+
if (isTexture(value))
|
|
160
|
+
found.add(value);
|
|
161
|
+
else if (isNode(value)) {
|
|
162
|
+
visit(Reflect.get(value, "value"));
|
|
163
|
+
for (const child of value.getChildren())
|
|
164
|
+
visit(child);
|
|
165
|
+
}
|
|
166
|
+
else if (Array.isArray(value))
|
|
167
|
+
for (const entry of value)
|
|
168
|
+
visit(entry);
|
|
169
|
+
else if ([Object.prototype, null].includes(Object.getPrototypeOf(value)))
|
|
170
|
+
for (const [key, entry] of Object.entries(value))
|
|
171
|
+
if (key !== "userData")
|
|
172
|
+
visit(entry);
|
|
173
|
+
};
|
|
174
|
+
object.traverse((node) => {
|
|
175
|
+
if (!isMesh(node))
|
|
176
|
+
return;
|
|
177
|
+
// userData is the application's, not what a material binds.
|
|
178
|
+
for (const material of [node.material].flat())
|
|
179
|
+
for (const [key, value] of Object.entries(material))
|
|
180
|
+
if (key !== "userData")
|
|
181
|
+
visit(value);
|
|
182
|
+
});
|
|
183
|
+
return found;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/levels/compile/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Material, Mesh, Renderer } from "three/webgpu";
|
|
2
|
+
import type { RenderContext } from "./contexts.js";
|
|
3
|
+
/** The next frame. */
|
|
4
|
+
export declare const frame: () => Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* r186 caches a pipeline before it finishes, but a compile reusing it receives none of its promises. Share that
|
|
7
|
+
* pipeline's readiness, not the readiness of every earlier level: wrap r186's `_pipelines.getForRender`, as no public
|
|
8
|
+
* API tells when a cached pipeline is ready. Installed once per renderer, by its LodGpu. The adapter
|
|
9
|
+
* follows the renderer's pipeline cache lifetime; pending entries disappear on success or failure and otherwise hold no
|
|
10
|
+
* completed pipelines.
|
|
11
|
+
*/
|
|
12
|
+
export declare function sharePipelines(renderer: Renderer): void;
|
|
13
|
+
/** What a level's draws are compiled for: the camera's draw, or a shadow map's with the material three overrides with. */
|
|
14
|
+
export interface CompileTarget {
|
|
15
|
+
context: RenderContext;
|
|
16
|
+
overrideMaterial: Material | null;
|
|
17
|
+
}
|
|
18
|
+
export declare function compileMesh(renderer: Renderer, mesh: Mesh, { context, overrideMaterial }: CompileTarget): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Run `compile`, which starts a compileAsync, so that it prepares draws for renders `depth` deep. Mirrors three r186
|
|
21
|
+
* (0.186.1): compileAsync takes its render context, as a render of its own, with the first `_renderContexts.get` of
|
|
22
|
+
* its synchronous start. Only that call is given `depth`; renders the compile starts meanwhile take their own. A three
|
|
23
|
+
* that no longer makes that call fails here rather than compiling for the wrong depth. No public API compiles for a
|
|
24
|
+
* depth other than 0.
|
|
25
|
+
*/
|
|
26
|
+
export declare function atDepth(renderer: Renderer, depth: number, compile: () => Promise<void>): Promise<void>;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/** The next frame. */
|
|
2
|
+
export const frame = () => new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
|
3
|
+
const isPipelines = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "getForRender") === "function";
|
|
4
|
+
/**
|
|
5
|
+
* r186 caches a pipeline before it finishes, but a compile reusing it receives none of its promises. Share that
|
|
6
|
+
* pipeline's readiness, not the readiness of every earlier level: wrap r186's `_pipelines.getForRender`, as no public
|
|
7
|
+
* API tells when a cached pipeline is ready. Installed once per renderer, by its LodGpu. The adapter
|
|
8
|
+
* follows the renderer's pipeline cache lifetime; pending entries disappear on success or failure and otherwise hold no
|
|
9
|
+
* completed pipelines.
|
|
10
|
+
*/
|
|
11
|
+
export function sharePipelines(renderer) {
|
|
12
|
+
const pipelines = Reflect.get(renderer, "_pipelines");
|
|
13
|
+
if (!isPipelines(pipelines))
|
|
14
|
+
throw new Error("Lod: three's renderer keeps no render pipelines (lod mirrors r186)");
|
|
15
|
+
if (Reflect.get(pipelines.getForRender, SHARED) === true)
|
|
16
|
+
return;
|
|
17
|
+
const get = pipelines.getForRender;
|
|
18
|
+
const pending = new WeakMap();
|
|
19
|
+
pipelines.getForRender = (object, promises) => {
|
|
20
|
+
const before = promises?.length ?? 0;
|
|
21
|
+
const pipeline = get.call(pipelines, object, promises);
|
|
22
|
+
if (!promises)
|
|
23
|
+
return pipeline;
|
|
24
|
+
if (typeof pipeline !== "object" || pipeline === null)
|
|
25
|
+
throw new Error("Lod: three returned no render pipeline");
|
|
26
|
+
let ready = pending.get(pipeline);
|
|
27
|
+
if (!ready) {
|
|
28
|
+
ready = pipelineReady(renderer, pipeline, promises.slice(before));
|
|
29
|
+
pending.set(pipeline, ready);
|
|
30
|
+
const clear = () => pending.delete(pipeline);
|
|
31
|
+
void ready.then(clear, clear);
|
|
32
|
+
}
|
|
33
|
+
promises.push(ready);
|
|
34
|
+
return pipeline;
|
|
35
|
+
};
|
|
36
|
+
Reflect.set(pipelines.getForRender, SHARED, true);
|
|
37
|
+
}
|
|
38
|
+
/** Marks the wrapped getForRender: a second LodGpu of the renderer shares its pipelines already. */
|
|
39
|
+
const SHARED = Symbol("lodSharedPipelines");
|
|
40
|
+
/**
|
|
41
|
+
* A cached pipeline may have been started by the host before the adapter was installed: wait until the backend's data
|
|
42
|
+
* for it holds a pipeline or an error. r186's `_isDeviceLost` is read as no public API tells a lost device.
|
|
43
|
+
*/
|
|
44
|
+
async function pipelineReady(renderer, pipeline, started) {
|
|
45
|
+
await Promise.all(started);
|
|
46
|
+
const get = Reflect.get(renderer.backend, "get");
|
|
47
|
+
if (typeof get !== "function")
|
|
48
|
+
throw new Error("Lod: three's backend keeps no pipeline data");
|
|
49
|
+
for (;;) {
|
|
50
|
+
const data = Reflect.apply(get, renderer.backend, [pipeline]);
|
|
51
|
+
if (typeof data !== "object" || data === null)
|
|
52
|
+
throw new Error("Lod: three's backend has no render pipeline data");
|
|
53
|
+
if (Reflect.get(data, "error") === true)
|
|
54
|
+
throw new Error("Lod: render pipeline compilation failed");
|
|
55
|
+
if (Reflect.get(renderer, "_isDeviceLost") === true)
|
|
56
|
+
throw new Error("Lod: device lost while compiling a render pipeline");
|
|
57
|
+
if (Reflect.get(data, "pipeline"))
|
|
58
|
+
return;
|
|
59
|
+
await frame();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* What r186's renderObject gives an override material for one draw, and puts back once it has handed the draw on.
|
|
64
|
+
* This and `DRAWN` mirror three 0.186.1's Renderer.renderObject; a three that sets other keys builds shadow shaders
|
|
65
|
+
* in the frame again.
|
|
66
|
+
*/
|
|
67
|
+
const DRAW_STATE = ["colorNode", "depthNode", "positionNode", "side", "displacementMap", "displacementScale", "displacementBias"];
|
|
68
|
+
/** The keys a draw adds to an override material that lacks them, in the order it adds them. */
|
|
69
|
+
const DRAWN = ["alphaMap", "displacementMap", "displacementScale", "displacementBias"];
|
|
70
|
+
/**
|
|
71
|
+
* A copy of the shadow map's override material for compiling one draw. r186's compileAsync builds the draw only after
|
|
72
|
+
* renderObject has put back the per-draw state it gave the override (the caster's shadow nodes and side), so with the
|
|
73
|
+
* shared material it would prepare a pipeline the shadow map never draws with. The copy holds the state of the draw.
|
|
74
|
+
* It is not disposed: that would release the pipeline before the shadow map draws with it.
|
|
75
|
+
*/
|
|
76
|
+
function keepingDrawState(material) {
|
|
77
|
+
const copy = material.clone();
|
|
78
|
+
// The build's cache key lists a material's keys in order. clone() leaves out those three adds to its shadow material,
|
|
79
|
+
// its flag and those its draws set, which the copy gets in the order the shared material has them once it drew.
|
|
80
|
+
for (const key of [...Object.keys(material), ...DRAWN])
|
|
81
|
+
if (!key.startsWith("_") && !Object.hasOwn(copy, key))
|
|
82
|
+
Reflect.set(copy, key, Reflect.get(material, key) ?? null);
|
|
83
|
+
for (const key of DRAW_STATE) {
|
|
84
|
+
let value = Reflect.get(copy, key);
|
|
85
|
+
let given = false;
|
|
86
|
+
Object.defineProperty(copy, key, {
|
|
87
|
+
get: () => value,
|
|
88
|
+
set: (next) => {
|
|
89
|
+
if (given)
|
|
90
|
+
return;
|
|
91
|
+
given = true;
|
|
92
|
+
value = next;
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return copy;
|
|
97
|
+
}
|
|
98
|
+
export function compileMesh(renderer, mesh, { context, overrideMaterial }) {
|
|
99
|
+
const { camera, scene } = context;
|
|
100
|
+
const target = renderer.getRenderTarget();
|
|
101
|
+
const mrt = renderer.getMRT();
|
|
102
|
+
const cubeFace = renderer.getActiveCubeFace();
|
|
103
|
+
const mipLevel = renderer.getActiveMipmapLevel();
|
|
104
|
+
const culled = mesh.frustumCulled;
|
|
105
|
+
const visible = mesh.visible;
|
|
106
|
+
const children = mesh.children;
|
|
107
|
+
const background = scene.background;
|
|
108
|
+
const backgroundNode = scene.backgroundNode;
|
|
109
|
+
const override = scene.overrideMaterial;
|
|
110
|
+
try {
|
|
111
|
+
renderer.setRenderTarget(context.target, context.cubeFace, context.mipLevel);
|
|
112
|
+
renderer.setMRT(context.mrt);
|
|
113
|
+
scene.overrideMaterial = overrideMaterial && keepingDrawState(overrideMaterial);
|
|
114
|
+
// Demanded levels can still be hidden or outside the last camera's frustum.
|
|
115
|
+
mesh.frustumCulled = false;
|
|
116
|
+
mesh.visible = true;
|
|
117
|
+
mesh.children = [];
|
|
118
|
+
// r186 compiles backgrounds first, which would postpone this mesh until after renderer state is restored.
|
|
119
|
+
scene.background = null;
|
|
120
|
+
scene.backgroundNode = null;
|
|
121
|
+
return atDepth(renderer, context.depth, () => renderer.compileAsync(mesh, camera, scene));
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
scene.background = background;
|
|
125
|
+
scene.backgroundNode = backgroundNode;
|
|
126
|
+
scene.overrideMaterial = override;
|
|
127
|
+
mesh.children = children;
|
|
128
|
+
mesh.frustumCulled = culled;
|
|
129
|
+
mesh.visible = visible;
|
|
130
|
+
renderer.setRenderTarget(target, cubeFace, mipLevel);
|
|
131
|
+
renderer.setMRT(mrt);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const isRenderContexts = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "get") === "function";
|
|
135
|
+
/**
|
|
136
|
+
* Run `compile`, which starts a compileAsync, so that it prepares draws for renders `depth` deep. Mirrors three r186
|
|
137
|
+
* (0.186.1): compileAsync takes its render context, as a render of its own, with the first `_renderContexts.get` of
|
|
138
|
+
* its synchronous start. Only that call is given `depth`; renders the compile starts meanwhile take their own. A three
|
|
139
|
+
* that no longer makes that call fails here rather than compiling for the wrong depth. No public API compiles for a
|
|
140
|
+
* depth other than 0.
|
|
141
|
+
*/
|
|
142
|
+
export function atDepth(renderer, depth, compile) {
|
|
143
|
+
if (depth === 0)
|
|
144
|
+
return compile();
|
|
145
|
+
const contexts = Reflect.get(renderer, "_renderContexts");
|
|
146
|
+
if (!isRenderContexts(contexts))
|
|
147
|
+
throw new Error("Lod: three's renderer keeps no render contexts");
|
|
148
|
+
const own = Object.hasOwn(contexts, "get");
|
|
149
|
+
const get = contexts.get;
|
|
150
|
+
let taken = false;
|
|
151
|
+
const restore = () => {
|
|
152
|
+
if (own)
|
|
153
|
+
contexts.get = get;
|
|
154
|
+
else
|
|
155
|
+
Reflect.deleteProperty(contexts, "get");
|
|
156
|
+
};
|
|
157
|
+
contexts.get = (target, mrt) => {
|
|
158
|
+
taken = true;
|
|
159
|
+
restore();
|
|
160
|
+
return get.call(contexts, target, mrt, depth);
|
|
161
|
+
};
|
|
162
|
+
let result;
|
|
163
|
+
try {
|
|
164
|
+
result = compile();
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
if (!taken)
|
|
168
|
+
restore();
|
|
169
|
+
}
|
|
170
|
+
// compileAsync returns at once on a lost device, which is no fault of three's version; r186's `_isDeviceLost` alone
|
|
171
|
+
// tells it.
|
|
172
|
+
if (taken || Reflect.get(renderer, "_isDeviceLost") === true)
|
|
173
|
+
return result;
|
|
174
|
+
void result.catch(() => { });
|
|
175
|
+
throw new Error("Lod: three's compileAsync took no render context as it started (lod mirrors three r186)");
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=pipelines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipelines.js","sourceRoot":"","sources":["../../../src/levels/compile/pipelines.ts"],"names":[],"mappings":"AAOA,sBAAsB;AACtB,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAElG,MAAM,WAAW,GAAG,CAAC,KAAc,EAAsB,EAAE,CACzD,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,UAAU,CAAC;AAE1G;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,QAAkB;IAC/C,MAAM,SAAS,GAAY,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC/D,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACnH,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,IAAI;QAAE,OAAO;IACjE,MAAM,GAAG,GAAG,SAAS,CAAC,YAAY,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAyB,CAAC;IACrD,SAAS,CAAC,YAAY,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACvD,IAAI,CAAC,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC/B,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QACjH,IAAI,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC7B,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7C,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AACpD,CAAC;AAED,oGAAoG;AACpG,MAAM,MAAM,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAE5C;;;GAGG;AACH,KAAK,UAAU,aAAa,CAAC,QAAkB,EAAE,QAAgB,EAAE,OAAoC;IACrG,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,MAAM,GAAG,GAAY,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC1D,IAAI,OAAO,GAAG,KAAK,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC9F,SAAS,CAAC;QACR,MAAM,IAAI,GAAY,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QACvE,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACnH,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACpG,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,eAAe,CAAC,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QAC3H,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC;YAAE,OAAO;QAC1C,MAAM,KAAK,EAAE,CAAC;IAChB,CAAC;AACH,CAAC;AAQD;;;;GAIG;AACH,MAAM,UAAU,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,kBAAkB,CAAC,CAAC;AAClI,+FAA+F;AAC/F,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,kBAAkB,CAAC,CAAC;AAEvF;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,QAAkB;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC9B,sHAAsH;IACtH,gHAAgH;IAChH,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,KAAK,CAAC;QACpD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC;IACpH,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,KAAK,GAAY,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC5C,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE;YAC/B,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK;YAChB,GAAG,EAAE,CAAC,IAAa,EAAE,EAAE;gBACrB,IAAI,KAAK;oBAAE,OAAO;gBAClB,KAAK,GAAG,IAAI,CAAC;gBACb,KAAK,GAAG,IAAI,CAAC;YACf,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAkB,EAAE,IAAU,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAiB;IACtG,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,QAAQ,CAAC,oBAAoB,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IACpC,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC;IAC5C,MAAM,QAAQ,GAAG,KAAK,CAAC,gBAAgB,CAAC;IACxC,IAAI,CAAC;QACH,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC7E,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7B,KAAK,CAAC,gBAAgB,GAAG,gBAAgB,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;QAChF,4EAA4E;QAC5E,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,0GAA0G;QAC1G,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;QACxB,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC;QAC5B,OAAO,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IAC5F,CAAC;YAAS,CAAC;QACT,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;QAC9B,KAAK,CAAC,cAAc,GAAG,cAAc,CAAC;QACtC,KAAK,CAAC,gBAAgB,GAAG,QAAQ,CAAC;QAClC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,QAAQ,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACrD,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAOD,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAA2B,EAAE,CACnE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,UAAU,CAAC;AAEjG;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,QAAkB,EAAE,KAAa,EAAE,OAA4B;IACrF,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,OAAO,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAY,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IACnE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACnG,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC;IACzB,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,IAAI,GAAG;YAAE,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC;;YACvB,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC;IACF,QAAQ,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QAC7B,KAAK,GAAG,IAAI,CAAC;QACb,OAAO,EAAE,CAAC;QACV,OAAO,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC,CAAC;IACF,IAAI,MAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,OAAO,EAAE,CAAC;IACrB,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;IACxB,CAAC;IACD,oHAAoH;IACpH,YAAY;IACZ,IAAI,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,eAAe,CAAC,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAC5E,KAAK,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC5B,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC,CAAC;AAC7G,CAAC"}
|