@drawcall/lod 0.3.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 +5 -8
- package/dist/bake.d.ts +16 -2
- package/dist/bake.js +92 -4
- package/dist/bake.js.map +1 -1
- package/dist/baked/index.d.ts +2 -2
- package/dist/baked/index.js +2 -2
- package/dist/baked/interior/faces.js +4 -2
- package/dist/baked/interior/faces.js.map +1 -1
- package/dist/baked/interior/material.js +1 -1
- package/dist/baked/interior/material.js.map +1 -1
- package/dist/baked/interior/rooms.d.ts +1 -1
- package/dist/baked/interior/rooms.js +1 -1
- package/dist/dispose.d.ts +3 -3
- package/dist/dispose.js +6 -6
- 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/index.d.ts +3 -3
- package/dist/impostor/bake/index.js +12 -3
- package/dist/impostor/bake/index.js.map +1 -1
- package/dist/impostor/bake/source.d.ts +2 -1
- package/dist/impostor/bake/source.js +2 -2
- package/dist/impostor/bake/source.js.map +1 -1
- package/dist/impostor/impostor.d.ts +1 -1
- package/dist/impostor/impostor.js +1 -1
- package/dist/impostor/ktx2/encode.js +5 -2
- package/dist/impostor/ktx2/encode.js.map +1 -1
- package/dist/impostor/ktx2/uastc.js +3 -2
- package/dist/impostor/ktx2/uastc.js.map +1 -1
- package/dist/impostor/ktx2/worker.js +0 -2
- package/dist/impostor/ktx2/worker.js.map +1 -1
- package/dist/impostor/mesh/card.d.ts +1 -1
- package/dist/impostor/mesh/index.d.ts +2 -2
- package/dist/impostor/mesh/index.js +3 -3
- package/dist/impostor/mesh/index.js.map +1 -1
- package/dist/index.d.ts +3 -6
- package/dist/index.js +3 -6
- package/dist/index.js.map +1 -1
- package/dist/instanced/camera.d.ts +13 -25
- package/dist/instanced/camera.js +17 -42
- package/dist/instanced/camera.js.map +1 -1
- 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 +3 -3
- package/dist/instanced/cull.js +2 -2
- package/dist/instanced/cull.js.map +1 -1
- 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 +1 -1
- package/dist/instanced/key.js +1 -1
- package/dist/instanced/key.js.map +1 -1
- package/dist/instanced/levels.d.ts +9 -9
- package/dist/instanced/levels.js +7 -6
- package/dist/instanced/levels.js.map +1 -1
- package/dist/instanced/lists.d.ts +26 -39
- package/dist/instanced/lists.js +42 -61
- package/dist/instanced/lists.js.map +1 -1
- package/dist/instanced/measure.d.ts +2 -2
- package/dist/instanced/measure.js +2 -2
- package/dist/instanced/meshes.d.ts +11 -9
- package/dist/instanced/meshes.js +26 -16
- package/dist/instanced/meshes.js.map +1 -1
- package/dist/instanced/mirror.d.ts +16 -12
- package/dist/instanced/mirror.js +51 -12
- package/dist/instanced/mirror.js.map +1 -1
- package/dist/instanced/raycast.d.ts +6 -9
- package/dist/instanced/raycast.js +15 -18
- package/dist/instanced/raycast.js.map +1 -1
- package/dist/instanced/rows.d.ts +15 -73
- package/dist/instanced/rows.js +16 -189
- package/dist/instanced/rows.js.map +1 -1
- package/dist/instanced/shape.d.ts +3 -1
- package/dist/instanced/shape.js +6 -3
- package/dist/instanced/shape.js.map +1 -1
- package/dist/instanced/sort.d.ts +32 -34
- package/dist/instanced/sort.js +162 -132
- package/dist/instanced/sort.js.map +1 -1
- package/dist/instanced/update.d.ts +16 -12
- package/dist/instanced/update.js +57 -84
- package/dist/instanced/update.js.map +1 -1
- package/dist/levels/compile/index.d.ts +4 -2
- package/dist/levels/compile/index.js +10 -2
- package/dist/levels/compile/index.js.map +1 -1
- package/dist/levels/compile/pipelines.d.ts +1 -1
- package/dist/levels/compile/pipelines.js +1 -6
- package/dist/levels/compile/pipelines.js.map +1 -1
- package/dist/levels/draw.d.ts +1 -1
- package/dist/levels/draw.js +3 -3
- package/dist/levels/fade.d.ts +13 -22
- package/dist/levels/fade.js +17 -38
- package/dist/levels/fade.js.map +1 -1
- package/dist/levels/index.d.ts +7 -7
- package/dist/levels/index.js +1 -1
- package/dist/levels/item.d.ts +10 -10
- package/dist/levels/item.js +15 -23
- package/dist/levels/item.js.map +1 -1
- package/dist/levels/load.d.ts +1 -1
- package/dist/levels/load.js +5 -3
- package/dist/levels/load.js.map +1 -1
- package/dist/levels/manager.d.ts +30 -31
- package/dist/levels/manager.js +75 -62
- package/dist/levels/manager.js.map +1 -1
- package/dist/levels/material.d.ts +2 -2
- package/dist/levels/material.js +2 -2
- package/dist/levels/renderer.d.ts +8 -5
- package/dist/levels/renderer.js +20 -4
- package/dist/levels/renderer.js.map +1 -1
- package/dist/levels/requests.d.ts +4 -1
- package/dist/levels/requests.js +3 -1
- package/dist/levels/requests.js.map +1 -1
- package/dist/loader/context.d.ts +9 -11
- package/dist/loader/context.js +12 -7
- package/dist/loader/context.js.map +1 -1
- 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 +49 -35
- package/dist/loader/index.js +123 -135
- package/dist/loader/index.js.map +1 -1
- package/dist/loader/level.js +5 -5
- package/dist/loader/level.js.map +1 -1
- 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 +11 -44
- package/dist/loader/request.js +7 -47
- package/dist/loader/request.js.map +1 -1
- package/dist/loader/url.d.ts +10 -9
- package/dist/loader/url.js +21 -17
- package/dist/loader/url.js.map +1 -1
- package/dist/lod.d.ts +122 -62
- package/dist/lod.js +331 -187
- package/dist/lod.js.map +1 -1
- package/dist/meshopt.d.ts +1 -1
- package/dist/meshopt.js +3 -2
- package/dist/meshopt.js.map +1 -1
- 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/index.d.ts +2 -2
- package/dist/simplify/index.js +7 -7
- package/dist/simplify/index.js.map +1 -1
- package/dist/source/detail.d.ts +7 -2
- package/dist/source/detail.js +24 -22
- package/dist/source/detail.js.map +1 -1
- package/dist/source/sampler.js +5 -2
- package/dist/source/sampler.js.map +1 -1
- package/dist/three.d.ts +7 -7
- package/dist/three.js +4 -4
- package/dist/three.js.map +1 -1
- package/dist/wind/bounds.js +1 -1
- package/dist/wind/bounds.js.map +1 -1
- package/dist/wind/hooks.d.ts +1 -1
- package/dist/wind/hooks.js +1 -1
- package/dist/wind/index.d.ts +3 -3
- package/dist/wind/index.js +11 -9
- package/dist/wind/index.js.map +1 -1
- package/package.json +10 -6
- package/skills/lod/SKILL.md +65 -54
- package/dist/gpu.d.ts +0 -39
- package/dist/gpu.js +0 -41
- package/dist/gpu.js.map +0 -1
- package/dist/instanced/chunk.d.ts +0 -97
- package/dist/instanced/chunk.js +0 -156
- package/dist/instanced/chunk.js.map +0 -1
- package/dist/instanced/chunks.d.ts +0 -60
- package/dist/instanced/chunks.js +0 -208
- package/dist/instanced/chunks.js.map +0 -1
- package/dist/instanced/index.d.ts +0 -120
- package/dist/instanced/index.js +0 -290
- package/dist/instanced/index.js.map +0 -1
- package/dist/instanced/pages/buffers.d.ts +0 -37
- package/dist/instanced/pages/buffers.js +0 -15
- package/dist/instanced/pages/buffers.js.map +0 -1
- package/dist/instanced/pages/chunk.d.ts +0 -51
- package/dist/instanced/pages/chunk.js +0 -81
- package/dist/instanced/pages/chunk.js.map +0 -1
- package/dist/instanced/pages/index.d.ts +0 -74
- package/dist/instanced/pages/index.js +0 -269
- package/dist/instanced/pages/index.js.map +0 -1
- package/dist/instanced/pages/passes.d.ts +0 -21
- package/dist/instanced/pages/passes.js +0 -52
- package/dist/instanced/pages/passes.js.map +0 -1
- package/dist/instanced/pages/slots.d.ts +0 -11
- package/dist/instanced/pages/slots.js +0 -90
- package/dist/instanced/pages/slots.js.map +0 -1
- package/dist/instanced/pages/workgroup.d.ts +0 -14
- package/dist/instanced/pages/workgroup.js +0 -38
- package/dist/instanced/pages/workgroup.js.map +0 -1
- package/dist/levels/wait.d.ts +0 -27
- package/dist/levels/wait.js +0 -61
- package/dist/levels/wait.js.map +0 -1
- package/dist/loader/cache.d.ts +0 -12
- package/dist/loader/cache.js +0 -68
- package/dist/loader/cache.js.map +0 -1
- package/dist/loader/dependencies.d.ts +0 -32
- package/dist/loader/dependencies.js +0 -113
- package/dist/loader/dependencies.js.map +0 -1
package/dist/instanced/lists.js
CHANGED
|
@@ -2,86 +2,77 @@ import { Frustum, Matrix4 } from "three/webgpu";
|
|
|
2
2
|
import { has } from "../levels/draw.js";
|
|
3
3
|
import { emptyLevels } from "../levels/index.js";
|
|
4
4
|
import { Key } from "./key.js";
|
|
5
|
+
import { Sorter } from "./sort.js";
|
|
5
6
|
const projection = new Matrix4();
|
|
6
|
-
/** What a camera's sort key starts with: how it lies to the instances
|
|
7
|
+
/** What a camera's sort key starts with: how it lies to the instances it sees, which says what else the key holds. */
|
|
7
8
|
const MODE = {
|
|
8
|
-
/**
|
|
9
|
+
/** It sees none: nothing draws, and no sort runs. */
|
|
9
10
|
hidden: 0,
|
|
10
|
-
/**
|
|
11
|
+
/** The key holds everything the sort reads. */
|
|
11
12
|
seen: 1,
|
|
12
|
-
/**
|
|
13
|
+
/** Every range wholly inside its frustum, each instance drawing one level without a fade and none culled: the key holds the level. */
|
|
13
14
|
oneLevel: 2,
|
|
14
|
-
/**
|
|
15
|
+
/** Every range wholly inside an orthographic camera's frustum, none culled: heights are alike from anywhere, so no eye. */
|
|
15
16
|
orthoInside: 3,
|
|
16
17
|
};
|
|
17
|
-
/** The lists of every camera drawing one
|
|
18
|
+
/** The lists of every camera drawing one Lod, and the sorts filling them. */
|
|
18
19
|
export class InstanceLists {
|
|
19
|
-
sorter;
|
|
20
20
|
cameras = new Map();
|
|
21
|
-
|
|
22
|
-
/** `listed` tells per level whether it has an instance list: whether it draws something
|
|
23
|
-
constructor(
|
|
24
|
-
this.sorter =
|
|
25
|
-
this.row = sorter.register(listed.reduce((mask, on, i) => (on ? mask | (1 << i) : mask), 0), listSize);
|
|
21
|
+
sorter;
|
|
22
|
+
/** `listed` tells per level whether it has an instance list: whether it draws something. */
|
|
23
|
+
constructor(listed) {
|
|
24
|
+
this.sorter = new Sorter(listed.reduce((mask, on, i) => (on ? mask | (1 << i) : mask), 0));
|
|
26
25
|
}
|
|
27
26
|
/** `camera`'s lists, made the first time it asks. */
|
|
28
27
|
of(camera) {
|
|
29
28
|
const found = this.cameras.get(camera);
|
|
30
29
|
if (found)
|
|
31
30
|
return found;
|
|
32
|
-
|
|
33
|
-
const lists = {
|
|
34
|
-
frustum: new Frustum(),
|
|
35
|
-
written: false,
|
|
36
|
-
sortKey: new Key(),
|
|
37
|
-
heightsKey: new Key(),
|
|
38
|
-
heights: [],
|
|
39
|
-
heightsVersion: 0,
|
|
40
|
-
wanted: 0,
|
|
41
|
-
shownKey: new Key(),
|
|
42
|
-
shown: 0,
|
|
43
|
-
onlyLevel: 0,
|
|
44
|
-
};
|
|
31
|
+
const lists = { frustum: new Frustum(), written: false, sortKey: new Key() };
|
|
45
32
|
this.cameras.set(camera, lists);
|
|
46
33
|
return lists;
|
|
47
34
|
}
|
|
48
|
-
/** Where `camera`'s lists and indirect draws lie. */
|
|
35
|
+
/** Where `camera`'s lists and indirect draws lie; null before a sort was written for it. */
|
|
49
36
|
slots(camera) {
|
|
50
|
-
this.
|
|
51
|
-
return this.sorter.slotsOf(camera, this.row);
|
|
37
|
+
return this.sorter.slotsOf(camera);
|
|
52
38
|
}
|
|
53
39
|
/** Every camera draws `draws` too, after the draws it has; where they start. */
|
|
54
40
|
appendDraws(draws) {
|
|
55
|
-
return this.sorter.appendDraws(
|
|
41
|
+
return this.sorter.appendDraws(draws);
|
|
56
42
|
}
|
|
57
|
-
/**
|
|
58
|
-
|
|
43
|
+
/** Survivors' scaled matrices for `capacity` instances. */
|
|
44
|
+
scaledMatrices(capacity) {
|
|
45
|
+
return this.sorter.scaledMatrices(capacity);
|
|
46
|
+
}
|
|
47
|
+
/** Sort for `camera` at its next draw, unless nothing it sorts by changed since its last sort; `limit` bounds its buffers. */
|
|
48
|
+
sort(camera, sort, limit) {
|
|
59
49
|
const lists = this.of(camera);
|
|
60
|
-
const { levels, eye, scale, ortho, cull, loaded, before, progress, source, reach } = sort;
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
// last sort read, which a camera that looks back at the instances as it was matches: that sort's lists still hold.
|
|
50
|
+
const { levels, eye, scale, ortho, cull, loaded, before, progress, source, reach, ranges } = sort;
|
|
51
|
+
const mode = modeOf(sort);
|
|
52
|
+
// No level mesh draws for the camera (see Lod.sort): its lists are not read. The key still holds what the last
|
|
53
|
+
// sort read, which a camera that looks back at the instances as it was matches: that sort's lists still hold.
|
|
65
54
|
if (mode === MODE.hidden)
|
|
66
55
|
return;
|
|
67
|
-
const key = lists.sortKey.start().put(mode).put(sort.
|
|
56
|
+
const key = lists.sortKey.start().put(mode).put(sort.version);
|
|
57
|
+
for (const value of ranges)
|
|
58
|
+
key.put(value);
|
|
68
59
|
if (mode === MODE.oneLevel)
|
|
69
60
|
key.put(sort.onlyLevel);
|
|
70
61
|
else if (mode === MODE.orthoInside)
|
|
71
62
|
key.screen(scale, ortho, levels, cull, source).put(loaded).put(before).put(progress).put(reach);
|
|
72
63
|
else if (mode === MODE.seen) {
|
|
73
|
-
for (const { normal, constant } of frustum.planes)
|
|
64
|
+
for (const { normal, constant } of lists.frustum.planes)
|
|
74
65
|
key.put(normal.x).put(normal.y).put(normal.z).put(constant);
|
|
75
66
|
key.camera(eye, scale, ortho, levels, cull, source).put(loaded).put(before).put(progress).put(reach);
|
|
76
67
|
}
|
|
77
68
|
if (!key.end())
|
|
78
69
|
return;
|
|
79
|
-
this.sorter.write(camera,
|
|
70
|
+
this.sorter.write(camera, { levels, eye, scale, ortho, cull, loaded, before, progress, source, reach, frustum: lists.frustum }, ranges, sort.instances, limit);
|
|
80
71
|
lists.written = true;
|
|
81
72
|
}
|
|
82
|
-
/** Sort
|
|
83
|
-
drawFor(camera) {
|
|
84
|
-
this.sorter.run(camera);
|
|
73
|
+
/** Sort for `camera` on `renderer`, reading `matrices`, if due: before a level mesh draws for it. */
|
|
74
|
+
drawFor(renderer, camera, matrices) {
|
|
75
|
+
this.sorter.run(renderer, camera, matrices);
|
|
85
76
|
}
|
|
86
77
|
/** Give back the lists of every camera other than `camera` that `rendering` says stopped drawing, as a clone made for one frame does. */
|
|
87
78
|
prune(camera, rendering) {
|
|
@@ -90,13 +81,12 @@ export class InstanceLists {
|
|
|
90
81
|
this.forget(other);
|
|
91
82
|
}
|
|
92
83
|
dispose() {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
this.sorter.unregister(this.row);
|
|
84
|
+
this.cameras.clear();
|
|
85
|
+
this.sorter.dispose();
|
|
96
86
|
}
|
|
97
87
|
forget(camera) {
|
|
98
88
|
this.cameras.delete(camera);
|
|
99
|
-
this.sorter.release(camera
|
|
89
|
+
this.sorter.release(camera);
|
|
100
90
|
}
|
|
101
91
|
}
|
|
102
92
|
/** Set `lists`' frustum to `camera`'s in the space of `space`, a world matrix, and return it. */
|
|
@@ -105,26 +95,17 @@ export function frustumIn(lists, camera, space) {
|
|
|
105
95
|
return lists.frustum.setFromProjectionMatrix(projection, camera.coordinateSystem, camera.reversedDepth);
|
|
106
96
|
}
|
|
107
97
|
/**
|
|
108
|
-
* How
|
|
109
|
-
* wherever the camera is: instances that all draw one level fill its list alike, and an orthographic camera
|
|
110
|
-
* their heights alike from anywhere.
|
|
98
|
+
* How the camera lies to `sort`'s instances (see MODE). Wholly inside its frustum, with no cullDistance, no instance is
|
|
99
|
+
* culled wherever the camera is: instances that all draw one level fill its list alike, and an orthographic camera
|
|
100
|
+
* measures their heights alike from anywhere.
|
|
111
101
|
*/
|
|
112
|
-
function modeOf(
|
|
113
|
-
if (
|
|
102
|
+
function modeOf({ ranges, inside, cull, onlyLevel, ortho }) {
|
|
103
|
+
if (ranges.length === 0)
|
|
114
104
|
return MODE.hidden;
|
|
115
|
-
if (cull !== null || !inside
|
|
105
|
+
if (cull !== null || !inside)
|
|
116
106
|
return MODE.seen;
|
|
117
107
|
return onlyLevel !== 0 ? MODE.oneLevel : ortho ? MODE.orthoInside : MODE.seen;
|
|
118
108
|
}
|
|
119
|
-
/** Whether `box` lies wholly inside `frustum`: its corner nearest each plane's outside lies inside. */
|
|
120
|
-
function inside(frustum, box) {
|
|
121
|
-
return frustum.planes.every(({ normal, constant }) => {
|
|
122
|
-
const x = normal.x > 0 ? box.min.x : box.max.x;
|
|
123
|
-
const y = normal.y > 0 ? box.min.y : box.max.y;
|
|
124
|
-
const z = normal.z > 0 ? box.min.z : box.max.z;
|
|
125
|
-
return normal.x * x + normal.y * y + normal.z * z + constant > 0;
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
109
|
/** Per level of `inputs`, whether it has an instance list: whether it draws something. */
|
|
129
110
|
export function listedOf(inputs) {
|
|
130
111
|
const empty = emptyLevels(inputs);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lists.js","sourceRoot":"","sources":["../../src/instanced/lists.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"lists.js","sourceRoot":"","sources":["../../src/instanced/lists.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,8 +21,8 @@ export declare const cullScale: import("typegpu").TgpuFn<(origin: d.Vec3f, dista
|
|
|
21
21
|
*/
|
|
22
22
|
export declare const instanceOnScreen: import("typegpu").TgpuFn<(matrix: d.Mat4x4f, source: d.Vec4f, grow: d.F32, eye: d.Vec3f, scale: d.F32, ortho: d.U32) => d.Vec4f>;
|
|
23
23
|
/**
|
|
24
|
-
* The level the instance at `offset` of `matrices` draws most of its pixels with (see `
|
|
25
|
-
*
|
|
24
|
+
* The level the instance at `offset` of `matrices` draws most of its pixels with (see `Lod.getLevelAt`), thinned out
|
|
25
|
+
* by `cull` and seen by `camera`, both in the Lod's space, of the levels of `loaded`, `source` the
|
|
26
26
|
* source's sphere; null if it draws nothing.
|
|
27
27
|
*/
|
|
28
28
|
export declare function instanceLevel(matrices: ArrayLike<number>, offset: number, cull: Cull | null, camera: LocalCamera, source: Sphere, loaded: number): number | null;
|
|
@@ -177,8 +177,8 @@ const toVec3f = ({
|
|
|
177
177
|
z
|
|
178
178
|
}) => d.vec3f(x, y, z);
|
|
179
179
|
/**
|
|
180
|
-
* The level the instance at `offset` of `matrices` draws most of its pixels with (see `
|
|
181
|
-
*
|
|
180
|
+
* The level the instance at `offset` of `matrices` draws most of its pixels with (see `Lod.getLevelAt`), thinned out
|
|
181
|
+
* by `cull` and seen by `camera`, both in the Lod's space, of the levels of `loaded`, `source` the
|
|
182
182
|
* source's sphere; null if it draws nothing.
|
|
183
183
|
*/
|
|
184
184
|
export function instanceLevel(matrices, offset, cull, camera, source, loaded) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Box3, type Camera, type Color, Matrix4, Mesh, type Object3D, type Sphere } from "three/webgpu";
|
|
1
|
+
import { type Box3, type Camera, type Color, type Layers, Matrix4, Mesh, type Object3D, type Sphere } from "three/webgpu";
|
|
2
2
|
import { type DrawnInstances, type InstanceSlots } from "../levels/fade.js";
|
|
3
3
|
import { type IndirectDraw } from "./rows.js";
|
|
4
4
|
/** A mesh of a level's object and one of its material groups, placed in the instance's space. */
|
|
@@ -8,25 +8,27 @@ export interface Part {
|
|
|
8
8
|
group: number;
|
|
9
9
|
draw: IndirectDraw;
|
|
10
10
|
}
|
|
11
|
-
/** What every level mesh of one
|
|
11
|
+
/** What every level mesh of one Lod draws from. */
|
|
12
12
|
export interface MeshInputs {
|
|
13
13
|
/** The instances, which a mesh made later draws too. */
|
|
14
14
|
readonly instances: DrawnInstances;
|
|
15
15
|
/**
|
|
16
|
-
* Around every instance, in the
|
|
16
|
+
* Around every instance, in the Lod's space: what its meshes are culled by, and their box, which three's
|
|
17
17
|
* Box3.setFromObject reads.
|
|
18
18
|
*/
|
|
19
19
|
readonly bounds: Sphere;
|
|
20
20
|
readonly box: Box3;
|
|
21
21
|
/** Per camera, the instances in each level's list and where its indirect draws lie. */
|
|
22
|
-
readonly slots: (camera: Camera) => InstanceSlots;
|
|
22
|
+
readonly slots: (camera: Camera) => InstanceSlots | null;
|
|
23
23
|
/** One instance's bounding radius in its own space, which shadow casters are cut off at. */
|
|
24
24
|
readonly radius: number;
|
|
25
|
+
/** The Lod's layers, which its meshes are on. */
|
|
26
|
+
readonly layers: Layers;
|
|
25
27
|
/**
|
|
26
|
-
* Where `camera`'s indirect draws lie as a mesh
|
|
27
|
-
*
|
|
28
|
+
* Where `camera`'s indirect draws lie as `renderer` draws a mesh for it, its lists sorted: the camera's due sort runs
|
|
29
|
+
* now; null before the Lod's first sort for it. Never throws: three is rendering.
|
|
28
30
|
*/
|
|
29
|
-
readonly drawFor: (renderer: unknown, camera: Camera) => InstanceSlots["args"];
|
|
31
|
+
readonly drawFor: (renderer: unknown, camera: Camera) => InstanceSlots["args"] | null;
|
|
30
32
|
}
|
|
31
33
|
/** `object`'s meshes and material groups, placed once in the instance's space, for level `level`. */
|
|
32
34
|
export declare function partsOf(object: Object3D, level: number): Part[];
|
|
@@ -42,5 +44,5 @@ export interface LevelMeshes {
|
|
|
42
44
|
export declare function levelMeshes(parts: readonly Part[], tint: Color, inputs: MeshInputs): LevelMeshes;
|
|
43
45
|
/** Release `mesh`, which may never have been added. */
|
|
44
46
|
export declare function freeMesh(mesh: Mesh): void;
|
|
45
|
-
/** Point every mesh of `meshes` at `instances
|
|
46
|
-
export declare function
|
|
47
|
+
/** Point every mesh of `meshes` at `instances`, which changed: survivors scale or no longer do, or the attributes were replaced. */
|
|
48
|
+
export declare function drawInstances(meshes: readonly Mesh[], instances: DrawnInstances): void;
|
package/dist/instanced/meshes.js
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
import { BufferGeometry, Matrix4, Mesh } from "three/webgpu";
|
|
1
|
+
import { BufferGeometry, IndirectStorageBufferAttribute, Matrix4, Mesh } from "three/webgpu";
|
|
2
2
|
import { setFadeSource } from "../levels/fade.js";
|
|
3
3
|
import { levelMaterial } from "../levels/material.js";
|
|
4
4
|
import { impostorInstances } from "../impostor/mesh/index.js";
|
|
5
|
-
import { isImpostorMesh, isInstancedMesh, isLOD, isMesh, rejectSkinned } from "../three.js";
|
|
5
|
+
import { isImpostorMesh, isInstancedMesh, isLOD, isLine, isMesh, isPoints, isSprite, rejectSkinned } from "../three.js";
|
|
6
6
|
import { DRAW_BYTES } from "./rows.js";
|
|
7
|
-
// The meshes that draw
|
|
7
|
+
// The meshes that draw a Lod's level: one plain three Mesh per mesh and material group of its object, or an
|
|
8
8
|
// ImpostorMesh for an impostor, each drawing every instance in its level's list for a camera with one indirect draw.
|
|
9
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);
|
|
10
12
|
/** `object`'s meshes and material groups, placed once in the instance's space, for level `level`. */
|
|
11
13
|
export function partsOf(object, level) {
|
|
12
|
-
rejectSkinned(object, "
|
|
14
|
+
rejectSkinned(object, "Lod");
|
|
13
15
|
object.updateWorldMatrix(true, true);
|
|
14
16
|
const outside = object.parent ? object.parent.matrixWorld.clone().invert() : new Matrix4();
|
|
15
17
|
const found = [];
|
|
16
18
|
object.traverse((node) => {
|
|
17
19
|
if (isLOD(node))
|
|
18
|
-
throw new Error(
|
|
20
|
+
throw new Error(`Lod: levels cannot contain a LOD ("${node.name}")`);
|
|
19
21
|
if (isInstancedMesh(node) && !isImpostorMesh(node))
|
|
20
|
-
throw new Error(`
|
|
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}"`);
|
|
21
25
|
if (!isMesh(node))
|
|
22
26
|
return;
|
|
23
27
|
const placement = outside.clone().multiply(node.matrixWorld);
|
|
@@ -49,28 +53,29 @@ export function levelMeshes(parts, tint, inputs) {
|
|
|
49
53
|
}
|
|
50
54
|
/** Release `mesh`, which may never have been added. */
|
|
51
55
|
export function freeMesh(mesh) {
|
|
52
|
-
// ImpostorMesh.dispose also destroys its instance buffers, which are the
|
|
56
|
+
// ImpostorMesh.dispose also destroys its instance buffers, which are the Lod's.
|
|
53
57
|
if (isImpostorMesh(mesh))
|
|
54
58
|
mesh.material.release();
|
|
55
59
|
mesh.geometry.dispose();
|
|
56
60
|
}
|
|
57
|
-
/** Point every mesh of `meshes` at `instances
|
|
58
|
-
export function
|
|
59
|
-
for (const mesh of meshes)
|
|
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) {
|
|
60
64
|
if (isImpostorMesh(mesh))
|
|
61
65
|
mesh.instanceMatrix = instances.matrices;
|
|
66
|
+
Object.assign(mesh, { instanceColor: instances.colors });
|
|
67
|
+
}
|
|
62
68
|
}
|
|
63
69
|
/**
|
|
64
70
|
* Material group `group` of `template` drawn for every instance in level `level`'s list, from byte `offset()` of a
|
|
65
|
-
* camera's draws, once there is one.
|
|
71
|
+
* camera's draws, once there is one, on the Lod's layers. Only the Lod's raycast hits its instances.
|
|
66
72
|
*/
|
|
67
73
|
function levelMesh({ template, placement, group }, offset, tint, inputs) {
|
|
68
|
-
const { instances, bounds, box, slots, radius, drawFor } = inputs;
|
|
74
|
+
const { instances, bounds, box, slots, radius, layers, drawFor } = inputs;
|
|
69
75
|
// An impostor card is placed in the shader; any other mesh draws its geometry moved into the instance's space, so
|
|
70
76
|
// the instance matrix is all it needs.
|
|
71
77
|
const mesh = isImpostorMesh(template) ? card(template, placement, inputs) : plain(template, placement, group, instances);
|
|
72
78
|
setFadeSource(mesh, {
|
|
73
|
-
kind: "instances",
|
|
74
79
|
slots,
|
|
75
80
|
radius,
|
|
76
81
|
tint,
|
|
@@ -79,6 +84,8 @@ function levelMesh({ template, placement, group }, offset, tint, inputs) {
|
|
|
79
84
|
mesh.name = template.name;
|
|
80
85
|
mesh.castShadow = template.castShadow;
|
|
81
86
|
mesh.receiveShadow = template.receiveShadow;
|
|
87
|
+
mesh.layers = layers;
|
|
88
|
+
mesh.raycast = () => { };
|
|
82
89
|
if (!isImpostorMesh(mesh))
|
|
83
90
|
mesh.geometry.boundingSphere = bounds;
|
|
84
91
|
mesh.geometry.boundingBox = box;
|
|
@@ -91,7 +98,10 @@ function levelMesh({ template, placement, group }, offset, tint, inputs) {
|
|
|
91
98
|
if (start === null)
|
|
92
99
|
return;
|
|
93
100
|
const args = drawFor(renderer, camera);
|
|
94
|
-
|
|
101
|
+
if (args)
|
|
102
|
+
mesh.geometry.setIndirect(args.attribute, args.offset + start);
|
|
103
|
+
else
|
|
104
|
+
mesh.geometry.setIndirect(NOTHING, 0);
|
|
95
105
|
};
|
|
96
106
|
return mesh;
|
|
97
107
|
}
|
|
@@ -127,11 +137,11 @@ function groupMaterial(mesh, group) {
|
|
|
127
137
|
const index = mesh.geometry.groups[group]?.materialIndex ?? 0;
|
|
128
138
|
const material = mesh.material[index];
|
|
129
139
|
if (!material)
|
|
130
|
-
throw new Error(`
|
|
140
|
+
throw new Error(`Lod: "${mesh.name}" has no material ${index}`);
|
|
131
141
|
return levelMaterial(material);
|
|
132
142
|
}
|
|
133
143
|
/**
|
|
134
|
-
* Placed copies of geometries, shared by every
|
|
144
|
+
* Placed copies of geometries, shared by every Lod drawing the same mesh the same way: a side table, as three's
|
|
135
145
|
* BufferGeometry has no room for a package's state.
|
|
136
146
|
*/
|
|
137
147
|
const copies = new WeakMap();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meshes.js","sourceRoot":"","sources":["../../src/instanced/meshes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,cAAc,EAA2B,OAAO,EAAE,IAAI,EAA8B,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"meshes.js","sourceRoot":"","sources":["../../src/instanced/meshes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
/**
|
|
3
|
-
* A storage attribute over a CPU chunk attribute's array, which the page pool reads it through, uploading what the app
|
|
4
|
-
* marks changed in it: binding the app's own attribute through storage() would flag it as a storage attribute, which
|
|
5
|
-
* three then pads (an RGB colour to four floats) and treats as one wherever else the app draws it.
|
|
6
|
-
*/
|
|
1
|
+
import { StorageInstancedBufferAttribute, type InstancedBufferAttribute } from "three/webgpu";
|
|
2
|
+
/** A CPU instanceMatrix's mirror, over the source's own array. */
|
|
7
3
|
export declare class Mirror {
|
|
8
4
|
readonly source: InstancedBufferAttribute;
|
|
9
|
-
|
|
10
|
-
readonly attribute: StorageBufferAttribute;
|
|
5
|
+
readonly attribute: StorageInstancedBufferAttribute;
|
|
11
6
|
/** The source's version it last took in. */
|
|
12
7
|
private version;
|
|
13
8
|
constructor(source: InstancedBufferAttribute);
|
|
14
|
-
/**
|
|
15
|
-
* Take in the source's edits, whose array it shares: upload the ranges the app marked changed (all of it without any),
|
|
16
|
-
* which three would upload and clear were it drawing the source itself. Whether the source changed.
|
|
17
|
-
*/
|
|
9
|
+
/** Take in the source's edits: the ranges the app marked changed, all of it without any. Whether it changed. */
|
|
18
10
|
refresh(): boolean;
|
|
19
11
|
dispose(): void;
|
|
20
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
|
+
}
|
package/dist/instanced/mirror.js
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*/
|
|
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
7
|
export class Mirror {
|
|
8
8
|
source;
|
|
9
|
-
/** A matrix per item, or floats one by one, which three never pads. */
|
|
10
9
|
attribute;
|
|
11
10
|
/** The source's version it last took in. */
|
|
12
11
|
version;
|
|
13
12
|
constructor(source) {
|
|
14
13
|
this.source = source;
|
|
15
|
-
this.attribute = new
|
|
14
|
+
this.attribute = new StorageInstancedBufferAttribute(source.array, 16);
|
|
16
15
|
this.version = source.version;
|
|
17
16
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Take in the source's edits, whose array it shares: upload the ranges the app marked changed (all of it without any),
|
|
20
|
-
* which three would upload and clear were it drawing the source itself. Whether the source changed.
|
|
21
|
-
*/
|
|
17
|
+
/** Take in the source's edits: the ranges the app marked changed, all of it without any. Whether it changed. */
|
|
22
18
|
refresh() {
|
|
23
19
|
const { source, attribute } = this;
|
|
24
20
|
if (source.version === this.version)
|
|
@@ -34,4 +30,47 @@ export class Mirror {
|
|
|
34
30
|
this.attribute.dispose();
|
|
35
31
|
}
|
|
36
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
|
+
}
|
|
37
76
|
//# sourceMappingURL=mirror.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../src/instanced/mirror.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../src/instanced/mirror.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { Sphere, type Intersection, type Object3D, type Raycaster } from "three/webgpu";
|
|
2
|
-
import type { InstancedLodChunk } from "./chunk.js";
|
|
3
2
|
import type { Part } from "./meshes.js";
|
|
4
|
-
/** A
|
|
5
|
-
export interface InstancedLodIntersection extends Intersection {
|
|
6
|
-
instanceId: number;
|
|
7
|
-
chunk: InstancedLodChunk;
|
|
8
|
-
}
|
|
9
|
-
/** An InstancedLod's source level as a raycast meets it: its parts, and the sphere around every level in an instance's space. */
|
|
3
|
+
/** A Lod's source level as a raycast meets it: its parts, and the sphere around every level in an instance's space. */
|
|
10
4
|
export interface RaycastSource {
|
|
11
5
|
readonly parts: readonly Part[];
|
|
12
6
|
readonly rest: Sphere;
|
|
13
7
|
}
|
|
14
|
-
/**
|
|
15
|
-
|
|
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;
|
|
@@ -6,28 +6,25 @@ const sphere = new Sphere();
|
|
|
6
6
|
const instance = new Matrix4();
|
|
7
7
|
const world = new Matrix4();
|
|
8
8
|
const hits = [];
|
|
9
|
-
/**
|
|
10
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Hits on the first `count` instances of `matrices`, `lod`'s, of `source`'s meshes, each raycast where an instance
|
|
11
|
+
* stands, with `instanceId` set as on an InstancedMesh's hits.
|
|
12
|
+
*/
|
|
13
|
+
export function raycastInstances(lod, source, matrices, count, raycaster, intersects) {
|
|
11
14
|
ray.copy(raycaster.ray).applyMatrix4(inverse.copy(lod.matrixWorld).invert());
|
|
12
15
|
// A mesh of several material groups is a part per group: it is hit once. A mesh's parts share its placement.
|
|
13
16
|
const meshes = new Map();
|
|
14
17
|
for (const { template, placement } of source.parts)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
for (const hit of hitsAt(mesh, world.multiplyMatrices(lod.matrixWorld, instance).multiply(placement), raycaster)) {
|
|
26
|
-
const found = Object.assign(hit, { object: lod, instanceId: index, chunk });
|
|
27
|
-
intersects.push(found);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
18
|
+
meshes.set(template, placement);
|
|
19
|
+
for (let index = 0; index < count; index++) {
|
|
20
|
+
instance.fromArray(matrices, index * 16);
|
|
21
|
+
sphere.center.copy(source.rest.center).applyMatrix4(instance);
|
|
22
|
+
sphere.radius = source.rest.radius * stretch(instance);
|
|
23
|
+
if (sphere.radius === 0 || !ray.intersectsSphere(sphere))
|
|
24
|
+
continue;
|
|
25
|
+
for (const [mesh, placement] of meshes)
|
|
26
|
+
for (const hit of hitsAt(mesh, world.multiplyMatrices(lod.matrixWorld, instance).multiply(placement), raycaster))
|
|
27
|
+
intersects.push({ ...hit, object: lod, instanceId: index });
|
|
31
28
|
}
|
|
32
29
|
}
|
|
33
30
|
/** `mesh`'s own raycast, as if it stood at `matrixWorld`. */
|