three-virtual-geometry 0.0.0-stage → 0.1.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/AGENTS.md +65 -0
- package/LICENSE +23 -0
- package/README.md +165 -2
- package/THIRD_PARTY_NOTICES.md +42 -0
- package/dist/bake.mjs +1378 -0
- package/dist/core/constants.d.ts +27 -0
- package/dist/core/import/fromObject3D.d.ts +116 -0
- package/dist/core/import/toNodeMaterial.d.ts +10 -0
- package/dist/core/io/cache.d.ts +32 -0
- package/dist/core/io/serialize.d.ts +21 -0
- package/dist/core/preprocess/buildVirtualMesh.d.ts +105 -0
- package/dist/core/preprocess/partition.d.ts +16 -0
- package/dist/core/preprocess/voxelProxy.d.ts +30 -0
- package/dist/core/runtime/GeometryPool.d.ts +219 -0
- package/dist/core/runtime/OcclusionCulling.d.ts +100 -0
- package/dist/core/runtime/VirtualGeometry.d.ts +201 -0
- package/dist/core/runtime/VirtualMesh.d.ts +93 -0
- package/dist/core/runtime/cut.d.ts +50 -0
- package/dist/core/runtime/vgMaterial.d.ts +33 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +2470 -0
- package/dist/index.js.map +1 -0
- package/dist/source.d.ts +34 -0
- package/dist/three-virtual-geometry.all.min.js +585 -0
- package/dist/three-virtual-geometry.all.min.js.map +6 -0
- package/dist/three-virtual-geometry.min.js +7 -0
- package/dist/three-virtual-geometry.min.js.map +6 -0
- package/docs/public/llms.txt +101 -0
- package/package.json +87 -4
package/dist/index.js
ADDED
|
@@ -0,0 +1,2470 @@
|
|
|
1
|
+
/*! three-virtual-geometry | MIT License | Independent implementation, not affiliated with Epic Games. Includes code derived from nanite-webgpu (MIT, Copyright (c) 2024 Marcin Matuszczyk). See THIRD_PARTY_NOTICES.md */
|
|
2
|
+
import { MeshoptClusterizer as e, MeshoptDecoder as t, MeshoptEncoder as n, MeshoptSimplifier as r } from "meshoptimizer";
|
|
3
|
+
import * as i from "three/webgpu";
|
|
4
|
+
import { Fn as a, If as o, Loop as s, Return as c, atomicAdd as l, atomicLoad as u, atomicStore as d, bitcast as f, bool as p, bumpMap as m, cameraViewMatrix as h, ceil as g, clamp as _, context as v, dot as y, exp2 as b, faceDirection as x, float as S, floor as C, hash as w, instanceIndex as T, int as E, ivec2 as D, length as O, localId as k, log2 as ee, mat3 as A, mat4 as te, materialColor as j, materialReference as M, max as N, min as P, negateOnBackSide as F, normalLocal as ne, normalView as I, normalize as re, numWorkgroups as ie, positionView as ae, select as L, sqrt as oe, storage as R, texture as se, transformNormalToView as ce, uint as z, uniform as B, unpackUnorm2x16 as le, uvec4 as ue, varyingProperty as V, vec3 as de, vec4 as H, vertexIndex as fe, workgroupArray as pe, workgroupBarrier as me, workgroupId as he } from "three/tsl";
|
|
5
|
+
//#region src/core/constants.ts
|
|
6
|
+
var ge = 128, _e = 128, ve = 1e30, ye = .001, be = {
|
|
7
|
+
shaded: 0,
|
|
8
|
+
meshlets: 1,
|
|
9
|
+
lodLevel: 2,
|
|
10
|
+
instances: 3
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/core/preprocess/partition.ts
|
|
14
|
+
function xe(e, t) {
|
|
15
|
+
let n = e.length;
|
|
16
|
+
if (n <= t) return [e.map((e, t) => t)];
|
|
17
|
+
let r = /* @__PURE__ */ new Map();
|
|
18
|
+
for (let t = 0; t < n; t++) for (let n of e[t].boundaryEdges) {
|
|
19
|
+
let e = r.get(n);
|
|
20
|
+
e ? e[e.length - 1] !== t && e.push(t) : r.set(n, [t]);
|
|
21
|
+
}
|
|
22
|
+
let i = Array.from({ length: n }, () => /* @__PURE__ */ new Map());
|
|
23
|
+
for (let e of r.values()) for (let t = 0; t < e.length; t++) for (let n = t + 1; n < e.length; n++) {
|
|
24
|
+
let r = e[t], a = e[n];
|
|
25
|
+
i[r].set(a, (i[r].get(a) || 0) + 1), i[a].set(r, (i[a].get(r) || 0) + 1);
|
|
26
|
+
}
|
|
27
|
+
let a = Ce(e.map((e) => e.center)), o = new Uint8Array(n), s = [];
|
|
28
|
+
for (let n of a) {
|
|
29
|
+
if (o[n]) continue;
|
|
30
|
+
let r = [n];
|
|
31
|
+
o[n] = 1;
|
|
32
|
+
let a = /* @__PURE__ */ new Map(), c = (e) => {
|
|
33
|
+
for (let [t, n] of i[e]) o[t] || a.set(t, (a.get(t) || 0) + n);
|
|
34
|
+
};
|
|
35
|
+
for (c(n); r.length < t && a.size > 0;) {
|
|
36
|
+
let t = -1, i = -1, s = Infinity;
|
|
37
|
+
for (let [r, c] of a) {
|
|
38
|
+
if (o[r]) continue;
|
|
39
|
+
let a = Se(e[r].center, e[n].center);
|
|
40
|
+
(c > i || c === i && a < s) && (t = r, i = c, s = a);
|
|
41
|
+
}
|
|
42
|
+
if (t < 0) break;
|
|
43
|
+
a.delete(t), o[t] = 1, r.push(t), c(t);
|
|
44
|
+
}
|
|
45
|
+
s.push(r);
|
|
46
|
+
}
|
|
47
|
+
let c = [], l = [], u = Math.max(2, Math.floor(t / 2));
|
|
48
|
+
for (let e of s) e.length >= u ? c.push(e) : (l.length + e.length > t && (c.push(l), l = []), l.push(...e));
|
|
49
|
+
return l.length > 0 && c.push(l), c;
|
|
50
|
+
}
|
|
51
|
+
function Se(e, t) {
|
|
52
|
+
let n = e[0] - t[0], r = e[1] - t[1], i = e[2] - t[2];
|
|
53
|
+
return n * n + r * r + i * i;
|
|
54
|
+
}
|
|
55
|
+
function Ce(e) {
|
|
56
|
+
let t = [
|
|
57
|
+
Infinity,
|
|
58
|
+
Infinity,
|
|
59
|
+
Infinity
|
|
60
|
+
], n = [
|
|
61
|
+
-Infinity,
|
|
62
|
+
-Infinity,
|
|
63
|
+
-Infinity
|
|
64
|
+
];
|
|
65
|
+
for (let r of e) for (let e = 0; e < 3; e++) t[e] = Math.min(t[e], r[e]), n[e] = Math.max(n[e], r[e]);
|
|
66
|
+
let r = Math.max(n[0] - t[0], n[1] - t[1], n[2] - t[2]) || 1, i = e.map((e) => {
|
|
67
|
+
let n = (n) => Math.min(1023, Math.max(0, Math.floor((e[n] - t[n]) / r * 1023)));
|
|
68
|
+
return we(n(0)) | we(n(1)) << 1 | we(n(2)) << 2;
|
|
69
|
+
});
|
|
70
|
+
return e.map((e, t) => t).sort((e, t) => i[e] - i[t]);
|
|
71
|
+
}
|
|
72
|
+
function we(e) {
|
|
73
|
+
return e &= 1023, e = (e | e << 16) & 50331903, e = (e | e << 8) & 50393103, e = (e | e << 4) & 51130563, e = (e | e << 2) & 153391689, e;
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/core/preprocess/voxelProxy.ts
|
|
77
|
+
function Te(e, t, n, r, i) {
|
|
78
|
+
if (n.length === 0) return null;
|
|
79
|
+
let a = [
|
|
80
|
+
Infinity,
|
|
81
|
+
Infinity,
|
|
82
|
+
Infinity
|
|
83
|
+
], o = [
|
|
84
|
+
-Infinity,
|
|
85
|
+
-Infinity,
|
|
86
|
+
-Infinity
|
|
87
|
+
];
|
|
88
|
+
for (let t = 0; t < n.length; t++) {
|
|
89
|
+
let r = n[t] * 3;
|
|
90
|
+
for (let t = 0; t < 3; t++) a[t] = Math.min(a[t], e[r + t]), o[t] = Math.max(o[t], e[r + t]);
|
|
91
|
+
}
|
|
92
|
+
let s = Math.max(o[0] - a[0], o[1] - a[1], o[2] - a[2]);
|
|
93
|
+
if (!(s > 0)) return null;
|
|
94
|
+
let c = s / r, l = [
|
|
95
|
+
0,
|
|
96
|
+
1,
|
|
97
|
+
2
|
|
98
|
+
].map((e) => Math.ceil((o[e] - a[e]) / c) + 1 + 6), u = [
|
|
99
|
+
0,
|
|
100
|
+
1,
|
|
101
|
+
2
|
|
102
|
+
].map((e) => a[e] - 3 * c), [d, f, p] = l, m = d, h = d * f, g = d * f * p, _ = new Uint8Array(g), v = t ? new Float32Array(g * 3) : null, y = t ? new Uint32Array(g) : null, b = i ? new Float32Array(g * 2).fill(NaN) : null, x = 0, S = 0, C = (e, t, n, r, i, a) => {
|
|
103
|
+
let o = Math.floor((e - u[0]) / c) * 1 + Math.floor((t - u[1]) / c) * m + Math.floor((n - u[2]) / c) * h;
|
|
104
|
+
_[o] = 1, b && Number.isNaN(b[o * 2]) && (b[o * 2] = x, b[o * 2 + 1] = S), v && (v[o * 3] += r, v[o * 3 + 1] += i, v[o * 3 + 2] += a, y[o]++);
|
|
105
|
+
};
|
|
106
|
+
for (let r = 0; r < n.length; r += 3) {
|
|
107
|
+
let a = n[r] * 3, o = n[r + 1] * 3, s = n[r + 2] * 3, l = Math.max(Ee(e, a, o), Ee(e, o, s), Ee(e, s, a)), u = Math.max(1, Math.ceil(l / (c * .5)));
|
|
108
|
+
for (let c = 0; c <= u; c++) for (let l = 0; l <= u - c; l++) {
|
|
109
|
+
let d = c / u, f = l / u, p = 1 - d - f, m = e[a] * p + e[o] * d + e[s] * f, h = e[a + 1] * p + e[o + 1] * d + e[s + 1] * f, g = e[a + 2] * p + e[o + 2] * d + e[s + 2] * f;
|
|
110
|
+
if (i) {
|
|
111
|
+
let e = n[r] * 2, t = n[r + 1] * 2, a = n[r + 2] * 2;
|
|
112
|
+
x = i[e] * p + i[t] * d + i[a] * f, S = i[e + 1] * p + i[t + 1] * d + i[a + 1] * f;
|
|
113
|
+
}
|
|
114
|
+
t ? C(m, h, g, t[a] * p + t[o] * d + t[s] * f, t[a + 1] * p + t[o + 1] * d + t[s + 1] * f, t[a + 2] * p + t[o + 2] * d + t[s + 2] * f) : C(m, h, g, 0, 0, 0);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
let w = De(U(_, l), l), T = new Float32Array(g);
|
|
118
|
+
for (let e = 0; e < g; e++) T[e] = w[e];
|
|
119
|
+
ke(T, l, 1, d), ke(T, l, m, f), ke(T, l, h, p);
|
|
120
|
+
let E = .5, D = d - 1, O = f - 1, k = p - 1, ee = new Int32Array(D * O * k).fill(-1), A = [], te = [], j = [], M = [], N = /* @__PURE__ */ new Float32Array(8);
|
|
121
|
+
for (let e = 0; e < k; e++) for (let t = 0; t < O; t++) for (let n = 0; n < D; n++) {
|
|
122
|
+
let r = n * 1 + t * m + e * h, i = 0;
|
|
123
|
+
for (let e = 0; e < 8; e++) N[e] = T[r + (e & 1) * 1 + (e >> 1 & 1) * m + (e >> 2 & 1) * h], N[e] >= E && i++;
|
|
124
|
+
if (i === 0 || i === 8) continue;
|
|
125
|
+
let a = 0, o = 0, s = 0, l = 0;
|
|
126
|
+
for (let e = 0; e < 8; e++) for (let t of [
|
|
127
|
+
1,
|
|
128
|
+
2,
|
|
129
|
+
4
|
|
130
|
+
]) {
|
|
131
|
+
if (e & t) continue;
|
|
132
|
+
let n = e | t, r = N[e], i = N[n];
|
|
133
|
+
if (r >= E == i >= E) continue;
|
|
134
|
+
let c = (E - r) / (i - r);
|
|
135
|
+
a += (e & 1) + (t === 1 ? c : 0), o += (e >> 1 & 1) + (t === 2 ? c : 0), s += (e >> 2 & 1) + (t === 4 ? c : 0), l++;
|
|
136
|
+
}
|
|
137
|
+
ee[n + t * D + e * D * O] = A.length / 3, A.push(u[0] + (n + .5 + a / l) * c, u[1] + (t + .5 + o / l) * c, u[2] + (e + .5 + s / l) * c);
|
|
138
|
+
let d = N[1] + N[3] + N[5] + N[7] - N[0] - N[2] - N[4] - N[6], f = N[2] + N[3] + N[6] + N[7] - N[0] - N[1] - N[4] - N[5], p = N[4] + N[5] + N[6] + N[7] - N[0] - N[1] - N[2] - N[3], g = Math.hypot(d, f, p) || 1;
|
|
139
|
+
if (te.push(-d / g, -f / g, -p / g), v) {
|
|
140
|
+
let e = 0, t = 0, n = 0, i = 0;
|
|
141
|
+
for (let a = 0; a < 8; a++) {
|
|
142
|
+
let o = r + (a & 1) * 1 + (a >> 1 & 1) * m + (a >> 2 & 1) * h;
|
|
143
|
+
y[o] && (e += v[o * 3], t += v[o * 3 + 1], n += v[o * 3 + 2], i += y[o]);
|
|
144
|
+
}
|
|
145
|
+
i ? j.push(e / i, t / i, n / i) : j.push(NaN, NaN, NaN);
|
|
146
|
+
}
|
|
147
|
+
if (b) {
|
|
148
|
+
let e = NaN, t = NaN;
|
|
149
|
+
for (let n = 0; n < 8 && Number.isNaN(e); n++) {
|
|
150
|
+
let i = r + (n & 1) * 1 + (n >> 1 & 1) * m + (n >> 2 & 1) * h;
|
|
151
|
+
e = b[i * 2], t = b[i * 2 + 1];
|
|
152
|
+
}
|
|
153
|
+
M.push(e, t);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
let P = [], F = (e, t, n) => ee[e + t * D + n * D * O], ne = (e, t, n, r, i, a, o) => {
|
|
157
|
+
let s = A[n * 3] - A[e * 3], c = A[n * 3 + 1] - A[e * 3 + 1], l = A[n * 3 + 2] - A[e * 3 + 2], u = A[r * 3] - A[t * 3], d = A[r * 3 + 1] - A[t * 3 + 1], f = A[r * 3 + 2] - A[t * 3 + 2], p = c * f - l * d, m = l * u - s * f, h = s * d - c * u;
|
|
158
|
+
p * i + m * a + h * o >= 0 ? P.push(e, t, n, e, n, r) : P.push(e, n, t, e, r, n);
|
|
159
|
+
};
|
|
160
|
+
for (let e = 1; e < p - 1; e++) for (let t = 1; t < f - 1; t++) for (let n = 1; n < d - 1; n++) {
|
|
161
|
+
let r = n * 1 + t * m + e * h, i = T[r] >= E;
|
|
162
|
+
if (i !== T[r + 1] >= E) {
|
|
163
|
+
let r = i ? 1 : -1;
|
|
164
|
+
ne(F(n, t - 1, e - 1), F(n, t, e - 1), F(n, t, e), F(n, t - 1, e), r, 0, 0);
|
|
165
|
+
}
|
|
166
|
+
if (i !== T[r + m] >= E) {
|
|
167
|
+
let r = i ? 1 : -1;
|
|
168
|
+
ne(F(n - 1, t, e - 1), F(n, t, e - 1), F(n, t, e), F(n - 1, t, e), 0, r, 0);
|
|
169
|
+
}
|
|
170
|
+
if (i !== T[r + h] >= E) {
|
|
171
|
+
let r = i ? 1 : -1;
|
|
172
|
+
ne(F(n - 1, t - 1, e), F(n, t - 1, e), F(n, t, e), F(n - 1, t, e), 0, 0, r);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (P.length === 0) return null;
|
|
176
|
+
let I = null;
|
|
177
|
+
v && (I = Float32Array.from(j), Ae(I, P, 3));
|
|
178
|
+
let re = null;
|
|
179
|
+
return b && (re = Float32Array.from(M), Ae(re, P, 2)), {
|
|
180
|
+
positions: Float32Array.from(A),
|
|
181
|
+
normals: Float32Array.from(te),
|
|
182
|
+
colors: I,
|
|
183
|
+
uvs: re,
|
|
184
|
+
indices: Uint32Array.from(P),
|
|
185
|
+
cellSize: c
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function Ee(e, t, n) {
|
|
189
|
+
return Math.hypot(e[t] - e[n], e[t + 1] - e[n + 1], e[t + 2] - e[n + 2]);
|
|
190
|
+
}
|
|
191
|
+
function U(e, t) {
|
|
192
|
+
let n = e;
|
|
193
|
+
for (let e = 0; e < 3; e++) n = Oe(n, t, e, 1);
|
|
194
|
+
return n;
|
|
195
|
+
}
|
|
196
|
+
function De(e, t) {
|
|
197
|
+
let n = e;
|
|
198
|
+
for (let e = 0; e < 3; e++) n = Oe(n, t, e, 0);
|
|
199
|
+
return n;
|
|
200
|
+
}
|
|
201
|
+
function Oe(e, t, n, r) {
|
|
202
|
+
let [i, a, o] = t, s = n === 0 ? 1 : n === 1 ? i : i * a, c = t[n], l = new Uint8Array(e.length);
|
|
203
|
+
for (let t = 0; t < o; t++) for (let o = 0; o < a; o++) for (let u = 0; u < i; u++) {
|
|
204
|
+
let d = u + o * i + t * i * a, f = n === 0 ? u : n === 1 ? o : t, p = f > 0 ? e[d - s] : 0, m = f < c - 1 ? e[d + s] : 0;
|
|
205
|
+
l[d] = r ? e[d] | p | m : e[d] & p & m;
|
|
206
|
+
}
|
|
207
|
+
return l;
|
|
208
|
+
}
|
|
209
|
+
function ke(e, t, n, r) {
|
|
210
|
+
let [i, a, o] = t, s = new Float32Array(r), c = i * a * o / r;
|
|
211
|
+
for (let t = 0; t < c; t++) {
|
|
212
|
+
let o;
|
|
213
|
+
o = n === 1 ? t * i : n === i ? t % i + Math.floor(t / i) * i * a : t;
|
|
214
|
+
for (let t = 0; t < r; t++) s[t] = e[o + t * n];
|
|
215
|
+
for (let t = 0; t < r; t++) {
|
|
216
|
+
let i = t > 0 ? s[t - 1] : 0, a = t < r - 1 ? s[t + 1] : 0;
|
|
217
|
+
e[o + t * n] = (i + s[t] + a) / 3;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function Ae(e, t, n) {
|
|
222
|
+
let r = e.length / n;
|
|
223
|
+
for (let i = 0; i < 8; i++) {
|
|
224
|
+
let i = 0, a = new Float32Array(r * n), o = new Uint32Array(r);
|
|
225
|
+
for (let r = 0; r < t.length; r += 3) for (let i = 0; i < 3; i++) {
|
|
226
|
+
let s = t[r + i];
|
|
227
|
+
if (Number.isNaN(e[s * n])) for (let c = 1; c < 3; c++) {
|
|
228
|
+
let l = t[r + (i + c) % 3];
|
|
229
|
+
if (!Number.isNaN(e[l * n])) {
|
|
230
|
+
for (let t = 0; t < n; t++) a[s * n + t] += e[l * n + t];
|
|
231
|
+
o[s]++;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
for (let t = 0; t < r; t++) if (Number.isNaN(e[t * n])) {
|
|
236
|
+
if (o[t]) for (let r = 0; r < n; r++) e[t * n + r] = a[t * n + r] / o[t];
|
|
237
|
+
else i++;
|
|
238
|
+
}
|
|
239
|
+
if (!i) return;
|
|
240
|
+
}
|
|
241
|
+
for (let t = 0; t < e.length; t++) Number.isNaN(e[t]) && (e[t] = .5);
|
|
242
|
+
}
|
|
243
|
+
//#endregion
|
|
244
|
+
//#region src/core/preprocess/buildVirtualMesh.ts
|
|
245
|
+
var je = {
|
|
246
|
+
groupSize: 12,
|
|
247
|
+
maxLodLevels: 24,
|
|
248
|
+
maxGroupKeepRatio: .9,
|
|
249
|
+
simplifyRatio: .5,
|
|
250
|
+
minLevelReduction: .03,
|
|
251
|
+
prune: !1,
|
|
252
|
+
tailSimplify: !0,
|
|
253
|
+
minRootTriangles: 4,
|
|
254
|
+
voxelLods: !0
|
|
255
|
+
}, Me = 1024, Ne = [
|
|
256
|
+
64,
|
|
257
|
+
32,
|
|
258
|
+
16,
|
|
259
|
+
8,
|
|
260
|
+
4
|
|
261
|
+
], Pe = () => new Promise((e) => setTimeout(e, 0));
|
|
262
|
+
async function Fe(t, n = {}) {
|
|
263
|
+
let i = {
|
|
264
|
+
...je,
|
|
265
|
+
...n
|
|
266
|
+
}, a = performance.now();
|
|
267
|
+
await e.ready, await r.ready;
|
|
268
|
+
let o = t.positions, s = t.normals, c = t.colors ?? null, l = t.uvs ?? null, u = r.generatePositionRemap(o, 3), d = 0, f = ["LockBorder", "ErrorAbsolute"];
|
|
269
|
+
i.prune && f.push("Prune");
|
|
270
|
+
let p = [], m = /* @__PURE__ */ new Map(), h = C(t.indices, 0, null, 0), g = h, _ = Ue(g), v = 1, y = Math.max(1, h.length * 2);
|
|
271
|
+
for (let e = 1; e <= i.maxLodLevels && g.length > 1 && !(i.tailSimplify && _ <= Me); e++) {
|
|
272
|
+
let t = xe(g, i.groupSize), n = [];
|
|
273
|
+
for (let a of t) {
|
|
274
|
+
let t = a.map((e) => g[e]), s = He(t), c = G(s, o), l = Math.max(3, Math.floor(s.length * i.simplifyRatio / 3) * 3), [u, d] = r.simplify(c.indices, c.positions, 3, l, 1e10, f);
|
|
275
|
+
if (u.length > s.length * i.maxGroupKeepRatio) continue;
|
|
276
|
+
let p = Ge(t.map((e) => e.lodSphere)), m = Math.max(...t.map((e) => e.error)), h = Math.max(d, W(c.indices, u, c.positions)), _ = m + Math.max(h, 1e-7);
|
|
277
|
+
for (let e of t) e.parentSphere = p, e.parentError = _;
|
|
278
|
+
let v = new Uint32Array(u.length);
|
|
279
|
+
for (let e = 0; e < u.length; e++) v[e] = c.toGlobal[u[e]];
|
|
280
|
+
if (v.length > 0) {
|
|
281
|
+
let r = C(v, e, p, _);
|
|
282
|
+
n.push(...r);
|
|
283
|
+
for (let e of t) e.replacements = r;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (await i.onProgress?.(Math.min(.99, p.length / y)), await Pe(), n.length === 0) break;
|
|
287
|
+
v = e + 1, g = n;
|
|
288
|
+
let a = Ue(g);
|
|
289
|
+
if (a > _ * (1 - i.minLevelReduction)) break;
|
|
290
|
+
_ = a;
|
|
291
|
+
}
|
|
292
|
+
return i.tailSimplify && (v = S(p.filter((e) => e.parentError >= ve), v)), await i.onProgress?.(1), Ie({
|
|
293
|
+
positions: o,
|
|
294
|
+
normals: s,
|
|
295
|
+
colors: c ?? void 0,
|
|
296
|
+
uvs: l ?? void 0,
|
|
297
|
+
indices: t.indices
|
|
298
|
+
}, p, v, d, performance.now() - a);
|
|
299
|
+
function b(e, t, n, r) {
|
|
300
|
+
let i = o.length / 3, a = e.length / 3, d = (e, t) => {
|
|
301
|
+
let n = new Float32Array(e.length + t.length);
|
|
302
|
+
return n.set(e), n.set(t, e.length), n;
|
|
303
|
+
};
|
|
304
|
+
o = d(o, e), s = d(s, t), c &&= d(c, n ?? new Float32Array(a * 3).fill(1)), l &&= d(l, r ?? new Float32Array(a * 2));
|
|
305
|
+
let f = new Uint32Array(u.length + a);
|
|
306
|
+
f.set(u);
|
|
307
|
+
for (let e = 0; e < a; e++) f[u.length + e] = i + e;
|
|
308
|
+
return u = f, i;
|
|
309
|
+
}
|
|
310
|
+
function x(e) {
|
|
311
|
+
return m.has(e) || m.set(e, Te(t.positions, t.colors, t.indices, e, t.uvs)), m.get(e);
|
|
312
|
+
}
|
|
313
|
+
function S(e, t) {
|
|
314
|
+
if (e.length === 0) return t;
|
|
315
|
+
let n = ["ErrorAbsolute"];
|
|
316
|
+
i.prune && n.push("Prune");
|
|
317
|
+
let a = e, s = t;
|
|
318
|
+
for (; s < t + i.maxLodLevels; s++) {
|
|
319
|
+
let e = He(a);
|
|
320
|
+
if (e.length / 3 <= i.minRootTriangles) break;
|
|
321
|
+
let t = G(e, o), c = Math.max(3, Math.floor(e.length / 2 / 3) * 3), l = e.length * i.maxGroupKeepRatio, u = Math.max(...a.map((e) => e.error)), [f, p] = r.simplify(t.indices, t.positions, 3, c, 1e10, n);
|
|
322
|
+
if (f.length > l) {
|
|
323
|
+
let [e, n] = r.simplifySloppy(t.indices, t.positions, 3, null, c, 1);
|
|
324
|
+
e.length < f.length && (f = e, p = n * r.getScale(t.positions, 3));
|
|
325
|
+
}
|
|
326
|
+
let m = null, h = Infinity;
|
|
327
|
+
if (f.length <= l) {
|
|
328
|
+
h = u + Math.max(Math.max(p, W(t.indices, f, t.positions)), 1e-7), m = new Uint32Array(f.length);
|
|
329
|
+
for (let e = 0; e < f.length; e++) m[e] = t.toGlobal[f[e]];
|
|
330
|
+
}
|
|
331
|
+
let g = null;
|
|
332
|
+
if (i.voxelLods) for (let e of Ne) {
|
|
333
|
+
let t = x(e);
|
|
334
|
+
if (!t) continue;
|
|
335
|
+
let n = Math.min(c, t.indices.length), [i, a] = r.simplify(t.indices, t.positions, 3, n, 1e10, ["ErrorAbsolute"]);
|
|
336
|
+
if (i.length === 0 || i.length > l) continue;
|
|
337
|
+
let o = Math.max(u * (1 + 1e-5) + 1e-7, 2 * t.cellSize + a);
|
|
338
|
+
o < h && (h = o, g = {
|
|
339
|
+
proxy: t,
|
|
340
|
+
indices: i
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
if (!Number.isFinite(h)) break;
|
|
344
|
+
if (g) {
|
|
345
|
+
let e = G(g.indices, g.proxy.positions), t = (t, n = 3) => {
|
|
346
|
+
let r = new Float32Array(e.toGlobal.length * n);
|
|
347
|
+
return e.toGlobal.forEach((e, i) => r.set(t.subarray(e * n, e * n + n), i * n)), r;
|
|
348
|
+
}, { proxy: n } = g, r = b(e.positions, t(n.normals), n.colors ? t(n.colors) : null, n.uvs ? t(n.uvs, 2) : null);
|
|
349
|
+
m = e.indices.map((e) => e + r), d++;
|
|
350
|
+
}
|
|
351
|
+
let _ = Ge(a.map((e) => e.lodSphere));
|
|
352
|
+
for (let e of a) e.parentSphere = _, e.parentError = h;
|
|
353
|
+
if (m.length === 0) return s + 1;
|
|
354
|
+
let v = C(m, s, _, h);
|
|
355
|
+
for (let e of a) e.replacements = v;
|
|
356
|
+
a = v;
|
|
357
|
+
}
|
|
358
|
+
return s;
|
|
359
|
+
}
|
|
360
|
+
function C(t, n, r, i) {
|
|
361
|
+
let a = G(t, o), s = e.buildMeshlets(a.indices, a.positions, 3, 128, 128, 0), c = [];
|
|
362
|
+
for (let e = 0; e < s.meshletCount; e++) {
|
|
363
|
+
let t = s.meshlets[e * 4 + 0], l = s.meshlets[e * 4 + 1], d = s.meshlets[e * 4 + 2], f = s.meshlets[e * 4 + 3], m = new Uint32Array(d);
|
|
364
|
+
for (let e = 0; e < d; e++) m[e] = a.toGlobal[s.vertices[t + e]];
|
|
365
|
+
let h = s.triangles.slice(l, l + f * 3), g = new Uint32Array(f * 3);
|
|
366
|
+
for (let e = 0; e < f * 3; e++) g[e] = m[h[e]];
|
|
367
|
+
let _ = We(g, o), v = {
|
|
368
|
+
indices: g,
|
|
369
|
+
lodLevel: n,
|
|
370
|
+
lodSphere: r ?? _,
|
|
371
|
+
error: i,
|
|
372
|
+
parentSphere: [
|
|
373
|
+
0,
|
|
374
|
+
0,
|
|
375
|
+
0,
|
|
376
|
+
0
|
|
377
|
+
],
|
|
378
|
+
parentError: ve,
|
|
379
|
+
cullSphere: _,
|
|
380
|
+
boundaryEdges: Be(g, u),
|
|
381
|
+
center: [
|
|
382
|
+
_[0],
|
|
383
|
+
_[1],
|
|
384
|
+
_[2]
|
|
385
|
+
],
|
|
386
|
+
replacements: [],
|
|
387
|
+
vertices: m,
|
|
388
|
+
localTriangles: h
|
|
389
|
+
};
|
|
390
|
+
c.push(v), p.push(v);
|
|
391
|
+
}
|
|
392
|
+
return c;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
function Ie(e, t, n, r, i) {
|
|
396
|
+
let a = [...t].sort((e, t) => e.lodLevel - t.lodLevel), o = a.length, s = new Uint32Array(a.reduce((e, t) => e + t.indices.length, 0)), c = new Float32Array(o * 16), l = new Uint32Array(o * 4), u = /* @__PURE__ */ new Map();
|
|
397
|
+
a.forEach((e, t) => u.set(e, t));
|
|
398
|
+
let d = new Uint32Array(o + 1), f = [];
|
|
399
|
+
a.forEach((e, t) => {
|
|
400
|
+
d[t] = f.length;
|
|
401
|
+
for (let t of e.replacements) f.push(u.get(t));
|
|
402
|
+
}), d[o] = f.length;
|
|
403
|
+
let p = new Uint32Array(a.reduce((e, t) => e + t.vertices.length, 0)), m = new Uint32Array(s.length / 3), h = 0, g = 0, _ = {
|
|
404
|
+
leafTriangles: 0,
|
|
405
|
+
leafMeshlets: 0,
|
|
406
|
+
rootTriangles: 0,
|
|
407
|
+
rootMeshlets: 0,
|
|
408
|
+
lodLevels: n,
|
|
409
|
+
voxelLevels: r,
|
|
410
|
+
buildMs: i
|
|
411
|
+
};
|
|
412
|
+
a.forEach((e, t) => {
|
|
413
|
+
s.set(e.indices, h), p.set(e.vertices, g);
|
|
414
|
+
let n = e.localTriangles;
|
|
415
|
+
for (let e = 0, t = h / 3; e < n.length; e += 3, t++) m[t] = n[e] | n[e + 1] << 8 | n[e + 2] << 16;
|
|
416
|
+
let r = t * 16;
|
|
417
|
+
c.set(e.lodSphere, r), c.set(e.parentSphere, r + 4), c[r + 8] = e.error, c[r + 9] = e.parentError, c.set(e.cullSphere, r + 12);
|
|
418
|
+
let i = e.indices.length / 3, a = t * 4;
|
|
419
|
+
l[a + 0] = i, l[a + 1] = h, l[a + 2] = e.lodLevel, l[a + 3] = g, h += e.indices.length, g += e.vertices.length, e.lodLevel === 0 && (_.leafTriangles += i, _.leafMeshlets += 1), e.parentError >= 1e30 && (_.rootTriangles += i, _.rootMeshlets += 1);
|
|
420
|
+
});
|
|
421
|
+
let v = Ge(a.filter((e) => e.lodLevel === 0).map((e) => e.cullSphere)), y = a.length ? a[a.length - 1].lodLevel + 1 : 0, b = new Uint32Array(y * 2), x = new Float32Array(y * 2), S = new Float32Array(y * 2);
|
|
422
|
+
for (let e = 0; e < y; e++) x[e * 2] = Infinity, x[e * 2 + 1] = 0, S[e * 2] = 0, S[e * 2 + 1] = Infinity;
|
|
423
|
+
a.forEach((e, t) => {
|
|
424
|
+
let n = e.lodLevel;
|
|
425
|
+
b[n * 2 + 1] === 0 && (b[n * 2] = t), b[n * 2 + 1]++, x[n * 2] = Math.min(x[n * 2], e.error), x[n * 2 + 1] = Math.max(x[n * 2 + 1], e.parentError), S[n * 2] = Math.max(S[n * 2], e.error), S[n * 2 + 1] = Math.min(S[n * 2 + 1], e.parentError);
|
|
426
|
+
});
|
|
427
|
+
let C = Ge([...a.map((e) => e.lodSphere), ...a.filter((e) => e.parentError < ve).map((e) => e.parentSphere)]), w = Ge(a.map((e) => e.cullSphere));
|
|
428
|
+
return {
|
|
429
|
+
positions: e.positions,
|
|
430
|
+
normals: e.normals,
|
|
431
|
+
colors: e.colors ?? null,
|
|
432
|
+
uvs: e.uvs ?? null,
|
|
433
|
+
indices: s,
|
|
434
|
+
meshletCount: o,
|
|
435
|
+
meshletBounds: c,
|
|
436
|
+
meshletInfo: l,
|
|
437
|
+
replacementStart: d,
|
|
438
|
+
replacementIndices: Uint32Array.from(f),
|
|
439
|
+
meshletVertices: p,
|
|
440
|
+
meshletTriangles: m,
|
|
441
|
+
levelRanges: b,
|
|
442
|
+
levelErrors: x,
|
|
443
|
+
levelGuardErrors: S,
|
|
444
|
+
lodBoundsSphere: C,
|
|
445
|
+
cullBoundsSphere: w,
|
|
446
|
+
boundingSphere: v,
|
|
447
|
+
stats: _
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
function W(e, t, n) {
|
|
451
|
+
let r = (e) => {
|
|
452
|
+
let t = [
|
|
453
|
+
Infinity,
|
|
454
|
+
Infinity,
|
|
455
|
+
Infinity
|
|
456
|
+
], r = [
|
|
457
|
+
-Infinity,
|
|
458
|
+
-Infinity,
|
|
459
|
+
-Infinity
|
|
460
|
+
];
|
|
461
|
+
for (let i = 0; i < e.length; i++) {
|
|
462
|
+
let a = e[i] * 3;
|
|
463
|
+
for (let e = 0; e < 3; e++) {
|
|
464
|
+
let i = n[a + e];
|
|
465
|
+
i < t[e] && (t[e] = i), i > r[e] && (r[e] = i);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return {
|
|
469
|
+
min: t,
|
|
470
|
+
max: r
|
|
471
|
+
};
|
|
472
|
+
}, i = r(e);
|
|
473
|
+
if (t.length === 0) return Math.max(i.max[0] - i.min[0], i.max[1] - i.min[1], i.max[2] - i.min[2]) / 2;
|
|
474
|
+
let a = r(t), o = 0;
|
|
475
|
+
for (let e = 0; e < 3; e++) o = Math.max(o, a.min[e] - i.min[e], i.max[e] - a.max[e]);
|
|
476
|
+
return o;
|
|
477
|
+
}
|
|
478
|
+
var Le = /* @__PURE__ */ new Int32Array();
|
|
479
|
+
function G(e, t) {
|
|
480
|
+
let n = t.length / 3;
|
|
481
|
+
Le.length < n && (Le = new Int32Array(n).fill(-1));
|
|
482
|
+
let r = new Uint32Array(e.length), i = new Uint32Array(e.length), a = 0;
|
|
483
|
+
for (let t = 0; t < e.length; t++) {
|
|
484
|
+
let n = e[t], o = Le[n];
|
|
485
|
+
o < 0 && (o = a++, Le[n] = o, r[o] = n), i[t] = o;
|
|
486
|
+
}
|
|
487
|
+
let o = r.subarray(0, a), s = new Float32Array(a * 3);
|
|
488
|
+
for (let e = 0; e < a; e++) {
|
|
489
|
+
let n = o[e];
|
|
490
|
+
Le[n] = -1, s[e * 3 + 0] = t[n * 3 + 0], s[e * 3 + 1] = t[n * 3 + 1], s[e * 3 + 2] = t[n * 3 + 2];
|
|
491
|
+
}
|
|
492
|
+
return {
|
|
493
|
+
indices: i,
|
|
494
|
+
positions: s,
|
|
495
|
+
toGlobal: o
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
var Re = /* @__PURE__ */ new Float64Array(1024), K = /* @__PURE__ */ new Uint8Array(1024), ze = /* @__PURE__ */ new Int32Array(512);
|
|
499
|
+
function Be(e, t) {
|
|
500
|
+
let n = e.length, r = Re.length;
|
|
501
|
+
if (r < n * 2) {
|
|
502
|
+
for (; r < n * 2;) r <<= 1;
|
|
503
|
+
Re = new Float64Array(r), K = new Uint8Array(r), ze = new Int32Array(r / 2);
|
|
504
|
+
}
|
|
505
|
+
let i = r - 1, a = 0;
|
|
506
|
+
for (let n = 0; n < e.length; n += 3) for (let r = 0; r < 3; r++) {
|
|
507
|
+
let o = t[e[n + r]], s = t[e[n + (r + 1) % 3]], c = Ve(o, s), l = (Math.imul(o < s ? o : s, 2654435761) ^ Math.imul(o < s ? s : o, 2246822507)) & i;
|
|
508
|
+
for (; K[l] !== 0 && Re[l] !== c;) l = l + 1 & i;
|
|
509
|
+
K[l] === 0 && (Re[l] = c, ze[a++] = l), K[l] < 255 && K[l]++;
|
|
510
|
+
}
|
|
511
|
+
let o = [];
|
|
512
|
+
for (let e = 0; e < a; e++) {
|
|
513
|
+
let t = ze[e];
|
|
514
|
+
K[t] === 1 && o.push(Re[t]), K[t] = 0;
|
|
515
|
+
}
|
|
516
|
+
return o;
|
|
517
|
+
}
|
|
518
|
+
var Ve = (e, t) => e < t ? e * 67108864 + t : t * 67108864 + e;
|
|
519
|
+
function He(e) {
|
|
520
|
+
let t = new Uint32Array(e.reduce((e, t) => e + t.indices.length, 0)), n = 0;
|
|
521
|
+
for (let r of e) t.set(r.indices, n), n += r.indices.length;
|
|
522
|
+
return t;
|
|
523
|
+
}
|
|
524
|
+
var Ue = (e) => e.reduce((e, t) => e + t.indices.length / 3, 0);
|
|
525
|
+
function We(e, t) {
|
|
526
|
+
let n = [
|
|
527
|
+
Infinity,
|
|
528
|
+
Infinity,
|
|
529
|
+
Infinity
|
|
530
|
+
], r = [
|
|
531
|
+
-Infinity,
|
|
532
|
+
-Infinity,
|
|
533
|
+
-Infinity
|
|
534
|
+
];
|
|
535
|
+
for (let i = 0; i < e.length; i++) {
|
|
536
|
+
let a = e[i] * 3;
|
|
537
|
+
for (let e = 0; e < 3; e++) {
|
|
538
|
+
let i = t[a + e];
|
|
539
|
+
i < n[e] && (n[e] = i), i > r[e] && (r[e] = i);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
let i = (n[0] + r[0]) / 2, a = (n[1] + r[1]) / 2, o = (n[2] + r[2]) / 2, s = 0;
|
|
543
|
+
for (let n = 0; n < e.length; n++) {
|
|
544
|
+
let r = e[n] * 3, c = t[r] - i, l = t[r + 1] - a, u = t[r + 2] - o;
|
|
545
|
+
s = Math.max(s, c * c + l * l + u * u);
|
|
546
|
+
}
|
|
547
|
+
return [
|
|
548
|
+
i,
|
|
549
|
+
a,
|
|
550
|
+
o,
|
|
551
|
+
Math.sqrt(s)
|
|
552
|
+
];
|
|
553
|
+
}
|
|
554
|
+
function Ge(t) {
|
|
555
|
+
if (t.length === 1) return [...t[0]];
|
|
556
|
+
let n = new Float32Array(t.length * 3), r = new Float32Array(t.length);
|
|
557
|
+
t.forEach((e, t) => {
|
|
558
|
+
n.set([
|
|
559
|
+
e[0],
|
|
560
|
+
e[1],
|
|
561
|
+
e[2]
|
|
562
|
+
], t * 3), r[t] = e[3];
|
|
563
|
+
});
|
|
564
|
+
let i = e.computeSphereBounds(n, 3, r, 1), a = i.radius;
|
|
565
|
+
for (let e of t) {
|
|
566
|
+
let t = Math.hypot(e[0] - i.centerX, e[1] - i.centerY, e[2] - i.centerZ) + e[3];
|
|
567
|
+
a = Math.max(a, t);
|
|
568
|
+
}
|
|
569
|
+
return [
|
|
570
|
+
i.centerX,
|
|
571
|
+
i.centerY,
|
|
572
|
+
i.centerZ,
|
|
573
|
+
a * 1.0001
|
|
574
|
+
];
|
|
575
|
+
}
|
|
576
|
+
//#endregion
|
|
577
|
+
//#region src/core/io/serialize.ts
|
|
578
|
+
var Ke = 1, qe = 1329940310, q = 16, Je = {
|
|
579
|
+
Int8Array,
|
|
580
|
+
Uint8Array,
|
|
581
|
+
Uint8ClampedArray,
|
|
582
|
+
Int16Array,
|
|
583
|
+
Uint16Array,
|
|
584
|
+
Int32Array,
|
|
585
|
+
Uint32Array,
|
|
586
|
+
Float32Array,
|
|
587
|
+
Float64Array
|
|
588
|
+
}, Ye = {
|
|
589
|
+
positions: { strides: [12] },
|
|
590
|
+
normals: { strides: [12] },
|
|
591
|
+
colors: { strides: [12] },
|
|
592
|
+
uvs: { strides: [8] },
|
|
593
|
+
tangents: { strides: [16] },
|
|
594
|
+
meshletBounds: {
|
|
595
|
+
strides: [64],
|
|
596
|
+
deflateRaw: !0
|
|
597
|
+
},
|
|
598
|
+
meshletInfo: { strides: [16] }
|
|
599
|
+
}, J = class extends Error {
|
|
600
|
+
constructor(e) {
|
|
601
|
+
super(`three-virtual-geometry: ${e}`), this.name = "VirtualMeshFormatError";
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
async function Xe(e, t = {}) {
|
|
605
|
+
let r = t.compress ?? !0;
|
|
606
|
+
r && await n.ready;
|
|
607
|
+
let i = e, a = Object.keys(i).filter((e) => i[e] !== void 0 && typeof i[e] != "function"), o = [], s = [], c = {}, l = 0;
|
|
608
|
+
for (let n of a) {
|
|
609
|
+
let a = i[n];
|
|
610
|
+
if (!ArrayBuffer.isView(a)) {
|
|
611
|
+
c[n] = a;
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
614
|
+
let u = a.constructor.name;
|
|
615
|
+
if (!(u in Je)) throw new J(`cannot serialize field "${n}" of type ${u}`);
|
|
616
|
+
let d = a, f, p;
|
|
617
|
+
n === "indices" && !t.keepIndices && tt(e) ? (p = {
|
|
618
|
+
name: n,
|
|
619
|
+
type: u,
|
|
620
|
+
length: d.length,
|
|
621
|
+
encoding: "meshlet-indices"
|
|
622
|
+
}, f = /* @__PURE__ */ new Uint8Array()) : r ? {entry: p, blob: f} = await $e(n, u, d, e, t.deflate ?? !0) : (p = {
|
|
623
|
+
name: n,
|
|
624
|
+
type: u,
|
|
625
|
+
length: d.length,
|
|
626
|
+
encoding: "raw"
|
|
627
|
+
}, f = ct(d)), o.push({
|
|
628
|
+
...p,
|
|
629
|
+
offset: l,
|
|
630
|
+
byteLength: f.length
|
|
631
|
+
}), s.push(f), l += st(f.length);
|
|
632
|
+
}
|
|
633
|
+
let u = {
|
|
634
|
+
generator: "three-virtual-geometry",
|
|
635
|
+
keys: a,
|
|
636
|
+
fields: o,
|
|
637
|
+
values: c
|
|
638
|
+
}, d = new TextEncoder().encode(JSON.stringify(u, mt)), f = st(d.length), p = new Uint8Array(q + f + l);
|
|
639
|
+
p.set(d, q), p.fill(32, q + d.length, q + f);
|
|
640
|
+
let m = q + f;
|
|
641
|
+
o.forEach((e, t) => p.set(s[t], m + e.offset));
|
|
642
|
+
let h = new DataView(p.buffer);
|
|
643
|
+
return h.setUint32(0, qe, !0), h.setUint32(4, 1, !0), h.setUint32(8, d.length, !0), h.setUint32(12, ut(p, q), !0), p;
|
|
644
|
+
}
|
|
645
|
+
async function Ze(e) {
|
|
646
|
+
let n = ArrayBuffer.isView(e) ? new Uint8Array(e.buffer, e.byteOffset, e.byteLength) : new Uint8Array(e);
|
|
647
|
+
n.byteOffset % 4 != 0 && (n = n.slice());
|
|
648
|
+
let r = new DataView(n.buffer, n.byteOffset, n.byteLength);
|
|
649
|
+
if (n.length < q || r.getUint32(0, !0) !== qe) throw new J("not a three-virtual-geometry geometry file (bad magic bytes)");
|
|
650
|
+
let i = r.getUint32(4, !0);
|
|
651
|
+
if (i !== 1) throw new J(`unsupported geometry format version ${i} (this build reads version 1); re-bake the file`);
|
|
652
|
+
let a = r.getUint32(8, !0), o = q + st(a);
|
|
653
|
+
if (o > n.length || n.length % 4 != 0) throw new J("geometry file is truncated");
|
|
654
|
+
let s;
|
|
655
|
+
try {
|
|
656
|
+
s = JSON.parse(new TextDecoder().decode(n.subarray(q, q + a)), ht);
|
|
657
|
+
} catch {
|
|
658
|
+
throw new J("geometry file is corrupt or truncated (unreadable header)");
|
|
659
|
+
}
|
|
660
|
+
if (!s || !Array.isArray(s.fields) || !Array.isArray(s.keys) || typeof s.values != "object") throw new J("geometry file is corrupt (malformed header)");
|
|
661
|
+
let c = n.subarray(o), l = {}, u = [...s.fields].sort((e, t) => nt(e.encoding) - nt(t.encoding));
|
|
662
|
+
u.some((e) => e.encoding !== "raw") && await t.ready;
|
|
663
|
+
for (let e of u) {
|
|
664
|
+
if (!Je[e.type] || !Number.isInteger(e.length) || e.length < 0) throw new J(`geometry file is corrupt (field "${e.name}")`);
|
|
665
|
+
if (e.offset % 4 != 0 || e.offset + e.byteLength > c.length) throw new J(`geometry file is truncated (field "${e.name}")`);
|
|
666
|
+
}
|
|
667
|
+
if (ut(n, q) !== r.getUint32(12, !0)) throw new J("geometry file is corrupt (checksum mismatch)");
|
|
668
|
+
let d = (e, t) => t instanceof J ? t : new J(`geometry file is corrupt (field "${e.name}": ${t.message})`), f = await Promise.all(u.map((e) => {
|
|
669
|
+
let t = c.subarray(e.offset, e.offset + e.byteLength);
|
|
670
|
+
return e.deflate ? pt(t).catch((t) => Promise.reject(d(e, t))) : t;
|
|
671
|
+
}));
|
|
672
|
+
for (let e = 0; e < u.length; e++) try {
|
|
673
|
+
l[u[e].name] = await rt({
|
|
674
|
+
...u[e],
|
|
675
|
+
deflate: !1
|
|
676
|
+
}, f[e], l);
|
|
677
|
+
} catch (t) {
|
|
678
|
+
throw d(u[e], t);
|
|
679
|
+
}
|
|
680
|
+
let p = {};
|
|
681
|
+
for (let e of s.keys) p[e] = e in l ? l[e] : s.values[e];
|
|
682
|
+
return p;
|
|
683
|
+
}
|
|
684
|
+
async function Qe(e, t) {
|
|
685
|
+
if (typeof e != "string" && !(e instanceof URL)) return Ze(e);
|
|
686
|
+
let n = await fetch(e, t);
|
|
687
|
+
if (!n.ok) throw Error(`three-virtual-geometry: failed to load ${e} (HTTP ${n.status})`);
|
|
688
|
+
return Ze(await n.arrayBuffer());
|
|
689
|
+
}
|
|
690
|
+
async function $e(e, t, r, i, a) {
|
|
691
|
+
let o = ct(r), s = {
|
|
692
|
+
name: e,
|
|
693
|
+
type: t,
|
|
694
|
+
length: r.length
|
|
695
|
+
}, c = Ye[e] ?? {}, l = {
|
|
696
|
+
entry: {
|
|
697
|
+
...s,
|
|
698
|
+
encoding: "raw"
|
|
699
|
+
},
|
|
700
|
+
blob: o
|
|
701
|
+
}, u = [l], d = e === "meshletTriangles" && r instanceof Uint32Array ? et(r, i.meshletInfo) : null;
|
|
702
|
+
if (d) u.push({
|
|
703
|
+
entry: {
|
|
704
|
+
...s,
|
|
705
|
+
encoding: "meshlet-triangles"
|
|
706
|
+
},
|
|
707
|
+
blob: d
|
|
708
|
+
});
|
|
709
|
+
else if (o.length % 4 == 0 && o.length > 0) {
|
|
710
|
+
let e = (c.strides ?? [Math.max(4, r.BYTES_PER_ELEMENT)]).filter((e) => e % 4 == 0 && e <= 256 && o.length % e === 0);
|
|
711
|
+
for (let t of e) {
|
|
712
|
+
let e = n.encodeVertexBufferLevel(o, o.length / t, t, 2, 1);
|
|
713
|
+
u.push({
|
|
714
|
+
entry: {
|
|
715
|
+
...s,
|
|
716
|
+
encoding: "meshopt-vertex",
|
|
717
|
+
stride: t
|
|
718
|
+
},
|
|
719
|
+
blob: e
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
if (u.sort((e, t) => e.blob.length - t.blob.length), a && dt() && o.length >= 64) {
|
|
724
|
+
let e = c.deflateRaw && u[0] !== l ? [u[0], l] : [u[0]];
|
|
725
|
+
for (let t of e) u.push({
|
|
726
|
+
entry: {
|
|
727
|
+
...t.entry,
|
|
728
|
+
deflate: !0
|
|
729
|
+
},
|
|
730
|
+
blob: await ft(t.blob)
|
|
731
|
+
});
|
|
732
|
+
u.sort((e, t) => e.blob.length - t.blob.length);
|
|
733
|
+
}
|
|
734
|
+
for (let e of u) if (lt(ct(await rt({
|
|
735
|
+
...e.entry,
|
|
736
|
+
offset: 0,
|
|
737
|
+
byteLength: e.blob.length
|
|
738
|
+
}, e.blob, { meshletInfo: i.meshletInfo })), o)) return e;
|
|
739
|
+
return l;
|
|
740
|
+
}
|
|
741
|
+
function et(e, r) {
|
|
742
|
+
if (!(r instanceof Uint32Array)) return null;
|
|
743
|
+
let i = new Uint32Array(e.length * 3), a = new Uint8Array(e.length);
|
|
744
|
+
for (let t = 0; t < r.length; t += 4) {
|
|
745
|
+
let n = r[t], o = r[t + 1] / 3, s = r[t + 3];
|
|
746
|
+
if (o + n > e.length) return null;
|
|
747
|
+
for (let t = o; t < o + n; t++) {
|
|
748
|
+
let n = e[t];
|
|
749
|
+
if (a[t] || n >>> 24) return null;
|
|
750
|
+
a[t] = 1, i[t * 3] = s + (n & 255), i[t * 3 + 1] = s + (n >> 8 & 255), i[t * 3 + 2] = s + (n >> 16 & 255);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
if (!a.every((e) => e === 1)) return null;
|
|
754
|
+
let o = n.encodeIndexBuffer(ct(i), i.length, 4), s = new Uint32Array(i.length);
|
|
755
|
+
t.decodeIndexBuffer(ct(s), i.length, 4, o);
|
|
756
|
+
let c = new Uint8Array(Math.ceil(e.length / 4));
|
|
757
|
+
for (let t = 0; t < e.length; t++) {
|
|
758
|
+
let e = i[t * 3], n = i[t * 3 + 1], r = i[t * 3 + 2], a = s[t * 3], o = s[t * 3 + 1], l = s[t * 3 + 2], u;
|
|
759
|
+
if (e === a && n === o && r === l) u = 0;
|
|
760
|
+
else if (e === o && n === l && r === a) u = 1;
|
|
761
|
+
else if (e === l && n === a && r === o) u = 2;
|
|
762
|
+
else return null;
|
|
763
|
+
c[t >> 2] |= u << (t & 3) * 2;
|
|
764
|
+
}
|
|
765
|
+
let l = new Uint8Array(4 + st(o.length) + c.length);
|
|
766
|
+
return new DataView(l.buffer).setUint32(0, o.length, !0), l.set(o, 4), l.set(c, 4 + st(o.length)), l;
|
|
767
|
+
}
|
|
768
|
+
function tt(e) {
|
|
769
|
+
let { indices: t, meshletInfo: n, meshletVertices: r, meshletTriangles: i } = e;
|
|
770
|
+
if (!(t instanceof Uint32Array && n instanceof Uint32Array && r instanceof Uint32Array && i instanceof Uint32Array)) return !1;
|
|
771
|
+
try {
|
|
772
|
+
return lt(ct(ot(t.length, n, r, i)), ct(t));
|
|
773
|
+
} catch {
|
|
774
|
+
return !1;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
var nt = (e) => e === "meshlet-triangles" ? 1 : e === "meshlet-indices" ? 2 : 0;
|
|
778
|
+
async function rt(e, n, r) {
|
|
779
|
+
let i = Je[e.type], a = new i(e.length), o = ct(a), s = e.deflate ? await pt(n) : n;
|
|
780
|
+
switch (e.encoding) {
|
|
781
|
+
case "raw":
|
|
782
|
+
if (s.length !== o.length) throw new J(`geometry file is corrupt (field "${e.name}" has the wrong size)`);
|
|
783
|
+
o.set(s);
|
|
784
|
+
break;
|
|
785
|
+
case "meshopt-vertex": {
|
|
786
|
+
let n = e.stride ?? 0;
|
|
787
|
+
if (n <= 0 || n % 4 != 0 || o.length % n !== 0) throw new J(`geometry file is corrupt (field "${e.name}" stride)`);
|
|
788
|
+
t.decodeVertexBuffer(o, o.length / n, n, s);
|
|
789
|
+
break;
|
|
790
|
+
}
|
|
791
|
+
case "meshlet-triangles":
|
|
792
|
+
at(a, s, it(r, "meshletInfo", e.name));
|
|
793
|
+
break;
|
|
794
|
+
case "meshlet-indices":
|
|
795
|
+
a.set(ot(e.length, it(r, "meshletInfo", e.name), it(r, "meshletVertices", e.name), it(r, "meshletTriangles", e.name)));
|
|
796
|
+
break;
|
|
797
|
+
default: throw new J(`unknown encoding "${e.encoding}" for field "${e.name}"`);
|
|
798
|
+
}
|
|
799
|
+
return a;
|
|
800
|
+
}
|
|
801
|
+
function it(e, t, n) {
|
|
802
|
+
let r = e[t];
|
|
803
|
+
if (!(r instanceof Uint32Array)) throw new J(`geometry file is corrupt ("${n}" needs "${t}")`);
|
|
804
|
+
return r;
|
|
805
|
+
}
|
|
806
|
+
function at(e, n, r) {
|
|
807
|
+
let i = new DataView(n.buffer, n.byteOffset, n.byteLength).getUint32(0, !0), a = 4 + st(i);
|
|
808
|
+
if (a + Math.ceil(e.length / 4) > n.length) throw Error("truncated triangle data");
|
|
809
|
+
let o = new Uint32Array(e.length * 3);
|
|
810
|
+
t.decodeIndexBuffer(ct(o), o.length, 4, n.subarray(4, 4 + i));
|
|
811
|
+
let s = n.subarray(a);
|
|
812
|
+
for (let t = 0; t < r.length; t += 4) {
|
|
813
|
+
let n = r[t], i = r[t + 1] / 3, a = r[t + 3];
|
|
814
|
+
if (i + n > e.length) throw Error("meshlet range out of bounds");
|
|
815
|
+
for (let t = i; t < i + n; t++) {
|
|
816
|
+
let n = s[t >> 2] >> (t & 3) * 2 & 3, r = o[t * 3] - a, i = o[t * 3 + 1] - a, c = o[t * 3 + 2] - a, [l, u, d] = n === 0 ? [
|
|
817
|
+
r,
|
|
818
|
+
i,
|
|
819
|
+
c
|
|
820
|
+
] : n === 1 ? [
|
|
821
|
+
i,
|
|
822
|
+
c,
|
|
823
|
+
r
|
|
824
|
+
] : [
|
|
825
|
+
c,
|
|
826
|
+
r,
|
|
827
|
+
i
|
|
828
|
+
];
|
|
829
|
+
if ((l | u | d) >>> 8) throw Error("meshlet-local vertex id out of range");
|
|
830
|
+
e[t] = l | u << 8 | d << 16;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
function ot(e, t, n, r) {
|
|
835
|
+
let i = new Uint32Array(e);
|
|
836
|
+
for (let a = 0; a < t.length; a += 4) {
|
|
837
|
+
let o = t[a], s = t[a + 1], c = t[a + 3];
|
|
838
|
+
if (s + o * 3 > e || s / 3 + o > r.length) throw new J("geometry file is corrupt (meshlet range out of bounds)");
|
|
839
|
+
for (let e = 0; e < o; e++) {
|
|
840
|
+
let t = r[s / 3 + e];
|
|
841
|
+
for (let r = 0; r < 3; r++) {
|
|
842
|
+
let a = c + (t >> 8 * r & 255);
|
|
843
|
+
if (a >= n.length) throw new J("geometry file is corrupt (meshlet vertex out of bounds)");
|
|
844
|
+
i[s + e * 3 + r] = n[a];
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
return i;
|
|
849
|
+
}
|
|
850
|
+
var st = (e) => e + 3 & -4;
|
|
851
|
+
function ct(e) {
|
|
852
|
+
return new Uint8Array(e.buffer, e.byteOffset, e.byteLength);
|
|
853
|
+
}
|
|
854
|
+
function lt(e, t) {
|
|
855
|
+
if (e.length !== t.length) return !1;
|
|
856
|
+
if (e.byteOffset % 4 == 0 && t.byteOffset % 4 == 0 && e.length % 4 == 0) {
|
|
857
|
+
let n = new Uint32Array(e.buffer, e.byteOffset, e.length / 4), r = new Uint32Array(t.buffer, t.byteOffset, t.length / 4);
|
|
858
|
+
for (let e = 0; e < n.length; e++) if (n[e] !== r[e]) return !1;
|
|
859
|
+
return !0;
|
|
860
|
+
}
|
|
861
|
+
for (let n = 0; n < e.length; n++) if (e[n] !== t[n]) return !1;
|
|
862
|
+
return !0;
|
|
863
|
+
}
|
|
864
|
+
function ut(e, t) {
|
|
865
|
+
let n = new Uint32Array(e.buffer, e.byteOffset + t, e.length - t >> 2), r = 2166136261 ^ n.length;
|
|
866
|
+
for (let e = 0; e < n.length; e++) r = Math.imul(r ^ n[e], 16777619), r ^= r >>> 15;
|
|
867
|
+
return r >>> 0;
|
|
868
|
+
}
|
|
869
|
+
var dt = () => typeof CompressionStream < "u" && typeof DecompressionStream < "u";
|
|
870
|
+
async function ft(e) {
|
|
871
|
+
let t = new Blob([e]).stream().pipeThrough(new CompressionStream("deflate-raw"));
|
|
872
|
+
return new Uint8Array(await new Response(t).arrayBuffer());
|
|
873
|
+
}
|
|
874
|
+
async function pt(e) {
|
|
875
|
+
if (typeof DecompressionStream > "u") throw new J("this environment cannot decompress the geometry file (no DecompressionStream)");
|
|
876
|
+
let t = new Blob([e]).stream().pipeThrough(new DecompressionStream("deflate-raw"));
|
|
877
|
+
return new Uint8Array(await new Response(t).arrayBuffer());
|
|
878
|
+
}
|
|
879
|
+
function mt(e, t) {
|
|
880
|
+
if (typeof t == "number" && !Number.isFinite(t)) return { $number: String(t) };
|
|
881
|
+
if (ArrayBuffer.isView(t)) throw new J(`typed array nested inside field "${e}" cannot be serialized; store it as a top-level field`);
|
|
882
|
+
return t;
|
|
883
|
+
}
|
|
884
|
+
function ht(e, t) {
|
|
885
|
+
if (t && typeof t == "object" && !Array.isArray(t)) {
|
|
886
|
+
let e = Object.keys(t);
|
|
887
|
+
if (e.length === 1 && e[0] === "$number") return Number(t.$number);
|
|
888
|
+
}
|
|
889
|
+
return t;
|
|
890
|
+
}
|
|
891
|
+
//#endregion
|
|
892
|
+
//#region src/core/io/cache.ts
|
|
893
|
+
var gt = 3, _t = "three-virtual-geometry-cache", Y = "meshes", X = "meta", vt = 536870912, yt = 3e3;
|
|
894
|
+
async function bt(e, t = {}) {
|
|
895
|
+
let { cache: n, ...r } = t;
|
|
896
|
+
if (n?.store === !1 || !Ct()) return Fe(e, r);
|
|
897
|
+
let i = performance.now(), a = await St(e, r, n?.key).catch(() => null), o = a ? await Tt() : null;
|
|
898
|
+
if (!o || !a) return Fe(e, r);
|
|
899
|
+
let s = await Et(o, a);
|
|
900
|
+
if (s) try {
|
|
901
|
+
let e = await Ze(s);
|
|
902
|
+
return e.stats && (e.stats.buildMs = performance.now() - i), Ot(o, a), await r.onProgress?.(1), e;
|
|
903
|
+
} catch {
|
|
904
|
+
kt(o, a);
|
|
905
|
+
}
|
|
906
|
+
let c = await Fe(e, r);
|
|
907
|
+
try {
|
|
908
|
+
Dt(o, a, await Xe(c, { deflate: !1 }));
|
|
909
|
+
} catch {}
|
|
910
|
+
return c;
|
|
911
|
+
}
|
|
912
|
+
async function xt() {
|
|
913
|
+
if (!Ct()) return;
|
|
914
|
+
let e = await Tt();
|
|
915
|
+
e && await new Promise((t) => {
|
|
916
|
+
try {
|
|
917
|
+
let n = e.transaction([Y, X], "readwrite");
|
|
918
|
+
n.objectStore(Y).clear(), n.objectStore(X).clear(), n.oncomplete = n.onerror = n.onabort = () => t();
|
|
919
|
+
} catch {
|
|
920
|
+
t();
|
|
921
|
+
}
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
async function St(e, t = {}, n) {
|
|
925
|
+
let r = "v3.1";
|
|
926
|
+
if (n !== void 0) return `${r}:key:${n}`;
|
|
927
|
+
let i = globalThis.crypto?.subtle;
|
|
928
|
+
if (!i) throw Error("crypto.subtle unavailable");
|
|
929
|
+
let a = e, o = Object.keys(a).filter((e) => a[e] !== void 0 && a[e] !== null).sort(), s = [], c = [];
|
|
930
|
+
for (let e of o) {
|
|
931
|
+
let t = a[e];
|
|
932
|
+
ArrayBuffer.isView(t) ? (s.push([
|
|
933
|
+
e,
|
|
934
|
+
t.constructor.name,
|
|
935
|
+
t.byteLength
|
|
936
|
+
]), c.push(i.digest("SHA-256", t))) : s.push([e, t]);
|
|
937
|
+
}
|
|
938
|
+
let l = Object.entries(t).filter(([, e]) => e !== void 0 && typeof e != "function").sort(([e], [t]) => e < t ? -1 : 1), u = new TextEncoder().encode(JSON.stringify({
|
|
939
|
+
versions: r,
|
|
940
|
+
source: s,
|
|
941
|
+
options: l
|
|
942
|
+
})), d = await Promise.all(c), f = new Uint8Array(u.length + d.length * 32);
|
|
943
|
+
f.set(u), d.forEach((e, t) => f.set(new Uint8Array(e), u.length + t * 32));
|
|
944
|
+
let p = new Uint8Array(await i.digest("SHA-256", f));
|
|
945
|
+
return `${r}:sha256:${Array.from(p, (e) => e.toString(16).padStart(2, "0")).join("")}`;
|
|
946
|
+
}
|
|
947
|
+
function Ct() {
|
|
948
|
+
try {
|
|
949
|
+
return typeof indexedDB < "u" && indexedDB !== null;
|
|
950
|
+
} catch {
|
|
951
|
+
return !1;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
var wt = null;
|
|
955
|
+
function Tt() {
|
|
956
|
+
return wt ??= new Promise((e) => {
|
|
957
|
+
let t = setTimeout(() => e(null), yt), n = (n) => {
|
|
958
|
+
clearTimeout(t), e(n);
|
|
959
|
+
};
|
|
960
|
+
try {
|
|
961
|
+
let e = indexedDB.open(_t, 1);
|
|
962
|
+
e.onupgradeneeded = () => {
|
|
963
|
+
let t = e.result;
|
|
964
|
+
t.objectStoreNames.contains(Y) || t.createObjectStore(Y), t.objectStoreNames.contains(X) || t.createObjectStore(X);
|
|
965
|
+
}, e.onsuccess = () => {
|
|
966
|
+
let t = e.result;
|
|
967
|
+
t.onversionchange = () => {
|
|
968
|
+
t.close(), wt = Promise.resolve(null);
|
|
969
|
+
}, n(t);
|
|
970
|
+
}, e.onerror = e.onblocked = () => n(null);
|
|
971
|
+
} catch {
|
|
972
|
+
n(null);
|
|
973
|
+
}
|
|
974
|
+
}), wt;
|
|
975
|
+
}
|
|
976
|
+
function Et(e, t) {
|
|
977
|
+
return new Promise((n) => {
|
|
978
|
+
try {
|
|
979
|
+
let r = e.transaction(Y, "readonly").objectStore(Y).get(t);
|
|
980
|
+
r.onsuccess = () => {
|
|
981
|
+
let e = r.result;
|
|
982
|
+
n(e instanceof ArrayBuffer ? new Uint8Array(e) : e instanceof Uint8Array ? e : null);
|
|
983
|
+
}, r.onerror = () => n(null);
|
|
984
|
+
} catch {
|
|
985
|
+
n(null);
|
|
986
|
+
}
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
function Dt(e, t, n) {
|
|
990
|
+
return new Promise((r) => {
|
|
991
|
+
try {
|
|
992
|
+
let i = e.transaction([Y, X], "readwrite");
|
|
993
|
+
i.objectStore(Y).put(n.buffer.byteLength === n.length ? n.buffer : n.slice().buffer, t), i.objectStore(X).put({
|
|
994
|
+
size: n.length,
|
|
995
|
+
lastUsed: Date.now()
|
|
996
|
+
}, t), i.oncomplete = () => r(), i.onerror = i.onabort = () => r();
|
|
997
|
+
} catch {
|
|
998
|
+
r();
|
|
999
|
+
}
|
|
1000
|
+
}).then(() => At(e, t));
|
|
1001
|
+
}
|
|
1002
|
+
function Ot(e, t) {
|
|
1003
|
+
try {
|
|
1004
|
+
let n = e.transaction(X, "readwrite").objectStore(X), r = n.get(t);
|
|
1005
|
+
r.onsuccess = () => {
|
|
1006
|
+
let e = r.result;
|
|
1007
|
+
e && n.put({
|
|
1008
|
+
...e,
|
|
1009
|
+
lastUsed: Date.now()
|
|
1010
|
+
}, t);
|
|
1011
|
+
};
|
|
1012
|
+
} catch {}
|
|
1013
|
+
}
|
|
1014
|
+
function kt(e, t) {
|
|
1015
|
+
try {
|
|
1016
|
+
let n = e.transaction([Y, X], "readwrite");
|
|
1017
|
+
n.objectStore(Y).delete(t), n.objectStore(X).delete(t);
|
|
1018
|
+
} catch {}
|
|
1019
|
+
}
|
|
1020
|
+
function At(e, t) {
|
|
1021
|
+
return new Promise((n) => {
|
|
1022
|
+
try {
|
|
1023
|
+
let r = e.transaction([Y, X], "readwrite"), i = r.objectStore(X), a = i.getAllKeys(), o = i.getAll();
|
|
1024
|
+
o.onsuccess = () => {
|
|
1025
|
+
let e = a.result, n = o.result.map((t, n) => ({
|
|
1026
|
+
key: e[n],
|
|
1027
|
+
...t
|
|
1028
|
+
})), s = n.reduce((e, t) => e + t.size, 0);
|
|
1029
|
+
n.sort((e, t) => e.lastUsed - t.lastUsed);
|
|
1030
|
+
for (let e of n) {
|
|
1031
|
+
if (s <= vt) break;
|
|
1032
|
+
e.key !== t && (r.objectStore(Y).delete(e.key), i.delete(e.key), s -= e.size);
|
|
1033
|
+
}
|
|
1034
|
+
}, r.oncomplete = r.onerror = r.onabort = () => n();
|
|
1035
|
+
} catch {
|
|
1036
|
+
n();
|
|
1037
|
+
}
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
//#endregion
|
|
1041
|
+
//#region src/core/runtime/cut.ts
|
|
1042
|
+
function jt(e, t, n) {
|
|
1043
|
+
let r = t.viewMatrix, i = e.meshletBounds, a = new Uint8Array(e.meshletCount), o = t.scale ?? 1, s = (e, n, i, a, s) => {
|
|
1044
|
+
if (s >= 5e29) return Infinity;
|
|
1045
|
+
let c = r[0] * e + r[4] * n + r[8] * i + r[12], l = r[1] * e + r[5] * n + r[9] * i + r[13], u = r[2] * e + r[6] * n + r[10] * i + r[14], d = Math.max(Math.hypot(c, l, u) - a * o, t.near);
|
|
1046
|
+
return s * o * t.projScale / d;
|
|
1047
|
+
};
|
|
1048
|
+
for (let t = 0; t < e.meshletCount; t++) {
|
|
1049
|
+
let e = t * 16, r = s(i[e], i[e + 1], i[e + 2], i[e + 3], i[e + 8]), o = s(i[e + 4], i[e + 5], i[e + 6], i[e + 7], i[e + 9]);
|
|
1050
|
+
a[t] = +(r <= n && o > n);
|
|
1051
|
+
}
|
|
1052
|
+
return a;
|
|
1053
|
+
}
|
|
1054
|
+
function Mt(e, t) {
|
|
1055
|
+
let n = new Int8Array(e.meshletCount).fill(-1), { replacementStart: r, replacementIndices: i } = e, a = (e) => {
|
|
1056
|
+
if (n[e] !== -1) return n[e] === 1;
|
|
1057
|
+
let o = t[e] === 1;
|
|
1058
|
+
for (let t = r[e]; !o && t < r[e + 1]; t++) o = a(i[t]);
|
|
1059
|
+
return n[e] = +!!o, o;
|
|
1060
|
+
}, o = [];
|
|
1061
|
+
for (let t = 0; t < e.meshletCount; t++) e.meshletInfo[t * 4 + 2] === 0 && !a(t) && o.push(t);
|
|
1062
|
+
return o;
|
|
1063
|
+
}
|
|
1064
|
+
function Nt(e, t) {
|
|
1065
|
+
let n = t.viewMatrix, [r, i, a, o] = e.lodBoundsSphere, s = n[0] * r + n[4] * i + n[8] * a + n[12], c = n[1] * r + n[5] * i + n[9] * a + n[13], l = n[2] * r + n[6] * i + n[10] * a + n[14], u = Math.hypot(s, c, l), d = o * (t.scale ?? 1);
|
|
1066
|
+
return [Math.max(u - d, t.near), Math.max(u + d, t.near)];
|
|
1067
|
+
}
|
|
1068
|
+
function Pt(e, t, n) {
|
|
1069
|
+
let [r, i] = Nt(e, t), a = (t.scale ?? 1) * t.projScale, o = -1, s = -1, c = e.levelRanges.length / 2;
|
|
1070
|
+
for (let t = 0; t < c; t++) {
|
|
1071
|
+
let c = e.levelErrors[t * 2], l = e.levelErrors[t * 2 + 1], u = c * a / i <= n, d = l >= 5e29 || l * a / r > n;
|
|
1072
|
+
u && d && (o < 0 && (o = t), s = t);
|
|
1073
|
+
}
|
|
1074
|
+
return o < 0 ? [0, 0] : [e.levelRanges[o * 2], e.levelRanges[s * 2] + e.levelRanges[s * 2 + 1]];
|
|
1075
|
+
}
|
|
1076
|
+
function Ft(e, t, n) {
|
|
1077
|
+
let [r, i] = Nt(e, t), a = ye, o = (t.scale ?? 1) * t.projScale, s = -1, c = -1, l = 0, u = 0, d = e.levelRanges.length / 2;
|
|
1078
|
+
for (let t = 0; t < d; t++) {
|
|
1079
|
+
let d = e.levelErrors[t * 2], f = e.levelErrors[t * 2 + 1], p = d * o / i <= n, m = f >= 5e29 || f * o / r > n;
|
|
1080
|
+
if (!p || !m) continue;
|
|
1081
|
+
s < 0 && (s = t), c = t;
|
|
1082
|
+
let h = e.levelRanges[t * 2 + 1];
|
|
1083
|
+
l += h;
|
|
1084
|
+
let g = e.levelGuardErrors[t * 2], _ = e.levelGuardErrors[t * 2 + 1], v = g * o / r <= n * (1 - a), y = _ >= 5e29 || _ * o / i > n * (1 + a);
|
|
1085
|
+
v && y && (u += h);
|
|
1086
|
+
}
|
|
1087
|
+
if (s < 0) return null;
|
|
1088
|
+
let f = e.levelRanges[s * 2], p = e.levelRanges[c * 2] + e.levelRanges[c * 2 + 1];
|
|
1089
|
+
return l !== p - f || u !== l || l > 4 ? null : [f, p];
|
|
1090
|
+
}
|
|
1091
|
+
//#endregion
|
|
1092
|
+
//#region src/core/runtime/vgMaterial.ts
|
|
1093
|
+
var It = V("vec2", "vVgUv");
|
|
1094
|
+
function Lt(e) {
|
|
1095
|
+
if (!(e?.isTextureNode !== !0 || e.isCubeTextureNode || e.isTexture3DNode)) return It;
|
|
1096
|
+
}
|
|
1097
|
+
function Rt(e) {
|
|
1098
|
+
return se(e, It).setUpdateMatrix(!0);
|
|
1099
|
+
}
|
|
1100
|
+
var zt = [
|
|
1101
|
+
i.RGFormat,
|
|
1102
|
+
i.RED_GREEN_RGTC2_Format,
|
|
1103
|
+
i.RG11_EAC_Format
|
|
1104
|
+
];
|
|
1105
|
+
function Bt(e, t, n = i.TangentSpaceNormalMap) {
|
|
1106
|
+
let r = Rt(e), a = r.xyz.mul(2).sub(1);
|
|
1107
|
+
if (zt.includes(e.format)) {
|
|
1108
|
+
let e = r.xy.mul(2).sub(1);
|
|
1109
|
+
a = de(e, oe(S(1).sub(e.dot(e)).max(0)));
|
|
1110
|
+
}
|
|
1111
|
+
if (a = de(a.xy.mul(t), a.z), n === i.ObjectSpaceNormalMap) return ce(a);
|
|
1112
|
+
let o = ae.dFdx(), s = ae.dFdy(), c = It.dFdx(), l = It.dFdy(), u = I, d = s.cross(u), f = u.cross(o), p = d.mul(c.x).add(f.mul(l.x)), m = d.mul(c.y).add(f.mul(l.y)), h = p.dot(p).max(m.dot(m)), g = h.equal(0).select(0, h.inverseSqrt());
|
|
1113
|
+
return A(F(p.mul(g)), F(m.mul(g)), u).mul(a).normalize();
|
|
1114
|
+
}
|
|
1115
|
+
function Vt(e) {
|
|
1116
|
+
let t = e;
|
|
1117
|
+
if (!t.colorNode && (Ht(t.map) || Ht(t.alphaMap))) {
|
|
1118
|
+
let e = H(j, 1);
|
|
1119
|
+
if (Ht(t.map)) {
|
|
1120
|
+
let n = Rt(t.map);
|
|
1121
|
+
e = H(j.mul(n.rgb), n.a);
|
|
1122
|
+
}
|
|
1123
|
+
Ht(t.alphaMap) && (e = H(e.rgb, e.a.mul(Rt(t.alphaMap).g))), t.colorNode = e, t.map = null, t.alphaMap = null;
|
|
1124
|
+
}
|
|
1125
|
+
t.normalNode || (Ht(t.normalMap) ? t.normalNode = Bt(t.normalMap, M("normalScale", "vec2"), t.normalMapType) : Ht(t.bumpMap) && (t.normalNode = m(Rt(t.bumpMap).r, M("bumpScale", "float")))), !t.clearcoatNormalNode && Ht(t.clearcoatNormalMap) && (t.clearcoatNormalNode = Bt(t.clearcoatNormalMap, M("clearcoatNormalScale", "vec2"))), t.contextNode = t.contextNode ? v(t.contextNode, { getUV: Lt }) : v({ getUV: Lt }), e.needsUpdate = !0;
|
|
1126
|
+
}
|
|
1127
|
+
var Ht = (e) => e?.isTexture === !0, Ut = P, Wt = N, Gt = V("vec3", "vVgWorldNormal"), Kt = V("float", "vVgMeshlet"), qt = V("float", "vVgLod"), Jt = V("float", "vVgInstance"), Yt = V("vec3", "vVgTint"), Xt = Math.ceil(Math.log2(128)), Zt = (1 << Xt) - 1, Qt = 65535, $t = 64, en = 64, tn = 64, nn = 48, Z = 6, Q = 5, $ = 2, rn = .15, an = 1e30, on = 5, sn = 0, cn = 1, ln = 2, un = 3, dn = 4, fn = 12, pn = class {
|
|
1128
|
+
make;
|
|
1129
|
+
itemSize;
|
|
1130
|
+
maxItems;
|
|
1131
|
+
array;
|
|
1132
|
+
attribute;
|
|
1133
|
+
used = 0;
|
|
1134
|
+
constructor(e, t, n, r = Infinity) {
|
|
1135
|
+
this.make = e, this.itemSize = t, this.maxItems = r, this.array = e(Math.max(1, n) * t), this.attribute = new i.StorageBufferAttribute(this.array, t);
|
|
1136
|
+
}
|
|
1137
|
+
get capacity() {
|
|
1138
|
+
return this.array.length / this.itemSize;
|
|
1139
|
+
}
|
|
1140
|
+
reserve(e) {
|
|
1141
|
+
if (this.used + e > this.capacity) return -1;
|
|
1142
|
+
let t = this.used;
|
|
1143
|
+
return this.used += e, t;
|
|
1144
|
+
}
|
|
1145
|
+
grow(e) {
|
|
1146
|
+
let t = this.make(Math.min(Math.max(e, Math.ceil(this.capacity * 1.6)), Math.max(e, this.maxItems)) * this.itemSize);
|
|
1147
|
+
t.set(this.array), this.array = t, this.attribute = new i.StorageBufferAttribute(this.array, this.itemSize);
|
|
1148
|
+
}
|
|
1149
|
+
touch(e, t) {
|
|
1150
|
+
t <= 0 || (this.attribute.addUpdateRange(e * this.itemSize, t * this.itemSize), this.attribute.needsUpdate = !0);
|
|
1151
|
+
}
|
|
1152
|
+
}, mn = (e) => new Float32Array(e), hn = (e) => new Uint32Array(e), gn = class {
|
|
1153
|
+
context;
|
|
1154
|
+
entries = [];
|
|
1155
|
+
meshSlots = B(0, "uint");
|
|
1156
|
+
cellCount = B(0, "uint");
|
|
1157
|
+
maxBytes;
|
|
1158
|
+
capacity;
|
|
1159
|
+
vertexData;
|
|
1160
|
+
vertexAttrs;
|
|
1161
|
+
meshletBounds;
|
|
1162
|
+
meshletInfo;
|
|
1163
|
+
meshletVertices;
|
|
1164
|
+
meshletTriangles;
|
|
1165
|
+
meshTable;
|
|
1166
|
+
instances;
|
|
1167
|
+
cells;
|
|
1168
|
+
meshSlotCapacity;
|
|
1169
|
+
levelUsed = 0;
|
|
1170
|
+
countersAttribute;
|
|
1171
|
+
drawArgsAttribute;
|
|
1172
|
+
cameraIndex;
|
|
1173
|
+
shadowIndex;
|
|
1174
|
+
computeNodes = [];
|
|
1175
|
+
positionNode = null;
|
|
1176
|
+
version = 0;
|
|
1177
|
+
needsRebuild = !0;
|
|
1178
|
+
indexBuffersReady = !1;
|
|
1179
|
+
pipelineState = "none";
|
|
1180
|
+
dirty = !0;
|
|
1181
|
+
hasCut = !1;
|
|
1182
|
+
constructor(e, t, n) {
|
|
1183
|
+
this.context = e, this.capacity = t, this.maxBytes = n, this.meshSlotCapacity = 64;
|
|
1184
|
+
let r = (e) => Math.floor(n / e);
|
|
1185
|
+
this.vertexData = new pn(hn, 4, 65536, r(16)), this.vertexAttrs = new pn(hn, 2, 65536, r(8)), this.meshletBounds = new pn(mn, 16, 4096, r(64)), this.meshletInfo = new pn(hn, 4, 4096, r(16)), this.meshletVertices = new pn(hn, 1, 1 << 18, r(4)), this.meshletTriangles = new pn(hn, 1, 1 << 18, r(4)), this.meshTable = new pn(mn, 4, this.meshSlotCapacity * Z + 1024, r(16)), this.meshTable.used = this.meshSlotCapacity * Z, this.instances = new pn(mn, 4, 4096, r(80) * Q), this.cells = new pn(mn, 4, 256, r(16));
|
|
1186
|
+
}
|
|
1187
|
+
static bytesOf(e) {
|
|
1188
|
+
return Math.max(e.positions.length / 3 * 16, e.meshletVertices.length * 4, e.meshletTriangles.length * 4, e.meshletCount * 64);
|
|
1189
|
+
}
|
|
1190
|
+
fits(e, t) {
|
|
1191
|
+
let n = (e, t, n) => (e + t) * n <= this.maxBytes;
|
|
1192
|
+
return n(this.vertexData.used, e.positions.length / 3, 16) && n(this.meshletBounds.used, e.meshletCount, 64) && n(this.meshletVertices.used, e.meshletVertices.length, 4) && n(this.meshletTriangles.used, e.meshletTriangles.length, 4) && n(this.instances.used, t * Q, 16);
|
|
1193
|
+
}
|
|
1194
|
+
add(e, t, n, r) {
|
|
1195
|
+
let i = this.entries.indexOf(null);
|
|
1196
|
+
i === -1 && (i = this.entries.length), i >= this.meshSlotCapacity && this.growMeshSlots(i + 1);
|
|
1197
|
+
let a = e.positions.length / 3, o = e.levelRanges.length / 2, s = t.length / 16, c = Math.ceil(s / 128), l = (e, t) => {
|
|
1198
|
+
let n = e.reserve(t);
|
|
1199
|
+
return n === -1 && (e.grow(e.used + t), this.needsRebuild = !0, n = e.reserve(t)), n;
|
|
1200
|
+
}, u = {
|
|
1201
|
+
slot: i,
|
|
1202
|
+
data: e,
|
|
1203
|
+
vertexBase: l(this.vertexData, a),
|
|
1204
|
+
meshletBase: l(this.meshletBounds, e.meshletCount),
|
|
1205
|
+
meshletVertexBase: l(this.meshletVertices, e.meshletVertices.length),
|
|
1206
|
+
triangleBase: l(this.meshletTriangles, e.meshletTriangles.length),
|
|
1207
|
+
levelBase: 0,
|
|
1208
|
+
levelCount: o,
|
|
1209
|
+
instanceBase: l(this.instances, s * Q) / Q,
|
|
1210
|
+
instanceCount: s,
|
|
1211
|
+
cellBase: l(this.cells, c * $) / $,
|
|
1212
|
+
cellCount: c,
|
|
1213
|
+
uvScale: [1, 1],
|
|
1214
|
+
uvOffset: [0, 0]
|
|
1215
|
+
};
|
|
1216
|
+
return l(this.meshletInfo, e.meshletCount), l(this.vertexAttrs, a), u.levelBase = this.meshSlotCapacity * Z + this.levelUsed, u.levelBase + o * 2 > this.meshTable.capacity && (this.meshTable.grow(u.levelBase + o * 2), this.needsRebuild = !0), this.levelUsed += o * 2, this.meshTable.used = Math.max(this.meshTable.used, u.levelBase + o * 2), this.entries[i] = u, this.writeGeometry(u), this.writeInstances(u, t, n, r), this.writeMeshRecord(u, {
|
|
1217
|
+
maxDrawDistance: an,
|
|
1218
|
+
minPixelRadius: 0,
|
|
1219
|
+
enabled: 1,
|
|
1220
|
+
shadow: 1,
|
|
1221
|
+
occlusion: 0
|
|
1222
|
+
}), this.meshSlots.value = Math.max(this.meshSlots.value, i + 1), this.cellCount.value = this.cells.used / $, this.dirty = !0, u;
|
|
1223
|
+
}
|
|
1224
|
+
remove(e) {
|
|
1225
|
+
this.writeFlags(e, { enabled: 0 }), this.entries[e.slot] = null, this.dirty = !0;
|
|
1226
|
+
}
|
|
1227
|
+
growMeshSlots(e) {
|
|
1228
|
+
let t = this.meshSlotCapacity, n = Math.max(e, t * 2), r = (n - t) * Z, i = t * Z, a = this.meshTable.used + r;
|
|
1229
|
+
a > this.meshTable.capacity && this.meshTable.grow(a);
|
|
1230
|
+
let o = this.meshTable.array;
|
|
1231
|
+
o.copyWithin((i + r) * 4, i * 4, this.meshTable.used * 4), o.fill(0, i * 4, (i + r) * 4), this.meshTable.used += r, this.meshSlotCapacity = n;
|
|
1232
|
+
for (let e of this.entries) e && (e.levelBase += r, o[(e.slot * Z + 3) * 4 + 3] = e.levelBase);
|
|
1233
|
+
this.needsRebuild = !0;
|
|
1234
|
+
}
|
|
1235
|
+
writeGeometry(e) {
|
|
1236
|
+
let t = e.data, n = t.positions.length / 3, r = this.vertexData.array, i = new Float32Array(r.buffer, r.byteOffset, r.length);
|
|
1237
|
+
for (let a = 0; a < n; a++) {
|
|
1238
|
+
let n = (e.vertexBase + a) * 4;
|
|
1239
|
+
i[n] = t.positions[a * 3], i[n + 1] = t.positions[a * 3 + 1], i[n + 2] = t.positions[a * 3 + 2], r[n + 3] = bn(t.normals[a * 3], t.normals[a * 3 + 1], t.normals[a * 3 + 2]);
|
|
1240
|
+
}
|
|
1241
|
+
this.vertexData.touch(e.vertexBase, n);
|
|
1242
|
+
let a = this.vertexAttrs.array, o = t.uvs ? xn(t.uvs) : null;
|
|
1243
|
+
o && (e.uvScale = o.scale, e.uvOffset = o.offset);
|
|
1244
|
+
let s = (e) => Math.round(Math.max(0, Math.min(1, e)) * 255);
|
|
1245
|
+
for (let r = 0; r < n; r++) {
|
|
1246
|
+
let n = (e.vertexBase + r) * 2;
|
|
1247
|
+
a[n] = t.colors ? (s(t.colors[r * 3]) | s(t.colors[r * 3 + 1]) << 8 | s(t.colors[r * 3 + 2]) << 16 | 255 << 24) >>> 0 : 4294967295, a[n + 1] = o ? o.packed[r] : 0;
|
|
1248
|
+
}
|
|
1249
|
+
this.vertexAttrs.touch(e.vertexBase, n), this.meshletBounds.array.set(t.meshletBounds, e.meshletBase * 16), this.meshletBounds.touch(e.meshletBase, t.meshletCount);
|
|
1250
|
+
let c = this.meshletInfo.array;
|
|
1251
|
+
for (let n = 0; n < t.meshletCount; n++) {
|
|
1252
|
+
let r = (e.meshletBase + n) * 4, i = n * 4;
|
|
1253
|
+
c[r] = t.meshletInfo[i], c[r + 1] = t.meshletInfo[i + 1] + e.triangleBase * 3, c[r + 2] = t.meshletInfo[i + 2], c[r + 3] = t.meshletInfo[i + 3] + e.meshletVertexBase;
|
|
1254
|
+
}
|
|
1255
|
+
this.meshletInfo.touch(e.meshletBase, t.meshletCount);
|
|
1256
|
+
let l = this.meshletVertices.array;
|
|
1257
|
+
for (let n = 0; n < t.meshletVertices.length; n++) l[e.meshletVertexBase + n] = t.meshletVertices[n] + e.vertexBase;
|
|
1258
|
+
this.meshletVertices.touch(e.meshletVertexBase, t.meshletVertices.length), this.meshletTriangles.array.set(t.meshletTriangles, e.triangleBase), this.meshletTriangles.touch(e.triangleBase, t.meshletTriangles.length);
|
|
1259
|
+
let u = this.meshTable.array;
|
|
1260
|
+
for (let n = 0; n < e.levelCount; n++) {
|
|
1261
|
+
let r = (e.levelBase + n * 2) * 4;
|
|
1262
|
+
u[r] = t.levelRanges[n * 2] + e.meshletBase, u[r + 1] = t.levelRanges[n * 2 + 1], u[r + 2] = t.levelErrors[n * 2], u[r + 3] = t.levelErrors[n * 2 + 1], u[r + 4] = t.levelGuardErrors[n * 2], u[r + 5] = t.levelGuardErrors[n * 2 + 1], u[r + 6] = 0, u[r + 7] = 0;
|
|
1263
|
+
}
|
|
1264
|
+
this.meshTable.touch(e.levelBase, e.levelCount * 2);
|
|
1265
|
+
}
|
|
1266
|
+
writeMeshRecord(e, t) {
|
|
1267
|
+
let n = this.meshTable.array, r = e.slot * Z * 4;
|
|
1268
|
+
n.set(e.data.boundingSphere, r), n.set(e.data.lodBoundsSphere, r + 4), n.set(e.data.cullBoundsSphere, r + 8), n.set([
|
|
1269
|
+
t.maxDrawDistance,
|
|
1270
|
+
t.minPixelRadius,
|
|
1271
|
+
e.levelCount,
|
|
1272
|
+
e.levelBase
|
|
1273
|
+
], r + 12), n.set([
|
|
1274
|
+
e.uvScale[0],
|
|
1275
|
+
e.uvScale[1],
|
|
1276
|
+
e.uvOffset[0],
|
|
1277
|
+
e.uvOffset[1]
|
|
1278
|
+
], r + 16), n.set([
|
|
1279
|
+
t.enabled,
|
|
1280
|
+
t.shadow,
|
|
1281
|
+
t.occlusion,
|
|
1282
|
+
0
|
|
1283
|
+
], r + 20), this.meshTable.touch(e.slot * Z, Z), this.dirty = !0;
|
|
1284
|
+
}
|
|
1285
|
+
writeFlags(e, t) {
|
|
1286
|
+
let n = this.meshTable.array, r = e.slot * Z * 4, i = (t, i) => {
|
|
1287
|
+
i !== void 0 && n[r + t] !== i && (n[r + t] = i, this.meshTable.touch(e.slot * Z + (t >> 2), 1), this.dirty = !0);
|
|
1288
|
+
};
|
|
1289
|
+
i(12, t.maxDrawDistance), i(13, t.minPixelRadius), i(20, t.enabled), i(21, t.shadow), i(22, t.occlusion);
|
|
1290
|
+
}
|
|
1291
|
+
readFlag(e, t) {
|
|
1292
|
+
return this.meshTable.array[e.slot * Z * 4 + {
|
|
1293
|
+
maxDrawDistance: 12,
|
|
1294
|
+
minPixelRadius: 13,
|
|
1295
|
+
enabled: 20,
|
|
1296
|
+
shadow: 21,
|
|
1297
|
+
occlusion: 22
|
|
1298
|
+
}[t]];
|
|
1299
|
+
}
|
|
1300
|
+
writeInstances(e, t, n, r) {
|
|
1301
|
+
let i = this.instances.array;
|
|
1302
|
+
for (let a = 0; a < e.instanceCount; a++) {
|
|
1303
|
+
let o = r[a], s = (e.instanceBase + a) * Q * 4;
|
|
1304
|
+
i.set(t.subarray(o * 16, o * 16 + 16), s), n ? i.set(n.subarray(o * 4, o * 4 + 3), s + 16) : i.fill(1, s + 16, s + 19), i[s + 19] = e.slot;
|
|
1305
|
+
}
|
|
1306
|
+
this.instances.touch(e.instanceBase * Q, e.instanceCount * Q);
|
|
1307
|
+
for (let t = 0; t < e.cellCount; t++) this.computeCell(e, t);
|
|
1308
|
+
this.cells.touch(e.cellBase * $, e.cellCount * $);
|
|
1309
|
+
}
|
|
1310
|
+
setMatrix(e, t, n) {
|
|
1311
|
+
n.toArray(this.instances.array, (e.instanceBase + t) * Q * 4);
|
|
1312
|
+
}
|
|
1313
|
+
commitInstances(e, t) {
|
|
1314
|
+
this.instances.touch(e.instanceBase * Q, e.instanceCount * Q);
|
|
1315
|
+
for (let n of t) this.computeCell(e, n), this.cells.touch((e.cellBase + n) * $, $);
|
|
1316
|
+
this.dirty = !0;
|
|
1317
|
+
}
|
|
1318
|
+
computeCell(e, t) {
|
|
1319
|
+
let n = this.instances.array, r = t * 128, i = Math.min(r + 128, e.instanceCount), a = /* @__PURE__ */ new Float64Array(4), o = [
|
|
1320
|
+
Infinity,
|
|
1321
|
+
Infinity,
|
|
1322
|
+
Infinity
|
|
1323
|
+
], s = [
|
|
1324
|
+
-Infinity,
|
|
1325
|
+
-Infinity,
|
|
1326
|
+
-Infinity
|
|
1327
|
+
], c = 0;
|
|
1328
|
+
for (let t = r; t < i; t++) {
|
|
1329
|
+
_n(n, (e.instanceBase + t) * Q * 4, e.data.boundingSphere, a);
|
|
1330
|
+
for (let e = 0; e < 3; e++) o[e] = Math.min(o[e], a[e] - a[3]), s[e] = Math.max(s[e], a[e] + a[3]);
|
|
1331
|
+
c = Math.max(c, a[3]);
|
|
1332
|
+
}
|
|
1333
|
+
let l = (o[0] + s[0]) / 2, u = (o[1] + s[1]) / 2, d = (o[2] + s[2]) / 2, f = 0;
|
|
1334
|
+
for (let t = r; t < i; t++) _n(n, (e.instanceBase + t) * Q * 4, e.data.boundingSphere, a), f = Math.max(f, Math.hypot(a[0] - l, a[1] - u, a[2] - d) + a[3]);
|
|
1335
|
+
let p = (e.cellBase + t) * $ * 4;
|
|
1336
|
+
this.cells.array.set([
|
|
1337
|
+
l,
|
|
1338
|
+
u,
|
|
1339
|
+
d,
|
|
1340
|
+
f * 1.0001 + .001,
|
|
1341
|
+
c * 1.0001 + 1e-4,
|
|
1342
|
+
e.slot,
|
|
1343
|
+
e.instanceBase + r,
|
|
1344
|
+
i - r
|
|
1345
|
+
], p);
|
|
1346
|
+
}
|
|
1347
|
+
prepare(e) {
|
|
1348
|
+
if (this.ensureBuilt(), this.indexBuffersReady) return;
|
|
1349
|
+
let t = e.backend;
|
|
1350
|
+
t.createIndexAttribute(this.cameraIndex), t.createIndexAttribute(this.shadowIndex), this.indexBuffersReady = !0;
|
|
1351
|
+
}
|
|
1352
|
+
ensureBuilt() {
|
|
1353
|
+
this.needsRebuild && this.build();
|
|
1354
|
+
}
|
|
1355
|
+
build() {
|
|
1356
|
+
this.needsRebuild = !1, this.indexBuffersReady = !1, this.pipelineState = "none", this.hasCut = !1, this.version++;
|
|
1357
|
+
for (let e of this.computeNodes) e.dispose();
|
|
1358
|
+
let e = this.context, t = this.capacity, n = this.meshSlotCapacity, r = t.meshlets, m = Math.floor(this.instances.capacity / Q), h = Math.floor(this.cells.capacity / $), g = t.triangles * 3, _ = t.shadowTriangles * 3, v = (e, t) => R(e.attribute, t, e.capacity), b = v(this.vertexData, "uvec4").toReadOnly(), x = v(this.vertexAttrs, "uvec2").toReadOnly(), C = v(this.meshletBounds, "vec4").toReadOnly(), w = v(this.meshletInfo, "uvec4").toReadOnly(), E = v(this.meshletVertices, "uint").toReadOnly(), D = v(this.meshletTriangles, "uint").toReadOnly(), ee = v(this.meshTable, "vec4").toReadOnly(), A = v(this.instances, "vec4").toReadOnly(), j = v(this.cells, "vec4").toReadOnly();
|
|
1359
|
+
this.countersAttribute = new i.StorageBufferAttribute(new Uint32Array(fn + 2 * n * 2), 1), this.drawArgsAttribute = new i.IndirectStorageBufferAttribute(new Uint32Array(2 * n * 5), 1), this.cameraIndex = new i.StorageBufferAttribute(new Uint32Array(g), 1), this.shadowIndex = new i.StorageBufferAttribute(new Uint32Array(_), 1);
|
|
1360
|
+
let M = new i.StorageBufferAttribute(new Uint32Array(h * 4), 4), F = new i.StorageBufferAttribute(new Uint32Array(m * 2 * 4), 4), I = new i.StorageBufferAttribute(new Uint32Array(r * 2 * 4), 4), ae = () => new i.IndirectStorageBufferAttribute(/* @__PURE__ */ new Uint32Array(3), 3), oe = ae(), se = [ae(), ae()], ce = [ae(), ae()], B = R(this.countersAttribute, "uint", this.countersAttribute.count).toAtomic(), V = R(this.drawArgsAttribute, "uint", this.drawArgsAttribute.count), de = R(this.cameraIndex, "uint", g), ge = R(this.shadowIndex, "uint", _), _e = R(M, "uvec4", h), be = R(M, "uvec4", h).toReadOnly(), xe = R(F, "uvec4", m * 2), Se = R(I, "uvec4", r * 2), Ce = R(I, "uvec4", r * 2).toReadOnly(), we = R(oe, "uint", 3), Te = se.map((e) => R(e, "uint", 3)), Ee = ce.map((e) => R(e, "uint", 3)), U = (e, t) => B.element(2 + e * on + t), De = (e, t) => B.element(z(fn + e * n * 2).add(t.mul(2))), Oe = (e, t) => B.element(z(fn + e * n * 2 + 1).add(t.mul(2))), ke = [g, _], Ae = [de, ge], je = e.errorThreshold.mul(e.shadowErrorScale), Me = [e.errorThreshold, je], Ne = e.minPixelRadius, Pe = e.occlusion, Fe = (e, t) => A.element(e.mul(Q).add(t)), Ie = (e) => {
|
|
1361
|
+
let t = [
|
|
1362
|
+
0,
|
|
1363
|
+
1,
|
|
1364
|
+
2,
|
|
1365
|
+
3
|
|
1366
|
+
].map((t) => Fe(e, t).toVar());
|
|
1367
|
+
return {
|
|
1368
|
+
model: te(t[0], t[1], t[2], t[3]).toVar(),
|
|
1369
|
+
scale: N(O(t[0].xyz), N(O(t[1].xyz), O(t[2].xyz))).toVar(),
|
|
1370
|
+
columns: t
|
|
1371
|
+
};
|
|
1372
|
+
}, W = (e, t) => ee.element(e.mul(Z).add(t)), Le = (t, n, r, i) => {
|
|
1373
|
+
let a = e.viewMatrix.mul(t.mul(H(r.xyz, 1))), o = N(O(a.xyz).sub(r.w.mul(n)), e.near), s = i.mul(n).div(o).mul(e.projScale);
|
|
1374
|
+
return L(i.greaterThanEqual(ve * .5), S(ve), s);
|
|
1375
|
+
}, G = (t, n) => {
|
|
1376
|
+
let r = S(1e30);
|
|
1377
|
+
for (let i of e.frustumPlanes) {
|
|
1378
|
+
let a = y(i.xyz, t).add(i.w);
|
|
1379
|
+
n !== !1 && (a = a.add(N(y(i.xyz, e.shadowSweep), 0).mul(n === !0 ? 1 : L(n, S(1), S(0))))), r = P(r, a);
|
|
1380
|
+
}
|
|
1381
|
+
return r;
|
|
1382
|
+
}, Re = (t, n, r) => {
|
|
1383
|
+
let i = e.viewMatrix.mul(H(n, 1)).xyz.toVar(), a = i.z.abs().mul(e.errorThreshold).div(e.projScale);
|
|
1384
|
+
return t.and(Pe.activeNode.equal(1)).and(Pe.occluded(i, r.add(a)));
|
|
1385
|
+
}, K = (e, t) => {
|
|
1386
|
+
e.element(0).assign(Ut(t, z(Qt))), e.element(1).assign(t.add(65534).div(Qt)), e.element(2).assign(z(1));
|
|
1387
|
+
}, ze = a(() => {
|
|
1388
|
+
let e = T;
|
|
1389
|
+
o(e.lessThan(z(fn)), () => {
|
|
1390
|
+
d(B.element(e), z(0));
|
|
1391
|
+
}), o(e.lessThan(this.meshSlots.mul(4)), () => {
|
|
1392
|
+
let t = e.div(this.meshSlots.mul(2)), r = e.mod(this.meshSlots.mul(2));
|
|
1393
|
+
d(B.element(z(fn).add(t.mul(n * 2)).add(r)), z(0));
|
|
1394
|
+
});
|
|
1395
|
+
})().compute(Math.max(fn, n * 4), [64]), Be = a(() => {
|
|
1396
|
+
o(T.greaterThanEqual(this.cellCount), () => {
|
|
1397
|
+
c();
|
|
1398
|
+
});
|
|
1399
|
+
let t = T.toVar(), n = j.element(t.mul($)).toVar(), r = j.element(t.mul($).add(1)).toVar(), i = z(r.y).toVar(), a = W(i, 5).toVar();
|
|
1400
|
+
o(a.x.equal(0), () => {
|
|
1401
|
+
c();
|
|
1402
|
+
});
|
|
1403
|
+
let s = n.xyz.toVar(), u = n.w.toVar();
|
|
1404
|
+
o(e.frustumCulling.equal(1).and(G(s, a.y.greaterThan(.5)).lessThan(u.negate())), () => {
|
|
1405
|
+
c();
|
|
1406
|
+
});
|
|
1407
|
+
let d = W(i, 3).toVar(), f = N(Ne, d.y), p = r.x, m = O(e.viewMatrix.mul(H(s, 1)).xyz).toVar().sub(u).toVar();
|
|
1408
|
+
o(m.greaterThan(p).and(p.mul(e.projScale).div(N(m, 1e-6)).lessThan(f)), () => {
|
|
1409
|
+
c();
|
|
1410
|
+
}), o(m.greaterThan(d.x), () => {
|
|
1411
|
+
c();
|
|
1412
|
+
});
|
|
1413
|
+
let h = l(B.element(0), z(1)).toVar();
|
|
1414
|
+
_e.element(h).assign(ue(i, z(r.z), z(r.w), t));
|
|
1415
|
+
})().compute(h, [$t]), Ve = a(() => {
|
|
1416
|
+
K(we, u(B.element(0)).toVar());
|
|
1417
|
+
})().compute(1), He = pe("vec4", 96), Ue = (t, n, i, a, c, u, d, f, p, h) => {
|
|
1418
|
+
let g = Me[t], _ = z(4294967295).toVar(), v = z(0).toVar(), y = z(0).toVar(), b = z(0).toVar();
|
|
1419
|
+
s({
|
|
1420
|
+
start: z(0),
|
|
1421
|
+
end: i,
|
|
1422
|
+
type: "uint",
|
|
1423
|
+
condition: "<"
|
|
1424
|
+
}, ({ i: e }) => {
|
|
1425
|
+
let t = He.element(e.mul(2)).toVar(), n = He.element(e.mul(2).add(1)).toVar(), r = z(t.x).toVar(), i = z(t.y).toVar(), a = t.z.mul(h).lessThanEqual(g).and(t.w.greaterThanEqual(ve * .5).or(t.w.mul(p).greaterThan(g))), s = n.x.mul(p).lessThanEqual(g.mul(1 - ye)).and(n.y.greaterThanEqual(ve * .5).or(n.y.mul(h).greaterThan(g.mul(1 + ye))));
|
|
1426
|
+
o(a, () => {
|
|
1427
|
+
_.assign(Ut(_, r)), v.assign(Wt(v, r.add(i))), y.addAssign(i), o(s, () => {
|
|
1428
|
+
b.addAssign(i);
|
|
1429
|
+
});
|
|
1430
|
+
});
|
|
1431
|
+
});
|
|
1432
|
+
let x = d.mul(H(c.xyz, 1)).xyz.toVar(), S = c.w.mul(f).toVar(), C = y.greaterThan(z(0)).and(y.equal(v.sub(_))).and(b.equal(y)).and(y.lessThanEqual(z(4))).and(e.frustumCulling.equal(0).or(G(x, t === 1).greaterThanEqual(S))).toVar();
|
|
1433
|
+
o(v.greaterThan(_), () => {
|
|
1434
|
+
l(U(t, ln), z(1)), o(C, () => {
|
|
1435
|
+
let e = l(U(t, sn), y).toVar();
|
|
1436
|
+
for (let i = 0; i < 4; i++) o(z(i).lessThan(y).and(e.add(i).lessThan(z(r))), () => {
|
|
1437
|
+
let a = _.add(i).toVar(), o = w.element(a).x.toVar(), s = l(De(t, n), o.mul(3)).toVar();
|
|
1438
|
+
Se.element(e.add(i + t * r)).assign(ue(u, a, s, o));
|
|
1439
|
+
});
|
|
1440
|
+
}).Else(() => {
|
|
1441
|
+
let e = l(U(t, un), z(1)).toVar(), r = n.bitOr(L(a, z(2147483648), z(0)));
|
|
1442
|
+
xe.element(e.add(t * m)).assign(ue(u, _, v, r));
|
|
1443
|
+
});
|
|
1444
|
+
});
|
|
1445
|
+
}, We = a(() => {
|
|
1446
|
+
let t = he.x.add(he.y.mul(ie.x)).toVar(), n = t.lessThan(u(B.element(0))).toVar(), r = be.element(Ut(t, z(h - 1))).toVar(), i = r.x, a = W(i, 3).toVar(), d = L(n, Ut(z(a.z), z(nn)), z(0)).toVar(), f = z(a.w).toVar();
|
|
1447
|
+
s({
|
|
1448
|
+
start: k.x,
|
|
1449
|
+
end: d.mul(2),
|
|
1450
|
+
type: "uint",
|
|
1451
|
+
condition: "<",
|
|
1452
|
+
update: $t
|
|
1453
|
+
}, ({ i: e }) => {
|
|
1454
|
+
He.element(e).assign(ee.element(f.add(e)));
|
|
1455
|
+
}), me(), o(n.not(), () => {
|
|
1456
|
+
c();
|
|
1457
|
+
});
|
|
1458
|
+
let m = W(i, 0).toVar(), g = W(i, 1).toVar(), _ = W(i, 2).toVar(), v = W(i, 5).toVar(), y = v.y.greaterThan(.5), b = v.z.greaterThan(.5), x = N(Ne, a.y).toVar(), S = a.x.toVar(), C = r.y.add(r.z);
|
|
1459
|
+
s({
|
|
1460
|
+
start: r.y.add(k.x),
|
|
1461
|
+
end: C,
|
|
1462
|
+
type: "uint",
|
|
1463
|
+
condition: "<",
|
|
1464
|
+
update: $t
|
|
1465
|
+
}, ({ i: t }) => {
|
|
1466
|
+
let n = t.toVar(), { model: r, scale: a } = Ie(n), s = r.mul(H(m.xyz, 1)).xyz.toVar(), c = m.w.mul(a).toVar(), u = e.frustumCulling.equal(0), f = u.or(G(s, !1).greaterThanEqual(c.negate())).toVar(), h = y.and(u.or(G(s, !0).greaterThanEqual(c.negate()))).toVar(), v = O(e.viewMatrix.mul(H(s, 1)).xyz).toVar(), C = v.greaterThan(c).and(c.mul(e.projScale).div(v).lessThan(x)), w = v.sub(c).greaterThan(S), T = f.or(h).and(C.not()).and(w.not());
|
|
1467
|
+
o(T, () => {
|
|
1468
|
+
o(f.and(Re(b, s, c)), () => {
|
|
1469
|
+
f.assign(p(!1)), l(B.element(1), z(1));
|
|
1470
|
+
});
|
|
1471
|
+
let t = e.viewMatrix.mul(r.mul(H(g.xyz, 1))), u = O(t.xyz).toVar(), m = g.w.mul(a), v = a.mul(e.projScale).div(N(u.sub(m), e.near)).toVar(), y = a.mul(e.projScale).div(N(u.add(m), e.near)).toVar();
|
|
1472
|
+
o(f, () => {
|
|
1473
|
+
Ue(0, i, d, b, _, n, r, a, v, y);
|
|
1474
|
+
}), o(h, () => {
|
|
1475
|
+
Ue(1, i, d, p(!1), _, n, r, a, v, y);
|
|
1476
|
+
});
|
|
1477
|
+
});
|
|
1478
|
+
});
|
|
1479
|
+
})().compute(oe, [$t]), Ge = (t) => [a(() => {
|
|
1480
|
+
K(Te[t], u(U(t, un)).toVar());
|
|
1481
|
+
})().compute(1), a(() => {
|
|
1482
|
+
let n = he.x.add(he.y.mul(ie.x)).toVar();
|
|
1483
|
+
o(n.greaterThanEqual(u(U(t, un))), () => {
|
|
1484
|
+
c();
|
|
1485
|
+
});
|
|
1486
|
+
let i = xe.element(n.add(t * m)).toVar(), a = i.x, d = i.w.bitAnd(2147483647).toVar(), f = i.w.shiftRight(31).equal(1), { model: p, scale: h } = Ie(a);
|
|
1487
|
+
s({
|
|
1488
|
+
start: i.y.add(k.x),
|
|
1489
|
+
end: i.z,
|
|
1490
|
+
type: "uint",
|
|
1491
|
+
condition: "<",
|
|
1492
|
+
update: en
|
|
1493
|
+
}, ({ i: n }) => {
|
|
1494
|
+
let i = n, s = i.mul(4).toVar(), c = C.element(s.add(3)), u = p.mul(H(c.xyz, 1)).xyz, m = e.frustumCulling.equal(0).or(G(u, t === 1).greaterThanEqual(c.w.mul(h).negate()));
|
|
1495
|
+
t === 0 && (m = m.and(Re(f, u, c.w.mul(h)).not()));
|
|
1496
|
+
let g = C.element(s.add(2)), _ = Le(p, h, C.element(s), g.x), v = Le(p, h, C.element(s.add(1)), g.y);
|
|
1497
|
+
o(m.and(_.lessThanEqual(Me[t])).and(v.greaterThan(Me[t])), () => {
|
|
1498
|
+
let e = l(U(t, sn), z(1)).toVar();
|
|
1499
|
+
o(e.lessThan(z(r)), () => {
|
|
1500
|
+
let n = w.element(i).x.toVar(), o = l(De(t, d), n.mul(3)).toVar();
|
|
1501
|
+
Se.element(e.add(t * r)).assign(ue(a, i, o, n));
|
|
1502
|
+
});
|
|
1503
|
+
});
|
|
1504
|
+
});
|
|
1505
|
+
})().compute(se[t], [en])], Ke = (e) => a(() => {
|
|
1506
|
+
let t = z(0).toVar(), i = z(ke[e]);
|
|
1507
|
+
s({
|
|
1508
|
+
start: z(0),
|
|
1509
|
+
end: this.meshSlots,
|
|
1510
|
+
type: "uint",
|
|
1511
|
+
condition: "<"
|
|
1512
|
+
}, ({ i: r }) => {
|
|
1513
|
+
let a = u(De(e, r)).toVar();
|
|
1514
|
+
d(Oe(e, r), t);
|
|
1515
|
+
let o = L(t.lessThan(i), i.sub(t), z(0)), s = z(e * n * 5).add(r.mul(5)).toVar();
|
|
1516
|
+
V.element(s).assign(Ut(a, o)), V.element(s.add(1)).assign(z(1)), V.element(s.add(2)).assign(t), V.element(s.add(3)).assign(z(0)), V.element(s.add(4)).assign(z(0)), t.addAssign(a);
|
|
1517
|
+
}), d(U(e, dn), t);
|
|
1518
|
+
let a = Ut(u(U(e, sn)), z(r)).toVar();
|
|
1519
|
+
d(U(e, cn), a), K(Ee[e], a);
|
|
1520
|
+
})().compute(1), qe = (e) => a(() => {
|
|
1521
|
+
let t = he.x.add(he.y.mul(ie.x)).toVar();
|
|
1522
|
+
o(t.greaterThanEqual(u(U(e, cn))), () => {
|
|
1523
|
+
c();
|
|
1524
|
+
});
|
|
1525
|
+
let n = t.add(e * r).toVar(), i = Ce.element(n).toVar(), a = z(Fe(i.x, 4).w).toVar(), l = u(Oe(e, a)).toVar(), d = w.element(i.y).y.div(3).toVar(), f = n.shiftLeft(Xt).toVar(), p = Ae[e];
|
|
1526
|
+
s({
|
|
1527
|
+
start: k.x,
|
|
1528
|
+
end: i.w,
|
|
1529
|
+
type: "uint",
|
|
1530
|
+
condition: "<",
|
|
1531
|
+
update: tn
|
|
1532
|
+
}, ({ i: t }) => {
|
|
1533
|
+
let n = l.add(i.z).add(t.mul(3)).toVar();
|
|
1534
|
+
o(n.add(2).lessThan(z(ke[e])), () => {
|
|
1535
|
+
let e = D.element(d.add(t)).toVar();
|
|
1536
|
+
p.element(n).assign(f.bitOr(e.bitAnd(255))), p.element(n.add(1)).assign(f.bitOr(e.shiftRight(8).bitAnd(255))), p.element(n.add(2)).assign(f.bitOr(e.shiftRight(16).bitAnd(255)));
|
|
1537
|
+
});
|
|
1538
|
+
});
|
|
1539
|
+
})().compute(ce[e], [tn]);
|
|
1540
|
+
this.computeNodes = [
|
|
1541
|
+
ze,
|
|
1542
|
+
Be,
|
|
1543
|
+
Ve,
|
|
1544
|
+
We,
|
|
1545
|
+
...Ge(0),
|
|
1546
|
+
...Ge(1),
|
|
1547
|
+
Ke(0),
|
|
1548
|
+
Ke(1),
|
|
1549
|
+
qe(0),
|
|
1550
|
+
qe(1)
|
|
1551
|
+
], this.positionNode = a(() => {
|
|
1552
|
+
let t = fe.shiftRight(Xt), n = fe.bitAnd(Zt), r = Ce.element(t).toVar(), i = r.x, a = r.y, o = w.element(a).toVar(), s = E.element(o.w.add(n)).toVar(), { model: c, columns: l } = Ie(i), u = Fe(i, 4).toVar(), d = z(u.w).toVar(), p = W(d, 3), m = W(d, 4).toVar(), h = b.element(s).toVar(), g = x.element(s).toVar(), _ = f(h.xyz, "vec3"), v = p.x, y = l[3].xyz, C = O(e.viewMatrix.mul(H(y, 1)).xyz), T = v.sub(C).div(v.mul(rn)).clamp(0, 1), D = y.add(c.mul(H(_, 0)).xyz.mul(T)), k = re(c.mul(H(vn(h.w), 0)).xyz);
|
|
1553
|
+
return ne.assign(k), Gt.assign(k), Kt.assign(S(a)), qt.assign(S(o.z)), Jt.assign(S(i)), Yt.assign(u.xyz.mul(yn(g.x).xyz)), It.assign(le(g.y).mul(m.xy).add(m.zw)), D;
|
|
1554
|
+
})();
|
|
1555
|
+
}
|
|
1556
|
+
async readCounters(e) {
|
|
1557
|
+
let t = new Uint32Array(await e.getArrayBufferAsync(this.countersAttribute)), n = this.meshSlotCapacity, r = (e) => ({
|
|
1558
|
+
selected: t[2 + e * on + sn],
|
|
1559
|
+
drawn: t[2 + e * on + cn],
|
|
1560
|
+
survived: t[2 + e * on + ln],
|
|
1561
|
+
requestedTriangles: t[2 + e * on + dn] / 3
|
|
1562
|
+
});
|
|
1563
|
+
return {
|
|
1564
|
+
camera: r(0),
|
|
1565
|
+
shadow: r(1),
|
|
1566
|
+
occluded: t[1],
|
|
1567
|
+
perMesh: (e, r) => t[fn + (e * n + r) * 2] / 3
|
|
1568
|
+
};
|
|
1569
|
+
}
|
|
1570
|
+
drawArgsOffset(e, t) {
|
|
1571
|
+
return (e * this.meshSlotCapacity + t) * 20;
|
|
1572
|
+
}
|
|
1573
|
+
dispose() {
|
|
1574
|
+
for (let e of this.computeNodes) e.dispose();
|
|
1575
|
+
this.computeNodes = [];
|
|
1576
|
+
}
|
|
1577
|
+
};
|
|
1578
|
+
function _n(e, t, n, r) {
|
|
1579
|
+
let [i, a, o, s] = n;
|
|
1580
|
+
r[0] = e[t] * i + e[t + 4] * a + e[t + 8] * o + e[t + 12], r[1] = e[t + 1] * i + e[t + 5] * a + e[t + 9] * o + e[t + 13], r[2] = e[t + 2] * i + e[t + 6] * a + e[t + 10] * o + e[t + 14];
|
|
1581
|
+
let c = Math.hypot(e[t], e[t + 1], e[t + 2]), l = Math.hypot(e[t + 4], e[t + 5], e[t + 6]), u = Math.hypot(e[t + 8], e[t + 9], e[t + 10]);
|
|
1582
|
+
r[3] = s * Math.max(c, l, u);
|
|
1583
|
+
}
|
|
1584
|
+
function vn(e) {
|
|
1585
|
+
let t = f(e, "int"), n = S(t.shiftLeft(16).shiftRight(16)).div(32767), r = S(t.shiftRight(16)).div(32767), i = S(1).sub(n.abs()).sub(r.abs()), a = Wt(i.negate(), 0), o = n.add(L(n.greaterThanEqual(0), a.negate(), a)), s = r.add(L(r.greaterThanEqual(0), a.negate(), a));
|
|
1586
|
+
return re(de(o, s, i));
|
|
1587
|
+
}
|
|
1588
|
+
function yn(e) {
|
|
1589
|
+
return H(S(e.bitAnd(255)), S(e.shiftRight(8).bitAnd(255)), S(e.shiftRight(16).bitAnd(255)), S(e.shiftRight(24))).div(255);
|
|
1590
|
+
}
|
|
1591
|
+
function bn(e, t, n) {
|
|
1592
|
+
let r = Math.abs(e) + Math.abs(t) + Math.abs(n) || 1, i = e / r, a = t / r;
|
|
1593
|
+
if (n < 0) {
|
|
1594
|
+
let e = (1 - Math.abs(a)) * (i >= 0 ? 1 : -1), t = (1 - Math.abs(i)) * (a >= 0 ? 1 : -1);
|
|
1595
|
+
i = e, a = t;
|
|
1596
|
+
}
|
|
1597
|
+
return (Math.round(Math.max(-1, Math.min(1, i)) * 32767) & 65535 | (Math.round(Math.max(-1, Math.min(1, a)) * 32767) & 65535) << 16) >>> 0;
|
|
1598
|
+
}
|
|
1599
|
+
function xn(e) {
|
|
1600
|
+
let t = e.length / 2, n = [Infinity, Infinity], r = [-Infinity, -Infinity];
|
|
1601
|
+
for (let t = 0; t < e.length; t++) {
|
|
1602
|
+
let i = t & 1;
|
|
1603
|
+
e[t] < n[i] && (n[i] = e[t]), e[t] > r[i] && (r[i] = e[t]);
|
|
1604
|
+
}
|
|
1605
|
+
t === 0 && (n[0] = n[1] = r[0] = r[1] = 0);
|
|
1606
|
+
let i = [r[0] - n[0] || 1, r[1] - n[1] || 1], a = new Uint32Array(t), o = (e, t) => Math.round(Math.max(0, Math.min(1, (e - n[t]) / i[t])) * 65535);
|
|
1607
|
+
for (let n = 0; n < t; n++) a[n] = (o(e[n * 2], 0) | o(e[n * 2 + 1], 1) << 16) >>> 0;
|
|
1608
|
+
return {
|
|
1609
|
+
packed: a,
|
|
1610
|
+
scale: i,
|
|
1611
|
+
offset: [n[0], n[1]]
|
|
1612
|
+
};
|
|
1613
|
+
}
|
|
1614
|
+
function Sn(e) {
|
|
1615
|
+
return e &= 1023, e = (e | e << 16) & 50331903, e = (e | e << 8) & 50393103, e = (e | e << 4) & 51130563, e = (e | e << 2) & 153391689, e;
|
|
1616
|
+
}
|
|
1617
|
+
function Cn(e, t) {
|
|
1618
|
+
let n = e.length / 16, r = /* @__PURE__ */ new Float64Array(4), i = new Float64Array(n * 3), a = [
|
|
1619
|
+
Infinity,
|
|
1620
|
+
Infinity,
|
|
1621
|
+
Infinity
|
|
1622
|
+
], o = [
|
|
1623
|
+
-Infinity,
|
|
1624
|
+
-Infinity,
|
|
1625
|
+
-Infinity
|
|
1626
|
+
];
|
|
1627
|
+
for (let s = 0; s < n; s++) {
|
|
1628
|
+
_n(e, s * 16, t, r);
|
|
1629
|
+
for (let e = 0; e < 3; e++) i[s * 3 + e] = r[e], a[e] = Math.min(a[e], r[e]), o[e] = Math.max(o[e], r[e]);
|
|
1630
|
+
}
|
|
1631
|
+
let s = Math.max(o[0] - a[0], o[1] - a[1], o[2] - a[2], 1e-9), c = new Uint32Array(n);
|
|
1632
|
+
for (let e = 0; e < n; e++) {
|
|
1633
|
+
let t = (t) => Math.min(1023, Math.max(0, Math.floor((i[e * 3 + t] - a[t]) / s * 1024)));
|
|
1634
|
+
c[e] = (Sn(t(0)) | Sn(t(1)) << 1 | Sn(t(2)) << 2) >>> 0;
|
|
1635
|
+
}
|
|
1636
|
+
return wn(c);
|
|
1637
|
+
}
|
|
1638
|
+
function wn(e) {
|
|
1639
|
+
let t = e.length, n = Uint32Array.from({ length: t }, (e, t) => t), r = new Uint32Array(t), i = /* @__PURE__ */ new Uint32Array(32768);
|
|
1640
|
+
for (let a of [0, 15]) {
|
|
1641
|
+
i.fill(0);
|
|
1642
|
+
for (let n = 0; n < t; n++) i[e[n] >>> a & 32767]++;
|
|
1643
|
+
let o = 0;
|
|
1644
|
+
for (let e = 0; e < i.length; e++) {
|
|
1645
|
+
let t = i[e];
|
|
1646
|
+
i[e] = o, o += t;
|
|
1647
|
+
}
|
|
1648
|
+
for (let o = 0; o < t; o++) {
|
|
1649
|
+
let t = n[o];
|
|
1650
|
+
r[i[e[t] >>> a & 32767]++] = t;
|
|
1651
|
+
}
|
|
1652
|
+
[n, r] = [r, n];
|
|
1653
|
+
}
|
|
1654
|
+
return n;
|
|
1655
|
+
}
|
|
1656
|
+
//#endregion
|
|
1657
|
+
//#region src/core/runtime/VirtualMesh.ts
|
|
1658
|
+
var Tn = /* @__PURE__ */ new WeakMap();
|
|
1659
|
+
function En(e) {
|
|
1660
|
+
let t = Tn.get(e);
|
|
1661
|
+
return t ? t.clone() : (Tn.set(e, e.clone()), e);
|
|
1662
|
+
}
|
|
1663
|
+
function Dn() {
|
|
1664
|
+
let e = new i.BufferGeometry();
|
|
1665
|
+
return e.setAttribute("position", new i.BufferAttribute(/* @__PURE__ */ new Float32Array(3), 3)), e.setAttribute("normal", new i.BufferAttribute(/* @__PURE__ */ new Float32Array(3), 3)), e;
|
|
1666
|
+
}
|
|
1667
|
+
var On = class extends i.Mesh {
|
|
1668
|
+
isVirtualMesh = !0;
|
|
1669
|
+
data;
|
|
1670
|
+
instanceCount;
|
|
1671
|
+
fullDetailTriangles;
|
|
1672
|
+
pool;
|
|
1673
|
+
entry;
|
|
1674
|
+
cameraGeometry = Dn();
|
|
1675
|
+
shadowGeometry = Dn();
|
|
1676
|
+
lastShadowFrame = 0;
|
|
1677
|
+
occluder;
|
|
1678
|
+
occlusionCulling = !0;
|
|
1679
|
+
gpuIndexOf;
|
|
1680
|
+
gpuToInput;
|
|
1681
|
+
dirtyCells = /* @__PURE__ */ new Set();
|
|
1682
|
+
drawingShadow = !1;
|
|
1683
|
+
poolVersion = -1;
|
|
1684
|
+
context;
|
|
1685
|
+
get maxDrawDistance() {
|
|
1686
|
+
let e = this.pool.readFlag(this.entry, "maxDrawDistance");
|
|
1687
|
+
return e >= 1e30 ? Infinity : e;
|
|
1688
|
+
}
|
|
1689
|
+
set maxDrawDistance(e) {
|
|
1690
|
+
this.pool.writeFlags(this.entry, { maxDrawDistance: Number.isFinite(e) ? Math.max(0, e) : an });
|
|
1691
|
+
}
|
|
1692
|
+
get minPixelRadius() {
|
|
1693
|
+
return this.pool.readFlag(this.entry, "minPixelRadius");
|
|
1694
|
+
}
|
|
1695
|
+
set minPixelRadius(e) {
|
|
1696
|
+
this.pool.writeFlags(this.entry, { minPixelRadius: Math.max(0, e) });
|
|
1697
|
+
}
|
|
1698
|
+
get capacity() {
|
|
1699
|
+
return {
|
|
1700
|
+
meshlets: this.pool.capacity.meshlets,
|
|
1701
|
+
triangles: this.pool.capacity.triangles
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
constructor(e, t, n, r, a = {}) {
|
|
1705
|
+
n = En(n);
|
|
1706
|
+
let o = Dn();
|
|
1707
|
+
super(o, n), this.context = e, this.data = t, this.frustumCulled = !1, this.instanceCount = r.matrices.length / 16, this.fullDetailTriangles = t.stats.leafTriangles * this.instanceCount, this.occluder = n.side !== i.DoubleSide && !n.transparent && n.alphaTest === 0 && !n.alphaHash, this.gpuToInput = Cn(r.matrices, t.boundingSphere), this.gpuIndexOf = new Uint32Array(this.instanceCount);
|
|
1708
|
+
for (let e = 0; e < this.instanceCount; e++) this.gpuIndexOf[this.gpuToInput[e]] = e;
|
|
1709
|
+
e.register(this, r), a.maxDrawDistance !== void 0 && (this.maxDrawDistance = a.maxDrawDistance), a.minPixelRadius !== void 0 && (this.minPixelRadius = a.minPixelRadius), Vt(n);
|
|
1710
|
+
let s = H(n.colorNode ?? j).toVar(), c = (e) => de(w(e), w(e.add(17.17)), w(e.add(43.43))), l = L(e.debugMode.equal(be.meshlets), c(Kt.add(Jt.mul(.618))), L(e.debugMode.equal(be.lodLevel), c(qt.add(3)), c(Jt)));
|
|
1711
|
+
n.colorNode = H(L(e.debugMode.equal(be.shaded), s.xyz.mul(Yt), l), s.w), n.side === i.DoubleSide && !n.normalNode && (n.normalNode = re(h.mul(H(Gt, 0)).xyz.mul(x))), this.syncPool(), this.geometry = this.cameraGeometry, o.dispose(), this.onBeforeShadow = (t, n, r, i) => {
|
|
1712
|
+
this.lastShadowFrame = e.frameCount, e.noteShadowCamera(i), this.drawingShadow = !0, this.geometry = this.shadowGeometry;
|
|
1713
|
+
};
|
|
1714
|
+
let u = this.onBeforeRender;
|
|
1715
|
+
this.onBeforeRender = (...e) => {
|
|
1716
|
+
this.drawingShadow ? this.drawingShadow = !1 : this.geometry = this.cameraGeometry, u.apply(this, e);
|
|
1717
|
+
};
|
|
1718
|
+
}
|
|
1719
|
+
syncPool() {
|
|
1720
|
+
let e = this.pool;
|
|
1721
|
+
this.poolVersion !== e.version && e.positionNode && (this.poolVersion = e.version, this.cameraGeometry.setIndex(e.cameraIndex), this.cameraGeometry.setIndirect(e.drawArgsAttribute, e.drawArgsOffset(0, this.entry.slot)), this.shadowGeometry.setIndex(e.shadowIndex), this.shadowGeometry.setIndirect(e.drawArgsAttribute, e.drawArgsOffset(1, this.entry.slot)), this.material.positionNode = e.positionNode, this.material.needsUpdate = !0);
|
|
1722
|
+
}
|
|
1723
|
+
markCutDirty() {
|
|
1724
|
+
this.pool.dirty = !0;
|
|
1725
|
+
}
|
|
1726
|
+
setMatrixAt(e, t) {
|
|
1727
|
+
let n = this.gpuIndexOf[e];
|
|
1728
|
+
this.pool.setMatrix(this.entry, n, t), this.dirtyCells.add(Math.floor(n / 128));
|
|
1729
|
+
}
|
|
1730
|
+
commitInstances() {
|
|
1731
|
+
this.pool.commitInstances(this.entry, this.dirtyCells), this.dirtyCells.clear();
|
|
1732
|
+
}
|
|
1733
|
+
dispose(e) {
|
|
1734
|
+
this.visible = !1, (e ?? this.context).unregister(this), this.removeFromParent();
|
|
1735
|
+
}
|
|
1736
|
+
async readStats(e) {
|
|
1737
|
+
let t = await this.pool.readCounters(e);
|
|
1738
|
+
return {
|
|
1739
|
+
drawnTriangles: t.perMesh(0, this.entry.slot),
|
|
1740
|
+
shadowTriangles: t.perMesh(1, this.entry.slot)
|
|
1741
|
+
};
|
|
1742
|
+
}
|
|
1743
|
+
}, kn = {
|
|
1744
|
+
MeshPhysicalMaterial: [i.MeshPhysicalMaterial, i.MeshPhysicalNodeMaterial],
|
|
1745
|
+
MeshStandardMaterial: [i.MeshStandardMaterial, i.MeshStandardNodeMaterial],
|
|
1746
|
+
MeshPhongMaterial: [i.MeshPhongMaterial, i.MeshPhongNodeMaterial],
|
|
1747
|
+
MeshLambertMaterial: [i.MeshLambertMaterial, i.MeshLambertNodeMaterial],
|
|
1748
|
+
MeshBasicMaterial: [i.MeshBasicMaterial, i.MeshBasicNodeMaterial],
|
|
1749
|
+
MeshToonMaterial: [i.MeshToonMaterial, i.MeshToonNodeMaterial],
|
|
1750
|
+
MeshMatcapMaterial: [i.MeshMatcapMaterial, i.MeshMatcapNodeMaterial],
|
|
1751
|
+
MeshNormalMaterial: [i.MeshNormalMaterial, i.MeshNormalNodeMaterial]
|
|
1752
|
+
}, An = [
|
|
1753
|
+
["isMeshPhysicalMaterial", "MeshPhysicalMaterial"],
|
|
1754
|
+
["isMeshStandardMaterial", "MeshStandardMaterial"],
|
|
1755
|
+
["isMeshPhongMaterial", "MeshPhongMaterial"],
|
|
1756
|
+
["isMeshLambertMaterial", "MeshLambertMaterial"],
|
|
1757
|
+
["isMeshBasicMaterial", "MeshBasicMaterial"],
|
|
1758
|
+
["isMeshToonMaterial", "MeshToonMaterial"],
|
|
1759
|
+
["isMeshMatcapMaterial", "MeshMatcapMaterial"],
|
|
1760
|
+
["isMeshNormalMaterial", "MeshNormalMaterial"]
|
|
1761
|
+
];
|
|
1762
|
+
function jn(e) {
|
|
1763
|
+
let t = e, n = kn[e.type] ? e.type : An.find(([e]) => t[e] === !0)?.[1];
|
|
1764
|
+
return n ? kn[n] : null;
|
|
1765
|
+
}
|
|
1766
|
+
function Mn(e) {
|
|
1767
|
+
return e.isNodeMaterial === !0 || jn(e) !== null;
|
|
1768
|
+
}
|
|
1769
|
+
function Nn(e) {
|
|
1770
|
+
if (e.isNodeMaterial) return e;
|
|
1771
|
+
let t = jn(e);
|
|
1772
|
+
if (!t) return null;
|
|
1773
|
+
let [n, r] = t, i = new r(), a = i.defines;
|
|
1774
|
+
return n.prototype.copy.call(i, e), i.defines = a, i;
|
|
1775
|
+
}
|
|
1776
|
+
//#endregion
|
|
1777
|
+
//#region src/source.ts
|
|
1778
|
+
var Pn = 1e-6, Fn = 1e-4;
|
|
1779
|
+
function In(e, t = {}) {
|
|
1780
|
+
let n = e.attributes.position, r = t.uvs ?? !0 ? e.attributes.uv : void 0, a = t.colors ? e.attributes.color : void 0, o = t.normals === "keep" ? e.attributes.normal : void 0, s = e.index, c = s ? s.count : n.count, l = Math.max(0, Math.min(c, t.range?.start ?? 0)), u = Math.floor((Math.min(c, l + (t.range?.count ?? c)) - l) / 3) * 3, d = (e) => s ? s.getX(l + e) : l + e, f = Rn(u, d, [{
|
|
1781
|
+
attribute: n,
|
|
1782
|
+
size: 3,
|
|
1783
|
+
tolerance: Pn
|
|
1784
|
+
}]), p = Ln(f.firstVertex, n, 3), m = null;
|
|
1785
|
+
if (!o) {
|
|
1786
|
+
let e = new i.BufferGeometry();
|
|
1787
|
+
e.setAttribute("position", new i.BufferAttribute(p, 3)), e.setIndex(new i.BufferAttribute(f.indices, 1)), e.computeVertexNormals(), m = e.attributes.normal.array;
|
|
1788
|
+
}
|
|
1789
|
+
if (!r && !a && !o) return {
|
|
1790
|
+
positions: p,
|
|
1791
|
+
normals: m,
|
|
1792
|
+
indices: f.indices
|
|
1793
|
+
};
|
|
1794
|
+
let h = [{
|
|
1795
|
+
attribute: n,
|
|
1796
|
+
size: 3,
|
|
1797
|
+
tolerance: Pn
|
|
1798
|
+
}];
|
|
1799
|
+
r && h.push({
|
|
1800
|
+
attribute: r,
|
|
1801
|
+
size: 2,
|
|
1802
|
+
tolerance: Pn
|
|
1803
|
+
}), o && h.push({
|
|
1804
|
+
attribute: o,
|
|
1805
|
+
size: 3,
|
|
1806
|
+
tolerance: Fn
|
|
1807
|
+
}), a && h.push({
|
|
1808
|
+
attribute: a,
|
|
1809
|
+
size: 3,
|
|
1810
|
+
tolerance: Fn
|
|
1811
|
+
});
|
|
1812
|
+
let g = Rn(u, d, h), _ = {
|
|
1813
|
+
positions: Ln(g.firstVertex, n, 3),
|
|
1814
|
+
normals: /* @__PURE__ */ new Float32Array(),
|
|
1815
|
+
indices: g.indices
|
|
1816
|
+
};
|
|
1817
|
+
if (o) {
|
|
1818
|
+
_.normals = Ln(g.firstVertex, o, 3);
|
|
1819
|
+
for (let e = 0; e < _.normals.length; e += 3) {
|
|
1820
|
+
let t = Math.hypot(_.normals[e], _.normals[e + 1], _.normals[e + 2]) || 1;
|
|
1821
|
+
_.normals[e] /= t, _.normals[e + 1] /= t, _.normals[e + 2] /= t;
|
|
1822
|
+
}
|
|
1823
|
+
} else {
|
|
1824
|
+
_.normals = new Float32Array(g.firstVertex.length * 3);
|
|
1825
|
+
for (let e = 0; e < g.firstVertex.length; e++) {
|
|
1826
|
+
let t = f.indices[g.firstCorner[e]];
|
|
1827
|
+
_.normals.set(m.subarray(t * 3, t * 3 + 3), e * 3);
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
return r && (_.uvs = Ln(g.firstVertex, r, 2)), a && (_.colors = Ln(g.firstVertex, a, 3)), _;
|
|
1831
|
+
}
|
|
1832
|
+
function Ln(e, t, n) {
|
|
1833
|
+
let r = new Float32Array(e.length * n);
|
|
1834
|
+
for (let i = 0; i < e.length; i++) for (let a = 0; a < n; a++) r[i * n + a] = t.getComponent(e[i], a);
|
|
1835
|
+
return r;
|
|
1836
|
+
}
|
|
1837
|
+
function Rn(e, t, n) {
|
|
1838
|
+
let r = n.reduce((e, t) => e + t.size, 0), i = n.map(({ tolerance: e }) => {
|
|
1839
|
+
let t = 10 ** Math.log10(1 / e);
|
|
1840
|
+
return {
|
|
1841
|
+
multiplier: t,
|
|
1842
|
+
additive: e * .5 * t
|
|
1843
|
+
};
|
|
1844
|
+
}), a = 1;
|
|
1845
|
+
for (; a < e * 2;) a <<= 1;
|
|
1846
|
+
let o = a - 1, s = new Int32Array(a).fill(-1), c = new Float64Array(e * r), l = new Float64Array(r), u = new Uint32Array(e), d = new Uint32Array(e), f = new Uint32Array(e), p = 0;
|
|
1847
|
+
for (let a = 0; a < e; a++) {
|
|
1848
|
+
let e = t(a), m = 0, h = 0;
|
|
1849
|
+
for (let t = 0; t < n.length; t++) {
|
|
1850
|
+
let { attribute: r, size: a } = n[t], { multiplier: o, additive: s } = i[t];
|
|
1851
|
+
for (let t = 0; t < a; t++, h++) l[h] = Math.trunc(r.getComponent(e, t) * o + s), m = m ^ Math.imul(l[h] | 0, zn[h % zn.length]) | 0;
|
|
1852
|
+
}
|
|
1853
|
+
for (m &= o;;) {
|
|
1854
|
+
let t = s[m];
|
|
1855
|
+
if (t < 0) {
|
|
1856
|
+
s[m] = p, c.set(l, p * r), u[p] = e, d[p] = a, f[a] = p++;
|
|
1857
|
+
break;
|
|
1858
|
+
}
|
|
1859
|
+
let n = !0;
|
|
1860
|
+
for (let e = 0; e < r && n; e++) n = c[t * r + e] === l[e];
|
|
1861
|
+
if (n) {
|
|
1862
|
+
f[a] = t;
|
|
1863
|
+
break;
|
|
1864
|
+
}
|
|
1865
|
+
m = m + 1 & o;
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
return {
|
|
1869
|
+
indices: f,
|
|
1870
|
+
firstVertex: u.slice(0, p),
|
|
1871
|
+
firstCorner: d.slice(0, p)
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
var zn = [
|
|
1875
|
+
73856093,
|
|
1876
|
+
19349663,
|
|
1877
|
+
83492791,
|
|
1878
|
+
2654435761,
|
|
1879
|
+
2246822519,
|
|
1880
|
+
3266489917,
|
|
1881
|
+
668265263,
|
|
1882
|
+
374761393,
|
|
1883
|
+
1181783497,
|
|
1884
|
+
3735928559,
|
|
1885
|
+
2028178513
|
|
1886
|
+
];
|
|
1887
|
+
function Bn(e) {
|
|
1888
|
+
let t = e.reduce((e, t) => e + t.mesh.positions.length / 3, 0), n = e.reduce((e, t) => e + t.mesh.indices.length, 0), r = new Float32Array(t * 3), a = new Float32Array(t * 3), o = new Float32Array(t * 3), s = e.some((e) => e.mesh.uvs) ? new Float32Array(t * 2) : null, c = new Uint32Array(n), l = new i.Color(), u = 0, d = 0;
|
|
1889
|
+
for (let { mesh: t, color: n = 16777215 } of e) {
|
|
1890
|
+
let e = t.positions.length / 3;
|
|
1891
|
+
if (r.set(t.positions, u * 3), a.set(t.normals, u * 3), s && t.uvs && s.set(t.uvs, u * 2), t.colors) o.set(t.colors, u * 3);
|
|
1892
|
+
else {
|
|
1893
|
+
l.set(n);
|
|
1894
|
+
for (let t = 0; t < e; t++) o.set([
|
|
1895
|
+
l.r,
|
|
1896
|
+
l.g,
|
|
1897
|
+
l.b
|
|
1898
|
+
], (u + t) * 3);
|
|
1899
|
+
}
|
|
1900
|
+
for (let e = 0; e < t.indices.length; e++) c[d + e] = t.indices[e] + u;
|
|
1901
|
+
u += e, d += t.indices.length;
|
|
1902
|
+
}
|
|
1903
|
+
return s ? {
|
|
1904
|
+
positions: r,
|
|
1905
|
+
normals: a,
|
|
1906
|
+
colors: o,
|
|
1907
|
+
uvs: s,
|
|
1908
|
+
indices: c
|
|
1909
|
+
} : {
|
|
1910
|
+
positions: r,
|
|
1911
|
+
normals: a,
|
|
1912
|
+
colors: o,
|
|
1913
|
+
indices: c
|
|
1914
|
+
};
|
|
1915
|
+
}
|
|
1916
|
+
//#endregion
|
|
1917
|
+
//#region src/core/import/fromObject3D.ts
|
|
1918
|
+
var Vn = bt, Hn = /* @__PURE__ */ new WeakSet();
|
|
1919
|
+
function Un(e) {
|
|
1920
|
+
let t = e;
|
|
1921
|
+
if (!t.isMesh) return "not a mesh";
|
|
1922
|
+
if (t.isVirtualMesh) return "already a VirtualMesh";
|
|
1923
|
+
if (t.isSkinnedMesh) return "skinned";
|
|
1924
|
+
if (t.isBatchedMesh) return "batched";
|
|
1925
|
+
let n = t.geometry;
|
|
1926
|
+
if (!n?.attributes?.position || n.isInstancedBufferGeometry) return "unsupported geometry";
|
|
1927
|
+
let r = n.morphAttributes;
|
|
1928
|
+
return (r.position?.length ?? 0) > 0 || (r.normal?.length ?? 0) > 0 || (t.morphTargetInfluences?.length ?? 0) > 0 ? "morph targets" : (Array.isArray(t.material) ? t.material : [t.material]).some((e) => !e || !Mn(e)) ? "material without a node equivalent" : null;
|
|
1929
|
+
}
|
|
1930
|
+
function Wn(e, t) {
|
|
1931
|
+
e.updateWorldMatrix(!0, !0);
|
|
1932
|
+
let n = /* @__PURE__ */ new Map(), r = [], a = [], o = new i.Matrix4(), s = new i.Matrix4(), c = new i.Color();
|
|
1933
|
+
e.traverse((e) => {
|
|
1934
|
+
if (!e.isMesh || Hn.has(e)) return;
|
|
1935
|
+
let i = e, l = Un(i) ?? (t && !t(i) ? "filtered out" : null);
|
|
1936
|
+
if (l) {
|
|
1937
|
+
a.push({
|
|
1938
|
+
object: i,
|
|
1939
|
+
reason: l
|
|
1940
|
+
});
|
|
1941
|
+
return;
|
|
1942
|
+
}
|
|
1943
|
+
let u = i.geometry, d = Array.isArray(i.material) ? i.material : [i.material], f = Gn(u, Array.isArray(i.material));
|
|
1944
|
+
if (f.length === 0) return;
|
|
1945
|
+
r.push(i);
|
|
1946
|
+
let p = i.isInstancedMesh ? i : null, m = p ? p.count : 1, h = Kn(i);
|
|
1947
|
+
for (let { start: e, count: t, materialIndex: r } of f) {
|
|
1948
|
+
let a = d[r];
|
|
1949
|
+
if (!a) continue;
|
|
1950
|
+
let l = a.vertexColors === !0 && u.attributes.color !== void 0, f = [
|
|
1951
|
+
u.id,
|
|
1952
|
+
e,
|
|
1953
|
+
t,
|
|
1954
|
+
a.uuid,
|
|
1955
|
+
i.castShadow,
|
|
1956
|
+
i.receiveShadow,
|
|
1957
|
+
h,
|
|
1958
|
+
i.renderOrder,
|
|
1959
|
+
i.layers.mask
|
|
1960
|
+
].join(":"), g = n.get(f);
|
|
1961
|
+
g || (g = {
|
|
1962
|
+
geometry: u,
|
|
1963
|
+
range: {
|
|
1964
|
+
start: e,
|
|
1965
|
+
count: t
|
|
1966
|
+
},
|
|
1967
|
+
material: a,
|
|
1968
|
+
matrices: /* @__PURE__ */ new Float32Array(),
|
|
1969
|
+
colors: null,
|
|
1970
|
+
instances: [],
|
|
1971
|
+
vertexColors: l,
|
|
1972
|
+
castShadow: i.castShadow,
|
|
1973
|
+
receiveShadow: i.receiveShadow,
|
|
1974
|
+
visible: h,
|
|
1975
|
+
renderOrder: i.renderOrder,
|
|
1976
|
+
layers: i.layers.mask,
|
|
1977
|
+
name: i.name,
|
|
1978
|
+
userData: { ...i.userData },
|
|
1979
|
+
matrixList: [],
|
|
1980
|
+
colorList: null
|
|
1981
|
+
}, n.set(f, g));
|
|
1982
|
+
for (let e = 0; e < m; e++) {
|
|
1983
|
+
p ? (p.getMatrixAt(e, o), s.multiplyMatrices(i.matrixWorld, o)) : s.copy(i.matrixWorld), g.matrixList.push(...s.elements);
|
|
1984
|
+
let t = !!p?.instanceColor;
|
|
1985
|
+
t && p.getColorAt(e, c), t && !g.colorList && (g.colorList = Array(g.instances.length * 4).fill(1)), g.colorList && (t ? g.colorList.push(c.r, c.g, c.b, 1) : g.colorList.push(1, 1, 1, 1)), g.instances.push({
|
|
1986
|
+
object: i,
|
|
1987
|
+
index: p ? e : -1
|
|
1988
|
+
});
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
});
|
|
1992
|
+
let l = [];
|
|
1993
|
+
for (let { matrixList: e, colorList: t, ...r } of n.values()) r.matrices = Float32Array.from(e), r.colors = t ? Float32Array.from(t) : null, l.push(r);
|
|
1994
|
+
return {
|
|
1995
|
+
groups: l,
|
|
1996
|
+
meshes: r,
|
|
1997
|
+
skipped: a
|
|
1998
|
+
};
|
|
1999
|
+
}
|
|
2000
|
+
function Gn(e, t) {
|
|
2001
|
+
let n = e.index ? e.index.count : e.attributes.position.count, r = Math.max(0, e.drawRange.start), i = Math.min(n, r + e.drawRange.count), a = t ? e.groups : [{
|
|
2002
|
+
start: 0,
|
|
2003
|
+
count: n,
|
|
2004
|
+
materialIndex: 0
|
|
2005
|
+
}], o = [];
|
|
2006
|
+
for (let e of a) {
|
|
2007
|
+
let t = Math.max(e.start, r), n = Math.min(e.start + e.count, i);
|
|
2008
|
+
n - t >= 3 && o.push({
|
|
2009
|
+
start: t,
|
|
2010
|
+
count: n - t,
|
|
2011
|
+
materialIndex: e.materialIndex ?? 0
|
|
2012
|
+
});
|
|
2013
|
+
}
|
|
2014
|
+
return o;
|
|
2015
|
+
}
|
|
2016
|
+
function Kn(e) {
|
|
2017
|
+
for (let t = e; t; t = t.parent) if (!t.visible) return !1;
|
|
2018
|
+
return !0;
|
|
2019
|
+
}
|
|
2020
|
+
var qn = class {
|
|
2021
|
+
context;
|
|
2022
|
+
object = new i.Group();
|
|
2023
|
+
meshes = [];
|
|
2024
|
+
groups;
|
|
2025
|
+
skipped;
|
|
2026
|
+
stats = {
|
|
2027
|
+
sourceMeshes: 0,
|
|
2028
|
+
instances: 0,
|
|
2029
|
+
uniqueGeometries: 0,
|
|
2030
|
+
buildMs: 0
|
|
2031
|
+
};
|
|
2032
|
+
hidden = /* @__PURE__ */ new Map();
|
|
2033
|
+
detached = /* @__PURE__ */ new Map();
|
|
2034
|
+
constructor(e, t) {
|
|
2035
|
+
this.context = e, this.object.name = "VirtualGeometryImport", this.groups = t.groups, this.skipped = t.skipped, this.stats.sourceMeshes = t.meshes.length, this.stats.instances = t.groups.reduce((e, t) => e + t.instances.length, 0);
|
|
2036
|
+
}
|
|
2037
|
+
hide(e, t) {
|
|
2038
|
+
let n = /* @__PURE__ */ new Set();
|
|
2039
|
+
for (let t of e) Hn.add(t), t.children.length === 0 && t.parent ? (this.detached.set(t, t.parent), n.add(t.parent), t.parent.remove(t)) : (this.hidden.has(t) || this.hidden.set(t, t.layers.mask), t.layers.disableAll());
|
|
2040
|
+
for (let e of n) for (; e !== t && e.children.length === 0 && e.parent && (e.type === "Group" || e.type === "Object3D");) {
|
|
2041
|
+
let t = e.parent;
|
|
2042
|
+
this.detached.set(e, t), t.remove(e), e = t;
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
worldMatrixOf(e) {
|
|
2046
|
+
let t = this.detached.get(e);
|
|
2047
|
+
return t ? (e.updateMatrix(), e.matrixWorld.multiplyMatrices(this.worldMatrixOf(t), e.matrix)) : (e.updateWorldMatrix(!0, !1), e.matrixWorld);
|
|
2048
|
+
}
|
|
2049
|
+
syncTransforms() {
|
|
2050
|
+
let e = new i.Matrix4(), t = new i.Matrix4(), n = /* @__PURE__ */ new Set();
|
|
2051
|
+
this.groups.forEach((r, i) => {
|
|
2052
|
+
let a = this.meshes[i];
|
|
2053
|
+
r.instances.forEach(({ object: r, index: i }, o) => {
|
|
2054
|
+
n.has(r) || (this.worldMatrixOf(r), n.add(r)), i >= 0 ? (r.getMatrixAt(i, t), e.multiplyMatrices(r.matrixWorld, t)) : e.copy(r.matrixWorld), a.setMatrixAt(o, e);
|
|
2055
|
+
}), a.commitInstances();
|
|
2056
|
+
});
|
|
2057
|
+
}
|
|
2058
|
+
dispose() {
|
|
2059
|
+
for (let e of this.meshes) e.dispose(this.context), e.material.dispose(), e.geometry.dispose();
|
|
2060
|
+
this.meshes.length = 0;
|
|
2061
|
+
for (let [e, t] of this.hidden) e.layers.mask = t, Hn.delete(e);
|
|
2062
|
+
this.hidden.clear();
|
|
2063
|
+
for (let [e, t] of this.detached) t.add(e), Hn.delete(e);
|
|
2064
|
+
this.detached.clear(), this.object.removeFromParent();
|
|
2065
|
+
}
|
|
2066
|
+
};
|
|
2067
|
+
async function Jn(e, t, n = {}) {
|
|
2068
|
+
let r = performance.now(), i = n.builder ?? Vn, a = Wn(t, n.filter), o = new qn(e, a), s = /* @__PURE__ */ new Map(), c = (e) => `${e.geometry.id}:${e.range.start}:${e.range.count}:${e.vertexColors}`;
|
|
2069
|
+
for (let e of o.groups) {
|
|
2070
|
+
let t = c(e);
|
|
2071
|
+
s.has(t) || s.set(t, {
|
|
2072
|
+
group: e,
|
|
2073
|
+
triangles: e.range.count / 3
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
o.stats.uniqueGeometries = s.size;
|
|
2077
|
+
let l = [...s.values()].reduce((e, t) => e + t.triangles, 0) || 1, u = 0;
|
|
2078
|
+
for (let e of s.values()) {
|
|
2079
|
+
let { geometry: t, range: r, vertexColors: a } = e.group;
|
|
2080
|
+
e.data = await i(In(t, {
|
|
2081
|
+
range: r,
|
|
2082
|
+
colors: a,
|
|
2083
|
+
normals: t.attributes.normal ? "keep" : "compute"
|
|
2084
|
+
}), {
|
|
2085
|
+
...n.build,
|
|
2086
|
+
onProgress: (t) => n.onProgress?.((u + t * e.triangles) / l)
|
|
2087
|
+
}), u += e.triangles;
|
|
2088
|
+
}
|
|
2089
|
+
let d = /* @__PURE__ */ new Map(), f = [], p = /* @__PURE__ */ new Set();
|
|
2090
|
+
for (let t of o.groups) {
|
|
2091
|
+
let r = Yn(t, n, d);
|
|
2092
|
+
if (!r) {
|
|
2093
|
+
for (let { object: e } of t.instances) p.add(e);
|
|
2094
|
+
continue;
|
|
2095
|
+
}
|
|
2096
|
+
let i = typeof n.mesh == "function" ? n.mesh(t) : n.mesh, a = e.createMesh(s.get(c(t)).data, r, {
|
|
2097
|
+
matrices: t.matrices,
|
|
2098
|
+
colors: t.colors ?? void 0
|
|
2099
|
+
}, i);
|
|
2100
|
+
a.matrixAutoUpdate = !1, a.matrixWorldAutoUpdate = !1, a.name = t.name, a.userData = { ...t.userData }, a.castShadow = t.castShadow, a.receiveShadow = t.receiveShadow, a.visible = t.visible, a.renderOrder = t.renderOrder, a.layers.mask = t.layers, o.meshes.push(a), f.push(t), o.object.add(a);
|
|
2101
|
+
}
|
|
2102
|
+
return o.groups = f, (n.replace ?? !0) && (o.hide(a.meshes.filter((e) => !p.has(e)), t), t.add(o.object)), await n.onProgress?.(1), o.stats.buildMs = performance.now() - r, o;
|
|
2103
|
+
}
|
|
2104
|
+
function Yn(e, t, n) {
|
|
2105
|
+
let r = e.material, i = !!(r.normalMap && e.geometry.attributes.tangent && r.normalMap.flipY === !1), a = `${r.uuid}:${i}`;
|
|
2106
|
+
if (n.has(a)) return n.get(a);
|
|
2107
|
+
let o;
|
|
2108
|
+
if (t.material ? o = t.material(r, e) : (o = Nn(r), o === r && (o = r.clone())), o && i) {
|
|
2109
|
+
let e = o.normalScale;
|
|
2110
|
+
e && (o.normalScale = e.clone().setY(-e.y));
|
|
2111
|
+
}
|
|
2112
|
+
return n.set(a, o), o;
|
|
2113
|
+
}
|
|
2114
|
+
//#endregion
|
|
2115
|
+
//#region src/core/runtime/OcclusionCulling.ts
|
|
2116
|
+
var Xn = 68, Zn = 64, Qn = 64, $n = [], er = (e) => e.reduce((e, t) => e + t, 0) / e.length, tr = P, nr = N, rr = class {
|
|
2117
|
+
enabled = !0;
|
|
2118
|
+
auto = !0;
|
|
2119
|
+
autoProbeFrames = 40;
|
|
2120
|
+
autoHoldFrames = 900;
|
|
2121
|
+
autoChoice = !1;
|
|
2122
|
+
phase = "hold";
|
|
2123
|
+
phaseFrames = this.autoHoldFrames - 120;
|
|
2124
|
+
samples = [];
|
|
2125
|
+
offMean = 0;
|
|
2126
|
+
lastTick = 0;
|
|
2127
|
+
resolutionScale = .5;
|
|
2128
|
+
maxSize;
|
|
2129
|
+
active = !1;
|
|
2130
|
+
activeNode = B(0, "uint");
|
|
2131
|
+
depthScene = new i.Scene();
|
|
2132
|
+
proxies = /* @__PURE__ */ new Map();
|
|
2133
|
+
projection;
|
|
2134
|
+
near;
|
|
2135
|
+
levelCapacity;
|
|
2136
|
+
levelOffsets = [];
|
|
2137
|
+
hzbAttribute;
|
|
2138
|
+
hzbWrite;
|
|
2139
|
+
hzbRead;
|
|
2140
|
+
buildNodes = [];
|
|
2141
|
+
renderTarget = null;
|
|
2142
|
+
width = 0;
|
|
2143
|
+
height = 0;
|
|
2144
|
+
levels = 0;
|
|
2145
|
+
bufferSize = new i.Vector2();
|
|
2146
|
+
constructor(e, t, n = 1024) {
|
|
2147
|
+
this.maxSize = Math.max(1, Math.min(32768, n)), this.projection = e, this.near = t;
|
|
2148
|
+
let r = this.maxSize, a = Xn, o = 0;
|
|
2149
|
+
for (; this.levelOffsets.push(a), a += r * r, o++, r !== 1;) r = Math.ceil(r / 2);
|
|
2150
|
+
this.levelCapacity = o, this.hzbAttribute = new i.StorageBufferAttribute(new Float32Array(a), 1), this.hzbWrite = R(this.hzbAttribute, "float", a), this.hzbRead = R(this.hzbAttribute, "float", a).toReadOnly();
|
|
2151
|
+
}
|
|
2152
|
+
occluded(e, t) {
|
|
2153
|
+
let n = this.projection, r = e.z.negate(), i = r.sub(t).toVar(), a = r.add(t), o = e.x.sub(t), s = e.x.add(t), c = e.y.sub(t), l = e.y.add(t), u = n.element(0).x, d = n.element(1).y, f = tr(o.div(i), o.div(a)).mul(u).sub(n.element(2).x), p = nr(s.div(i), s.div(a)).mul(u).sub(n.element(2).x), m = tr(c.div(i), c.div(a)).mul(d).sub(n.element(2).y), h = nr(l.div(i), l.div(a)).mul(d).sub(n.element(2).y), v = n.element(3).z.div(i).sub(n.element(2).z), y = i.lessThanEqual(this.near), x = this.hzbRead, w = x.element(1), T = x.element(2), E = S(0), D = _(C(f.mul(.5).add(.5).mul(w)), E, w.sub(1)), O = _(C(p.mul(.5).add(.5).mul(w)), E, w.sub(1)), k = _(C(S(.5).sub(h.mul(.5)).mul(T)), E, T.sub(1)), A = _(C(S(.5).sub(m.mul(.5)).mul(T)), E, T.sub(1)), te = nr(O.sub(D), A.sub(k)).add(1), j = tr(g(ee(te)), x.element(Zn).sub(1)), M = z(j).mul(4), N = b(j), P = x.element(M), F = x.element(M.add(1)), ne = x.element(M.add(2)), I = (e, t) => {
|
|
2154
|
+
let n = _(C(e.div(N)), E, F.sub(1)), r = _(C(t.div(N)), E, ne.sub(1));
|
|
2155
|
+
return x.element(z(P.add(r.mul(F)).add(n)));
|
|
2156
|
+
}, re = nr(nr(I(D, k), I(O, k)), nr(I(D, A), I(O, A)));
|
|
2157
|
+
return y.not().and(v.lessThan(1)).and(v.greaterThan(re.add(1e-6)));
|
|
2158
|
+
}
|
|
2159
|
+
tick(e) {
|
|
2160
|
+
let t = this.lastTick ? e - this.lastTick : 0;
|
|
2161
|
+
this.lastTick = e, this.auto && this.enabled && (this.phaseFrames++, this.phase !== "hold" && this.phaseFrames > 5 && t > 0 && t < 250 && this.samples.push(t), this.phase === "probeOff" && this.samples.length >= this.autoProbeFrames ? (this.offMean = er(this.samples), this.next("probeOn")) : this.phase === "probeOn" && this.samples.length >= this.autoProbeFrames ? (this.autoChoice = er(this.samples) < this.offMean * .97, this.next("hold")) : this.phase === "hold" && this.phaseFrames >= this.autoHoldFrames && this.next("probeOff"));
|
|
2162
|
+
}
|
|
2163
|
+
next(e) {
|
|
2164
|
+
this.phase = e, this.phaseFrames = 0, this.samples = [];
|
|
2165
|
+
}
|
|
2166
|
+
autoWanted() {
|
|
2167
|
+
return this.phase === "probeOn" || this.phase === "hold" && this.autoChoice;
|
|
2168
|
+
}
|
|
2169
|
+
proxyOf(e) {
|
|
2170
|
+
let t = this.proxies.get(e);
|
|
2171
|
+
t || (t = new i.Mesh(e.cameraGeometry, new i.MeshBasicNodeMaterial({ colorWrite: !1 })), t.frustumCulled = !1, this.depthScene.add(t), this.proxies.set(e, t));
|
|
2172
|
+
let n = t.material;
|
|
2173
|
+
return n.positionNode !== e.pool.positionNode && (n.positionNode = e.pool.positionNode, n.needsUpdate = !0), t;
|
|
2174
|
+
}
|
|
2175
|
+
unregisterMesh(e) {
|
|
2176
|
+
let t = this.proxies.get(e);
|
|
2177
|
+
t && (this.proxies.delete(e), t.removeFromParent(), t.material.dispose());
|
|
2178
|
+
}
|
|
2179
|
+
wantsFrame(e, t, n) {
|
|
2180
|
+
let r = e, i = t.isPerspectiveCamera && !r.reversedDepthBuffer && !r.logarithmicDepthBuffer;
|
|
2181
|
+
return this.enabled && i && (!this.auto || this.autoWanted());
|
|
2182
|
+
}
|
|
2183
|
+
beginFrame(e, t, n) {
|
|
2184
|
+
let r = !1;
|
|
2185
|
+
for (let e of n) {
|
|
2186
|
+
let t = e.visible && e.occluder && e.pool.hasCut && !!e.pool.positionNode;
|
|
2187
|
+
if (!t && !this.proxies.has(e)) continue;
|
|
2188
|
+
let n = this.proxyOf(e);
|
|
2189
|
+
n.visible = t, r ||= t;
|
|
2190
|
+
}
|
|
2191
|
+
if (this.active = r, this.activeNode.value = +!!r, !r) return $n;
|
|
2192
|
+
e.getDrawingBufferSize(this.bufferSize);
|
|
2193
|
+
let i = Math.min(this.resolutionScale, this.maxSize / Math.max(this.bufferSize.x, this.bufferSize.y)), a = Math.max(1, Math.round(this.bufferSize.x * i)), o = Math.max(1, Math.round(this.bufferSize.y * i));
|
|
2194
|
+
(a !== this.width || o !== this.height) && this.resize(a, o);
|
|
2195
|
+
let s = e.getRenderTarget();
|
|
2196
|
+
return e.setRenderTarget(this.renderTarget), e.render(this.depthScene, t), e.setRenderTarget(s), this.buildNodes;
|
|
2197
|
+
}
|
|
2198
|
+
resize(e, t) {
|
|
2199
|
+
let n = this.buildNodes;
|
|
2200
|
+
this.renderTarget?.dispose();
|
|
2201
|
+
let r = new i.DepthTexture(e, t);
|
|
2202
|
+
r.type = i.FloatType, this.renderTarget = new i.RenderTarget(e, t, {
|
|
2203
|
+
depthBuffer: !0,
|
|
2204
|
+
depthTexture: r
|
|
2205
|
+
}), this.width = e, this.height = t;
|
|
2206
|
+
let s = this.hzbAttribute.array;
|
|
2207
|
+
s.fill(0, 0, Xn);
|
|
2208
|
+
let l = e, u = t, d = 0;
|
|
2209
|
+
for (let e = 0; e < this.levelCapacity && (s[e * 4] = this.levelOffsets[e], s[e * 4 + 1] = l, s[e * 4 + 2] = u, d++, l !== 1 || u !== 1); e++) l = Math.max(1, Math.ceil(l / 2)), u = Math.max(1, Math.ceil(u / 2));
|
|
2210
|
+
this.levels = d, s[Zn] = d, this.hzbAttribute.needsUpdate = !0;
|
|
2211
|
+
let f = se(r), p = this.hzbWrite, m = a(() => {
|
|
2212
|
+
let e = T, t = z(p.element(1)), n = z(p.element(2));
|
|
2213
|
+
o(e.greaterThanEqual(t.mul(n)), () => {
|
|
2214
|
+
c();
|
|
2215
|
+
});
|
|
2216
|
+
let r = e.mod(t), i = e.div(t), a = z(p.element(0)).toVar();
|
|
2217
|
+
p.element(a.add(e)).assign(f.load(D(E(r), E(i))));
|
|
2218
|
+
})().compute(e * t, [Qn]);
|
|
2219
|
+
this.buildNodes = [m], l = e, u = t;
|
|
2220
|
+
for (let e = 1; e < d; e++) l = Math.max(1, Math.ceil(l / 2)), u = Math.max(1, Math.ceil(u / 2)), this.buildNodes.push(a(() => {
|
|
2221
|
+
let t = T, n = z(p.element(e * 4)).toVar(), r = z(p.element(e * 4 + 1)), i = z(p.element(e * 4 + 2));
|
|
2222
|
+
o(t.greaterThanEqual(r.mul(i)), () => {
|
|
2223
|
+
c();
|
|
2224
|
+
});
|
|
2225
|
+
let a = t.mod(r), s = t.div(r), l = z(p.element((e - 1) * 4)).toVar(), u = z(p.element((e - 1) * 4 + 1)), d = z(p.element((e - 1) * 4 + 2)), f = a.mul(2), m = s.mul(2), h = tr(f.add(1), u.sub(1)), g = tr(m.add(1), d.sub(1)), _ = l.add(m.mul(u)), v = l.add(g.mul(u)), y = nr(nr(p.element(_.add(f)), p.element(_.add(h))), nr(p.element(v.add(f)), p.element(v.add(h))));
|
|
2226
|
+
p.element(n.add(t)).assign(y);
|
|
2227
|
+
})().compute(l * u, [Qn]));
|
|
2228
|
+
for (let e of n) e.dispose();
|
|
2229
|
+
}
|
|
2230
|
+
dispose() {
|
|
2231
|
+
this.renderTarget?.dispose(), this.renderTarget = null;
|
|
2232
|
+
for (let e of [...this.proxies.keys()]) this.unregisterMesh(e);
|
|
2233
|
+
}
|
|
2234
|
+
}, ir = 44, ar = new i.Vector3();
|
|
2235
|
+
function or(e, t) {
|
|
2236
|
+
return Math.min(64, e * Math.min(2, Math.max(1.04, Math.sqrt(t / .85))));
|
|
2237
|
+
}
|
|
2238
|
+
var sr = class {
|
|
2239
|
+
viewMatrix = B(new i.Matrix4());
|
|
2240
|
+
projectionMatrix = B(new i.Matrix4());
|
|
2241
|
+
projScale = B(1);
|
|
2242
|
+
near = B(.1);
|
|
2243
|
+
errorThreshold = B(1);
|
|
2244
|
+
triangleBudget = 0;
|
|
2245
|
+
thresholdRange = [.5, 3];
|
|
2246
|
+
lastStats = null;
|
|
2247
|
+
statsInterval = 10;
|
|
2248
|
+
frameCount = 0;
|
|
2249
|
+
guardBase = null;
|
|
2250
|
+
outOfBand = 0;
|
|
2251
|
+
guardWritten = NaN;
|
|
2252
|
+
statsPending = !1;
|
|
2253
|
+
frustumCulling = B(1, "uint");
|
|
2254
|
+
debugMode = B(0, "uint");
|
|
2255
|
+
minPixelRadius = B(.7);
|
|
2256
|
+
frustumPlanes = Array.from({ length: 6 }, () => B(new i.Vector4()));
|
|
2257
|
+
shadowSweep = B(new i.Vector3());
|
|
2258
|
+
autoShadowSweep = !0;
|
|
2259
|
+
shadowErrorScale = B(3);
|
|
2260
|
+
detectedSweep = new i.Vector3();
|
|
2261
|
+
detectedSweepFrame = -Infinity;
|
|
2262
|
+
occlusion = new rr(this.projectionMatrix, this.near);
|
|
2263
|
+
freeze = !1;
|
|
2264
|
+
autoUpdate = !0;
|
|
2265
|
+
errorInCssPixels = !0;
|
|
2266
|
+
meshes = [];
|
|
2267
|
+
pools = [];
|
|
2268
|
+
capacity;
|
|
2269
|
+
maxPoolBytes;
|
|
2270
|
+
constructor(e = {}) {
|
|
2271
|
+
this.capacity = {
|
|
2272
|
+
triangles: e.maxTriangles ?? 1e7,
|
|
2273
|
+
shadowTriangles: e.maxShadowTriangles ?? 4e6,
|
|
2274
|
+
meshlets: Math.min(e.maxMeshlets ?? 1 << 20, 1 << 24)
|
|
2275
|
+
}, this.maxPoolBytes = e.maxPoolBytes ?? 125829120;
|
|
2276
|
+
}
|
|
2277
|
+
frustum = new i.Frustum();
|
|
2278
|
+
projScreen = new i.Matrix4();
|
|
2279
|
+
size = new i.Vector2();
|
|
2280
|
+
computeList = [];
|
|
2281
|
+
dispatchedPools = [];
|
|
2282
|
+
skippedFrames = 0;
|
|
2283
|
+
cutInputs = new Float64Array(ir).fill(NaN);
|
|
2284
|
+
cutInputsScratch = new Float64Array(ir);
|
|
2285
|
+
sceneHooks = /* @__PURE__ */ new WeakMap();
|
|
2286
|
+
autoCall = -1;
|
|
2287
|
+
autoCamera = null;
|
|
2288
|
+
manualCall = -1;
|
|
2289
|
+
manualCamera = null;
|
|
2290
|
+
updatingAuto = !1;
|
|
2291
|
+
add(e, t) {
|
|
2292
|
+
return Jn(this, e, t);
|
|
2293
|
+
}
|
|
2294
|
+
createMesh(e, t, n, r) {
|
|
2295
|
+
return new On(this, e, t, n, r);
|
|
2296
|
+
}
|
|
2297
|
+
asyncCompile = !0;
|
|
2298
|
+
compilePool(e, t) {
|
|
2299
|
+
t.pipelineState = "compiling";
|
|
2300
|
+
let n = t.version, r = () => {
|
|
2301
|
+
t.version === n && (t.pipelineState = "ready", t.dirty = !0);
|
|
2302
|
+
};
|
|
2303
|
+
e.compileComputeAsync(t.computeNodes).then(r, r);
|
|
2304
|
+
}
|
|
2305
|
+
preparePools(e) {
|
|
2306
|
+
for (let t of this.pools) t.prepare(e);
|
|
2307
|
+
for (let e of this.meshes) e.syncPool();
|
|
2308
|
+
}
|
|
2309
|
+
async compileAsync(e, t, n) {
|
|
2310
|
+
this.preparePools(e);
|
|
2311
|
+
let r = this.pools.filter((e) => e.pipelineState !== "ready");
|
|
2312
|
+
for (let e of r) e.pipelineState = "compiling";
|
|
2313
|
+
await Promise.all(r.map((t) => e.compileComputeAsync(t.computeNodes).catch(() => void 0)));
|
|
2314
|
+
for (let e of r) e.pipelineState = "ready", e.dirty = !0;
|
|
2315
|
+
await e.compileAsync(t, n);
|
|
2316
|
+
}
|
|
2317
|
+
noteShadowCamera(e) {
|
|
2318
|
+
if (this.detectedSweepFrame === this.frameCount) return;
|
|
2319
|
+
let t = e;
|
|
2320
|
+
if (!t.isOrthographicCamera) return;
|
|
2321
|
+
let n = Math.max(t.top - t.bottom, t.right - t.left) / t.zoom;
|
|
2322
|
+
e.getWorldDirection(this.detectedSweep).multiplyScalar(n), this.detectedSweepFrame = this.frameCount;
|
|
2323
|
+
}
|
|
2324
|
+
register(e, t) {
|
|
2325
|
+
let n = t.matrices.length / 16;
|
|
2326
|
+
if (gn.bytesOf(e.data) > this.maxPoolBytes) throw Error(`VirtualGeometry: a single mesh needs more than maxPoolBytes (${this.maxPoolBytes} bytes) of GPU buffer`);
|
|
2327
|
+
let r = this.pools.find((t) => t.fits(e.data, n));
|
|
2328
|
+
r || (r = new gn(this, this.capacity, this.maxPoolBytes), this.pools.push(r)), e.pool = r, e.entry = r.add(e.data, t.matrices, t.colors, e.gpuToInput), r.ensureBuilt(), this.meshes.push(e), e.onBeforeRender = (e, t, n) => this.autoUpdateFor(e, t, n, !1);
|
|
2329
|
+
}
|
|
2330
|
+
autoUpdateFor(e, t, n, r) {
|
|
2331
|
+
if (!this.autoUpdate || this.meshes.length === 0 || t.overrideMaterial && t.overrideMaterial.isShadowPassMaterial) return;
|
|
2332
|
+
if (!r && t.isScene) {
|
|
2333
|
+
if (t.onBeforeRender === this.sceneHooks.get(t)) return;
|
|
2334
|
+
let e = t.onBeforeRender, n = this, r = function(t, r, i, ...a) {
|
|
2335
|
+
n.autoUpdateFor(t, r, i, !0), e.call(this, t, r, i, ...a);
|
|
2336
|
+
};
|
|
2337
|
+
t.onBeforeRender = r, this.sceneHooks.set(t, r);
|
|
2338
|
+
}
|
|
2339
|
+
let i = e.info.render.calls;
|
|
2340
|
+
if ((n !== this.autoCamera || i !== this.autoCall) && (n !== this.manualCamera || i !== this.manualCall + 1)) {
|
|
2341
|
+
this.autoCall = i, this.autoCamera = n, this.updatingAuto = !0;
|
|
2342
|
+
try {
|
|
2343
|
+
this.update(e, n);
|
|
2344
|
+
} finally {
|
|
2345
|
+
this.updatingAuto = !1;
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2349
|
+
unregister(e) {
|
|
2350
|
+
let t = this.meshes.indexOf(e);
|
|
2351
|
+
t !== -1 && (this.meshes.splice(t, 1), e.pool.remove(e.entry), this.occlusion.unregisterMesh(e));
|
|
2352
|
+
}
|
|
2353
|
+
dispose() {
|
|
2354
|
+
for (let e of [...this.meshes]) e.dispose(this);
|
|
2355
|
+
for (let e of this.pools) e.dispose();
|
|
2356
|
+
this.pools.length = 0, this.occlusion.dispose();
|
|
2357
|
+
}
|
|
2358
|
+
update(e, t) {
|
|
2359
|
+
if (this.updatingAuto || (this.manualCall = e.info.render.calls, this.manualCamera = t), this.freeze) return;
|
|
2360
|
+
this.occlusion.tick(performance.now()), t.updateMatrixWorld(), this.viewMatrix.value.copy(t.matrixWorldInverse), this.projectionMatrix.value.equals(t.projectionMatrix) || this.projectionMatrix.value.copy(t.projectionMatrix), e.getDrawingBufferSize(this.size);
|
|
2361
|
+
let n = this.size.y / (this.errorInCssPixels ? e.getPixelRatio() : 1), r = t.projectionMatrix.elements[5] * n * .5;
|
|
2362
|
+
this.projScale.value !== r && (this.projScale.value = r), this.near.value !== t.near && (this.near.value = t.near), this.projScreen.multiplyMatrices(t.projectionMatrix, t.matrixWorldInverse), this.frustum.setFromProjectionMatrix(this.projScreen, i.WebGPUCoordinateSystem);
|
|
2363
|
+
for (let e = 0; e < 6; e++) {
|
|
2364
|
+
let { normal: t, constant: n } = this.frustum.planes[e], r = this.frustumPlanes[e].value;
|
|
2365
|
+
(r.x !== t.x || r.y !== t.y || r.z !== t.z || r.w !== n) && r.set(t.x, t.y, t.z, n);
|
|
2366
|
+
}
|
|
2367
|
+
if (this.autoShadowSweep) {
|
|
2368
|
+
let e = this.frameCount - this.detectedSweepFrame <= 2 ? this.detectedSweep : ar;
|
|
2369
|
+
this.shadowSweep.value.equals(e) || this.shadowSweep.value.copy(e);
|
|
2370
|
+
}
|
|
2371
|
+
let a = this.occlusion.wantsFrame(e, t, this.frameCount);
|
|
2372
|
+
for (let e of this.meshes) e.pool.writeFlags(e.entry, {
|
|
2373
|
+
enabled: +!!e.visible,
|
|
2374
|
+
shadow: e.castShadow && this.frameCount - e.lastShadowFrame <= 2 ? 1 : 0,
|
|
2375
|
+
occlusion: a && e.occlusionCulling ? 1 : 0
|
|
2376
|
+
});
|
|
2377
|
+
if (this.cutInputsChanged(t, e.getPixelRatio())) for (let e of this.pools) e.dirty = !0;
|
|
2378
|
+
this.preparePools(e);
|
|
2379
|
+
let o = this.computeList;
|
|
2380
|
+
o.length = 0;
|
|
2381
|
+
let s = this.dispatchedPools;
|
|
2382
|
+
s.length = 0;
|
|
2383
|
+
for (let t of this.pools) if (t.dirty && t.entries.length !== 0) {
|
|
2384
|
+
if (t.pipelineState !== "ready") {
|
|
2385
|
+
if (this.asyncCompile) {
|
|
2386
|
+
t.pipelineState === "none" && this.compilePool(e, t);
|
|
2387
|
+
continue;
|
|
2388
|
+
}
|
|
2389
|
+
t.pipelineState = "ready";
|
|
2390
|
+
}
|
|
2391
|
+
for (let e of t.computeNodes) o.push(e);
|
|
2392
|
+
s.push(t);
|
|
2393
|
+
}
|
|
2394
|
+
if (o.length > 0) {
|
|
2395
|
+
let n = a ? this.occlusion.beginFrame(e, t, this.meshes) : [];
|
|
2396
|
+
n.length && o.unshift(...n), e.compute(o);
|
|
2397
|
+
for (let e of s) e.dirty = !1, e.hasCut = !0;
|
|
2398
|
+
} else this.skippedFrames++;
|
|
2399
|
+
this.frameCount++, this.meshes.length > 0 && !this.statsPending && this.frameCount % this.statsInterval === 0 && (this.statsPending = !0, this.readStats(e).then((e) => {
|
|
2400
|
+
this.lastStats = e, this.adaptThreshold(e);
|
|
2401
|
+
}).finally(() => this.statsPending = !1));
|
|
2402
|
+
}
|
|
2403
|
+
cutInputsChanged(e, t) {
|
|
2404
|
+
let n = this.cutInputsScratch, r = 0;
|
|
2405
|
+
for (let t = 0; t < 16; t++) n[r++] = e.matrixWorldInverse.elements[t];
|
|
2406
|
+
for (let t = 0; t < 16; t++) n[r++] = e.projectionMatrix.elements[t];
|
|
2407
|
+
n[r++] = e.near, n[r++] = this.size.x, n[r++] = this.size.y, n[r++] = t, n[r++] = +!!this.errorInCssPixels, n[r++] = this.errorThreshold.value, n[r++] = this.minPixelRadius.value, n[r++] = this.frustumCulling.value, n[r++] = this.debugMode.value;
|
|
2408
|
+
let i = this.shadowSweep.value;
|
|
2409
|
+
n[r++] = i.x, n[r++] = i.y, n[r++] = i.z;
|
|
2410
|
+
for (let e = 0; e < ir; e++) if (n[e] !== this.cutInputs[e]) return this.cutInputs.set(n), !0;
|
|
2411
|
+
return !1;
|
|
2412
|
+
}
|
|
2413
|
+
adaptThreshold(e) {
|
|
2414
|
+
let t = this.errorThreshold.value, n = e.capacityUse;
|
|
2415
|
+
if (this.triangleBudget <= 0) {
|
|
2416
|
+
this.guardCapacity(e, t);
|
|
2417
|
+
return;
|
|
2418
|
+
}
|
|
2419
|
+
this.guardBase = null;
|
|
2420
|
+
let [r, i] = this.thresholdRange;
|
|
2421
|
+
if (e.overflow || n > .9) {
|
|
2422
|
+
this.errorThreshold.value = or(t, n);
|
|
2423
|
+
return;
|
|
2424
|
+
}
|
|
2425
|
+
if (e.drawnTriangles <= 0) return;
|
|
2426
|
+
let a = e.drawnTriangles / this.triangleBudget;
|
|
2427
|
+
if (Math.abs(a - 1) < .2) {
|
|
2428
|
+
this.outOfBand = 0;
|
|
2429
|
+
return;
|
|
2430
|
+
}
|
|
2431
|
+
if (++this.outOfBand < 3) return;
|
|
2432
|
+
let o = t * Math.min(1.03, Math.max(.97, Math.sqrt(a)));
|
|
2433
|
+
o = t > i ? Math.max(i, Math.min(o, t * .97)) : Math.min(i, Math.max(r, o)), !(o < t && n * (t / o) ** 2 > .85) && (this.errorThreshold.value = o);
|
|
2434
|
+
}
|
|
2435
|
+
guardCapacity(e, t) {
|
|
2436
|
+
t !== this.guardWritten && (this.guardBase = null);
|
|
2437
|
+
let n = t;
|
|
2438
|
+
if (e.overflow || e.capacityUse > .9) this.guardBase ??= t, n = or(t, e.capacityUse);
|
|
2439
|
+
else if (this.guardBase !== null && t > this.guardBase) {
|
|
2440
|
+
let r = Math.max(this.guardBase, t * .97);
|
|
2441
|
+
e.capacityUse * (t / r) ** 2 <= .85 && (n = r), n === this.guardBase && (this.guardBase = null);
|
|
2442
|
+
}
|
|
2443
|
+
n !== t && (this.errorThreshold.value = n), this.guardWritten = this.errorThreshold.value;
|
|
2444
|
+
}
|
|
2445
|
+
async readStats(e) {
|
|
2446
|
+
let t = {
|
|
2447
|
+
drawnMeshlets: 0,
|
|
2448
|
+
drawnTriangles: 0,
|
|
2449
|
+
fullDetailTriangles: 0,
|
|
2450
|
+
instances: 0,
|
|
2451
|
+
visibleInstances: 0,
|
|
2452
|
+
requestedTriangles: 0,
|
|
2453
|
+
overflow: !1,
|
|
2454
|
+
capacityUse: 0,
|
|
2455
|
+
occludedInstances: 0,
|
|
2456
|
+
shadowTriangles: 0
|
|
2457
|
+
};
|
|
2458
|
+
for (let e of this.meshes) e.visible && (t.fullDetailTriangles += e.fullDetailTriangles, t.instances += e.instanceCount);
|
|
2459
|
+
for (let n of this.pools) {
|
|
2460
|
+
if (!n.hasCut) continue;
|
|
2461
|
+
let r = await n.readCounters(e), i = n.capacity;
|
|
2462
|
+
t.drawnMeshlets += r.camera.drawn, t.drawnTriangles += Math.min(r.camera.requestedTriangles, i.triangles), t.requestedTriangles += r.camera.requestedTriangles, t.visibleInstances += r.camera.survived, t.occludedInstances += r.occluded, t.shadowTriangles += Math.min(r.shadow.requestedTriangles, i.shadowTriangles), (r.camera.selected > i.meshlets || r.camera.requestedTriangles > i.triangles) && (t.overflow = !0), (r.shadow.selected > i.meshlets || r.shadow.requestedTriangles > i.shadowTriangles) && (t.overflow = !0), t.capacityUse = Math.max(t.capacityUse, r.camera.requestedTriangles / i.triangles, r.camera.selected / i.meshlets, r.shadow.requestedTriangles / i.shadowTriangles, r.shadow.selected / i.meshlets);
|
|
2463
|
+
}
|
|
2464
|
+
return t;
|
|
2465
|
+
}
|
|
2466
|
+
};
|
|
2467
|
+
//#endregion
|
|
2468
|
+
export { ge as MAX_MESHLET_TRIANGLES, _e as MAX_MESHLET_VERTICES, gt as VG_BUILD_VERSION, be as VG_DEBUG_MODES, Ke as VG_FORMAT_VERSION, sr as VirtualGeometry, qn as VirtualGeometryImport, On as VirtualMesh, J as VirtualMeshFormatError, Vt as bindVirtualGeometryTextures, Fe as buildVirtualMesh, bt as buildVirtualMeshCached, Mn as canConvertToNodeMaterial, xt as clearVirtualMeshCache, Wn as collectVirtualGeometryGroups, Ze as decodeVirtualMesh, Xe as encodeVirtualMesh, In as fromBufferGeometry, Ft as instanceGuaranteedRange, Pt as instanceMeshletRange, Qe as loadVirtualMesh, Bn as mergeSources, xe as partitionMeshlets, jt as selectCut, Nn as toNodeMaterial, Mt as verifyCutCoverage, Bt as vgNormalMap, Rt as vgTexture, It as vgUv, Gt as vgWorldNormal, St as virtualMeshCacheKey, Jn as virtualMeshesFromObject3D };
|
|
2469
|
+
|
|
2470
|
+
//# sourceMappingURL=index.js.map
|