@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
package/dist/instanced/meshes.js
CHANGED
|
@@ -1,191 +1,179 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { drawOf, setDraw } from "../fade.js";
|
|
1
|
+
import { BufferGeometry, IndirectStorageBufferAttribute, Matrix4, Mesh } from "three/webgpu";
|
|
2
|
+
import { setFadeSource } from "../levels/fade.js";
|
|
3
|
+
import { levelMaterial } from "../levels/material.js";
|
|
5
4
|
import { impostorInstances } from "../impostor/mesh/index.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
5
|
+
import { isImpostorMesh, isInstancedMesh, isLOD, isLine, isMesh, isPoints, isSprite, rejectSkinned } from "../three.js";
|
|
6
|
+
import { DRAW_BYTES } from "./rows.js";
|
|
7
|
+
// The meshes that draw a Lod's level: one plain three Mesh per mesh and material group of its object, or an
|
|
8
|
+
// ImpostorMesh for an impostor, each drawing every instance in its level's list for a camera with one indirect draw.
|
|
9
|
+
const IDENTITY = new Matrix4();
|
|
10
|
+
/** One indirect draw of nothing: what a level mesh draws before its Lod's first sort for a camera. */
|
|
11
|
+
const NOTHING = new IndirectStorageBufferAttribute(new Uint32Array(DRAW_BYTES / 4), 1);
|
|
12
|
+
/** `object`'s meshes and material groups, placed once in the instance's space, for level `level`. */
|
|
13
|
+
export function partsOf(object, level) {
|
|
14
|
+
rejectSkinned(object, "Lod");
|
|
15
|
+
object.updateWorldMatrix(true, true);
|
|
16
|
+
const outside = object.parent ? object.parent.matrixWorld.clone().invert() : new Matrix4();
|
|
17
|
+
const found = [];
|
|
18
|
+
object.traverse((node) => {
|
|
19
|
+
if (isLOD(node))
|
|
20
|
+
throw new Error(`Lod: levels cannot contain a LOD ("${node.name}")`);
|
|
21
|
+
if (isInstancedMesh(node) && !isImpostorMesh(node))
|
|
22
|
+
throw new Error(`Lod: levels cannot contain an InstancedMesh ("${node.name}")`);
|
|
23
|
+
if (isLine(node) || isPoints(node) || isSprite(node))
|
|
24
|
+
throw new Error(`Lod: levels draw meshes, not the line, points or sprite "${node.name}"`);
|
|
25
|
+
if (!isMesh(node))
|
|
26
|
+
return;
|
|
27
|
+
const placement = outside.clone().multiply(node.matrixWorld);
|
|
28
|
+
ranges(node).forEach((range, group) => found.push({ template: node, placement, group, draw: { level, ...range } }));
|
|
29
|
+
});
|
|
30
|
+
return found;
|
|
32
31
|
}
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
/** Re-point every mesh at the indirect argument table, which moves as deferred levels append to it. */
|
|
66
|
-
relocate() {
|
|
67
|
-
const { args, argsOffset } = this.selection;
|
|
68
|
-
for (const [mesh, offset] of this.offsets)
|
|
69
|
-
mesh.geometry.setIndirect(args, argsOffset + offset);
|
|
70
|
-
}
|
|
71
|
-
/** Release `mesh`, which may never have been added. */
|
|
72
|
-
free(mesh) {
|
|
73
|
-
this.offsets.delete(mesh);
|
|
74
|
-
// ImpostorMesh.dispose also destroys instance buffers; the Selection owns ours.
|
|
32
|
+
/** The index (or vertex) ranges `mesh` draws, clipped to its draw range, in group order, empty draws included. */
|
|
33
|
+
function ranges(mesh) {
|
|
34
|
+
const { geometry } = mesh;
|
|
35
|
+
const indexed = geometry.index !== null;
|
|
36
|
+
const total = geometry.index?.count ?? geometry.getAttribute("position").count;
|
|
37
|
+
const groups = Array.isArray(mesh.material) ? geometry.groups : [{ start: 0, count: total }];
|
|
38
|
+
return groups.map(({ start, count }) => {
|
|
39
|
+
const first = Math.min(total, Math.max(0, start, geometry.drawRange.start));
|
|
40
|
+
const end = Math.min(total, start + count, geometry.drawRange.start + geometry.drawRange.count);
|
|
41
|
+
return { count: Math.max(0, end - first), start: first, indexed };
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/** The meshes drawing `parts`, tinted by `tint`. */
|
|
45
|
+
export function levelMeshes(parts, tint, inputs) {
|
|
46
|
+
let first = null;
|
|
47
|
+
const offset = (i) => (first === null ? null : (first + i) * DRAW_BYTES);
|
|
48
|
+
return {
|
|
49
|
+
meshes: parts.map((part, i) => levelMesh(part, () => offset(i), tint, inputs)),
|
|
50
|
+
draws: parts.map((part) => part.draw),
|
|
51
|
+
drawFrom: (start) => void (first = start),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** Release `mesh`, which may never have been added. */
|
|
55
|
+
export function freeMesh(mesh) {
|
|
56
|
+
// ImpostorMesh.dispose also destroys its instance buffers, which are the Lod's.
|
|
57
|
+
if (isImpostorMesh(mesh))
|
|
58
|
+
mesh.material.release();
|
|
59
|
+
mesh.geometry.dispose();
|
|
60
|
+
}
|
|
61
|
+
/** Point every mesh of `meshes` at `instances`, which changed: survivors scale or no longer do, or the attributes were replaced. */
|
|
62
|
+
export function drawInstances(meshes, instances) {
|
|
63
|
+
for (const mesh of meshes) {
|
|
75
64
|
if (isImpostorMesh(mesh))
|
|
76
|
-
mesh.
|
|
77
|
-
mesh.
|
|
78
|
-
}
|
|
79
|
-
/** Every level's meshes draw the instance colours the selection has begun to carry. */
|
|
80
|
-
recolor() {
|
|
81
|
-
for (const mesh of this.byLevel.flat()) {
|
|
82
|
-
mesh.instanceColor = this.selection.slots.colors;
|
|
83
|
-
// Instance colours change the shader.
|
|
84
|
-
if (!isImpostorMesh(mesh))
|
|
85
|
-
for (const material of [mesh.material].flat())
|
|
86
|
-
material.needsUpdate = true;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
/** Show only levels whose conservative bounds contain a possible selected instance; whether any may draw for `camera`. */
|
|
90
|
-
show(camera, matrixWorld) {
|
|
91
|
-
let shown = false;
|
|
92
|
-
for (let level = 0; level < this.byLevel.length; level++) {
|
|
93
|
-
const reach = at(this.reaches, level);
|
|
94
|
-
const visible = !reach.isEmpty();
|
|
95
|
-
const meshes = at(this.byLevel, level);
|
|
96
|
-
for (const mesh of meshes)
|
|
97
|
-
mesh.visible = visible;
|
|
98
|
-
shown ||= visible && meshes.length > 0 && inView(camera, matrixWorld, reach);
|
|
99
|
-
}
|
|
100
|
-
return shown;
|
|
65
|
+
mesh.instanceMatrix = instances.matrices;
|
|
66
|
+
Object.assign(mesh, { instanceColor: instances.colors });
|
|
101
67
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Material group `group` of `template` drawn for every instance in level `level`'s list, from byte `offset()` of a
|
|
71
|
+
* camera's draws, once there is one, on the Lod's layers. Only the Lod's raycast hits its instances.
|
|
72
|
+
*/
|
|
73
|
+
function levelMesh({ template, placement, group }, offset, tint, inputs) {
|
|
74
|
+
const { instances, bounds, box, slots, radius, layers, drawFor } = inputs;
|
|
75
|
+
// An impostor card is placed in the shader; any other mesh draws its geometry moved into the instance's space, so
|
|
76
|
+
// the instance matrix is all it needs.
|
|
77
|
+
const mesh = isImpostorMesh(template) ? card(template, placement, inputs) : plain(template, placement, group, instances);
|
|
78
|
+
setFadeSource(mesh, {
|
|
79
|
+
slots,
|
|
80
|
+
radius,
|
|
81
|
+
tint,
|
|
82
|
+
level: isImpostorMesh(template) ? undefined : { instances, space: placement.clone().invert() },
|
|
83
|
+
});
|
|
84
|
+
mesh.name = template.name;
|
|
85
|
+
mesh.castShadow = template.castShadow;
|
|
86
|
+
mesh.receiveShadow = template.receiveShadow;
|
|
87
|
+
mesh.layers = layers;
|
|
88
|
+
mesh.raycast = () => { };
|
|
89
|
+
if (!isImpostorMesh(mesh))
|
|
90
|
+
mesh.geometry.boundingSphere = bounds;
|
|
91
|
+
mesh.geometry.boundingBox = box;
|
|
92
|
+
const previous = mesh.onBeforeRender;
|
|
93
|
+
// Each camera draws the instances in its own lists. A level compiling to join draws nothing yet: its pipelines do not
|
|
94
|
+
// depend on the indirect draw.
|
|
95
|
+
mesh.onBeforeRender = (renderer, scene, camera, geometry, material, drawn) => {
|
|
96
|
+
previous.call(mesh, renderer, scene, camera, geometry, material, drawn);
|
|
97
|
+
const start = offset();
|
|
98
|
+
if (start === null)
|
|
99
|
+
return;
|
|
100
|
+
const args = drawFor(renderer, camera);
|
|
101
|
+
if (args)
|
|
102
|
+
mesh.geometry.setIndirect(args.attribute, args.offset + start);
|
|
106
103
|
else
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// An ImpostorMesh frees its own material and geometry; the other meshes' faded
|
|
111
|
-
// materials go with the levels' originals.
|
|
112
|
-
for (const mesh of this.byLevel.flat()) {
|
|
113
|
-
mesh.removeFromParent();
|
|
114
|
-
this.free(mesh);
|
|
115
|
-
}
|
|
116
|
-
due.delete(this.selection);
|
|
117
|
-
this.byLevel.length = 0;
|
|
118
|
-
this.offsets.clear();
|
|
119
|
-
}
|
|
120
|
-
/** Material group `part.group` of `part.template` drawn for every instance in `level`'s slots. */
|
|
121
|
-
mesh(level, { template, placement, group }, offset) {
|
|
122
|
-
const { selection, owner } = this;
|
|
123
|
-
// An impostor card is placed in the shader; any other mesh draws its geometry moved
|
|
124
|
-
// into the instance's space, so the instance matrix is all it needs.
|
|
125
|
-
const mesh = isImpostorMesh(template)
|
|
126
|
-
? card(template, placement, selection)
|
|
127
|
-
: new Instances(placed(template.geometry, placement), groupMaterial(template, group), selection);
|
|
128
|
-
mesh.geometry = indirect(mesh.geometry, selection, offset);
|
|
129
|
-
this.offsets.set(mesh, offset);
|
|
130
|
-
setDraw(mesh, { kind: "instances", fades: selection.slots.fades, radius: this.radius, tint: level.tint });
|
|
131
|
-
if (!isImpostorMesh(template))
|
|
132
|
-
placeInterior(mesh, placement);
|
|
133
|
-
mesh.name = template.name;
|
|
134
|
-
mesh.castShadow = template.castShadow;
|
|
135
|
-
mesh.receiveShadow = template.receiveShadow;
|
|
136
|
-
mesh.boundingSphere = at(this.reaches, level.index);
|
|
137
|
-
watchViewport(mesh);
|
|
138
|
-
const previous = mesh.onBeforeRender;
|
|
139
|
-
// Selected once per view, before the first level mesh draws: in the view, or in a
|
|
140
|
-
// shadow pass that comes first. The GPU runs it before anything drawn after it.
|
|
141
|
-
mesh.onBeforeRender = (renderer, scene, camera, geometry, material, group) => {
|
|
142
|
-
if (!owner.live())
|
|
143
|
-
return;
|
|
144
|
-
previous.call(mesh, renderer, scene, camera, geometry, material, group);
|
|
145
|
-
const gpu = gpuRenderer(renderer);
|
|
146
|
-
// A caster outside the viewing frustum still needs its selection in a shadow draw.
|
|
147
|
-
due.add(selection);
|
|
148
|
-
// Each level's draws start at its slots (see select.ts).
|
|
149
|
-
if (!gpu.hasFeature("indirect-first-instance"))
|
|
150
|
-
throw new Error("InstancedLod: needs the GPU feature indirect-first-instance, which this device lacks");
|
|
151
|
-
passes.length = 0;
|
|
152
|
-
for (const each of due)
|
|
153
|
-
passes.push(...each.take(gpu));
|
|
154
|
-
due.clear();
|
|
155
|
-
if (passes.length > 0)
|
|
156
|
-
gpu.compute(passes);
|
|
157
|
-
};
|
|
158
|
-
const after = mesh.onAfterRender;
|
|
159
|
-
mesh.onAfterRender = (renderer, scene, camera, geometry, material, group) => {
|
|
160
|
-
after.call(mesh, renderer, scene, camera, geometry, material, group);
|
|
161
|
-
if (!inShadowPass(scene))
|
|
162
|
-
owner.drawn(camera, mesh);
|
|
163
|
-
};
|
|
164
|
-
return mesh;
|
|
165
|
-
}
|
|
104
|
+
mesh.geometry.setIndirect(NOTHING, 0);
|
|
105
|
+
};
|
|
106
|
+
return mesh;
|
|
166
107
|
}
|
|
167
|
-
/**
|
|
168
|
-
|
|
108
|
+
/**
|
|
109
|
+
* A plain mesh drawing `template`'s geometry moved by `placement`, with a geometry of its own, which its draws point
|
|
110
|
+
* at their camera's indirect draws, over the moved one's buffers.
|
|
111
|
+
*/
|
|
112
|
+
function plain(template, placement, group, instances) {
|
|
113
|
+
const moved = placed(template.geometry, placement);
|
|
114
|
+
const geometry = new BufferGeometry();
|
|
115
|
+
geometry.index = moved.index;
|
|
116
|
+
for (const [name, attribute] of Object.entries(moved.attributes))
|
|
117
|
+
geometry.setAttribute(name, attribute);
|
|
118
|
+
geometry.morphAttributes = moved.morphAttributes;
|
|
119
|
+
// three's NodeMaterial multiplies a draw's colour by the varying vInstanceColor wherever its object has an
|
|
120
|
+
// instanceColor; placeInstances (see fade.ts) writes it.
|
|
121
|
+
return Object.assign(new Mesh(geometry, groupMaterial(template, group)), { instanceColor: instances.colors });
|
|
122
|
+
}
|
|
123
|
+
/** An impostor's cards for the instances in a level's list. */
|
|
124
|
+
function card(template, placement, { instances, bounds }) {
|
|
169
125
|
const mesh = impostorInstances(template, 0, placement);
|
|
170
|
-
// Indirect
|
|
171
|
-
// used by Three to specialize its shader for one object's storage bindings.
|
|
126
|
+
// Indirect draws give the count. Three otherwise keys a card's shader by its count, one per object.
|
|
172
127
|
mesh.count = 1;
|
|
173
|
-
mesh.instanceMatrix =
|
|
174
|
-
mesh.instanceColor =
|
|
128
|
+
mesh.instanceMatrix = instances.matrices;
|
|
129
|
+
mesh.instanceColor = instances.colors;
|
|
130
|
+
mesh.boundingSphere = bounds;
|
|
175
131
|
return mesh;
|
|
176
132
|
}
|
|
177
|
-
/**
|
|
178
|
-
function
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
133
|
+
/** The level material of `mesh`'s material group `group`. */
|
|
134
|
+
function groupMaterial(mesh, group) {
|
|
135
|
+
if (!Array.isArray(mesh.material))
|
|
136
|
+
return levelMaterial(mesh.material);
|
|
137
|
+
const index = mesh.geometry.groups[group]?.materialIndex ?? 0;
|
|
138
|
+
const material = mesh.material[index];
|
|
139
|
+
if (!material)
|
|
140
|
+
throw new Error(`Lod: "${mesh.name}" has no material ${index}`);
|
|
141
|
+
return levelMaterial(material);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Placed copies of geometries, shared by every Lod drawing the same mesh the same way: a side table, as three's
|
|
145
|
+
* BufferGeometry has no room for a package's state.
|
|
146
|
+
*/
|
|
147
|
+
const copies = new WeakMap();
|
|
148
|
+
/** `geometry` moved by `placement`: itself for the identity, else a copy made once. */
|
|
149
|
+
function placed(geometry, placement) {
|
|
150
|
+
if (placement.equals(IDENTITY))
|
|
151
|
+
return geometry;
|
|
152
|
+
const known = copies.get(geometry) ?? [];
|
|
153
|
+
copies.set(geometry, known);
|
|
154
|
+
const hit = known.find((entry) => entry.placement.equals(placement));
|
|
155
|
+
if (hit)
|
|
156
|
+
return hit.geometry;
|
|
157
|
+
const copy = geometry.clone();
|
|
158
|
+
const box = copy.boundingBox;
|
|
159
|
+
const sphere = copy.boundingSphere;
|
|
160
|
+
// applyMatrix4 otherwise recomputes both bounds by walking the transformed vertices.
|
|
161
|
+
copy.boundingBox = null;
|
|
162
|
+
copy.boundingSphere = null;
|
|
163
|
+
// Translations leave normals and tangents unchanged; scanning them stalls large source arrivals.
|
|
164
|
+
if (placement.clone().setPosition(0, 0, 0).equals(IDENTITY)) {
|
|
165
|
+
const position = copy.getAttribute("position");
|
|
166
|
+
if (position) {
|
|
167
|
+
position.applyMatrix4(placement);
|
|
168
|
+
position.needsUpdate = true;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else
|
|
172
|
+
copy.applyMatrix4(placement);
|
|
173
|
+
copy.boundingBox = box?.applyMatrix4(placement) ?? null;
|
|
174
|
+
copy.boundingSphere = sphere?.applyMatrix4(placement) ?? null;
|
|
175
|
+
geometry.addEventListener("dispose", () => copy.dispose());
|
|
176
|
+
known.push({ placement: placement.clone(), geometry: copy });
|
|
177
|
+
return copy;
|
|
190
178
|
}
|
|
191
179
|
//# sourceMappingURL=meshes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meshes.js","sourceRoot":"","sources":["../../src/instanced/meshes.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"meshes.js","sourceRoot":"","sources":["../../src/instanced/meshes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { StorageInstancedBufferAttribute, type InstancedBufferAttribute } from "three/webgpu";
|
|
2
|
+
/** A CPU instanceMatrix's mirror, over the source's own array. */
|
|
3
|
+
export declare class Mirror {
|
|
4
|
+
readonly source: InstancedBufferAttribute;
|
|
5
|
+
readonly attribute: StorageInstancedBufferAttribute;
|
|
6
|
+
/** The source's version it last took in. */
|
|
7
|
+
private version;
|
|
8
|
+
constructor(source: InstancedBufferAttribute);
|
|
9
|
+
/** Take in the source's edits: the ranges the app marked changed, all of it without any. Whether it changed. */
|
|
10
|
+
refresh(): boolean;
|
|
11
|
+
dispose(): void;
|
|
12
|
+
}
|
|
13
|
+
/** A CPU instanceColor's mirror: its RGB padded to the four floats a storage colour holds, in an array of its own. */
|
|
14
|
+
export declare class ColorMirror {
|
|
15
|
+
readonly source: InstancedBufferAttribute;
|
|
16
|
+
readonly attribute: StorageInstancedBufferAttribute;
|
|
17
|
+
private version;
|
|
18
|
+
constructor(source: InstancedBufferAttribute);
|
|
19
|
+
/** Take in the source's edits: the instances of the ranges the app marked changed, all without any. Whether it changed. */
|
|
20
|
+
refresh(): boolean;
|
|
21
|
+
dispose(): void;
|
|
22
|
+
/** Copy instances `first` to `end` (exclusive) of the source, white's alpha padding them. */
|
|
23
|
+
private copy;
|
|
24
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { StorageInstancedBufferAttribute } from "three/webgpu";
|
|
2
|
+
// Storage attributes the GPU reads a Lod's CPU attributes through, uploading what the app marks changed in them, as
|
|
3
|
+
// three uploads an InstancedMesh's: binding the app's own attribute through storage() would flag it as a storage
|
|
4
|
+
// attribute, which three then pads (an RGB colour to four floats) and treats as one wherever else the app draws it. Each
|
|
5
|
+
// takes and clears the source's update ranges, so an InstancedMesh also drawing the source uploads it whole.
|
|
6
|
+
/** A CPU instanceMatrix's mirror, over the source's own array. */
|
|
7
|
+
export class Mirror {
|
|
8
|
+
source;
|
|
9
|
+
attribute;
|
|
10
|
+
/** The source's version it last took in. */
|
|
11
|
+
version;
|
|
12
|
+
constructor(source) {
|
|
13
|
+
this.source = source;
|
|
14
|
+
this.attribute = new StorageInstancedBufferAttribute(source.array, 16);
|
|
15
|
+
this.version = source.version;
|
|
16
|
+
}
|
|
17
|
+
/** Take in the source's edits: the ranges the app marked changed, all of it without any. Whether it changed. */
|
|
18
|
+
refresh() {
|
|
19
|
+
const { source, attribute } = this;
|
|
20
|
+
if (source.version === this.version)
|
|
21
|
+
return false;
|
|
22
|
+
this.version = source.version;
|
|
23
|
+
for (const { start, count } of source.updateRanges)
|
|
24
|
+
attribute.addUpdateRange(start, count);
|
|
25
|
+
source.clearUpdateRanges();
|
|
26
|
+
attribute.needsUpdate = true;
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
dispose() {
|
|
30
|
+
this.attribute.dispose();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** A CPU instanceColor's mirror: its RGB padded to the four floats a storage colour holds, in an array of its own. */
|
|
34
|
+
export class ColorMirror {
|
|
35
|
+
source;
|
|
36
|
+
attribute;
|
|
37
|
+
version;
|
|
38
|
+
constructor(source) {
|
|
39
|
+
this.source = source;
|
|
40
|
+
this.attribute = new StorageInstancedBufferAttribute(new Float32Array(source.count * 4), 4);
|
|
41
|
+
this.copy(0, source.count);
|
|
42
|
+
this.version = source.version;
|
|
43
|
+
}
|
|
44
|
+
/** Take in the source's edits: the instances of the ranges the app marked changed, all without any. Whether it changed. */
|
|
45
|
+
refresh() {
|
|
46
|
+
const { source, attribute } = this;
|
|
47
|
+
if (source.version === this.version)
|
|
48
|
+
return false;
|
|
49
|
+
this.version = source.version;
|
|
50
|
+
const ranges = source.updateRanges.length > 0 ? source.updateRanges : [{ start: 0, count: source.array.length }];
|
|
51
|
+
for (const { start, count } of ranges) {
|
|
52
|
+
const first = Math.floor(start / 3);
|
|
53
|
+
const end = Math.min(Math.ceil((start + count) / 3), source.count);
|
|
54
|
+
this.copy(first, end);
|
|
55
|
+
attribute.addUpdateRange(first * 4, (end - first) * 4);
|
|
56
|
+
}
|
|
57
|
+
source.clearUpdateRanges();
|
|
58
|
+
attribute.needsUpdate = true;
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
dispose() {
|
|
62
|
+
this.attribute.dispose();
|
|
63
|
+
}
|
|
64
|
+
/** Copy instances `first` to `end` (exclusive) of the source, white's alpha padding them. */
|
|
65
|
+
copy(first, end) {
|
|
66
|
+
const from = this.source.array;
|
|
67
|
+
const to = this.attribute.array;
|
|
68
|
+
for (let i = first; i < end; i++) {
|
|
69
|
+
to[i * 4] = from[i * 3] ?? 0;
|
|
70
|
+
to[i * 4 + 1] = from[i * 3 + 1] ?? 0;
|
|
71
|
+
to[i * 4 + 2] = from[i * 3 + 2] ?? 0;
|
|
72
|
+
to[i * 4 + 3] = 1;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=mirror.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../src/instanced/mirror.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { Sphere, type Intersection, type Object3D, type Raycaster } from "three/webgpu";
|
|
2
|
-
import type { Part } from "./
|
|
3
|
-
/**
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
private readonly probes;
|
|
8
|
-
/** `matrices` are the instances', 16 floats each; `rest` bounds every level in an instance's space. */
|
|
9
|
-
constructor(matrices: Float32Array, rest: Sphere);
|
|
10
|
-
add(parts: readonly Part[]): void;
|
|
11
|
-
/** Hits on `owner`'s instances, with `object` set to `owner` and `instanceId` to the instance. */
|
|
12
|
-
raycast(owner: Object3D, raycaster: Raycaster, intersects: Intersection[]): void;
|
|
2
|
+
import type { Part } from "./meshes.js";
|
|
3
|
+
/** A Lod's source level as a raycast meets it: its parts, and the sphere around every level in an instance's space. */
|
|
4
|
+
export interface RaycastSource {
|
|
5
|
+
readonly parts: readonly Part[];
|
|
6
|
+
readonly rest: Sphere;
|
|
13
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Hits on the first `count` instances of `matrices`, `lod`'s, of `source`'s meshes, each raycast where an instance
|
|
10
|
+
* stands, with `instanceId` set as on an InstancedMesh's hits.
|
|
11
|
+
*/
|
|
12
|
+
export declare function raycastInstances(lod: Object3D, source: RaycastSource, matrices: ArrayLike<number>, count: number, raycaster: Raycaster, intersects: Intersection[]): void;
|