@drawcall/lod 0.1.2 → 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 +13 -70
- package/dist/at.d.ts +2 -0
- package/dist/at.js +8 -0
- package/dist/at.js.map +1 -0
- 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 +5 -5
- package/dist/baked/codec.js +58 -158
- 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 +16 -6
- package/dist/baked/index.js +23 -21
- 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.d.ts +2 -2
- package/dist/baked/low.js +9 -8
- 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/codec/mesh.js +220 -0
- package/dist/codec/mesh.js.map +1 -0
- package/dist/dispose.d.ts +11 -4
- package/dist/dispose.js +39 -12
- 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 +23 -14
- package/dist/impostor/bake/index.js +42 -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 +60 -12
- 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 +5 -11
- package/dist/impostor/codec.js +37 -121
- 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 +11 -8
- package/dist/impostor/mesh/card.js.map +1 -1
- package/dist/impostor/mesh/index.d.ts +10 -7
- package/dist/impostor/mesh/index.js +15 -18
- package/dist/impostor/mesh/index.js.map +1 -1
- package/dist/impostor/mesh/material.d.ts +24 -13
- package/dist/impostor/mesh/material.js +67 -51
- package/dist/impostor/mesh/material.js.map +1 -1
- package/dist/impostor/mesh/surface.d.ts +20 -16
- package/dist/impostor/mesh/surface.js +81 -58
- 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/impostor/octahedral.d.ts +1 -8
- package/dist/impostor/octahedral.js +3 -18
- package/dist/impostor/octahedral.js.map +1 -1
- package/dist/index.d.ts +16 -10
- package/dist/index.js +14 -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 -92
- package/dist/instanced/index.js +229 -512
- 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 +46 -14
- package/dist/instanced/meshes.js +137 -22
- 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 +15 -0
- package/dist/instanced/raycast.js +46 -0
- package/dist/instanced/raycast.js.map +1 -0
- 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} +13 -7
- 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 +12 -15
- package/dist/loader/cache.js +64 -33
- 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/dependencies.d.ts +32 -0
- package/dist/loader/dependencies.js +113 -0
- 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 +16 -0
- package/dist/loader/url.js +35 -0
- package/dist/loader/url.js.map +1 -0
- package/dist/lod.d.ts +79 -49
- package/dist/lod.js +209 -153
- 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} +42 -22
- package/dist/simplify/index.js.map +1 -0
- package/dist/{bounds.d.ts → source/detail.d.ts} +4 -13
- package/dist/{bounds.js → source/detail.js} +62 -32
- package/dist/source/detail.js.map +1 -0
- package/dist/source/{error.d.ts → deviation.d.ts} +3 -3
- package/dist/source/{error.js → deviation.js} +12 -12
- package/dist/source/deviation.js.map +1 -0
- 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 +2 -2
- package/dist/source/source.js +2 -2
- 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 +20 -19
- package/dist/three.js +29 -35
- package/dist/three.js.map +1 -1
- package/dist/tsl.d.ts +10 -14
- package/dist/tsl.js +12 -47
- 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 +4 -4
- package/dist/wind/index.js +43 -40
- package/dist/wind/index.js.map +1 -1
- package/dist/wind/sway.d.ts +4 -1
- package/dist/wind/sway.js +4 -1
- package/dist/wind/sway.js.map +1 -1
- package/package.json +24 -8
- package/skills/lod/SKILL.md +147 -108
- package/dist/bounds.js.map +0 -1
- package/dist/fade.d.ts +0 -44
- package/dist/fade.js +0 -78
- package/dist/fade.js.map +0 -1
- package/dist/impostor/cache.d.ts +0 -15
- package/dist/impostor/cache.js +0 -44
- package/dist/impostor/cache.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/bounds.d.ts +0 -50
- package/dist/instanced/bounds.js +0 -271
- package/dist/instanced/bounds.js.map +0 -1
- package/dist/instanced/dirty.d.ts +0 -12
- package/dist/instanced/dirty.js +0 -61
- package/dist/instanced/dirty.js.map +0 -1
- package/dist/instanced/select.d.ts +0 -84
- package/dist/instanced/select.js +0 -264
- package/dist/instanced/select.js.map +0 -1
- package/dist/lazy.d.ts +0 -64
- package/dist/lazy.js +0 -187
- package/dist/lazy.js.map +0 -1
- package/dist/levels.d.ts +0 -72
- package/dist/levels.js +0 -146
- package/dist/levels.js.map +0 -1
- package/dist/loader/dispose.d.ts +0 -3
- package/dist/loader/dispose.js +0 -25
- package/dist/loader/dispose.js.map +0 -1
- package/dist/loader.d.ts +0 -99
- package/dist/loader.js +0 -234
- package/dist/loader.js.map +0 -1
- package/dist/material.js.map +0 -1
- package/dist/pause.d.ts +0 -6
- package/dist/pause.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/simplify.js.map +0 -1
- package/dist/source/error.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 -30
- package/dist/view.js +0 -75
- package/dist/view.js.map +0 -1
- /package/dist/{material.d.ts → levels/material.d.ts} +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Box3, Vector3 } from "three/webgpu";
|
|
2
|
+
import { MeshoptSimplifier } from "meshoptimizer";
|
|
3
|
+
import { at } from "../at.js";
|
|
4
|
+
import { triangleArea } from "../source/surface.js";
|
|
5
|
+
import { isTexture } from "../three.js";
|
|
6
|
+
// Simplifying cards: the alpha-tested quads foliage draws (needles, leaves), which simplify decimates card by card rather
|
|
7
|
+
// than collapsing their edges.
|
|
8
|
+
/** Per material of `mesh`, whether it alpha-tests a texture, so draws cards. */
|
|
9
|
+
export function cardMaterials(mesh) {
|
|
10
|
+
const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
|
|
11
|
+
return materials.map((m) => m.alphaTest > 0 && ["map" in m && m.map, "alphaMap" in m && m.alphaMap].some(isTexture));
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* About `ratio` of the cards (connected parts, touching where vertices share a position)
|
|
15
|
+
* of the triangles `indices`, spread evenly over them by meshopt's point simplifier on the
|
|
16
|
+
* cards' centres. Each picked card is enlarged about its centre, in `positions`, so the picked
|
|
17
|
+
* cards cover as much area as all did; a card larger than most grows only as far as a
|
|
18
|
+
* card of the median size does, or a long spray would reach far out of the crown, and no
|
|
19
|
+
* card grows past the bounds of all, which a level must stay inside.
|
|
20
|
+
* Edge collapse would instead shrink and warp each card, and so cut most of an
|
|
21
|
+
* alpha-tested texture (needles, leaves) away.
|
|
22
|
+
*/
|
|
23
|
+
export function decimateCards(indices, positions, ratio) {
|
|
24
|
+
const { card, count } = cards(indices, positions);
|
|
25
|
+
const corner = (t, k) => indices[t * 3 + k] ?? 0;
|
|
26
|
+
const point = new Vector3();
|
|
27
|
+
const area = new Float64Array(count);
|
|
28
|
+
const centre = Array.from({ length: count }, () => new Vector3());
|
|
29
|
+
const corners = new Uint32Array(count);
|
|
30
|
+
card.forEach((c, t) => {
|
|
31
|
+
area[c] = (area[c] ?? 0) + triangleArea(positions, 3, indices, t * 3);
|
|
32
|
+
for (let k = 0; k < 3; k++)
|
|
33
|
+
at(centre, c).add(point.fromArray(positions, corner(t, k) * 3));
|
|
34
|
+
corners[c] = (corners[c] ?? 0) + 3;
|
|
35
|
+
});
|
|
36
|
+
centre.forEach((p, c) => p.divideScalar(corners[c] ?? 1));
|
|
37
|
+
const radius = new Float64Array(count);
|
|
38
|
+
const box = Array.from({ length: count }, () => new Box3());
|
|
39
|
+
const bounds = new Box3();
|
|
40
|
+
card.forEach((c, t) => {
|
|
41
|
+
for (let k = 0; k < 3; k++) {
|
|
42
|
+
point.fromArray(positions, corner(t, k) * 3);
|
|
43
|
+
radius[c] = Math.max(radius[c] ?? 0, point.distanceTo(at(centre, c)));
|
|
44
|
+
at(box, c).expandByPoint(point);
|
|
45
|
+
bounds.expandByPoint(point);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const median = Float64Array.from(radius).sort()[count >> 1] ?? 0;
|
|
49
|
+
// The most each card can grow about its centre and stay inside `bounds`.
|
|
50
|
+
const fit = centre.map((p, c) => {
|
|
51
|
+
const { min, max } = at(box, c);
|
|
52
|
+
let most = Infinity;
|
|
53
|
+
for (const axis of ["x", "y", "z"]) {
|
|
54
|
+
if (max[axis] > p[axis])
|
|
55
|
+
most = Math.min(most, (bounds.max[axis] - p[axis]) / (max[axis] - p[axis]));
|
|
56
|
+
if (min[axis] < p[axis])
|
|
57
|
+
most = Math.min(most, (p[axis] - bounds.min[axis]) / (p[axis] - min[axis]));
|
|
58
|
+
}
|
|
59
|
+
return Math.max(1, most);
|
|
60
|
+
});
|
|
61
|
+
const picked = new Uint8Array(count);
|
|
62
|
+
const target = Math.max(1, Math.round(count * ratio));
|
|
63
|
+
const points = Float32Array.from(centre.flatMap((p) => p.toArray()));
|
|
64
|
+
for (const c of target < count ? MeshoptSimplifier.simplifyPoints(points, 3, target) : picked.keys())
|
|
65
|
+
picked[c] = 1;
|
|
66
|
+
// `scale` enlarges a median card; bisect for the one at which the picked cards cover what all did.
|
|
67
|
+
const grow = (c, scale) => Math.min(scale, fit[c] ?? 1, Math.max(1, (scale * median) / Math.max(radius[c] ?? 0, 1e-30)));
|
|
68
|
+
const covered = (scale) => area.reduce((sum, a, c) => sum + (picked[c] ? a * grow(c, scale) ** 2 : 0), 0);
|
|
69
|
+
const total = area.reduce((sum, a) => sum + a, 0);
|
|
70
|
+
let [low, high] = [1, 1];
|
|
71
|
+
while (covered(high) < total && high < 1e6)
|
|
72
|
+
high *= 2;
|
|
73
|
+
for (let i = 0; i < 40; i++) {
|
|
74
|
+
const mid = (low + high) / 2;
|
|
75
|
+
if (covered(mid) < total)
|
|
76
|
+
low = mid;
|
|
77
|
+
else
|
|
78
|
+
high = mid;
|
|
79
|
+
}
|
|
80
|
+
const out = [];
|
|
81
|
+
const moved = new Uint8Array(positions.length / 3);
|
|
82
|
+
card.forEach((c, t) => {
|
|
83
|
+
if (!picked[c])
|
|
84
|
+
return;
|
|
85
|
+
const p = at(centre, c);
|
|
86
|
+
for (let k = 0; k < 3; k++) {
|
|
87
|
+
const v = corner(t, k);
|
|
88
|
+
out.push(v);
|
|
89
|
+
if (moved[v])
|
|
90
|
+
continue;
|
|
91
|
+
moved[v] = 1;
|
|
92
|
+
point
|
|
93
|
+
.fromArray(positions, v * 3)
|
|
94
|
+
.sub(p)
|
|
95
|
+
.multiplyScalar(grow(c, high))
|
|
96
|
+
.add(p)
|
|
97
|
+
.toArray(positions, v * 3);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return Uint32Array.from(out);
|
|
101
|
+
}
|
|
102
|
+
/** The card of each triangle, numbered 0..count-1. */
|
|
103
|
+
function cards(indices, positions) {
|
|
104
|
+
const remap = MeshoptSimplifier.generatePositionRemap(positions, 3);
|
|
105
|
+
const parent = Uint32Array.from(remap.keys());
|
|
106
|
+
const root = (vertex) => {
|
|
107
|
+
let v = remap[vertex] ?? vertex;
|
|
108
|
+
while (parent[v] !== v)
|
|
109
|
+
v = parent[v] = parent[parent[v] ?? v] ?? v;
|
|
110
|
+
return v;
|
|
111
|
+
};
|
|
112
|
+
for (let i = 0; i < indices.length; i += 3) {
|
|
113
|
+
const a = root(indices[i] ?? 0);
|
|
114
|
+
parent[root(indices[i + 1] ?? 0)] = a;
|
|
115
|
+
parent[root(indices[i + 2] ?? 0)] = a;
|
|
116
|
+
}
|
|
117
|
+
const number = new Map();
|
|
118
|
+
const card = new Uint32Array(indices.length / 3);
|
|
119
|
+
for (let t = 0; t < card.length; t++) {
|
|
120
|
+
const r = root(indices[t * 3] ?? 0);
|
|
121
|
+
let c = number.get(r);
|
|
122
|
+
if (c === undefined)
|
|
123
|
+
number.set(r, (c = number.size));
|
|
124
|
+
card[t] = c;
|
|
125
|
+
}
|
|
126
|
+
return { card, count: number.size };
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=cards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cards.js","sourceRoot":"","sources":["../../src/simplify/cards.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { type Object3D } from "three/webgpu";
|
|
2
2
|
export interface SimplifyOptions {
|
|
3
|
-
/** share of each mesh's triangles
|
|
3
|
+
/** share of each mesh's triangles that remains, in (0, 1]; default 0.5 */
|
|
4
4
|
ratio?: number;
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* A copy of `object` with the geometry of every mesh drawn at full detail decimated by
|
|
8
8
|
* meshoptimizer to about `ratio` of its triangles: of a nested LOD only level 0 (its other
|
|
9
|
-
* levels are
|
|
9
|
+
* levels stay as they are), of an InstancedMesh the geometry its instances share. Materials (and
|
|
10
10
|
* so textures) are the originals, shared with `object`. Meshes that share a geometry
|
|
11
11
|
* share the simplified one. Morph targets are dropped. ImpostorMeshes and hidden meshes
|
|
12
|
-
*
|
|
12
|
+
* stay as they are. Skinned meshes and InstancedLods are refused: simplify an
|
|
13
13
|
* InstancedLod's source and build a new InstancedLod of it.
|
|
14
14
|
*
|
|
15
|
-
* Per material group it
|
|
15
|
+
* Per material group it preserves UV and normal seams; if that cannot reach the target it
|
|
16
16
|
* lets seams collapse, and as a last resort ignores topology (meshopt's sloppy mode).
|
|
17
|
+
* A group drawn with an alpha-tested texture (foliage cards) is decimated card by card
|
|
18
|
+
* instead: about `ratio` of its cards remain, whole, spread evenly and enlarged to cover
|
|
19
|
+
* what all covered (see `decimateCards`).
|
|
17
20
|
*
|
|
18
21
|
* How far the copy's surface is from `object`'s (the 99.9th percentile of the distance
|
|
19
22
|
* between the two, by area, over the parts seen from outside; ImpostorMeshes left out)
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
import { BufferAttribute, BufferGeometry } from "three/webgpu";
|
|
2
2
|
import { mergeVertices } from "three/addons/utils/BufferGeometryUtils.js";
|
|
3
3
|
import { MeshoptSimplifier } from "meshoptimizer";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { readSource } from "
|
|
8
|
-
import { merge } from "
|
|
9
|
-
import { isImpostorMesh, isInstancedLod, isMesh, isSkinnedMesh } from "
|
|
4
|
+
import { recordDeviation } from "../levels/index.js";
|
|
5
|
+
import { detailed } from "../source/detail.js";
|
|
6
|
+
import { measureDeviation } from "../source/deviation.js";
|
|
7
|
+
import { readSource } from "../source/source.js";
|
|
8
|
+
import { merge } from "../source/surface.js";
|
|
9
|
+
import { isImpostorMesh, isInstancedLod, isMesh, isSkinnedMesh } from "../three.js";
|
|
10
|
+
import { cardMaterials, decimateCards } from "./cards.js";
|
|
10
11
|
/**
|
|
11
12
|
* A copy of `object` with the geometry of every mesh drawn at full detail decimated by
|
|
12
13
|
* meshoptimizer to about `ratio` of its triangles: of a nested LOD only level 0 (its other
|
|
13
|
-
* levels are
|
|
14
|
+
* levels stay as they are), of an InstancedMesh the geometry its instances share. Materials (and
|
|
14
15
|
* so textures) are the originals, shared with `object`. Meshes that share a geometry
|
|
15
16
|
* share the simplified one. Morph targets are dropped. ImpostorMeshes and hidden meshes
|
|
16
|
-
*
|
|
17
|
+
* stay as they are. Skinned meshes and InstancedLods are refused: simplify an
|
|
17
18
|
* InstancedLod's source and build a new InstancedLod of it.
|
|
18
19
|
*
|
|
19
|
-
* Per material group it
|
|
20
|
+
* Per material group it preserves UV and normal seams; if that cannot reach the target it
|
|
20
21
|
* lets seams collapse, and as a last resort ignores topology (meshopt's sloppy mode).
|
|
22
|
+
* A group drawn with an alpha-tested texture (foliage cards) is decimated card by card
|
|
23
|
+
* instead: about `ratio` of its cards remain, whole, spread evenly and enlarged to cover
|
|
24
|
+
* what all covered (see `decimateCards`).
|
|
21
25
|
*
|
|
22
26
|
* How far the copy's surface is from `object`'s (the 99.9th percentile of the distance
|
|
23
27
|
* between the two, by area, over the parts seen from outside; ImpostorMeshes left out)
|
|
@@ -25,7 +29,7 @@ import { isImpostorMesh, isInstancedLod, isMesh, isSkinnedMesh } from "./three.j
|
|
|
25
29
|
*/
|
|
26
30
|
export async function simplify(object, options = {}) {
|
|
27
31
|
const copy = await decimate(object, options.ratio ?? 0.5);
|
|
28
|
-
|
|
32
|
+
recordDeviation(copy, measureDeviation(readSource(object, "simplify", "measure"), merge(copy, "simplify")).deviation);
|
|
29
33
|
return copy;
|
|
30
34
|
}
|
|
31
35
|
/** A copy of `object` decimated to `ratio`, as `simplify` makes it, without measuring it. */
|
|
@@ -33,7 +37,7 @@ export async function decimate(object, ratio) {
|
|
|
33
37
|
if (!(ratio > 0 && ratio <= 1))
|
|
34
38
|
throw new Error(`simplify: ratio must be in (0, 1], got ${ratio}`);
|
|
35
39
|
await MeshoptSimplifier.ready;
|
|
36
|
-
// clone() also visits hidden children, whose
|
|
40
|
+
// clone() also visits hidden children, whose InstancedLod allocations must never be
|
|
37
41
|
// created just to reject them (or skipped by the visible-detail walk below).
|
|
38
42
|
object.traverse((node) => {
|
|
39
43
|
if (isInstancedLod(node))
|
|
@@ -45,18 +49,23 @@ export async function decimate(object, ratio) {
|
|
|
45
49
|
decimateTree(copy, ratio, new Map());
|
|
46
50
|
return copy;
|
|
47
51
|
}
|
|
48
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Decimate the meshes of `node` drawn at full detail; `done` maps each geometry, with
|
|
54
|
+
* which of its material indices are cards, to its simplified one.
|
|
55
|
+
*/
|
|
49
56
|
function decimateTree(node, ratio, done) {
|
|
50
57
|
if (isMesh(node) && !isImpostorMesh(node)) {
|
|
51
|
-
|
|
58
|
+
const cards = cardMaterials(node);
|
|
59
|
+
const key = `${node.geometry.uuid} ${cards.join()}`;
|
|
60
|
+
let geometry = done.get(key);
|
|
52
61
|
if (!geometry)
|
|
53
|
-
done.set(
|
|
62
|
+
done.set(key, (geometry = simplifyGeometry(node.geometry, ratio, cards)));
|
|
54
63
|
node.geometry = geometry;
|
|
55
64
|
}
|
|
56
65
|
for (const child of detailed(node))
|
|
57
66
|
decimateTree(child, ratio, done);
|
|
58
67
|
}
|
|
59
|
-
function simplifyGeometry(source, ratio) {
|
|
68
|
+
function simplifyGeometry(source, ratio, cards) {
|
|
60
69
|
const geometry = source.index ? source : mergeVertices(source);
|
|
61
70
|
const index = geometry.index;
|
|
62
71
|
if (!index)
|
|
@@ -65,12 +74,20 @@ function simplifyGeometry(source, ratio) {
|
|
|
65
74
|
const { attributes, stride, weights } = simplifierAttributes(geometry);
|
|
66
75
|
const groups = geometry.groups.length > 0 ? geometry.groups : [{ start: 0, count: index.count, materialIndex: 0 }];
|
|
67
76
|
const parts = [];
|
|
77
|
+
let decimatedCards = false;
|
|
68
78
|
for (const group of groups) {
|
|
69
79
|
const indices = new Uint32Array(Math.min(group.count, index.count - group.start));
|
|
70
80
|
for (let i = 0; i < indices.length; i++)
|
|
71
81
|
indices[i] = index.getX(group.start + i);
|
|
72
|
-
const
|
|
73
|
-
|
|
82
|
+
const materialIndex = group.materialIndex ?? 0;
|
|
83
|
+
// A single material draws every group.
|
|
84
|
+
const card = (cards.length === 1 ? cards[0] : cards[materialIndex]) ?? false;
|
|
85
|
+
if (card)
|
|
86
|
+
decimatedCards = true;
|
|
87
|
+
const simplified = card
|
|
88
|
+
? decimateCards(indices, positions, ratio)
|
|
89
|
+
: simplifyIndices(indices, positions, attributes, stride, weights, Math.floor((indices.length / 3) * ratio) * 3)[0];
|
|
90
|
+
parts.push({ indices: simplified, materialIndex });
|
|
74
91
|
}
|
|
75
92
|
const all = new Uint32Array(parts.reduce((n, p) => n + p.indices.length, 0));
|
|
76
93
|
const out = new BufferGeometry();
|
|
@@ -82,8 +99,11 @@ function simplifyGeometry(source, ratio) {
|
|
|
82
99
|
offset += part.indices.length;
|
|
83
100
|
}
|
|
84
101
|
const [remap, unique] = MeshoptSimplifier.compactMesh(all); // rewrites `all` in place
|
|
85
|
-
for (const [name, attribute] of Object.entries(geometry.attributes))
|
|
86
|
-
|
|
102
|
+
for (const [name, attribute] of Object.entries(geometry.attributes)) {
|
|
103
|
+
// decimateCards moved the remaining cards' vertices, past the range a quantized position may hold.
|
|
104
|
+
const from = name === "position" && decimatedCards ? new BufferAttribute(positions, 3) : attribute;
|
|
105
|
+
out.setAttribute(name, compactAttribute(from, remap, unique));
|
|
106
|
+
}
|
|
87
107
|
out.setIndex(new BufferAttribute(all, 1));
|
|
88
108
|
out.computeBoundingBox();
|
|
89
109
|
out.computeBoundingSphere();
|
|
@@ -98,7 +118,7 @@ function simplifyIndices(indices, positions, attributes, stride, weights, target
|
|
|
98
118
|
if (reached(permissive[0]))
|
|
99
119
|
return permissive;
|
|
100
120
|
const sloppy = MeshoptSimplifier.simplifySloppy(indices, positions, 3, null, target, 1);
|
|
101
|
-
// Sloppy can collapse a tiny target to nothing; then
|
|
121
|
+
// Sloppy can collapse a tiny target to nothing; then use the permissive result.
|
|
102
122
|
return sloppy[0].length > 0 ? sloppy : permissive;
|
|
103
123
|
}
|
|
104
124
|
/** Normal (weight 0.5) and UV (weight 1) packed per vertex for simplifyWithAttributes. */
|
|
@@ -124,7 +144,7 @@ function simplifierAttributes(geometry) {
|
|
|
124
144
|
}
|
|
125
145
|
function compactAttribute(attribute, remap, unique) {
|
|
126
146
|
const size = attribute.itemSize;
|
|
127
|
-
// A slice
|
|
147
|
+
// A slice has the array's type, so normalized and integer attributes hold their encoding;
|
|
128
148
|
// every element is written below (unique <= count, so it is long enough).
|
|
129
149
|
const out = new BufferAttribute(attribute.array.slice(0, unique * size), size, attribute.normalized);
|
|
130
150
|
for (let i = 0; i < remap.length; i++) {
|
|
@@ -145,4 +165,4 @@ function toFloat32(attribute) {
|
|
|
145
165
|
}
|
|
146
166
|
return out;
|
|
147
167
|
}
|
|
148
|
-
//# sourceMappingURL=
|
|
168
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/simplify/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Box3, Matrix4,
|
|
1
|
+
import { Box3, Matrix4, Vector3, type Mesh, type Object3D } from "three/webgpu";
|
|
2
2
|
/**
|
|
3
3
|
* Call `visit` with every mesh of `root` drawn at full detail, and the matrix that places
|
|
4
4
|
* it in `root`'s own space (`root`'s own transform not applied): `root` itself and its
|
|
@@ -10,6 +10,8 @@ import { Box3, Matrix4, Sphere, Vector3, type Mesh, type Object3D } from "three/
|
|
|
10
10
|
export declare function forEachMesh(root: Object3D, visit: (mesh: Mesh, placement: Matrix4) => void): void;
|
|
11
11
|
/** The children of `node` drawn at full detail: of a LOD its level 0, whatever it shows, else the visible ones. */
|
|
12
12
|
export declare function detailed(node: Object3D): Object3D[];
|
|
13
|
+
/** `node`'s matrix in its parent's space, up to date. */
|
|
14
|
+
export declare function local(node: Object3D): Matrix4;
|
|
13
15
|
/** Show level 0 of every LOD under `root` and stop them switching: a bake sees full detail. */
|
|
14
16
|
export declare function showDetail(root: Object3D): void;
|
|
15
17
|
/**
|
|
@@ -18,16 +20,5 @@ export declare function showDetail(root: Object3D): void;
|
|
|
18
20
|
* an ImpostorMesh. `visit` gets one reused vector.
|
|
19
21
|
*/
|
|
20
22
|
export declare function forEachVertex(root: Object3D, visit: (p: Vector3) => void): void;
|
|
21
|
-
/**
|
|
23
|
+
/** Conservative full-detail bounds from cached geometry boxes and deferred metadata, in the root's space: what a bake measures. */
|
|
22
24
|
export declare function boundingBox(root: Object3D): Box3;
|
|
23
|
-
/** The centre and half diagonal of `boundingBox(root)`: an impostor baked from `root` has the same box. */
|
|
24
|
-
export declare function boundingSphere(root: Object3D): Sphere;
|
|
25
|
-
/**
|
|
26
|
-
* The sphere fades measure for a Lod's levels (see `boundingSphere`): level 0's, or the
|
|
27
|
-
* first level's that draws anything when level 0 draws nothing; `own` in that level's
|
|
28
|
-
* own space, `placed` in its parent's (the Lod's). `who` names the caller in the error.
|
|
29
|
-
*/
|
|
30
|
-
export declare function measureLevels(levels: readonly Object3D[], who: string): {
|
|
31
|
-
own: Sphere;
|
|
32
|
-
placed: Sphere;
|
|
33
|
-
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Box3, Matrix4,
|
|
2
|
-
import { isBatchedMesh, isImpostorMesh, isInstancedLod, isInstancedMesh, isLOD, isMesh } from "
|
|
1
|
+
import { Box3, Matrix4, Vector3 } from "three/webgpu";
|
|
2
|
+
import { isBatchedMesh, isImpostorMesh, isInstancedLod, isInstancedMesh, isLOD, isMesh, isStorageInstanced } from "../three.js";
|
|
3
3
|
// What an object is at full detail: its meshes, where they sit and the vertices they draw.
|
|
4
4
|
/**
|
|
5
5
|
* Call `visit` with every mesh of `root` drawn at full detail, and the matrix that places
|
|
@@ -20,8 +20,8 @@ function walk(node, placement, visit) {
|
|
|
20
20
|
if (!source)
|
|
21
21
|
return;
|
|
22
22
|
const instance = new Matrix4();
|
|
23
|
-
for (
|
|
24
|
-
walk(source, local(source).premultiply(
|
|
23
|
+
for (const { chunk, index } of instancesOf(node))
|
|
24
|
+
walk(source, local(source).premultiply(chunk.getMatrixAt(index, instance)).premultiply(placement), visit);
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
if (isInstancedMesh(node) || isImpostorMesh(node)) {
|
|
@@ -38,11 +38,11 @@ function walk(node, placement, visit) {
|
|
|
38
38
|
export function detailed(node) {
|
|
39
39
|
if (!isLOD(node))
|
|
40
40
|
return node.children.filter((child) => child.visible);
|
|
41
|
-
const source = node.levels[0];
|
|
42
|
-
return source ? [source
|
|
41
|
+
const source = node.levels[0]?.object;
|
|
42
|
+
return source ? [source] : [];
|
|
43
43
|
}
|
|
44
44
|
/** `node`'s matrix in its parent's space, up to date. */
|
|
45
|
-
function local(node) {
|
|
45
|
+
export function local(node) {
|
|
46
46
|
if (node.matrixAutoUpdate)
|
|
47
47
|
node.updateMatrix();
|
|
48
48
|
return node.matrix.clone();
|
|
@@ -55,7 +55,10 @@ export function showDetail(root) {
|
|
|
55
55
|
}
|
|
56
56
|
if (isLOD(root)) {
|
|
57
57
|
root.autoUpdate = false;
|
|
58
|
-
root.levels.forEach((level, i) =>
|
|
58
|
+
root.levels.forEach((level, i) => {
|
|
59
|
+
if (level.object)
|
|
60
|
+
level.object.visible = i === 0;
|
|
61
|
+
});
|
|
59
62
|
}
|
|
60
63
|
for (const child of detailed(root))
|
|
61
64
|
showDetail(child);
|
|
@@ -94,34 +97,61 @@ export function forEachVertex(root, visit) {
|
|
|
94
97
|
visit(mesh.getVertexPosition(i, point).applyMatrix4(placement));
|
|
95
98
|
});
|
|
96
99
|
}
|
|
97
|
-
/**
|
|
100
|
+
/** Conservative full-detail bounds from cached geometry boxes and deferred metadata, in the root's space: what a bake measures. */
|
|
98
101
|
export function boundingBox(root) {
|
|
99
102
|
const box = new Box3();
|
|
100
|
-
|
|
103
|
+
boxes(root, new Matrix4(), box);
|
|
101
104
|
return box;
|
|
102
105
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
function boxes(node, placement, box) {
|
|
107
|
+
if (isInstancedLod(node)) {
|
|
108
|
+
const source = node.levels[0];
|
|
109
|
+
if (!source)
|
|
110
|
+
return;
|
|
111
|
+
// Its level 0 at every instance, as forEachMesh visits them: tighter than its level meshes' box (see InstancedLod).
|
|
112
|
+
// The box it declares, else the one it draws.
|
|
113
|
+
const own = source.box?.clone() ?? (source.object ? boundingBox(source.object).applyMatrix4(local(source.object)) : new Box3());
|
|
114
|
+
const instance = new Matrix4();
|
|
115
|
+
for (const { chunk, index } of instancesOf(node))
|
|
116
|
+
box.union(own.clone().applyMatrix4(chunk.getMatrixAt(index, instance).premultiply(placement)));
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (isLOD(node) && !node.levels[0]?.object) {
|
|
120
|
+
const metadata = node.levels[0]?.box;
|
|
121
|
+
if (metadata)
|
|
122
|
+
box.union(metadata.clone().applyMatrix4(placement));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (isMesh(node) && [node.material].flat().some((material) => material.visible && material.colorWrite)) {
|
|
126
|
+
if (isBatchedMesh(node)) {
|
|
127
|
+
if (!node.boundingBox)
|
|
128
|
+
node.computeBoundingBox();
|
|
129
|
+
if (node.boundingBox)
|
|
130
|
+
box.union(node.boundingBox.clone().applyMatrix4(placement));
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
if (!node.geometry.boundingBox)
|
|
134
|
+
node.geometry.computeBoundingBox();
|
|
135
|
+
const own = node.geometry.boundingBox;
|
|
136
|
+
if (own && (isInstancedMesh(node) || isImpostorMesh(node))) {
|
|
137
|
+
const instance = new Matrix4();
|
|
138
|
+
for (let i = 0; i < node.count; i++)
|
|
139
|
+
box.union(own.clone().applyMatrix4(node.getMatrixAt(i, instance).premultiply(placement)));
|
|
140
|
+
}
|
|
141
|
+
else if (own)
|
|
142
|
+
box.union(own.clone().applyMatrix4(placement));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
for (const child of detailed(node))
|
|
146
|
+
boxes(child, local(child).premultiply(placement), box);
|
|
109
147
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
for (const level of levels) {
|
|
118
|
-
const own = sphereOf(boundingBox(level));
|
|
119
|
-
if (!own)
|
|
120
|
-
continue;
|
|
121
|
-
if (level.matrixAutoUpdate)
|
|
122
|
-
level.updateMatrix();
|
|
123
|
-
return { own, placed: own.clone().applyMatrix4(level.matrix) };
|
|
148
|
+
/** Every instance of `lod`'s chunks; a GPU chunk's live on the GPU, where the CPU cannot visit them. */
|
|
149
|
+
function* instancesOf(lod) {
|
|
150
|
+
for (const chunk of lod.chunks) {
|
|
151
|
+
if (isStorageInstanced(chunk.instanceMatrix))
|
|
152
|
+
throw new Error("@drawcall/lod: a GPU chunk's instances live on the GPU: the CPU cannot visit its meshes");
|
|
153
|
+
for (let index = 0; index < chunk.count; index++)
|
|
154
|
+
yield { chunk, index };
|
|
124
155
|
}
|
|
125
|
-
throw new Error(`${who}: no level has visible geometry to measure`);
|
|
126
156
|
}
|
|
127
|
-
//# sourceMappingURL=
|
|
157
|
+
//# sourceMappingURL=detail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detail.js","sourceRoot":"","sources":["../../src/source/detail.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,11 +4,11 @@ import { type Surface } from "./surface.js";
|
|
|
4
4
|
* How far a level's surface `low` is from `source`'s: the distances from points spread
|
|
5
5
|
* evenly by area over each surface to the other, measured with a BVH. Source points
|
|
6
6
|
* nobody sees from outside (a floor inside, the inner side of a partition) are left out:
|
|
7
|
-
* they need no counterpart on the level. `
|
|
7
|
+
* they need no counterpart on the level. `deviation` is the 99.9th percentile of the
|
|
8
8
|
* distances, `widest` the largest. A high percentile, as what a level moves (a part
|
|
9
9
|
* collapsed or cut off) is often a sliver of the area.
|
|
10
10
|
*/
|
|
11
|
-
export declare function
|
|
12
|
-
|
|
11
|
+
export declare function measureDeviation(source: Source, low: Surface): {
|
|
12
|
+
deviation: number;
|
|
13
13
|
widest: number;
|
|
14
14
|
};
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { BufferAttribute, BufferGeometry, Vector3 } from "three/webgpu";
|
|
2
2
|
import { MeshBVH } from "three-mesh-bvh";
|
|
3
|
-
import {
|
|
3
|
+
import { MaterialEvaluator } from "./evaluator.js";
|
|
4
4
|
import { triangleArea } from "./surface.js";
|
|
5
|
-
import {
|
|
6
|
-
/** Points sampled per surface to measure the
|
|
5
|
+
import { SourceRaycaster } from "./raycaster.js";
|
|
6
|
+
/** Points sampled per surface to measure the deviation. */
|
|
7
7
|
const SAMPLES = 20000;
|
|
8
8
|
/**
|
|
9
9
|
* How far a level's surface `low` is from `source`'s: the distances from points spread
|
|
10
10
|
* evenly by area over each surface to the other, measured with a BVH. Source points
|
|
11
11
|
* nobody sees from outside (a floor inside, the inner side of a partition) are left out:
|
|
12
|
-
* they need no counterpart on the level. `
|
|
12
|
+
* they need no counterpart on the level. `deviation` is the 99.9th percentile of the
|
|
13
13
|
* distances, `widest` the largest. A high percentile, as what a level moves (a part
|
|
14
14
|
* collapsed or cut off) is often a sliver of the area.
|
|
15
15
|
*/
|
|
16
|
-
export function
|
|
16
|
+
export function measureDeviation(source, low) {
|
|
17
17
|
const geometry = new BufferGeometry();
|
|
18
18
|
geometry.setAttribute("position", new BufferAttribute(low.positions, 3));
|
|
19
19
|
// The BVH reorders the index it is built on.
|
|
@@ -27,12 +27,12 @@ export function measureError(source, low) {
|
|
|
27
27
|
distances.push(closest(toLow, point));
|
|
28
28
|
});
|
|
29
29
|
const sorted = Float64Array.from(distances).sort();
|
|
30
|
-
return {
|
|
30
|
+
return { deviation: sorted[Math.floor(0.999 * (sorted.length - 1))] ?? 0, widest: sorted[sorted.length - 1] ?? 0 };
|
|
31
31
|
}
|
|
32
32
|
const hit = { point: new Vector3(), distance: 0, faceIndex: 0 };
|
|
33
33
|
function closest(bvh, point) {
|
|
34
34
|
if (!bvh.closestPointToPoint(point, hit))
|
|
35
|
-
throw new Error("@drawcall/lod: no closest point to measure the
|
|
35
|
+
throw new Error("@drawcall/lod: no closest point to measure the deviation by");
|
|
36
36
|
return hit.distance;
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
@@ -46,14 +46,14 @@ function visibility(source) {
|
|
|
46
46
|
const bounds = geometry.boundingSphere;
|
|
47
47
|
if (!bounds)
|
|
48
48
|
throw new Error("@drawcall/lod: the source has no bounds");
|
|
49
|
-
const
|
|
50
|
-
const
|
|
49
|
+
const evaluator = new MaterialEvaluator(source, 0);
|
|
50
|
+
const raycaster = new SourceRaycaster(source, evaluator);
|
|
51
51
|
const normal = new Vector3();
|
|
52
52
|
const corner = new Vector3();
|
|
53
53
|
const origin = new Vector3();
|
|
54
54
|
const epsilon = bounds.radius * 1e-4;
|
|
55
55
|
const far = bounds.radius * 4;
|
|
56
|
-
const escapes = (point, direction) =>
|
|
56
|
+
const escapes = (point, direction) => raycaster.cast(origin.copy(point).addScaledVector(direction, epsilon), direction, far, null) !== "opaque";
|
|
57
57
|
return (point, triangle) => {
|
|
58
58
|
const { positions, index } = source;
|
|
59
59
|
const a = (index[triangle * 3] ?? 0) * 3;
|
|
@@ -62,7 +62,7 @@ function visibility(source) {
|
|
|
62
62
|
normal.cross(corner).normalize();
|
|
63
63
|
if (escapes(point, normal))
|
|
64
64
|
return true;
|
|
65
|
-
return
|
|
65
|
+
return evaluator.material(triangle).doubleSided && escapes(point, normal.negate());
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
/** Call `visit` with points spread evenly by area over `from`, and the triangle of each. */
|
|
@@ -91,4 +91,4 @@ function measure(from, visit) {
|
|
|
91
91
|
visit(point, t);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
-
//# sourceMappingURL=
|
|
94
|
+
//# sourceMappingURL=deviation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deviation.js","sourceRoot":"","sources":["../../src/source/deviation.ts"],"names":[],"mappings":"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"}
|