UNPKG

three-virtual-geometry

Version:

Virtual geometry for three.js WebGPU: automatic cluster LOD and GPU-driven culling for billions of triangles. Independent implementation, not affiliated with Epic Games.

3,031 lines • 121 kB
/*! 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 */
import { MeshoptClusterizer as e, MeshoptDecoder as t, MeshoptEncoder as n, MeshoptSimplifier as r } from "meshoptimizer";
import { Fn as i, If as a, Loop as o, Return as s, atomicAdd as c, atomicLoad as l, atomicStore as u, bitcast as d, bool as f, bumpMap as p, cameraViewMatrix as m, ceil as h, clamp as g, context as _, dot as v, exp2 as y, faceDirection as b, float as x, floor as S, fract as C, hash as w, instanceIndex as T, int as E, ivec2 as D, length as O, localId as k, log as ee, log2 as A, mat3 as te, mat4 as ne, materialColor as j, materialReference as M, max as N, min as P, modelWorldMatrix as re, mrt as F, negateOnBackSide as ie, normalLocal as ae, normalView as oe, normalize as se, numWorkgroups as ce, positionLocal as le, positionView as ue, screenCoordinate as I, select as L, smoothstep as de, sqrt as fe, storage as R, texture as pe, transformNormalToView as me, uint as z, uniform as B, unpackUnorm2x16 as he, uvec4 as ge, varyingProperty as V, vec2 as _e, vec3 as ve, vec4 as H, velocity as ye, vertexIndex as be, workgroupArray as xe, workgroupBarrier as Se, workgroupId as Ce } from "three/tsl";
import * as U from "three/webgpu";
//#region src/core/constants.ts
var we = 128, Te = 128, Ee = 1e30, De = .001, Oe = {
	shaded: 0,
	meshlets: 1,
	lodLevel: 2,
	instances: 3
};
//#endregion
//#region src/core/preprocess/partition.ts
function ke(e, t) {
	let n = e.length;
	if (n <= t) return [e.map((e, t) => t)];
	let r = /* @__PURE__ */ new Map();
	for (let t = 0; t < n; t++) for (let n of e[t].boundaryEdges) {
		let e = r.get(n);
		e ? e[e.length - 1] !== t && e.push(t) : r.set(n, [t]);
	}
	let i = Array.from({ length: n }, () => /* @__PURE__ */ new Map());
	for (let e of r.values()) for (let t = 0; t < e.length; t++) for (let n = t + 1; n < e.length; n++) {
		let r = e[t], a = e[n];
		i[r].set(a, (i[r].get(a) || 0) + 1), i[a].set(r, (i[a].get(r) || 0) + 1);
	}
	let a = je(e.map((e) => e.center)), o = new Uint8Array(n), s = [];
	for (let n of a) {
		if (o[n]) continue;
		let r = [n];
		o[n] = 1;
		let a = /* @__PURE__ */ new Map(), c = (e) => {
			for (let [t, n] of i[e]) o[t] || a.set(t, (a.get(t) || 0) + n);
		};
		for (c(n); r.length < t && a.size > 0;) {
			let t = -1, i = -1, s = Infinity;
			for (let [r, c] of a) {
				if (o[r]) continue;
				let a = Ae(e[r].center, e[n].center);
				(c > i || c === i && a < s) && (t = r, i = c, s = a);
			}
			if (t < 0) break;
			a.delete(t), o[t] = 1, r.push(t), c(t);
		}
		s.push(r);
	}
	let c = [], l = [], u = Math.max(2, Math.floor(t / 2));
	for (let e of s) e.length >= u ? c.push(e) : (l.length + e.length > t && (c.push(l), l = []), l.push(...e));
	return l.length > 0 && c.push(l), c;
}
function Ae(e, t) {
	let n = e[0] - t[0], r = e[1] - t[1], i = e[2] - t[2];
	return n * n + r * r + i * i;
}
function je(e) {
	let t = [
		Infinity,
		Infinity,
		Infinity
	], n = [
		-Infinity,
		-Infinity,
		-Infinity
	];
	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]);
	let r = Math.max(n[0] - t[0], n[1] - t[1], n[2] - t[2]) || 1, i = e.map((e) => {
		let n = (n) => Math.min(1023, Math.max(0, Math.floor((e[n] - t[n]) / r * 1023)));
		return Me(n(0)) | Me(n(1)) << 1 | Me(n(2)) << 2;
	});
	return e.map((e, t) => t).sort((e, t) => i[e] - i[t]);
}
function Me(e) {
	return e &= 1023, e = (e | e << 16) & 50331903, e = (e | e << 8) & 50393103, e = (e | e << 4) & 51130563, e = (e | e << 2) & 153391689, e;
}
//#endregion
//#region src/core/preprocess/voxelProxy.ts
function Ne(e, t, n, r, i) {
	if (n.length === 0) return null;
	let a = [
		Infinity,
		Infinity,
		Infinity
	], o = [
		-Infinity,
		-Infinity,
		-Infinity
	];
	for (let t = 0; t < n.length; t++) {
		let r = n[t] * 3;
		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]);
	}
	let s = Math.max(o[0] - a[0], o[1] - a[1], o[2] - a[2]);
	if (!(s > 0)) return null;
	let c = s / r, l = [
		0,
		1,
		2
	].map((e) => Math.ceil((o[e] - a[e]) / c) + 1 + 6), u = [
		0,
		1,
		2
	].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) => {
		let o = Math.floor((e - u[0]) / c) * 1 + Math.floor((t - u[1]) / c) * m + Math.floor((n - u[2]) / c) * h;
		_[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]++);
	};
	for (let r = 0; r < n.length; r += 3) {
		let a = n[r] * 3, o = n[r + 1] * 3, s = n[r + 2] * 3, l = Math.max(Pe(e, a, o), Pe(e, o, s), Pe(e, s, a)), u = Math.max(1, Math.ceil(l / (c * .5)));
		for (let c = 0; c <= u; c++) for (let l = 0; l <= u - c; l++) {
			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;
			if (i) {
				let e = n[r] * 2, t = n[r + 1] * 2, a = n[r + 2] * 2;
				x = i[e] * p + i[t] * d + i[a] * f, S = i[e + 1] * p + i[t + 1] * d + i[a + 1] * f;
			}
			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);
		}
	}
	let w = Fe(W(_, l), l), T = new Float32Array(g);
	for (let e = 0; e < g; e++) T[e] = w[e];
	Le(T, l, 1, d), Le(T, l, m, f), Le(T, l, h, p);
	let E = .5, D = d - 1, O = f - 1, k = p - 1, ee = new Int32Array(D * O * k).fill(-1), A = [], te = [], ne = [], j = [], M = /* @__PURE__ */ new Float32Array(8);
	for (let e = 0; e < k; e++) for (let t = 0; t < O; t++) for (let n = 0; n < D; n++) {
		let r = n * 1 + t * m + e * h, i = 0;
		for (let e = 0; e < 8; e++) M[e] = T[r + (e & 1) * 1 + (e >> 1 & 1) * m + (e >> 2 & 1) * h], M[e] >= E && i++;
		if (i === 0 || i === 8) continue;
		let a = 0, o = 0, s = 0, l = 0;
		for (let e = 0; e < 8; e++) for (let t of [
			1,
			2,
			4
		]) {
			if (e & t) continue;
			let n = e | t, r = M[e], i = M[n];
			if (r >= E == i >= E) continue;
			let c = (E - r) / (i - r);
			a += (e & 1) + (t === 1 ? c : 0), o += (e >> 1 & 1) + (t === 2 ? c : 0), s += (e >> 2 & 1) + (t === 4 ? c : 0), l++;
		}
		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);
		let d = M[1] + M[3] + M[5] + M[7] - M[0] - M[2] - M[4] - M[6], f = M[2] + M[3] + M[6] + M[7] - M[0] - M[1] - M[4] - M[5], p = M[4] + M[5] + M[6] + M[7] - M[0] - M[1] - M[2] - M[3], g = Math.hypot(d, f, p) || 1;
		if (te.push(-d / g, -f / g, -p / g), v) {
			let e = 0, t = 0, n = 0, i = 0;
			for (let a = 0; a < 8; a++) {
				let o = r + (a & 1) * 1 + (a >> 1 & 1) * m + (a >> 2 & 1) * h;
				y[o] && (e += v[o * 3], t += v[o * 3 + 1], n += v[o * 3 + 2], i += y[o]);
			}
			i ? ne.push(e / i, t / i, n / i) : ne.push(NaN, NaN, NaN);
		}
		if (b) {
			let e = NaN, t = NaN;
			for (let n = 0; n < 8 && Number.isNaN(e); n++) {
				let i = r + (n & 1) * 1 + (n >> 1 & 1) * m + (n >> 2 & 1) * h;
				e = b[i * 2], t = b[i * 2 + 1];
			}
			j.push(e, t);
		}
	}
	let N = [], P = (e, t, n) => ee[e + t * D + n * D * O], re = (e, t, n, r, i, a, o) => {
		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;
		p * i + m * a + h * o >= 0 ? N.push(e, t, n, e, n, r) : N.push(e, n, t, e, r, n);
	};
	for (let e = 1; e < p - 1; e++) for (let t = 1; t < f - 1; t++) for (let n = 1; n < d - 1; n++) {
		let r = n * 1 + t * m + e * h, i = T[r] >= E;
		if (i !== T[r + 1] >= E) {
			let r = i ? 1 : -1;
			re(P(n, t - 1, e - 1), P(n, t, e - 1), P(n, t, e), P(n, t - 1, e), r, 0, 0);
		}
		if (i !== T[r + m] >= E) {
			let r = i ? 1 : -1;
			re(P(n - 1, t, e - 1), P(n, t, e - 1), P(n, t, e), P(n - 1, t, e), 0, r, 0);
		}
		if (i !== T[r + h] >= E) {
			let r = i ? 1 : -1;
			re(P(n - 1, t - 1, e), P(n, t - 1, e), P(n, t, e), P(n - 1, t, e), 0, 0, r);
		}
	}
	if (N.length === 0) return null;
	let F = null;
	v && (F = Float32Array.from(ne), Re(F, N, 3));
	let ie = null;
	return b && (ie = Float32Array.from(j), Re(ie, N, 2)), {
		positions: Float32Array.from(A),
		normals: Float32Array.from(te),
		colors: F,
		uvs: ie,
		indices: Uint32Array.from(N),
		cellSize: c
	};
}
function Pe(e, t, n) {
	return Math.hypot(e[t] - e[n], e[t + 1] - e[n + 1], e[t + 2] - e[n + 2]);
}
function W(e, t) {
	let n = e;
	for (let e = 0; e < 3; e++) n = Ie(n, t, e, 1);
	return n;
}
function Fe(e, t) {
	let n = e;
	for (let e = 0; e < 3; e++) n = Ie(n, t, e, 0);
	return n;
}
function Ie(e, t, n, r) {
	let [i, a, o] = t, s = n === 0 ? 1 : n === 1 ? i : i * a, c = t[n], l = new Uint8Array(e.length);
	for (let t = 0; t < o; t++) for (let o = 0; o < a; o++) for (let u = 0; u < i; u++) {
		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;
		l[d] = r ? e[d] | p | m : e[d] & p & m;
	}
	return l;
}
function Le(e, t, n, r) {
	let [i, a, o] = t, s = new Float32Array(r), c = i * a * o / r;
	for (let t = 0; t < c; t++) {
		let o;
		o = n === 1 ? t * i : n === i ? t % i + Math.floor(t / i) * i * a : t;
		for (let t = 0; t < r; t++) s[t] = e[o + t * n];
		for (let t = 0; t < r; t++) {
			let i = t > 0 ? s[t - 1] : 0, a = t < r - 1 ? s[t + 1] : 0;
			e[o + t * n] = (i + s[t] + a) / 3;
		}
	}
}
function Re(e, t, n) {
	let r = e.length / n;
	for (let i = 0; i < 8; i++) {
		let i = 0, a = new Float32Array(r * n), o = new Uint32Array(r);
		for (let r = 0; r < t.length; r += 3) for (let i = 0; i < 3; i++) {
			let s = t[r + i];
			if (Number.isNaN(e[s * n])) for (let c = 1; c < 3; c++) {
				let l = t[r + (i + c) % 3];
				if (!Number.isNaN(e[l * n])) {
					for (let t = 0; t < n; t++) a[s * n + t] += e[l * n + t];
					o[s]++;
				}
			}
		}
		for (let t = 0; t < r; t++) if (Number.isNaN(e[t * n])) {
			if (o[t]) for (let r = 0; r < n; r++) e[t * n + r] = a[t * n + r] / o[t];
			else i++;
		}
		if (!i) return;
	}
	for (let t = 0; t < e.length; t++) Number.isNaN(e[t]) && (e[t] = .5);
}
//#endregion
//#region src/core/preprocess/aggregate.ts
var ze = 24;
function Be(e, t, n, i, a, o) {
	let s = e.length / 3, c = /* @__PURE__ */ new Map(), l = (e) => {
		let t = e;
		for (; c.get(t) !== t;) t = c.get(t);
		for (; c.get(e) !== t;) {
			let n = c.get(e);
			c.set(e, t), e = n;
		}
		return t;
	};
	for (let t = 0; t < e.length; t++) {
		let r = n[e[t]];
		c.has(r) || c.set(r, r);
	}
	for (let t = 0; t < e.length; t += 3) {
		let r = l(n[e[t]]);
		for (let i = 1; i < 3; i++) {
			let a = l(n[e[t + i]]);
			r !== a && c.set(a, r);
		}
	}
	let u = /* @__PURE__ */ new Map();
	for (let t = 0; t < s; t++) {
		let r = l(n[e[t * 3]]), i = u.get(r);
		i || u.set(r, i = []), i.push(t);
	}
	if (u.size < 2) return null;
	let d = [];
	for (let t of u.values()) {
		let r = new Uint32Array(t.length * 3), o = !0;
		t.forEach((t, s) => {
			for (let c = 0; c < 3; c++) {
				let l = e[t * 3 + c];
				r[s * 3 + c] = l, i[n[l]] !== a && (o = !1);
			}
		}), d.push({
			indices: r,
			free: o
		});
	}
	let f = [h(!0), h(!1)].filter((e) => e !== null), p = f.filter((e) => e.indices.length / 3 <= o * 1.25), m = p.length ? p : f;
	return m.sort((e, t) => p.length ? e.error - t.error : e.indices.length - t.indices.length), m[0] ?? null;
	function h(n) {
		let i = 0, a = d.map((e) => ({ ...e })), c = o / s, l = 0;
		for (let e of a) {
			let a = Math.max(6, Math.floor(e.indices.length * c / 3) * 3);
			if (n && e.free && e.indices.length > a) {
				let n = We(e.indices, t), [o, s] = r.simplify(n.indices, n.positions, 3, a, 1e10, ["ErrorAbsolute"]);
				o.length > 0 && o.length < e.indices.length && (e.indices = o.map((e) => n.toGlobal[e]), i = Math.max(i, s));
			}
			l += e.indices.length / 3;
		}
		let u = [], f = [], p = t.length / 3;
		if (l > o) {
			let e = a.map((e, t) => ({
				p: e,
				i: t
			})).filter(({ p: e }) => e.free), n = /* @__PURE__ */ new Map();
			for (let { p: r, i } of e) n.set(i, He(r.indices, t));
			let r = e.map(({ i: e }) => e), s = Ge(r.map((e) => n.get(e).center)), c = Math.max(s[3] - s[0], s[4] - s[1], s[5] - s[2], 1e-9), d = (e) => Ke([
				(e[0] - s[0]) / c,
				(e[1] - s[1]) / c,
				(e[2] - s[2]) / c
			]);
			r.sort((e, t) => d(n.get(e).center) - d(n.get(t).center));
			let m = r.map((e, t) => {
				let i = Infinity;
				for (let a = Math.max(0, t - ze); a < Math.min(r.length, t + 1 + ze); a++) a !== t && (i = Math.min(i, G(n.get(e).center, n.get(r[a]).center)));
				return i;
			}), h = [...m].sort((e, t) => e - t)[Math.floor(m.length / 2)], g = /* @__PURE__ */ new Set();
			for (let e = 0; e < r.length && l > o; e++) {
				let o = r[e];
				if (g.has(o)) continue;
				let s = -1, c = h * 2;
				for (let t = e + 1; t < Math.min(r.length, e + 1 + ze); t++) {
					let e = r[t];
					if (g.has(e)) continue;
					let i = G(n.get(o).center, n.get(e).center);
					i <= c && (c = i, s = e);
				}
				if (s < 0) continue;
				g.add(o), g.add(s);
				let [d, m] = n.get(o).area >= n.get(s).area ? [o, s] : [s, o], _ = n.get(d), v = n.get(m), y = Math.max(_.area + v.area, 1e-12), b = y / Math.max(_.area, 1e-12), x = v.area / y, S = [
					0,
					1,
					2
				].map((e) => (v.center[e] - _.center[e]) * x), C = Ve(a[d].indices, t, _, b, S, p + f.length, u, f);
				i = Math.max(i, c * Math.max(x, 1 - x), C.growth), l -= a[m].indices.length / 3, a[d].indices = C.indices, a[m].indices = /* @__PURE__ */ new Uint32Array();
			}
		}
		let m = new Uint32Array(a.reduce((e, t) => e + t.indices.length, 0)), h = 0;
		for (let e of a) m.set(e.indices, h), h += e.indices.length;
		return m.length >= e.length ? null : {
			indices: m,
			error: i,
			newPositions: Float32Array.from(u),
			newSources: Uint32Array.from(f),
			firstNewVertex: p
		};
	}
}
function Ve(e, t, n, r, i, a, o, s) {
	let c = n.extent[0] > n.extent[1] * 2 ? [1, r] : [Math.sqrt(r), Math.sqrt(r)], l = Math.max((c[0] - 1) * n.extent[0], (c[1] - 1) * n.extent[1]) / 2, u = /* @__PURE__ */ new Map(), d = new Uint32Array(e.length), f = n.center;
	for (let r = 0; r < e.length; r++) {
		let l = e[r], p = u.get(l);
		if (p === void 0) {
			p = a + u.size, u.set(l, p);
			let e = [
				t[l * 3] - f[0],
				t[l * 3 + 1] - f[1],
				t[l * 3 + 2] - f[2]
			], r = [
				t[l * 3] + i[0],
				t[l * 3 + 1] + i[1],
				t[l * 3 + 2] + i[2]
			];
			for (let t = 0; t < 2; t++) {
				let i = n.axes[t], a = e[0] * i[0] + e[1] * i[1] + e[2] * i[2];
				for (let e = 0; e < 3; e++) r[e] += (c[t] - 1) * a * i[e];
			}
			o.push(r[0], r[1], r[2]), s.push(l);
		}
		d[r] = p;
	}
	return {
		indices: d,
		growth: l
	};
}
function He(e, t) {
	let n = [...new Set(e)], r = [
		0,
		0,
		0
	];
	for (let e of n) for (let i = 0; i < 3; i++) r[i] += t[e * 3 + i] / n.length;
	let i = [
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0
	];
	for (let e of n) {
		let n = [
			t[e * 3] - r[0],
			t[e * 3 + 1] - r[1],
			t[e * 3 + 2] - r[2]
		];
		for (let e = 0; e < 3; e++) for (let t = 0; t < 3; t++) i[e * 3 + t] += n[e] * n[t];
	}
	let a = Ue(i), o = [
		0,
		0,
		0
	];
	for (let e = 0; e < 3; e++) {
		let i = Infinity, s = -Infinity;
		for (let o of n) {
			let n = (t[o * 3] - r[0]) * a[e][0] + (t[o * 3 + 1] - r[1]) * a[e][1] + (t[o * 3 + 2] - r[2]) * a[e][2];
			i = Math.min(i, n), s = Math.max(s, n);
		}
		o[e] = s - i;
	}
	let s = 0;
	for (let n = 0; n < e.length; n += 3) {
		let r = e[n] * 3, i = e[n + 1] * 3, a = e[n + 2] * 3, o = [
			t[i] - t[r],
			t[i + 1] - t[r + 1],
			t[i + 2] - t[r + 2]
		], c = [
			t[a] - t[r],
			t[a + 1] - t[r + 1],
			t[a + 2] - t[r + 2]
		];
		s += .5 * Math.hypot(o[1] * c[2] - o[2] * c[1], o[2] * c[0] - o[0] * c[2], o[0] * c[1] - o[1] * c[0]);
	}
	return {
		area: s,
		center: r,
		axes: a,
		extent: o
	};
}
function Ue(e) {
	let t = [...e], n = [
		1,
		0,
		0,
		0,
		1,
		0,
		0,
		0,
		1
	];
	for (let e = 0; e < 24 && !(Math.abs(t[1]) + Math.abs(t[2]) + Math.abs(t[5]) < 1e-12 * (Math.abs(t[0]) + Math.abs(t[4]) + Math.abs(t[8]) + 1e-30)); e++) for (let [e, r] of [
		[0, 1],
		[0, 2],
		[1, 2]
	]) {
		let i = t[e * 3 + r];
		if (Math.abs(i) < 1e-30) continue;
		let a = (t[r * 3 + r] - t[e * 3 + e]) / (2 * i), o = Math.sign(a || 1) / (Math.abs(a) + Math.sqrt(a * a + 1)), s = 1 / Math.sqrt(o * o + 1), c = o * s;
		for (let n = 0; n < 3; n++) {
			let i = t[n * 3 + e], a = t[n * 3 + r];
			t[n * 3 + e] = s * i - c * a, t[n * 3 + r] = c * i + s * a;
		}
		for (let n = 0; n < 3; n++) {
			let i = t[e * 3 + n], a = t[r * 3 + n];
			t[e * 3 + n] = s * i - c * a, t[r * 3 + n] = c * i + s * a;
		}
		for (let t = 0; t < 3; t++) {
			let i = n[t * 3 + e], a = n[t * 3 + r];
			n[t * 3 + e] = s * i - c * a, n[t * 3 + r] = c * i + s * a;
		}
	}
	return [
		0,
		1,
		2
	].sort((e, n) => t[n * 3 + n] - t[e * 3 + e]).map((e) => {
		let t = n[e], r = n[3 + e], i = n[6 + e], a = Math.hypot(t, r, i) || 1;
		return [
			t / a,
			r / a,
			i / a
		];
	});
}
function We(e, t) {
	let n = /* @__PURE__ */ new Map(), r = [], i = new Uint32Array(e.length);
	for (let t = 0; t < e.length; t++) {
		let a = n.get(e[t]);
		a === void 0 && (a = r.length, n.set(e[t], a), r.push(e[t])), i[t] = a;
	}
	let a = new Float32Array(r.length * 3);
	return r.forEach((e, n) => a.set(t.subarray(e * 3, e * 3 + 3), n * 3)), {
		indices: i,
		positions: a,
		toGlobal: r
	};
}
function Ge(e) {
	let t = [
		Infinity,
		Infinity,
		Infinity,
		-Infinity,
		-Infinity,
		-Infinity
	];
	for (let n of e) for (let e = 0; e < 3; e++) t[e] = Math.min(t[e], n[e]), t[e + 3] = Math.max(t[e + 3], n[e]);
	return t;
}
var G = (e, t) => Math.hypot(e[0] - t[0], e[1] - t[1], e[2] - t[2]);
function Ke(e) {
	let t = (e) => {
		let t = Math.min(1023, Math.max(0, Math.floor(e * 1024))) & 1023;
		return t = (t | t << 16) & 50331903, t = (t | t << 8) & 50393103, t = (t | t << 4) & 51130563, t = (t | t << 2) & 153391689, t;
	};
	return (t(e[0]) | t(e[1]) << 1 | t(e[2]) << 2) >>> 0;
}
//#endregion
//#region src/core/preprocess/buildVirtualMesh.ts
var qe = {
	groupSize: 12,
	maxLodLevels: 24,
	maxGroupKeepRatio: .9,
	simplifyRatio: .5,
	minLevelReduction: .03,
	prune: !1,
	tailSimplify: !0,
	minRootTriangles: 4,
	voxelLods: !0,
	voxelResolution: 64,
	aggregateLods: !0
}, Je = 1024, Ye = (e) => {
	let t = [];
	for (let n = Math.max(4, Math.round(e)); n >= 4; n = Math.floor(n / 2)) t.push(n);
	return t;
}, Xe = () => new Promise((e) => setTimeout(e, 0));
async function Ze(t, n = {}) {
	let i = {
		...qe,
		...n
	}, a = performance.now();
	await e.ready, await r.ready;
	let o = t.positions, s = t.normals, c = t.colors ?? null, l = t.uvs ?? null, u = r.generatePositionRemap(o, 3), d = 0, f = 0, p = ["LockBorder", "ErrorAbsolute"];
	i.prune && p.push("Prune");
	let m = [], h = /* @__PURE__ */ new Map(), g = D(t.indices, 0, null, 0), _ = g, v = st(_), y = 1, b = Math.max(1, g.length * 2);
	for (let e = 1; e <= i.maxLodLevels && _.length > 1 && !(i.tailSimplify && v <= Je || i.tailSimplify && i.voxelLods && f > 0 && S(_, v)); e++) {
		let t = ke(_, i.groupSize), n = [], a = i.aggregateLods ? C(t, _) : null, d = NaN;
		for (let [m, h] of t.entries()) {
			let t = h.map((e) => _[e]), g = ot(t), y = tt(g, o), b = Math.max(3, Math.floor(g.length * i.simplifyRatio / 3) * 3), [S, C] = r.simplify(y.indices, y.positions, 3, b, 1e10, p), T = new Uint32Array(S.length);
			for (let e = 0; e < S.length; e++) T[e] = y.toGlobal[S[e]];
			let E = Math.max(C, $e(y.indices, S, y.positions));
			if (a && S.length > b * 1.25) {
				let e = Be(g, o, u, a, m, b / 3);
				e && Number.isNaN(d) && (d = i.tailSimplify && i.voxelLods ? x(v) : Infinity);
				let n = Math.max(...t.map((e) => e.error));
				if (e && e.indices.length < S.length && n + e.error < d) {
					let t = e.newSources;
					if (t.length > 0) {
						let n = (e, n) => {
							let r = new Float32Array(t.length * n);
							return t.forEach((t, i) => r.set(e.subarray(t * n, t * n + n), i * n)), r;
						};
						w(e.newPositions, n(s, 3), c ? n(c, 3) : null, l ? n(l, 2) : null);
					}
					T = e.indices, E = Math.max(e.error, $e(g, T, o)), f++;
				}
			}
			if (T.length > g.length * i.maxGroupKeepRatio) continue;
			let O = lt(t.map((e) => e.lodSphere)), k = Math.max(...t.map((e) => e.error)) + Math.max(E, 1e-7);
			for (let e of t) e.parentSphere = O, e.parentError = k;
			if (T.length > 0) {
				let r = D(T, e, O, k);
				n.push(...r);
				for (let e of t) e.replacements = r;
			}
		}
		if (await i.onProgress?.(Math.min(.99, m.length / b)), await Xe(), n.length === 0) break;
		y = e + 1, _ = n;
		let h = st(_);
		if (h > v * (1 - i.minLevelReduction)) break;
		v = h;
	}
	return i.tailSimplify && (y = E(m.filter((e) => e.parentError >= Ee), y)), await i.onProgress?.(1), Qe({
		positions: o,
		normals: s,
		colors: c ?? void 0,
		uvs: l ?? void 0,
		indices: t.indices
	}, m, y, d, performance.now() - a, f);
	function x(e) {
		let t = Math.max(3, Math.floor(e / 2) * 3), n = Infinity;
		for (let e of Ye(i.voxelResolution)) {
			let i = T(e);
			if (!i) continue;
			let [a, o] = r.simplify(i.indices, i.positions, 3, Math.min(t, i.indices.length), 1e10, ["ErrorAbsolute"]);
			a.length > 0 && a.length <= t && (n = Math.min(n, 2 * i.cellSize + o));
		}
		return n;
	}
	function S(e, t) {
		let n = 0;
		for (let t of e) n = Math.max(n, t.error);
		return x(t) <= n;
	}
	function C(e, t) {
		let n = new Int32Array(u.length).fill(-1);
		return e.forEach((e, r) => {
			for (let i of e) {
				let e = t[i].indices;
				for (let t = 0; t < e.length; t++) {
					let i = u[e[t]];
					n[i] === -1 ? n[i] = r : n[i] !== r && (n[i] = -2);
				}
			}
		}), n;
	}
	function w(e, t, n, r) {
		let i = o.length / 3, a = e.length / 3, d = (e, t) => {
			let n = new Float32Array(e.length + t.length);
			return n.set(e), n.set(t, e.length), n;
		};
		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));
		let f = new Uint32Array(u.length + a);
		f.set(u);
		for (let e = 0; e < a; e++) f[u.length + e] = i + e;
		return u = f, i;
	}
	function T(e) {
		return h.has(e) || h.set(e, Ne(t.positions, t.colors, t.indices, e, t.uvs)), h.get(e);
	}
	function E(e, t) {
		if (e.length === 0) return t;
		let n = ["ErrorAbsolute"];
		i.prune && n.push("Prune");
		let a = e, s = t;
		for (; s < t + i.maxLodLevels; s++) {
			let e = ot(a);
			if (e.length / 3 <= i.minRootTriangles) break;
			let t = tt(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);
			if (f.length > l) {
				let [e, n] = r.simplifySloppy(t.indices, t.positions, 3, null, c, 1);
				e.length < f.length && (f = e, p = n * r.getScale(t.positions, 3));
			}
			let m = null, h = Infinity;
			if (f.length <= l) {
				h = u + Math.max(Math.max(p, $e(t.indices, f, t.positions)), 1e-7), m = new Uint32Array(f.length);
				for (let e = 0; e < f.length; e++) m[e] = t.toGlobal[f[e]];
			}
			let g = null;
			if (i.voxelLods) for (let e of Ye(i.voxelResolution)) {
				let t = T(e);
				if (!t) continue;
				let n = Math.min(c, t.indices.length), [i, a] = r.simplify(t.indices, t.positions, 3, n, 1e10, ["ErrorAbsolute"]);
				if (i.length === 0 || i.length > l) continue;
				let o = Math.max(u * (1 + 1e-5) + 1e-7, 2 * t.cellSize + a);
				o < h && (h = o, g = {
					proxy: t,
					indices: i
				});
			}
			if (!Number.isFinite(h)) break;
			if (g) {
				let e = tt(g.indices, g.proxy.positions), t = (t, n = 3) => {
					let r = new Float32Array(e.toGlobal.length * n);
					return e.toGlobal.forEach((e, i) => r.set(t.subarray(e * n, e * n + n), i * n)), r;
				}, { proxy: n } = g, r = w(e.positions, t(n.normals), n.colors ? t(n.colors) : null, n.uvs ? t(n.uvs, 2) : null);
				m = e.indices.map((e) => e + r), d++;
			}
			let _ = lt(a.map((e) => e.lodSphere));
			for (let e of a) e.parentSphere = _, e.parentError = h;
			if (m.length === 0) return s + 1;
			let v = D(m, s, _, h);
			for (let e of a) e.replacements = v;
			a = v;
		}
		return s;
	}
	function D(t, n, r, i) {
		let a = tt(t, o), s = e.buildMeshlets(a.indices, a.positions, 3, 128, 128, 0), c = [];
		for (let e = 0; e < s.meshletCount; e++) {
			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], p = new Uint32Array(d);
			for (let e = 0; e < d; e++) p[e] = a.toGlobal[s.vertices[t + e]];
			let h = s.triangles.slice(l, l + f * 3), g = new Uint32Array(f * 3);
			for (let e = 0; e < f * 3; e++) g[e] = p[h[e]];
			let _ = ct(g, o), v = {
				indices: g,
				lodLevel: n,
				lodSphere: r ?? _,
				error: i,
				parentSphere: [
					0,
					0,
					0,
					0
				],
				parentError: Ee,
				cullSphere: _,
				boundaryEdges: it(g, u),
				center: [
					_[0],
					_[1],
					_[2]
				],
				replacements: [],
				vertices: p,
				localTriangles: h
			};
			c.push(v), m.push(v);
		}
		return c;
	}
}
function Qe(e, t, n, r, i, a) {
	let o = [...t].sort((e, t) => e.lodLevel - t.lodLevel), s = o.length, c = new Uint32Array(o.reduce((e, t) => e + t.indices.length, 0)), l = new Float32Array(s * 16), u = new Uint32Array(s * 4), d = /* @__PURE__ */ new Map();
	o.forEach((e, t) => d.set(e, t));
	let f = new Int32Array(s).fill(-1), p = /* @__PURE__ */ new Map(), m = [0], h = 0;
	o.forEach((e, t) => {
		if (e.replacements.length === 0) return;
		let n = p.get(e.replacements);
		n === void 0 && (n = p.size, p.set(e.replacements, n), h += e.replacements.length, m.push(h)), f[t] = n;
	});
	let g = Uint32Array.from(m), _ = new Uint32Array(h);
	for (let [e, t] of p) e.forEach((e, n) => _[g[t] + n] = d.get(e));
	let v = new Uint32Array(o.reduce((e, t) => e + t.vertices.length, 0)), y = new Uint32Array(c.length / 3), b = 0, x = 0, S = {
		leafTriangles: 0,
		leafMeshlets: 0,
		rootTriangles: 0,
		rootMeshlets: 0,
		lodLevels: n,
		voxelLevels: r,
		aggregateGroups: a,
		buildMs: i
	};
	o.forEach((e, t) => {
		c.set(e.indices, b), v.set(e.vertices, x);
		let n = e.localTriangles;
		for (let e = 0, t = b / 3; e < n.length; e += 3, t++) y[t] = n[e] | n[e + 1] << 8 | n[e + 2] << 16;
		let r = t * 16;
		l.set(e.lodSphere, r), l.set(e.parentSphere, r + 4), l[r + 8] = e.error, l[r + 9] = e.parentError, l.set(e.cullSphere, r + 12);
		let i = e.indices.length / 3, a = t * 4;
		u[a + 0] = i, u[a + 1] = b, u[a + 2] = e.lodLevel, u[a + 3] = x, b += e.indices.length, x += e.vertices.length, e.lodLevel === 0 && (S.leafTriangles += i, S.leafMeshlets += 1), e.parentError >= 1e30 && (S.rootTriangles += i, S.rootMeshlets += 1);
	});
	let C = lt(o.filter((e) => e.lodLevel === 0).map((e) => e.cullSphere)), w = o.length ? o[o.length - 1].lodLevel + 1 : 0, T = new Uint32Array(w * 2), E = new Float32Array(w * 2), D = new Float32Array(w * 2);
	for (let e = 0; e < w; e++) E[e * 2] = Infinity, E[e * 2 + 1] = 0, D[e * 2] = 0, D[e * 2 + 1] = Infinity;
	o.forEach((e, t) => {
		let n = e.lodLevel;
		T[n * 2 + 1] === 0 && (T[n * 2] = t), T[n * 2 + 1]++, E[n * 2] = Math.min(E[n * 2], e.error), E[n * 2 + 1] = Math.max(E[n * 2 + 1], e.parentError), D[n * 2] = Math.max(D[n * 2], e.error), D[n * 2 + 1] = Math.min(D[n * 2 + 1], e.parentError);
	});
	let O = lt([...o.map((e) => e.lodSphere), ...o.filter((e) => e.parentError < Ee).map((e) => e.parentSphere)]), k = lt(o.map((e) => e.cullSphere));
	return {
		positions: e.positions,
		normals: e.normals,
		colors: e.colors ?? null,
		uvs: e.uvs ?? null,
		indices: c,
		meshletCount: s,
		meshletBounds: l,
		meshletInfo: u,
		replacementGroup: f,
		replacementStart: g,
		replacementIndices: _,
		meshletVertices: v,
		meshletTriangles: y,
		levelRanges: T,
		levelErrors: E,
		levelGuardErrors: D,
		lodBoundsSphere: O,
		cullBoundsSphere: k,
		boundingSphere: C,
		stats: S
	};
}
function $e(e, t, n) {
	let r = (e) => {
		let t = [
			Infinity,
			Infinity,
			Infinity
		], r = [
			-Infinity,
			-Infinity,
			-Infinity
		];
		for (let i = 0; i < e.length; i++) {
			let a = e[i] * 3;
			for (let e = 0; e < 3; e++) {
				let i = n[a + e];
				i < t[e] && (t[e] = i), i > r[e] && (r[e] = i);
			}
		}
		return {
			min: t,
			max: r
		};
	}, i = r(e);
	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;
	let a = r(t), o = 0;
	for (let e = 0; e < 3; e++) o = Math.max(o, a.min[e] - i.min[e], i.max[e] - a.max[e]);
	return o;
}
var et = /* @__PURE__ */ new Int32Array();
function tt(e, t) {
	let n = t.length / 3;
	et.length < n && (et = new Int32Array(n).fill(-1));
	let r = new Uint32Array(e.length), i = new Uint32Array(e.length), a = 0;
	for (let t = 0; t < e.length; t++) {
		let n = e[t], o = et[n];
		o < 0 && (o = a++, et[n] = o, r[o] = n), i[t] = o;
	}
	let o = r.subarray(0, a), s = new Float32Array(a * 3);
	for (let e = 0; e < a; e++) {
		let n = o[e];
		et[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];
	}
	return {
		indices: i,
		positions: s,
		toGlobal: o
	};
}
var nt = /* @__PURE__ */ new Float64Array(1024), K = /* @__PURE__ */ new Uint8Array(1024), rt = /* @__PURE__ */ new Int32Array(512);
function it(e, t) {
	let n = e.length, r = nt.length;
	if (r < n * 2) {
		for (; r < n * 2;) r <<= 1;
		nt = new Float64Array(r), K = new Uint8Array(r), rt = new Int32Array(r / 2);
	}
	let i = r - 1, a = 0;
	for (let n = 0; n < e.length; n += 3) for (let r = 0; r < 3; r++) {
		let o = t[e[n + r]], s = t[e[n + (r + 1) % 3]], c = at(o, s), l = (Math.imul(o < s ? o : s, 2654435761) ^ Math.imul(o < s ? s : o, 2246822507)) & i;
		for (; K[l] !== 0 && nt[l] !== c;) l = l + 1 & i;
		K[l] === 0 && (nt[l] = c, rt[a++] = l), K[l] < 255 && K[l]++;
	}
	let o = [];
	for (let e = 0; e < a; e++) {
		let t = rt[e];
		K[t] === 1 && o.push(nt[t]), K[t] = 0;
	}
	return o;
}
var at = (e, t) => e < t ? e * 67108864 + t : t * 67108864 + e;
function ot(e) {
	let t = new Uint32Array(e.reduce((e, t) => e + t.indices.length, 0)), n = 0;
	for (let r of e) t.set(r.indices, n), n += r.indices.length;
	return t;
}
var st = (e) => e.reduce((e, t) => e + t.indices.length / 3, 0);
function ct(e, t) {
	let n = [
		Infinity,
		Infinity,
		Infinity
	], r = [
		-Infinity,
		-Infinity,
		-Infinity
	];
	for (let i = 0; i < e.length; i++) {
		let a = e[i] * 3;
		for (let e = 0; e < 3; e++) {
			let i = t[a + e];
			i < n[e] && (n[e] = i), i > r[e] && (r[e] = i);
		}
	}
	let i = (n[0] + r[0]) / 2, a = (n[1] + r[1]) / 2, o = (n[2] + r[2]) / 2, s = 0;
	for (let n = 0; n < e.length; n++) {
		let r = e[n] * 3, c = t[r] - i, l = t[r + 1] - a, u = t[r + 2] - o;
		s = Math.max(s, c * c + l * l + u * u);
	}
	return [
		i,
		a,
		o,
		Math.sqrt(s)
	];
}
function lt(t) {
	if (t.length === 1) return [...t[0]];
	let n = new Float32Array(t.length * 3), r = new Float32Array(t.length);
	t.forEach((e, t) => {
		n.set([
			e[0],
			e[1],
			e[2]
		], t * 3), r[t] = e[3];
	});
	let i = e.computeSphereBounds(n, 3, r, 1), a = i.radius;
	for (let e of t) {
		let t = Math.hypot(e[0] - i.centerX, e[1] - i.centerY, e[2] - i.centerZ) + e[3];
		a = Math.max(a, t);
	}
	return [
		i.centerX,
		i.centerY,
		i.centerZ,
		a * 1.0001
	];
}
//#endregion
//#region src/core/io/serialize.ts
var ut = 1, dt = 1329940310, q = 16, ft = {
	Int8Array,
	Uint8Array,
	Uint8ClampedArray,
	Int16Array,
	Uint16Array,
	Int32Array,
	Uint32Array,
	Float32Array,
	Float64Array
}, pt = {
	positions: { strides: [12] },
	normals: { strides: [12] },
	colors: { strides: [12] },
	uvs: { strides: [8] },
	tangents: { strides: [16] },
	meshletBounds: {
		strides: [64],
		deflateRaw: !0
	},
	meshletInfo: { strides: [16] }
}, J = class extends Error {
	constructor(e) {
		super(`three-virtual-geometry: ${e}`), this.name = "VirtualMeshFormatError";
	}
};
async function mt(e, t = {}) {
	let r = t.compress ?? !0;
	r && await n.ready;
	let i = e, a = Object.keys(i).filter((e) => i[e] !== void 0 && typeof i[e] != "function"), o = [], s = [], c = {}, l = 0;
	for (let n of a) {
		let a = i[n];
		if (!ArrayBuffer.isView(a)) {
			c[n] = a;
			continue;
		}
		let u = a.constructor.name;
		if (!(u in ft)) throw new J(`cannot serialize field "${n}" of type ${u}`);
		let d = a, f, p;
		n === "indices" && !t.keepIndices && yt(e) ? (p = {
			name: n,
			type: u,
			length: d.length,
			encoding: "meshlet-indices"
		}, f = /* @__PURE__ */ new Uint8Array()) : r ? {entry: p, blob: f} = await _t(n, u, d, e, t.deflate ?? !0) : (p = {
			name: n,
			type: u,
			length: d.length,
			encoding: "raw"
		}, f = Et(d)), o.push({
			...p,
			offset: l,
			byteLength: f.length
		}), s.push(f), l += Tt(f.length);
	}
	let u = {
		generator: "three-virtual-geometry",
		keys: a,
		fields: o,
		values: c
	}, d = new TextEncoder().encode(JSON.stringify(u, Mt)), f = Tt(d.length), p = new Uint8Array(q + f + l);
	p.set(d, q), p.fill(32, q + d.length, q + f);
	let m = q + f;
	o.forEach((e, t) => p.set(s[t], m + e.offset));
	let h = new DataView(p.buffer);
	return h.setUint32(0, dt, !0), h.setUint32(4, 1, !0), h.setUint32(8, d.length, !0), h.setUint32(12, Ot(p, q), !0), p;
}
async function ht(e) {
	let n = ArrayBuffer.isView(e) ? new Uint8Array(e.buffer, e.byteOffset, e.byteLength) : new Uint8Array(e);
	n.byteOffset % 4 != 0 && (n = n.slice());
	let r = new DataView(n.buffer, n.byteOffset, n.byteLength);
	if (n.length < q || r.getUint32(0, !0) !== dt) throw new J("not a three-virtual-geometry geometry file (bad magic bytes)");
	let i = r.getUint32(4, !0);
	if (i !== 1) throw new J(`unsupported geometry format version ${i} (this build reads version 1); re-bake the file`);
	let a = r.getUint32(8, !0), o = q + Tt(a);
	if (o > n.length || n.length % 4 != 0) throw new J("geometry file is truncated");
	let s;
	try {
		s = JSON.parse(new TextDecoder().decode(n.subarray(q, q + a)), Nt);
	} catch {
		throw new J("geometry file is corrupt or truncated (unreadable header)");
	}
	if (!s || !Array.isArray(s.fields) || !Array.isArray(s.keys) || typeof s.values != "object") throw new J("geometry file is corrupt (malformed header)");
	let c = n.subarray(o), l = {}, u = [...s.fields].sort((e, t) => bt(e.encoding) - bt(t.encoding));
	u.some((e) => e.encoding !== "raw") && await t.ready;
	for (let e of u) {
		if (!ft[e.type] || !Number.isInteger(e.length) || e.length < 0) throw new J(`geometry file is corrupt (field "${e.name}")`);
		if (e.offset % 4 != 0 || e.offset + e.byteLength > c.length) throw new J(`geometry file is truncated (field "${e.name}")`);
	}
	if (Ot(n, q) !== r.getUint32(12, !0)) throw new J("geometry file is corrupt (checksum mismatch)");
	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) => {
		let t = c.subarray(e.offset, e.offset + e.byteLength);
		return e.deflate ? jt(t).catch((t) => Promise.reject(d(e, t))) : t;
	}));
	for (let e = 0; e < u.length; e++) try {
		l[u[e].name] = await xt({
			...u[e],
			deflate: !1
		}, f[e], l);
	} catch (t) {
		throw d(u[e], t);
	}
	let p = {};
	for (let e of s.keys) p[e] = e in l ? l[e] : s.values[e];
	return p;
}
async function gt(e, t) {
	if (typeof e != "string" && !(e instanceof URL)) return ht(e);
	let n = await fetch(e, t);
	if (!n.ok) throw Error(`three-virtual-geometry: failed to load ${e} (HTTP ${n.status})`);
	return ht(await n.arrayBuffer());
}
async function _t(e, t, r, i, a) {
	let o = Et(r), s = {
		name: e,
		type: t,
		length: r.length
	}, c = pt[e] ?? {}, l = {
		entry: {
			...s,
			encoding: "raw"
		},
		blob: o
	}, u = [l], d = e === "meshletTriangles" && r instanceof Uint32Array ? vt(r, i.meshletInfo) : null;
	if (d) u.push({
		entry: {
			...s,
			encoding: "meshlet-triangles"
		},
		blob: d
	});
	else if (o.length % 4 == 0 && o.length > 0) {
		let e = (c.strides ?? [Math.max(4, r.BYTES_PER_ELEMENT)]).filter((e) => e % 4 == 0 && e <= 256 && o.length % e === 0);
		for (let t of e) {
			let e = n.encodeVertexBufferLevel(o, o.length / t, t, 2, 1);
			u.push({
				entry: {
					...s,
					encoding: "meshopt-vertex",
					stride: t
				},
				blob: e
			});
		}
	}
	if (u.sort((e, t) => e.blob.length - t.blob.length), a && kt() && o.length >= 64) {
		let e = c.deflateRaw && u[0] !== l ? [u[0], l] : [u[0]];
		for (let t of e) u.push({
			entry: {
				...t.entry,
				deflate: !0
			},
			blob: await At(t.blob)
		});
		u.sort((e, t) => e.blob.length - t.blob.length);
	}
	for (let e of u) if (Dt(Et(await xt({
		...e.entry,
		offset: 0,
		byteLength: e.blob.length
	}, e.blob, { meshletInfo: i.meshletInfo })), o)) return e;
	return l;
}
function vt(e, r) {
	if (!(r instanceof Uint32Array)) return null;
	let i = new Uint32Array(e.length * 3), a = new Uint8Array(e.length);
	for (let t = 0; t < r.length; t += 4) {
		let n = r[t], o = r[t + 1] / 3, s = r[t + 3];
		if (o + n > e.length) return null;
		for (let t = o; t < o + n; t++) {
			let n = e[t];
			if (a[t] || n >>> 24) return null;
			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);
		}
	}
	if (!a.every((e) => e === 1)) return null;
	let o = n.encodeIndexBuffer(Et(i), i.length, 4), s = new Uint32Array(i.length);
	t.decodeIndexBuffer(Et(s), i.length, 4, o);
	let c = new Uint8Array(Math.ceil(e.length / 4));
	for (let t = 0; t < e.length; t++) {
		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;
		if (e === a && n === o && r === l) u = 0;
		else if (e === o && n === l && r === a) u = 1;
		else if (e === l && n === a && r === o) u = 2;
		else return null;
		c[t >> 2] |= u << (t & 3) * 2;
	}
	let l = new Uint8Array(4 + Tt(o.length) + c.length);
	return new DataView(l.buffer).setUint32(0, o.length, !0), l.set(o, 4), l.set(c, 4 + Tt(o.length)), l;
}
function yt(e) {
	let { indices: t, meshletInfo: n, meshletVertices: r, meshletTriangles: i } = e;
	if (!(t instanceof Uint32Array && n instanceof Uint32Array && r instanceof Uint32Array && i instanceof Uint32Array)) return !1;
	try {
		return Dt(Et(wt(t.length, n, r, i)), Et(t));
	} catch {
		return !1;
	}
}
var bt = (e) => e === "meshlet-triangles" ? 1 : e === "meshlet-indices" ? 2 : 0;
async function xt(e, n, r) {
	let i = ft[e.type], a = new i(e.length), o = Et(a), s = e.deflate ? await jt(n) : n;
	switch (e.encoding) {
		case "raw":
			if (s.length !== o.length) throw new J(`geometry file is corrupt (field "${e.name}" has the wrong size)`);
			o.set(s);
			break;
		case "meshopt-vertex": {
			let n = e.stride ?? 0;
			if (n <= 0 || n % 4 != 0 || o.length % n !== 0) throw new J(`geometry file is corrupt (field "${e.name}" stride)`);
			t.decodeVertexBuffer(o, o.length / n, n, s);
			break;
		}
		case "meshlet-triangles":
			Ct(a, s, St(r, "meshletInfo", e.name));
			break;
		case "meshlet-indices":
			a.set(wt(e.length, St(r, "meshletInfo", e.name), St(r, "meshletVertices", e.name), St(r, "meshletTriangles", e.name)));
			break;
		default: throw new J(`unknown encoding "${e.encoding}" for field "${e.name}"`);
	}
	return a;
}
function St(e, t, n) {
	let r = e[t];
	if (!(r instanceof Uint32Array)) throw new J(`geometry file is corrupt ("${n}" needs "${t}")`);
	return r;
}
function Ct(e, n, r) {
	let i = new DataView(n.buffer, n.byteOffset, n.byteLength).getUint32(0, !0), a = 4 + Tt(i);
	if (a + Math.ceil(e.length / 4) > n.length) throw Error("truncated triangle data");
	let o = new Uint32Array(e.length * 3);
	t.decodeIndexBuffer(Et(o), o.length, 4, n.subarray(4, 4 + i));
	let s = n.subarray(a);
	for (let t = 0; t < r.length; t += 4) {
		let n = r[t], i = r[t + 1] / 3, a = r[t + 3];
		if (i + n > e.length) throw Error("meshlet range out of bounds");
		for (let t = i; t < i + n; t++) {
			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 ? [
				r,
				i,
				c
			] : n === 1 ? [
				i,
				c,
				r
			] : [
				c,
				r,
				i
			];
			if ((l | u | d) >>> 8) throw Error("meshlet-local vertex id out of range");
			e[t] = l | u << 8 | d << 16;
		}
	}
}
function wt(e, t, n, r) {
	let i = new Uint32Array(e);
	for (let a = 0; a < t.length; a += 4) {
		let o = t[a], s = t[a + 1], c = t[a + 3];
		if (s + o * 3 > e || s / 3 + o > r.length) throw new J("geometry file is corrupt (meshlet range out of bounds)");
		for (let e = 0; e < o; e++) {
			let t = r[s / 3 + e];
			for (let r = 0; r < 3; r++) {
				let a = c + (t >> 8 * r & 255);
				if (a >= n.length) throw new J("geometry file is corrupt (meshlet vertex out of bounds)");
				i[s + e * 3 + r] = n[a];
			}
		}
	}
	return i;
}
var Tt = (e) => e + 3 & -4;
function Et(e) {
	return new Uint8Array(e.buffer, e.byteOffset, e.byteLength);
}
function Dt(e, t) {
	if (e.length !== t.length) return !1;
	if (e.byteOffset % 4 == 0 && t.byteOffset % 4 == 0 && e.length % 4 == 0) {
		let n = new Uint32Array(e.buffer, e.byteOffset, e.length / 4), r = new Uint32Array(t.buffer, t.byteOffset, t.length / 4);
		for (let e = 0; e < n.length; e++) if (n[e] !== r[e]) return !1;
		return !0;
	}
	for (let n = 0; n < e.length; n++) if (e[n] !== t[n]) return !1;
	return !0;
}
function Ot(e, t) {
	let n = new Uint32Array(e.buffer, e.byteOffset + t, e.length - t >> 2), r = 2166136261 ^ n.length;
	for (let e = 0; e < n.length; e++) r = Math.imul(r ^ n[e], 16777619), r ^= r >>> 15;
	return r >>> 0;
}
var kt = () => typeof CompressionStream < "u" && typeof DecompressionStream < "u";
async function At(e) {
	let t = new Blob([e]).stream().pipeThrough(new CompressionStream("deflate-raw"));
	return new Uint8Array(await new Response(t).arrayBuffer());
}
async function jt(e) {
	if (typeof DecompressionStream > "u") throw new J("this environment cannot decompress the geometry file (no DecompressionStream)");
	let t = new Blob([e]).stream().pipeThrough(new DecompressionStream("deflate-raw"));
	return new Uint8Array(await new Response(t).arrayBuffer());
}
function Mt(e, t) {
	if (typeof t == "number" && !Number.isFinite(t)) return { $number: String(t) };
	if (ArrayBuffer.isView(t)) throw new J(`typed array nested inside field "${e}" cannot be serialized; store it as a top-level field`);
	return t;
}
function Nt(e, t) {
	if (t && typeof t == "object" && !Array.isArray(t)) {
		let e = Object.keys(t);
		if (e.length === 1 && e[0] === "$number") return Number(t.$number);
	}
	return t;
}
//#endregion
//#region src/core/io/cache.ts
var Pt = 8, Ft = "three-virtual-geometry-cache", Y = "meshes", X = "meta", It = 536870912, Lt = 3e3;
async function Rt(e, t = {}) {
	let { cache: n, ...r } = t;
	if (n?.store === !1 || !Vt()) return Ze(e, r);
	let i = performance.now(), a = await Bt(e, r, n?.key).catch(() => null), o = a ? await Ut() : null;
	if (!o || !a) return Ze(e, r);
	let s = await Wt(o, a);
	if (s) try {
		let e = await ht(s);
		return e.stats && (e.stats.buildMs = performance.now() - i), Kt(o, a), await r.onProgress?.(1), e;
	} catch {
		qt(o, a);
	}
	let c = await Ze(e, r);
	try {
		Gt(o, a, await mt(c, { deflate: !1 }), n?.maxBytes);
	} catch {}
	return c;
}
async function zt() {
	if (!Vt()) return;
	let e = await Ut();
	e && await new Promise((t) => {
		try {
			let n = e.transaction([Y, X], "readwrite");
			n.objectStore(Y).clear(), n.objectStore(X).clear(), n.oncomplete = n.onerror = n.onabort = () => t();
		} catch {
			t();
		}
	});
}
async function Bt(e, t = {}, n) {
	let r = "v8.1";
	if (n !== void 0) return `${r}:key:${n}`;
	let i = globalThis.crypto?.subtle;
	if (!i) throw Error("crypto.subtle unavailable");
	let a = e, o = Object.keys(a).filter((e) => a[e] !== void 0 && a[e] !== null).sort(), s = [], c = [];
	for (let e of o) {
		let t = a[e];
		ArrayBuffer.isView(t) ? (s.push([
			e,
			t.constructor.name,
			t.byteLength
		]), c.push(i.digest("SHA-256", t))) : s.push([e, t]);
	}
	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({
		versions: r,
		source: s,
		options: l
	})), d = await Promise.all(c), f = new Uint8Array(u.length + d.length * 32);
	f.set(u), d.forEach((e, t) => f.set(new Uint8Array(e), u.length + t * 32));
	let p = new Uint8Array(await i.digest("SHA-256", f));
	return `${r}:sha256:${Array.from(p, (e) => e.toString(16).padStart(2, "0")).join("")}`;
}
function Vt() {
	try {
		return typeof indexedDB < "u" && indexedDB !== null;
	} catch {
		return !1;
	}
}
var Ht = null;
function Ut() {
	return Ht ??= new Promise((e) => {
		let t = setTimeout(() => e(null), Lt), n = (n) => {
			clearTimeout(t), e(n);
		};
		try {
			let e = indexedDB.open(Ft, 1);
			e.onupgradeneeded = () => {
				let t = e.result;
				t.objectStoreNames.contains(Y) || t.createObjectStore(Y), t.objectStoreNames.contains(X) || t.createObjectStore(X);
			}, e.onsuccess = () => {
				let t = e.result;
				t.onversionchange = () => {
					t.close(), Ht = Promise.resolve(null);
				}, n(t);
			}, e.onerror = e.onblocked = () => n(null);
		} catch {
			n(null);
		}
	}), Ht;
}
function Wt(e, t) {
	return new Promise((n) => {
		try {
			let r = e.transaction(Y, "readonly").objectStore(Y).get(t);
			r.onsuccess = () => {
				let e = r.result;
				n(e instanceof ArrayBuffer ? new Uint8Array(e) : e instanceof Uint8Array ? e : null);
			}, r.onerror = () => n(null);
		} catch {
			n(null);
		}
	});
}
function Gt(e, t, n, r = It) {
	return new Promise((r) => {
		try {
			let i = e.transaction([Y, X], "readwrite");
			i.objectStore(Y).put(n.buffer.byteLength === n.length ? n.buffer : n.slice().buffer, t), i.objectStore(X).put({
				size: n.length,
				lastUsed: Date.now()
			}, t), i.oncomplete = () => r(), i.onerror = i.onabort = () => r();
		} catch {
			r();
		}
	}).then(() => Jt(e, t, r));
}
function Kt(e, t) {
	try {
		let n = e.transaction(X, "readwrite").objectStore(X), r = n.get(t);
		r.onsuccess = () => {
			let e = r.result;
			e && n.put({
				...e,
				lastUsed: Date.now()
			}, t);
		};
	} catch {}
}
function qt(e, t) {
	try {
		let n = e.transaction([Y, X], "readwrite");
		n.objectStore(Y).delete(t), n.objectStore(X).delete(t);
	} catch {}
}
function Jt(e, t, n) {
	return new Promise((r) => {
		try {
			let i = e.transaction([Y, X], "readwrite"), a = i.objectStore(X), o = a.getAllKeys(), s = a.getAll();
			s.onsuccess = () => {
				let e = o.result, r = s.result.map((t, n) => ({
					key: e[n],
					...t
				})), c = r.reduce((e, t) => e + t.size, 0);
				r.sort((e, t) => e.lastUsed - t.lastUsed);
				for (let e of r) {
					if (c <= n) break;
					e.key !== t && (i.objectStore(Y).delete(e.key), a.delete(e.key), c -= e.size);
				}
			}, i.oncomplete = i.onerror = i.onabort = () => r();
		} catch {
			r();
		}
	});
}
//#endregion
//#region src/core/runtime/lodBlend.ts
var Yt = 255, Xt = 255 << 16, Zt = V("vec2", "vVgFade"), Qt = B(0);
function $t() {
	let e = I, t = e.x.add(x(Qt).mul(5.588238)), n = C(C(t.mul(.06711056).add(e.y.mul(.00583715))).mul(52.9829189)), r = S(n.mul(255)), i = Zt.round();
	return r.greaterThanEqual(i.x).and(r.lessThan(i.y));
}
function en(e, t, n, r) {
	if (!(e <= (r > 1 ? n * r : n) && t > n)) return null;
	if (!(r > 1)) return [0, 255];
	let i = 255 / Math.log(r), a = (e) => Math.min(255, Math.max(0, Math.round(Math.log(Math.max(e, 1e-30) / n) * i))), o = a(e), s = Number.isFinite(t) ? a(t) : 255;
	return s > o ? [o, s] : null;
}
//#endregion
//#region src/core/runtime/cut.ts
function tn(e, t, n) {
	let r = t.viewMatrix, i = e.meshletBounds, a = new Uint8Array(e.meshletCount), o = t.scale ?? 1, s = (e, n, i, a, s) => {
		if (s >= 5e29) return Infinity;
		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);
		return s * o * t.projScale / d;
	};
	for (let t = 0; t < e.meshletCount; t++) {
		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]);
		a[t] = +(r <= n && o > n);
	}
	return a;
}
function nn(e, t, n, r) {
	let i = t.viewMatrix, a = e.meshletBounds, o = new Uint8Array(e.meshletCount), s = new Uint8Array(e.meshletCount), c = t.scale ?? 1, l = (e, n, r, a, o) => {
		if (o >= 5e29) return Infinity;
		let s = i[0] * e + i[4] * n + i[8] * r + i[12], l = i[1] * e + i[5] * n + i[9] * r + i[13], u = i[2] * e + i[6] * n + i[10] * r + i[14];
		return o * c * t.projScale / Math.max(Math.hypot(s, l, u) - a * c, t.near);
	};
	for (let t = 0; t < e.meshletCount; t++) {
		let e = t * 16, i = en(l(a[e], a[e + 1], a[e + 2], a[e + 3], a[e + 8]), l(a[e + 4], a[e + 5], a[e + 6], a[e + 7], a[e + 9]), n, r);
		i && ([o[t], s[t]] = i);
	}
	return {
		lo: o,
		hi: s
	};
}
function rn(e, t) {
	let { replacementGroup: n, replacementStart: r, replacementIndices: i } = e, a = new Int8Array(e.meshletCount).fill(-1), o = (e) => {
		if (a[e] !== -1) return a[e] === 1;
		let s = !1, c = n[e];
		if (c >= 0) for (let e = r[c]; !s && e < r[c + 1]; e++) s = t[i[e]] === 1 || o(i[e]);
		return a[e] = +!!s, s;
	}, s = [];
	for (let n = 0; n < e.meshletCount; n++) t[n] && o(n) && s.push(n);
	return s;
}
function an(e, t) {
	let n = new Int8Array(e.meshletCount).fill(-1), { replacementGroup: r, replacementStart: i, replacementIndices: a } = e, o = (e) => {
		if (n[e] !== -1) return n[e] === 1;
		let s = t[e] === 1, c = r[e];
		if (c >= 0) for (let e = i[c]; !s && e < i[c + 1]; e++) s = o(a[e]);
		return n[e] = +!!s, s;
	}, s = [];
	for (let t = 0; t < e.meshletCount; t++) e.meshletInfo[t * 4 + 2] === 0 && !o(t) && s.push(t);
	return s;
}
function on(e, t) {
	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);
	return [Math.max(u - d, t.near), Math.max(u + d, t.near)];
}
function sn(e, t, n, r = 1) {
	let [i, a] = on(e, t), o = n * Math.max(1, r), s = (t.scale ?? 1) * t.projScale, c = -1, l = -1, u = e.levelRanges.length / 2;
	for (let t = 0; t < u; t++) {
		let r = e.levelErrors[t * 2], u = e.levelErrors[t * 2 + 1], d = r * s / a <= o, f = u >= 5e29 || u * s / i > n;
		d && f && (c < 0 && (c = t), l = t);
	}
	return c < 0 ? [0, 0] : [e.levelRanges[c * 2], e.levelRanges[l * 2] + e.levelRanges[l * 2 + 1]];
}
function cn(e, t, n, r = 1) {
	let [i, a] = on(e, t), o = n * Math.max(1, r), s = De, c = (t.scale ?? 1) * t.projScale, l = -1, u = -1, d = 0, f = 0, p = e.levelRanges.length / 2;
	for (let t = 0; t < p; t++) {
		let r = e.levelErrors[t * 2], p = e.levelErrors[t * 2 + 1], m = r * c / a <= o, h = p >= 5e29 || p * c / i > n;
		if (!m || !h) continue;
		l < 0 && (l = t), u = t;
		let g = e.levelRanges[t * 2 + 1];
		d += g;
		let _ = e.levelGuardErrors[t * 2], v = e.levelGuardErrors[t * 2 + 1], y = _ * c / i <= n * (1 - s), b = v >= 5e29 || v * c / a > o * (1 + s);
		y && b && (f += g);
	}
	if (l < 0) return null;
	let m = e.levelRanges[l * 2], h = e.levelRanges[u * 2] + e.levelRanges[u * 2 + 1];
	return d !== h - m || f !== d || d > 4 ? null : [m, h];
}
//#endregion
//#region src/core/runtime/vgMaterial.ts
var ln = V("vec2", "vVgUv");
function un(e) {
	if (!(e?.isTextureNode !== !0 || e.isCubeTextureNode || e.isTexture3DNode)) return ln;
}
function dn(e) {
	return pe(e, ln).setUpdateMatrix(!0);
}
var fn = [
	U.RGFormat,
	U.RED_GREEN_RGTC2_Format,
	U.RG11_EAC_Format
];
function pn(e, t, n = U.TangentSpaceNormalMap) {
	let r = dn(e), i = r.xyz.mul(2).sub(1);
	if (fn.includes(e.format)) {
		let e = r.xy.mul(2).sub(1);
		i = ve(e, fe(x(1).sub(e.dot(e)).max(0)));
	}
	if (i = ve(i.xy.mul(t), i.z), n === U.ObjectSpaceNormalMap) return me(i);
	let a = ue.dFdx(), o = ue.dFdy(), s = ln.dFdx(), c = ln.dFdy(), l = oe, u = o.cross(l), d = l.cross(a), f = u.mul(s.x).add(d.mul(c.x)), p = u.mul(s.y).add(d.mul(c.y)), m = f.dot(f).max(p.dot(p)), h = m.equal(0).select(0, m.inverseSqrt());
	return te(ie(f.mul(h)), ie(p.mul(h)), l).mul(i).normalize();
}
function mn(e) {
	let t = e;
	if (!t.colorNode && (hn(t.map) || hn(t.alphaMap))) {
		let e = H(j, 1);
		if (hn(t.map)) {
			let n = dn(t.map);
			e = H(j.mul(n.rgb), n.a);
		}
		hn(t.alphaMap) && (e = H(e.rgb, e.a.mul(dn(t.alphaMap).g))), t.colorNode = e, t.map = null, t.alphaMap = null;
	}
	t.normalNode || (hn(t.normalMap) ? t.normalNode = pn(t.normalMap, M("normalScale", "vec2"), t.normalMapType) : hn(t.bumpMap) && (t.normalNode = p(dn(t.bumpMap).r, M("bumpScale", "float")))), !t.clearcoatNormalNode && hn(t.clearcoatNormalMap) && (t.clearcoatNormalNode = pn(t.clearcoatNormalMap, M("clearcoatNormalScale", "vec2"))), t.contextNode = t.contextNode ? _(t.contextNode, { getUV: un }) : _({ getUV: un }), e.needsUpdate = !0;
}
var hn = (e) => e?.isTexture === !0, gn = P, _n = N, vn = ee, yn = V("vec3", "vVgWorldNormal"), bn = V("float", "vVgMeshlet"), xn = V("float", "vVgLod"), Sn = V("float", "vVgInstance"), Cn = V("vec3", "vVgTint"), wn = V("vec3", "vVgInstanceOrigin"), Tn = Math.ceil(Math.log2(128)), En = (1 << Tn) - 1, Dn = 65535, On = 64, kn = 64, An = 64, jn = 48, Z = 6, Q = 5, $ = 2, Mn = .15, Nn = 1e30, Pn = 5, Fn = 0, In = 1, Ln = 2, Rn = 3, zn = 4, Bn = 12, Vn = 0, Hn = 2, Un = 4, Wn = 8, Gn = 1e4, Kn = 2, qn = .82, Jn = .9, Yn = .75, Xn = 1.25, Zn = 2.5, Qn = class {
	make;
	itemSize;
	maxItems;
	array;
	attribute;
	used = 0;
	constructor(e, t, n, r = Infinity) {
		this.make = e, this.itemSize = t, this.maxItems = r, this.array = e(Math.max(1, n) * t), this.attribute = new U.StorageBufferAttribute(this.array, t);
	}
	get capacity() {
		return this.array.length / this.itemSize;
	}
	reserve(e) {
		if (this.used + e > this.capacity) return -1;
		let t = this.used;
		return this.used += e, t;
	}
	grow(e) {
		let t = this.make(Math.min(Math.max(e, Math.ceil(this.capacity * 1.6)), Math.max(e, this.maxItems)) * this.itemSize);
		t.set(this.array), this.array = t, this.attribute = new U.StorageBufferAttribute(this.array, this.itemSize);
	}
	touch(e, t) {
		t <= 0 || (this.attribute.addUpdateRange(e * this.itemSize, t * this.itemSize), this.attribute.needsUpdate = !0);
	}
}, $n = (e) => new Float32Array(e), er = (e) => new Uint32Array(e), tr = class {
	context;
	entries = [];
	meshSlots = B(0, "uint");
	cellCount = B(0, "uint");
	maxBytes;
	capacity;
	vertexData;
	vertexAttrs;
	meshletBounds;
	meshletInfo;
	meshletVertices;
	meshletTriangles;
	meshTable;
	instances;
	cells;
	meshSlotCapacity;
	levelUsed = 0;
	countersAttribute;
	lodStateBase = 0;
	controllerActive = !1;
	drawArgsAttribute;
	cameraIndex;
	shadowIndex;
	computeNodes = [];
	positionNode = null;
	version = 0;
	needsRebuild = !0;
	indexBuffersReady = !1;
	pipelineState = "none";
	dirty = !0;
	hasCut = !1;
	dedicated = !1;
	disabled = !1;
	constructor(e, t, n) {
		this.context = e, this.capacity = t, this.maxBytes = n, this.meshSlotCapacity = 64;
		let r = (e) => Math.floor(n / e);
		this.vertexData = new Qn(er, 4, 65536, r(16)), this.vertexAttrs = new Qn(er, 2, 65536, r(8)), this.meshletBounds = new Qn($n, 16, 4096, r(64)), this.meshletInfo = new Qn(er, 4, 4096, r(16)), this.meshletVertices = new Qn(er, 1, 1 << 18, r(4)), this.meshletTriangles = new Qn(er, 1, 1 << 18, r(4)), this.meshTable = new Qn($n, 4, this.meshSlotCapacity * Z + 1024, r(16)), this.meshTable.used = this.meshSlotCapacity * Z, this.instances = new Qn($n, 4, 4096, r(80) * Q), this.cells = new Qn($n, 4, 256, r(16));
	}
	static bytesOf(e) {
		return Math.max(e.positions.length / 3 * 16, e.meshletVertices.length * 4, e.meshletTriangles.length * 4, e.meshletCount * 64);
	}
	fits(e, t) {
		let n = (e, t, n) => (e + t) * n <= this.maxBytes;
		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);
	}
	add(e, t, n, r) {
		let i = this.entries.indexOf(null);
		i === -1 && (i = this.entries.length), i >= this.meshSlotCapacity && this.growMeshSlots(i + 1);
		let a = e.positions.length / 3, o = e.levelRanges.length / 2, s = t.length / 16, c = Math.ceil(s / 128), l = (e, t) => {
			let n = e.reserve(t);
			return n === -1 && (e.grow(e.used + t), this.needsRebuild = !0, n = e.reserve(t)), n;
		}, u = {
			slot: i,
			data: e,
			vertexBase: l(this.vertexData, a),
			meshletBase: l(this.meshletBounds, e.meshletCount),
			meshletVertexBase: l(this.meshletVertices, e.meshletVertices.length),
			triangleBase: l(this.meshletTriangles, e.meshletTriangles.length),
			levelBase: 0,
			levelCount: o,
			instanceBase: l(this.instances, s * Q) / Q,
			instanceCount: s,
			cellBase: l(this.cells, c * $) / $,
			cellCount: c,
			uvScale: [1, 1],
			uvOffset: [0, 0]
		};
		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, {
			maxDrawDistance: Nn,
			minPixelRadius: 0,
			enabled: 1,
			shadow: 1,
			occlusion: 0
		}), this.meshSlots.value = Math.max(this.meshSlots.value, i + 1), this.cellCount.value = this.cells.used / $, this.dirty = !0, u;
	}
	remove(e) {
		this.writeFlags(e, { enabled: 0 }), this.entries[e.slot] = null, this.dirty = !0;
	}
	growMeshSlots(e) {
		let t = this.meshSlotCapacity, n = Math.max(e, t * 2), r = (n - t) * Z, i = t * Z, a = this.meshTable.used + r;
		a > this.meshTable.capacity && this.meshTable.grow(a);
		let o = this.meshTable.array;
		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;
		for (let e of this.entries) e && (e.levelBase += r, o[(e.slot * Z + 3) * 4 + 3] = e.levelBase);
		this.needsRebuild = !0;
	}
	writeGeometry(e) {
		let t = e.data, n = t.positions.length / 3, r = this.vertexData.array, i = new Float32Array(r.buffer, r.byteOffset, r.length);
		for (let a = 0; a < n; a++) {
			let n = (e.vertexBase + a) * 4;
			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] = ar(t.normals[a * 3], t.normals[a * 3 + 1], t.normals[a * 3 + 2]);
		}
		this.vertexData.touch(e.vertexBase, n);
		let a = this.vertexAttrs.array, o = t.uvs ? or(t.uvs) : null;
		o && (e.uvScale = o.scale, e.uvOffset = o.offset);
		let s = (e) => Math.round(Math.max(0, Math.min(1, e)) * 255);
		for (let r = 0; r < n; r++) {
			let n = (e.vertexBase + r) * 2;
			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;
		}
		this.vertexAttrs.touch(e.vertexBase, n), this.meshletBounds.array.set(t.meshletBounds, e.meshletBase * 16), this.meshletBounds.touch(e.meshletBase, t.meshletCount);
		let c = this.meshletInfo.array;
		for (let n = 0; n < t.meshletCount; n++) {
			let r = (e.meshletBase + n) * 4, i = n * 4;
			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;
		}
		this.meshletInfo.touch(e.meshletBase, t.meshletCount);
		let l = this.meshletVertices.array;
		for (let n = 0; n < t.meshletVertices.length; n++) l[e.meshletVertexBase + n] = t.meshletVertices[n] + e.vertexBase;
		this.meshletVertices.touch(e.meshletVertexBase, t.meshletVertices.length), this.meshletTriangles.array.set(t.meshletTriangles, e.triangleBase), this.meshletTriangles.touch(e.triangleBase, t.meshletTriangles.length);
		let u = this.meshTable.array;
		for (let n = 0; n < e.levelCount; n++) {
			let r = (e.levelBase + n * 2) * 4;
			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;
		}
		this.meshTable.touch(e.levelBase, e.levelCount * 2);
	}
	writeMeshRecord(e, t) {
		let n = this.meshTable.array, r = e.slot * Z * 4;
		n.set(e.data.boundingSphere, r), n.set(e.data.lodBoundsSphere, r + 4), n.set(e.data.cullBoundsSphere, r + 8), n.set([
			t.maxDrawDistance,
			t.minPixelRadius,
			e.levelCount,
			e.levelBase
		], r + 12), n.set([
			e.uvScale[0],
			e.uvScale[1],
			e.uvOffset[0],
			e.uvOffset[1]
		], r + 16), n.set([
			t.enabled,
			t.shadow,
			t.occlusion,
			0
		], r + 20), this.meshTable.touch(e.slot * Z, Z), this.dirty = !0;
	}
	writeFlags(e, t) {
		let n = this.meshTable.array, r = e.slot * Z * 4, i = (t, i) => {
			i !== void 0 && n[r + t] !== i && (n[r + t] = i, this.meshTable.touch(e.slot * Z + (t >> 2), 1), this.dirty = !0);
		};
		i(12, t.maxDrawDistance), i(13, t.minPixelRadius), i(20, t.enabled), i(21, t.shadow), i(22, t.occlusion);
	}
	readFlag(e, t) {
		return this.meshTable.array[e.slot * Z * 4 + {
			maxDrawDistance: 12,
			minPixelRadius: 13,
			enabled: 20,
			shadow: 21,
			occlusion: 22
		}[t]];
	}
	writeInstances(e, t, n, r) {
		let i = this.instances.array;
		for (let a = 0; a < e.instanceCount; a++) {
			let o = r[a], s = (e.instanceBase + a) * Q * 4;
			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;
		}
		this.instances.touch(e.instanceBase * Q, e.instanceCount * Q);
		for (let t = 0; t < e.cellCount; t++) this.computeCell(e, t);
		this.cells.touch(e.cellBase * $, e.cellCount * $);
	}
	setMatrix(e, t, n) {
		n.toArray(this.instances.array, (e.instanceBase + t) * Q * 4);
	}
	commitInstances(e, t) {
		this.instances.touch(e.instanceBase * Q, e.instanceCount * Q);
		for (let n of t) this.computeCell(e, n), this.cells.touch((e.cellBase + n) * $, $);
		this.dirty = !0;
	}
	computeCell(e, t) {
		let n = this.instances.array, r = t * 128, i = Math.min(r + 128, e.instanceCount), a = /* @__PURE__ */ new Float64Array(4), o = [
			Infinity,
			Infinity,
			Infinity
		], s = [
			-Infinity,
			-Infinity,
			-Infinity
		], c = 0;
		for (let t = r; t < i; t++) {
			nr(n, (e.instanceBase + t) * Q * 4, e.data.boundingSphere, a);
			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]);
			c = Math.max(c, a[3]);
		}
		let l = (o[0] + s[0]) / 2, u = (o[1] + s[1]) / 2, d = (o[2] + s[2]) / 2, f = 0;
		for (let t = r; t < i; t++) nr(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]);
		let p = (e.cellBase + t) * $ * 4;
		this.cells.array.set([
			l,
			u,
			d,
			f * 1.0001 + .001,
			c * 1.0001 + 1e-4,
			e.slot,
			e.instanceBase + r,
			i - r
		], p);
	}
	prepare(e) {
		if (this.ensureBuilt(), this.indexBuffersReady) return;
		let t = e.backend;
		t.createIndexAttribute(this.cameraIndex), t.createIndexAttribute(this.shadowIndex), this.indexBuffersReady = !0;
	}
	ensureBuilt() {
		this.needsRebuild && this.build();
	}
	build() {
		this.needsRebuild = !1, this.indexBuffersReady = !1, this.pipelineState = "none", this.hasCut = !1, this.version++;
		for (let e of this.computeNodes) e.dispose();
		let e = this.context, t = this.capacity, n = this.meshSlotCapacity, r = t.meshlets, p = Math.floor(this.instances.capacity / Q), m = Math.floor(this.cells.capacity / $), h = t.triangles * 3, g = t.shadowTriangles * 3, _ = (e, t) => R(e.attribute, t, e.capacity), y = _(this.vertexData, "uvec4").toReadOnly(), b = _(this.vertexAttrs, "uvec2").toReadOnly(), S = _(this.meshletBounds, "vec4").toReadOnly(), C = _(this.meshletInfo, "uvec4").toReadOnly(), w = _(this.meshletVertices, "uint").toReadOnly(), E = _(this.meshletTriangles, "uint").toReadOnly(), D = _(this.meshTable, "vec4").toReadOnly(), ee = _(this.instances, "vec4").toReadOnly(), A = _(this.cells, "vec4").toReadOnly();
		this.lodStateBase = Bn + 2 * n * 4;
		let te = new Uint32Array(this.lodStateBase + Wn);
		te.fill(Gn, this.lodStateBase, this.lodStateBase + 2), this.countersAttribute = new U.StorageBufferAttribute(te, 1), this.drawArgsAttribute = new U.IndirectStorageBufferAttribute(new Uint32Array(2 * n * 2 * 5), 1), this.cameraIndex = new U.StorageBufferAttribute(new Uint32Array(h), 1), this.shadowIndex = new U.StorageBufferAttribute(new Uint32Array(g), 1);
		let j = new U.StorageBufferAttribute(new Uint32Array(m * 4), 4), M = new U.StorageBufferAttribute(new Uint32Array(p * 2 * 4), 4), re = new U.StorageBufferAttribute(new Uint32Array(r * 2 * 4), 4), F = () => new U.IndirectStorageBufferAttribute(/* @__PURE__ */ new Uint32Array(3), 3), ie = F(), oe = [F(), F()], le = [F(), F()], ue = F(), I = R(this.countersAttribute, "uint", this.countersAttribute.count).toAtomic(), pe = (e) => I.element(this.lodStateBase + e), me = (e) => x(l(pe(e)).toVar()).div(Gn), B = (e, t) => u(pe(e), z(x(t).mul(Gn).round())), V = R(ue, "uint", 3), ve = R(this.drawArgsAttribute, "uint", this.drawArgsAttribute.count), ye = R(this.cameraIndex, "uint", h), we = R(this.shadowIndex, "uint", g), Te = R(j, "uvec4", m), Oe = R(j, "uvec4", m).toReadOnly(), ke = R(M, "uvec4", p * 2), Ae = R(re, "uvec4", r * 2), je = R(re, "uvec4", r * 2).toReadOnly(), Me = R(ie, "uint", 3), Ne = oe.map((e) => R(e, "uint", 3)), Pe = le.map((e) => R(e, "uint", 3)), W = (e, t) => I.element(2 + e * Pn + t), Fe = (e, t, r) => I.element(z(Bn + e * n * 4).add(t.mul(4)).add(z(r).mul(2))), Ie = (e, t, r) => I.element(z(Bn + e * n * 4 + 1).add(t.mul(4)).add(z(r).mul(2))), Le = (e) => L(e.bitAnd(16776960).equal(Xt), z(0), z(1)), Re = [h, g], ze = [ye, we], Be = [], Ve = () => {
			let t = me(Vn).toVar(), n = me(1).toVar(), r = x(1).add(e.lodBlendMax.sub(1).mul(de(Xn, Zn, e.errorThreshold.mul(t)))).toVar(), i = r.greaterThan(1.001).toVar(), a = L(i, x(255).div(vn(r)), x(0)).toVar();
			Be = [0, 1].map((o) => {
				let s = o === 0 ? t : _n(t, n), c = (o === 0 ? e.errorThreshold : e.errorThreshold.mul(e.shadowErrorScale)).mul(s).toVar();
				return {
					low: c,
					high: L(i, c.mul(r), c).toVar(),
					fadeScale: a
				};
			});
		}, He = e.minPixelRadius, Ue = e.occlusion, We = (e, t) => ee.element(e.mul(Q).add(t)), Ge = (e) => {
			let t = [
				0,
				1,
				2,
				3
			].map((t) => We(e, t).toVar());
			return {
				model: ne(t[0], t[1], t[2], t[3]).toVar(),
				scale: N(O(t[0].xyz), N(O(t[1].xyz), O(t[2].xyz))).toVar(),
				columns: t
			};
		}, G = (e, t) => D.element(e.mul(Z).add(t)), Ke = (t, n, r, i) => {
			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);
			return L(i.greaterThanEqual(Ee * .5), x(Ee), s);
		}, qe = (t, n) => {
			let r = x(1e30);
			for (let i of e.frustumPlanes) {
				let a = v(i.xyz, t).add(i.w);
				n !== !1 && (a = a.add(N(v(i.xyz, e.shadowSweep), 0).mul(n === !0 ? 1 : L(n, x(1), x(0))))), r = P(r, a);
			}
			return r;
		}, Je = (t, n, r) => {
			let i = e.viewMatrix.mul(H(n, 1)).xyz.toVar(), a = i.z.abs().mul(Be[0].high).div(e.projScale);
			return t.and(Ue.activeNode.equal(1)).and(Ue.occluded(i, r.add(a)));
		}, Ye = (e, t) => {
			e.element(0).assign(gn(t, z(Dn))), e.element(1).assign(t.add(65534).div(Dn)), e.element(2).assign(z(1));
		}, Xe = i(() => {
			let e = T;
			a(e.lessThan(z(Bn)), () => {
				u(I.element(e), z(0));
			}), a(e.lessThan(this.meshSlots.mul(8)), () => {
				let t = e.div(this.meshSlots.mul(4)), r = e.mod(this.meshSlots.mul(4));
				u(I.element(z(Bn).add(t.mul(n * 4)).add(r)), z(0));
			});
		})().compute(Math.max(Bn, n * 8), [64]), Ze = i(() => {
			a(T.greaterThanEqual(this.cellCount), () => {
				s();
			});
			let t = T.toVar(), n = A.element(t.mul($)).toVar(), r = A.element(t.mul($).add(1)).toVar(), i = z(r.y).toVar(), o = G(i, 5).toVar();
			a(o.x.equal(0), () => {
				s();
			});
			let l = n.xyz.toVar(), u = n.w.toVar();
			a(e.frustumCulling.equal(1).and(qe(l, o.y.greaterThan(.5)).lessThan(u.negate())), () => {
				s();
			});
			let d = G(i, 3).toVar(), f = N(He, d.y), p = r.x, m = O(e.viewMatrix.mul(H(l, 1)).xyz).toVar().sub(u).toVar();
			a(m.greaterThan(p).and(p.mul(e.projScale).div(N(m, 1e-6)).lessThan(f)), () => {
				s();
			}), a(m.greaterThan(d.x), () => {
				s();
			});
			let h = c(I.element(0), z(1)).toVar();
			Te.element(h).assign(ge(i, z(r.z), z(r.w), t));
		})().compute(m, [On]), Qe = i(() => {
			Ye(Me, l(I.element(0)).toVar());
		})().compute(1), $e = xe("vec4", 96), et = (t, n, i, s, l, u, d, f, m, h) => {
			let { low: g, high: _ } = Be[t], v = z(4294967295).toVar(), y = z(0).toVar(), b = z(0).toVar(), x = z(0).toVar();
			o({
				start: z(0),
				end: i,
				type: "uint",
				condition: "<"
			}, ({ i: e }) => {
				let t = $e.element(e.mul(2)).toVar(), n = $e.element(e.mul(2).add(1)).toVar(), r = z(t.x).toVar(), i = z(t.y).toVar(), o = t.z.mul(h).lessThanEqual(_).and(t.w.greaterThanEqual(Ee * .5).or(t.w.mul(m).greaterThan(g))), s = n.x.mul(m).lessThanEqual(g.mul(1 - De)).and(n.y.greaterThanEqual(Ee * .5).or(n.y.mul(h).greaterThan(_.mul(1 + De))));
				a(o, () => {
					v.assign(gn(v, r)), y.assign(_n(y, r.add(i))), b.addAssign(i), a(s, () => {
						x.addAssign(i);
					});
				});
			});
			let S = d.mul(H(l.xyz, 1)).xyz.toVar(), w = l.w.mul(f).toVar(), T = b.greaterThan(z(0)).and(b.equal(y.sub(v))).and(x.equal(b)).and(b.lessThanEqual(z(4))).and(e.frustumCulling.equal(0).or(qe(S, t === 1).greaterThanEqual(w))).toVar();
			a(y.greaterThan(v), () => {
				c(W(t, Ln), z(1)), a(T, () => {
					let e = c(W(t, Fn), b).toVar();
					for (let i = 0; i < 4; i++) a(z(i).lessThan(b).and(e.add(i).lessThan(z(r))), () => {
						let a = v.add(i).toVar(), o = C.element(a).x.toVar(), s = c(Fe(t, n, 0), o.mul(3)).toVar();
						Ae.element(e.add(i + t * r)).assign(ge(u, a, s, o.bitOr(Xt)));
					});
				}).Else(() => {
					let e = c(W(t, Rn), z(1)).toVar(), r = n.bitOr(L(s, z(2147483648), z(0)));
					ke.element(e.add(t * p)).assign(ge(u, v, y, r));
				});
			});
		}, tt = (t) => i(() => {
			let n = Ce.x.add(Ce.y.mul(ce.x)).toVar(), r = n.lessThan(l(I.element(0))).toVar(), i = Oe.element(gn(n, z(m - 1))).toVar(), u = i.x, d = G(u, 3).toVar(), p = L(r, gn(z(d.z), z(jn)), z(0)).toVar(), h = z(d.w).toVar();
			o({
				start: k.x,
				end: p.mul(2),
				type: "uint",
				condition: "<",
				update: On
			}, ({ i: e }) => {
				$e.element(e).assign(D.element(h.add(e)));
			}), Se(), a(r.not(), () => {
				s();
			}), Ve();
			let g = G(u, 0).toVar(), _ = G(u, 1).toVar(), v = G(u, 2).toVar(), y = G(u, 5).toVar(), b = y.y.greaterThan(.5), x = y.z.greaterThan(.5), S = N(He, d.y).toVar(), C = d.x.toVar(), w = i.y.add(i.z);
			o({
				start: i.y.add(k.x),
				end: w,
				type: "uint",
				condition: "<",
				update: On
			}, ({ i: n }) => {
				let r = n.toVar(), { model: i, scale: o } = Ge(r), s = i.mul(H(g.xyz, 1)).xyz.toVar(), l = g.w.mul(o).toVar(), d = e.frustumCulling.equal(0), m = d.or(qe(s, !1).greaterThanEqual(l.negate())).toVar(), h = b.and(d.or(qe(s, !0).greaterThanEqual(l.negate()))).toVar();
				if (t) {
					let e = me(Un).toVar(), t = me(5).toVar();
					m.assign(m.and(e.greaterThan(.5))), h.assign(h.and(t.greaterThan(.5)));
				}
				let y = O(e.viewMatrix.mul(H(s, 1)).xyz).toVar(), w = y.greaterThan(l).and(l.mul(e.projScale).div(y).lessThan(S)), T = y.sub(l).greaterThan(C), E = m.or(h).and(w.not()).and(T.not());
				a(E, () => {
					a(m.and(Je(x, s, l)), () => {
						m.assign(f(!1)), c(I.element(1), z(1));
					});
					let t = e.viewMatrix.mul(i.mul(H(_.xyz, 1))), n = O(t.xyz).toVar(), d = _.w.mul(o), g = o.mul(e.projScale).div(N(n.sub(d), e.near)).toVar(), y = o.mul(e.projScale).div(N(n.add(d), e.near)).toVar();
					a(m, () => {
						et(0, u, p, x, v, r, i, o, g, y);
					}), a(h, () => {
						et(1, u, p, f(!1), v, r, i, o, g, y);
					});
				});
			});
		})().compute(t ? ue : ie, [On]), nt = (t) => ({
			argsNode: i(() => {
				Ye(Ne[t], l(W(t, Rn)).toVar());
			})().compute(1),
			retryArgsNode: i(() => {
				let e = me(Un + t).toVar(), n = l(W(t, Rn)).toVar();
				Ye(Ne[t], L(e.greaterThan(.5), n, z(0)).toVar());
			})().compute(1),
			passNode: i(() => {
				let n = Ce.x.add(Ce.y.mul(ce.x)).toVar();
				a(n.greaterThanEqual(l(W(t, Rn))), () => {
					s();
				});
				let i = ke.element(n.add(t * p)).toVar(), u = i.x, d = i.w.bitAnd(2147483647).toVar(), f = i.w.shiftRight(31).equal(1), { model: m, scale: h } = Ge(u);
				Ve();
				let { low: g, high: _, fadeScale: v } = Be[t];
				o({
					start: i.y.add(k.x),
					end: i.z,
					type: "uint",
					condition: "<",
					update: kn
				}, ({ i: n }) => {
					let i = n, o = i.mul(4).toVar(), s = S.element(o.add(3)), l = m.mul(H(s.xyz, 1)).xyz, p = e.frustumCulling.equal(0).or(qe(l, t === 1).greaterThanEqual(s.w.mul(h).negate()));
					t === 0 && (p = p.and(Je(f, l, s.w.mul(h)).not()));
					let y = S.element(o.add(2)), b = Ke(m, h, S.element(o), y.x).toVar(), x = Ke(m, h, S.element(o.add(1)), y.y).toVar(), w = (e) => z(vn(_n(e, 1e-30).div(g)).mul(v).round().clamp(0, 255)), T = L(v.greaterThan(0), w(b), z(0)).toVar(), E = L(v.greaterThan(0), w(x), z(255)).toVar(), D = T.shiftLeft(8).bitOr(E.shiftLeft(16)), O = p.and(b.lessThanEqual(_)).and(x.greaterThan(g)).and(E.greaterThan(T));
					a(O, () => {
						let e = c(W(t, Fn), z(1)).toVar();
						a(e.lessThan(z(r)), () => {
							let n = C.element(i).x.toVar(), a = n.bitOr(D).toVar(), o = c(Fe(t, d, Le(a)), n.mul(3)).toVar();
							Ae.element(e.add(t * r)).assign(ge(u, i, o, a));
						});
					});
				});
			})().compute(oe[t], [kn])
		}), K = (e) => i(() => {
			let t = z(0).toVar(), i = z(Re[e]);
			o({
				start: z(0),
				end: this.meshSlots,
				type: "uint",
				condition: "<"
			}, ({ i: r }) => {
				for (let a of [0, 1]) {
					let o = l(Fe(e, r, a)).toVar();
					u(Ie(e, r, a), t);
					let s = L(t.lessThan(i), i.sub(t), z(0)), c = z(e * n * 10 + a * 5).add(r.mul(10)).toVar();
					ve.element(c).assign(gn(o, s)), ve.element(c.add(1)).assign(z(1)), ve.element(c.add(2)).assign(t), ve.element(c.add(3)).assign(z(0)), ve.element(c.add(4)).assign(z(0)), t.addAssign(o);
				}
			}), u(W(e, zn), t);
			let a = gn(l(W(e, Fn)), z(r)).toVar();
			u(W(e, In), a), Ye(Pe[e], a);
		})().compute(1), rt = (e) => i(() => {
			let t = Ce.x.add(Ce.y.mul(ce.x)).toVar();
			a(t.greaterThanEqual(l(W(e, In))), () => {
				s();
			});
			let n = t.add(e * r).toVar(), i = je.element(n).toVar(), c = z(We(i.x, 4).w).toVar(), u = l(Ie(e, c, Le(i.w))).toVar(), d = C.element(i.y).y.div(3).toVar(), f = n.shiftLeft(Tn).toVar(), p = ze[e], m = i.w.bitAnd(255).toVar();
			o({
				start: k.x,
				end: m,
				type: "uint",
				condition: "<",
				update: An
			}, ({ i: t }) => {
				let n = u.add(i.z).add(t.mul(3)).toVar();
				a(n.add(2).lessThan(z(Re[e])), () => {
					let e = E.element(d.add(t)).toVar();
					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)));
				});
			});
		})().compute(le[e], [An]), it = (e) => {
			let t = l(W(e, zn)).toVar(), n = l(W(e, Fn)).toVar();
			return _n(x(t).div(Re[e]), x(n).div(r));
		}, at = i(() => {
			let t = f(!1).toVar();
			for (let n of [0, 1]) {
				let r = it(n).toVar(), i = me(Vn + n).toVar();
				B(Un + n, 0), a(r.greaterThan(1).and(i.lessThan(e.lodScaleLimit)), () => {
					B(Vn + n, gn(i.mul(fe(r.div(qn)).clamp(1.1, 4)), e.lodScaleLimit)), B(Un + n, 1), t.assign(!0);
					for (let e of [
						Fn,
						In,
						Ln,
						Rn,
						zn
					]) u(W(n, e), z(0));
					n === 0 && u(I.element(1), z(0)), o({
						start: z(0),
						end: this.meshSlots,
						type: "uint",
						condition: "<"
					}, ({ i: e }) => {
						u(Fe(n, e, 0), z(0)), u(Fe(n, e, 1), z(0));
					});
				});
			}
			V.element(0).assign(L(t, Me.element(0), z(0))), V.element(1).assign(L(t, Me.element(1), z(1))), V.element(2).assign(z(1));
		})().compute(1), ot = i(() => {
			for (let t of [0, 1]) {
				let n = it(t).toVar(), r = me(Vn + t).toVar();
				a(n.greaterThan(Jn), () => {
					r.assign(r.mul(gn(fe(n.div(qn)), 1.03)));
				}).ElseIf(n.lessThan(Yn), () => {
					r.assign(r.div(1.01));
				}), B(Vn + t, _n(gn(r, e.lodScaleLimit), 1)), B(Hn + t, n);
			}
		})().compute(1), st = [nt(0), nt(1)], ct = [K(0), K(1)], lt = tt(!1), ut = tt(!0), dt = [];
		for (let e = 0; e < Kn; e++) {
			dt.push(at, ut);
			for (let e of st) dt.push(e.retryArgsNode, e.passNode);
			dt.push(...ct);
		}
		this.computeNodes = [
			Xe,
			Ze,
			Qe,
			lt,
			...st.flatMap((e) => [e.argsNode, e.passNode]),
			...ct,
			...dt,
			ot,
			rt(0),
			rt(1)
		], this.positionNode = i(() => {
			let t = be.shiftRight(Tn), n = be.bitAnd(En), r = je.element(t).toVar(), i = r.x, a = r.y, o = C.element(a).toVar(), s = w.element(o.w.add(n)).toVar(), { model: c, columns: l } = Ge(i), u = We(i, 4).toVar(), f = z(u.w).toVar(), p = G(f, 3), m = G(f, 4).toVar(), h = y.element(s).toVar(), g = b.element(s).toVar(), _ = d(h.xyz, "vec3"), v = p.x, S = l[3].xyz;
			wn.assign(S);
			let T = O(e.viewMatrix.mul(H(S, 1)).xyz), E = v.sub(T).div(v.mul(Mn)).clamp(0, 1), D = S.add(c.mul(H(_, 0)).xyz.mul(E)), k = se(c.mul(H(rr(h.w), 0)).xyz);
			return ae.assign(k), yn.assign(k), bn.assign(x(a)), Zt.assign(_e(x(r.w.shiftRight(8).bitAnd(255)), x(r.w.shiftRight(16).bitAnd(255)))), xn.assign(x(o.z)), Sn.assign(x(i)), Cn.assign(u.xyz.mul(ir(g.x).xyz)), ln.assign(he(g.y).mul(m.xy).add(m.zw)), D;
		})();
	}
	async readCounters(e) {
		let t = new Uint32Array(await e.getArrayBufferAsync(this.countersAttribute)), n = Array.from(t.subarray(this.lodStateBase, this.lodStateBase + Wn), (e) => e / Gn), r = [n[Vn], n[1]], i = [n[Hn], n[3]];
		this.controllerActive = i.some((e, t) => e > Jn || e < Yn && r[t] > 1.0001);
		let a = this.meshSlotCapacity, o = (e) => ({
			selected: t[2 + e * Pn + Fn],
			drawn: t[2 + e * Pn + In],
			survived: t[2 + e * Pn + Ln],
			requestedTriangles: t[2 + e * Pn + zn] / 3
		});
		return {
			camera: o(0),
			shadow: o(1),
			occluded: t[1],
			perMesh: (e, n) => (t[Bn + (e * a + n) * 4] + t[Bn + (e * a + n) * 4 + 2]) / 3,
			scale: r,
			fill: i
		};
	}
	drawArgsOffset(e, t, n = 0) {
		return ((e * this.meshSlotCapacity + t) * 2 + n) * 20;
	}
	dispose() {
		for (let e of this.computeNodes) e.dispose();
		this.computeNodes = [];
	}
};
function nr(e, t, n, r) {
	let [i, a, o, s] = n;
	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];
	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]);
	r[3] = s * Math.max(c, l, u);
}
function rr(e) {
	let t = d(e, "int"), n = x(t.shiftLeft(16).shiftRight(16)).div(32767), r = x(t.shiftRight(16)).div(32767), i = x(1).sub(n.abs()).sub(r.abs()), a = _n(i.negate(), 0), o = n.add(L(n.greaterThanEqual(0), a.negate(), a)), s = r.add(L(r.greaterThanEqual(0), a.negate(), a));
	return se(ve(o, s, i));
}
function ir(e) {
	return H(x(e.bitAnd(255)), x(e.shiftRight(8).bitAnd(255)), x(e.shiftRight(16).bitAnd(255)), x(e.shiftRight(24))).div(255);
}
function ar(e, t, n) {
	let r = Math.abs(e) + Math.abs(t) + Math.abs(n) || 1, i = e / r, a = t / r;
	if (n < 0) {
		let e = (1 - Math.abs(a)) * (i >= 0 ? 1 : -1), t = (1 - Math.abs(i)) * (a >= 0 ? 1 : -1);
		i = e, a = t;
	}
	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;
}
function or(e) {
	let t = e.length / 2, n = [Infinity, Infinity], r = [-Infinity, -Infinity];
	for (let t = 0; t < e.length; t++) {
		let i = t & 1;
		e[t] < n[i] && (n[i] = e[t]), e[t] > r[i] && (r[i] = e[t]);
	}
	t === 0 && (n[0] = n[1] = r[0] = r[1] = 0);
	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);
	for (let n = 0; n < t; n++) a[n] = (o(e[n * 2], 0) | o(e[n * 2 + 1], 1) << 16) >>> 0;
	return {
		packed: a,
		scale: i,
		offset: [n[0], n[1]]
	};
}
function sr(e) {
	return e &= 1023, e = (e | e << 16) & 50331903, e = (e | e << 8) & 50393103, e = (e | e << 4) & 51130563, e = (e | e << 2) & 153391689, e;
}
function cr(e, t) {
	let n = e.length / 16, r = /* @__PURE__ */ new Float64Array(4), i = new Float64Array(n * 3), a = [
		Infinity,
		Infinity,
		Infinity
	], o = [
		-Infinity,
		-Infinity,
		-Infinity
	];
	for (let s = 0; s < n; s++) {
		nr(e, s * 16, t, r);
		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]);
	}
	let s = Math.max(o[0] - a[0], o[1] - a[1], o[2] - a[2], 1e-9), c = new Uint32Array(n);
	for (let e = 0; e < n; e++) {
		let t = (t) => Math.min(1023, Math.max(0, Math.floor((i[e * 3 + t] - a[t]) / s * 1024)));
		c[e] = (sr(t(0)) | sr(t(1)) << 1 | sr(t(2)) << 2) >>> 0;
	}
	return lr(c);
}
function lr(e) {
	let t = e.length, n = Uint32Array.from({ length: t }, (e, t) => t), r = new Uint32Array(t), i = /* @__PURE__ */ new Uint32Array(32768);
	for (let a of [0, 15]) {
		i.fill(0);
		for (let n = 0; n < t; n++) i[e[n] >>> a & 32767]++;
		let o = 0;
		for (let e = 0; e < i.length; e++) {
			let t = i[e];
			i[e] = o, o += t;
		}
		for (let o = 0; o < t; o++) {
			let t = n[o];
			r[i[e[t] >>> a & 32767]++] = t;
		}
		[n, r] = [r, n];
	}
	return n;
}
var ur = new class extends U.TempNode {
	projection = B(new U.Matrix4());
	previousProjection = B(new U.Matrix4());
	previousView = B(new U.Matrix4());
	history = /* @__PURE__ */ new WeakMap();
	constructor() {
		super("vec2"), this.updateType = U.NodeUpdateType.RENDER;
	}
	update({ frameId: e, camera: t }) {
		if (!t) return;
		let n = ye.projectionMatrix ?? t.projectionMatrix, r = this.history.get(t);
		r ? r.frame !== e && (r.frame = e, r.previousProjection.copy(r.projection), r.previousView.copy(r.view), r.projection.copy(n), r.view.copy(t.matrixWorldInverse)) : (r = {
			frame: e,
			projection: n.clone(),
			view: t.matrixWorldInverse.clone(),
			previousProjection: n.clone(),
			previousView: t.matrixWorldInverse.clone()
		}, this.history.set(t, r)), this.projection.value.copy(r.projection), this.previousProjection.value.copy(r.previousProjection), this.previousView.value.copy(r.previousView);
	}
	setup() {
		let e = re.mul(H(le, 1)), t = this.projection.mul(m).mul(e), n = this.previousProjection.mul(this.previousView).mul(e);
		return t.xy.div(t.w).sub(n.xy.div(n.w));
	}
}(), dr = F({ velocity: ur }), fr = /* @__PURE__ */ new WeakMap();
function pr(e) {
	let t = fr.get(e);
	return t ? t.clone() : (fr.set(e, e.clone()), e);
}
var mr = /* @__PURE__ */ new Set([
	"uuid",
	"id",
	"name",
	"version",
	"userData",
	"maskNode",
	"_listeners",
	"_cacheKey",
	"_needsUpdate",
	"isMaterial"
]);
function hr() {
	let e = new U.BufferGeometry();
	return e.setAttribute("position", new U.BufferAttribute(/* @__PURE__ */ new Float32Array(3), 3)), e.setAttribute("normal", new U.BufferAttribute(/* @__PURE__ */ new Float32Array(3), 3)), e;
}
var gr = class extends U.Mesh {
	isVirtualMesh = !0;
	data;
	instanceCount;
	fullDetailTriangles;
	pool;
	entry;
	cameraGeometry = hr();
	shadowGeometry = hr();
	blendPart;
	cameraBlendGeometry = hr();
	shadowBlendGeometry = hr();
	blendSourceVersion = -1;
	lastShadowFrame = 0;
	occluder;
	occlusionCulling = !0;
	gpuIndexOf;
	gpuToInput;
	dirtyCells = /* @__PURE__ */ new Set();
	drawingShadow = !1;
	poolVersion = -1;
	ownMrt;
	velocityOutput = !1;
	deform;
	context;
	get maxDrawDistance() {
		let e = this.pool.readFlag(this.entry, "maxDrawDistance");
		return e >= 1e30 ? Infinity : e;
	}
	set maxDrawDistance(e) {
		this.pool.writeFlags(this.entry, { maxDrawDistance: Number.isFinite(e) ? Math.max(0, e) : Nn });
	}
	get minPixelRadius() {
		return this.pool.readFlag(this.entry, "minPixelRadius");
	}
	set minPixelRadius(e) {
		this.pool.writeFlags(this.entry, { minPixelRadius: Math.max(0, e) });
	}
	get capacity() {
		return {
			meshlets: this.pool.capacity.meshlets,
			triangles: this.pool.capacity.triangles
		};
	}
	constructor(e, t, n, r, i = {}) {
		n = pr(n);
		let a = hr();
		super(a, n), this.deform = i.deform, 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 !== U.DoubleSide && !n.transparent && n.alphaTest === 0 && !n.alphaHash, this.gpuToInput = cr(r.matrices, t.boundingSphere), this.gpuIndexOf = new Uint32Array(this.instanceCount);
		for (let e = 0; e < this.instanceCount; e++) this.gpuIndexOf[this.gpuToInput[e]] = e;
		e.register(this, r), i.maxDrawDistance !== void 0 && (this.maxDrawDistance = i.maxDrawDistance), i.minPixelRadius !== void 0 && (this.minPixelRadius = i.minPixelRadius), mn(n);
		let o = n;
		this.ownMrt = o.mrtNode ?? null;
		let s = H(n.colorNode ?? j).toVar(), c = (e) => ve(w(e), w(e.add(17.17)), w(e.add(43.43))), l = L(e.debugMode.equal(Oe.meshlets), c(bn.add(Sn.mul(.618))), L(e.debugMode.equal(Oe.lodLevel), c(xn.add(3)), c(Sn)));
		n.colorNode = H(L(e.debugMode.equal(Oe.shaded), s.xyz.mul(Cn), l), s.w), n.side === U.DoubleSide && !n.normalNode && (n.normalNode = se(m.mul(H(yn, 0)).xyz.mul(b))), this.blendPart = new U.Mesh(this.cameraBlendGeometry, n.clone()), this.blendPart.name = "lod blend", Object.assign(this.blendPart, { isVirtualMeshPart: !0 }), this.blendPart.frustumCulled = !1, this.add(this.blendPart), this.syncBlendPart(), this.syncPool(), this.geometry = this.cameraGeometry, a.dispose(), this.onBeforeShadow = (t, n, r, i) => {
			this.lastShadowFrame = e.frameCount, e.noteShadowCamera(i), this.drawingShadow = !0, this.geometry = this.shadowGeometry;
		};
		let u = this.onBeforeRender;
		this.onBeforeRender = (...e) => {
			this.drawingShadow ? this.drawingShadow = !1 : this.geometry = this.cameraGeometry, u.apply(this, e);
		};
		let d = !1;
		this.blendPart.onBeforeShadow = () => {
			d = !0, this.blendPart.geometry = this.shadowBlendGeometry;
		}, this.blendPart.onBeforeRender = () => {
			d ? d = !1 : this.blendPart.geometry = this.cameraBlendGeometry;
		};
	}
	syncBlendPart() {
		let e = this.blendPart;
		e.castShadow = this.castShadow, e.receiveShadow = this.receiveShadow, e.renderOrder = this.renderOrder, e.layers.mask = this.layers.mask;
		let t = this.material, n = e.material, r = t.version !== this.blendSourceVersion;
		for (let e of Object.keys(t)) {
			if (mr.has(e)) continue;
			let r = t[e], i = n[e];
			r && typeof r == "object" && typeof r.copy == "function" && typeof r.equals == "function" && i && i !== r && typeof i.copy == "function" ? i.equals(r) || i.copy(r) : i !== r && (n[e] = r);
		}
		(r || !n.maskNode) && (n.maskNode = t.maskNode ? f(t.maskNode).and($t()) : $t()), r && (this.blendSourceVersion = t.version, n.needsUpdate = !0);
	}
	syncPool() {
		let e = this.pool;
		if (this.poolVersion === e.version || !e.positionNode) return;
		this.poolVersion = e.version;
		let t = this.entry.slot, n = [
			[
				this.cameraGeometry,
				e.cameraIndex,
				0,
				0
			],
			[
				this.shadowGeometry,
				e.shadowIndex,
				1,
				0
			],
			[
				this.cameraBlendGeometry,
				e.cameraIndex,
				0,
				1
			],
			[
				this.shadowBlendGeometry,
				e.shadowIndex,
				1,
				1
			]
		];
		for (let [r, i, a, o] of n) r.setIndex(i), r.setIndirect(e.drawArgsAttribute, e.drawArgsOffset(a, t, o));
		this.material.positionNode = this.deform ? this.deform(e.positionNode, { instanceOrigin: wn }) : e.positionNode, this.material.needsUpdate = !0, this.syncBlendPart();
	}
	setVelocityOutput(e) {
		if (e === this.velocityOutput) return;
		this.velocityOutput = e;
		let t = this.material;
		t.mrtNode = e ? this.ownMrt ? this.ownMrt.merge(dr) : dr : this.ownMrt, this.material.needsUpdate = !0, this.syncBlendPart();
	}
	markCutDirty() {
		this.pool.dirty = !0;
	}
	setMatrixAt(e, t) {
		let n = this.gpuIndexOf[e];
		this.pool.setMatrix(this.entry, n, t), this.dirtyCells.add(Math.floor(n / 128));
	}
	commitInstances() {
		this.pool.commitInstances(this.entry, this.dirtyCells), this.dirtyCells.clear();
	}
	dispose(e) {
		this.visible = !1, (e ?? this.context).unregister(this), this.removeFromParent();
	}
	async readStats(e) {
		let t = await this.pool.readCounters(e);
		return {
			drawnTriangles: t.perMesh(0, this.entry.slot),
			shadowTriangles: t.perMesh(1, this.entry.slot)
		};
	}
}, _r = {
	MeshPhysicalMaterial: [U.MeshPhysicalMaterial, U.MeshPhysicalNodeMaterial],
	MeshStandardMaterial: [U.MeshStandardMaterial, U.MeshStandardNodeMaterial],
	MeshPhongMaterial: [U.MeshPhongMaterial, U.MeshPhongNodeMaterial],
	MeshLambertMaterial: [U.MeshLambertMaterial, U.MeshLambertNodeMaterial],
	MeshBasicMaterial: [U.MeshBasicMaterial, U.MeshBasicNodeMaterial],
	MeshToonMaterial: [U.MeshToonMaterial, U.MeshToonNodeMaterial],
	MeshMatcapMaterial: [U.MeshMatcapMaterial, U.MeshMatcapNodeMaterial],
	MeshNormalMaterial: [U.MeshNormalMaterial, U.MeshNormalNodeMaterial]
}, vr = [
	["isMeshPhysicalMaterial", "MeshPhysicalMaterial"],
	["isMeshStandardMaterial", "MeshStandardMaterial"],
	["isMeshPhongMaterial", "MeshPhongMaterial"],
	["isMeshLambertMaterial", "MeshLambertMaterial"],
	["isMeshBasicMaterial", "MeshBasicMaterial"],
	["isMeshToonMaterial", "MeshToonMaterial"],
	["isMeshMatcapMaterial", "MeshMatcapMaterial"],
	["isMeshNormalMaterial", "MeshNormalMaterial"]
];
function yr(e) {
	let t = e, n = _r[e.type] ? e.type : vr.find(([e]) => t[e] === !0)?.[1];
	return n ? _r[n] : null;
}
function br(e) {
	return e.isNodeMaterial === !0 || yr(e) !== null;
}
function xr(e) {
	if (e.isNodeMaterial) return e;
	let t = yr(e);
	if (!t) return null;
	let [n, r] = t, i = new r(), a = i.defines;
	return n.prototype.copy.call(i, e), i.defines = a, i;
}
//#endregion
//#region src/source.ts
var Sr = 1e-6, Cr = 1e-4;
function wr(e, t = {}) {
	let n = e.attributes.position, r = t.uvs ?? !0 ? e.attributes.uv : void 0, i = t.colors ? e.attributes.color : void 0, a = t.normals === "keep" ? e.attributes.normal : void 0, o = e.index, s = o ? o.count : n.count, c = Math.max(0, Math.min(s, t.range?.start ?? 0)), l = Math.floor((Math.min(s, c + (t.range?.count ?? s)) - c) / 3) * 3, u = (e) => o ? o.getX(c + e) : c + e, d = Er(l, u, [{
		attribute: n,
		size: 3,
		tolerance: Sr
	}]), f = Tr(d.firstVertex, n, 3), p = null;
	if (!a) {
		let e = new U.BufferGeometry();
		e.setAttribute("position", new U.BufferAttribute(f, 3)), e.setIndex(new U.BufferAttribute(d.indices, 1)), e.computeVertexNormals(), p = e.attributes.normal.array;
	}
	if (!r && !i && !a) return {
		positions: f,
		normals: p,
		indices: d.indices
	};
	let m = [{
		attribute: n,
		size: 3,
		tolerance: Sr
	}];
	r && m.push({
		attribute: r,
		size: 2,
		tolerance: Sr
	}), a && m.push({
		attribute: a,
		size: 3,
		tolerance: Cr
	}), i && m.push({
		attribute: i,
		size: 3,
		tolerance: Cr
	});
	let h = Er(l, u, m), g = {
		positions: Tr(h.firstVertex, n, 3),
		normals: /* @__PURE__ */ new Float32Array(),
		indices: h.indices
	};
	if (a) {
		g.normals = Tr(h.firstVertex, a, 3);
		for (let e = 0; e < g.normals.length; e += 3) {
			let t = Math.hypot(g.normals[e], g.normals[e + 1], g.normals[e + 2]) || 1;
			g.normals[e] /= t, g.normals[e + 1] /= t, g.normals[e + 2] /= t;
		}
	} else {
		g.normals = new Float32Array(h.firstVertex.length * 3);
		for (let e = 0; e < h.firstVertex.length; e++) {
			let t = d.indices[h.firstCorner[e]];
			g.normals.set(p.subarray(t * 3, t * 3 + 3), e * 3);
		}
	}
	return r && (g.uvs = Tr(h.firstVertex, r, 2)), i && (g.colors = Tr(h.firstVertex, i, 3)), g;
}
function Tr(e, t, n) {
	let r = new Float32Array(e.length * n);
	for (let i = 0; i < e.length; i++) for (let a = 0; a < n; a++) r[i * n + a] = t.getComponent(e[i], a);
	return r;
}
function Er(e, t, n) {
	let r = n.reduce((e, t) => e + t.size, 0), i = n.map(({ tolerance: e }) => {
		let t = 10 ** Math.log10(1 / e);
		return {
			multiplier: t,
			additive: e * .5 * t
		};
	}), a = 1;
	for (; a < e * 2;) a <<= 1;
	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;
	for (let a = 0; a < e; a++) {
		let e = t(a), m = 0, h = 0;
		for (let t = 0; t < n.length; t++) {
			let { attribute: r, size: a } = n[t], { multiplier: o, additive: s } = i[t];
			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, Dr[h % Dr.length]) | 0;
		}
		for (m &= o;;) {
			let t = s[m];
			if (t < 0) {
				s[m] = p, c.set(l, p * r), u[p] = e, d[p] = a, f[a] = p++;
				break;
			}
			let n = !0;
			for (let e = 0; e < r && n; e++) n = c[t * r + e] === l[e];
			if (n) {
				f[a] = t;
				break;
			}
			m = m + 1 & o;
		}
	}
	return {
		indices: f,
		firstVertex: u.slice(0, p),
		firstCorner: d.slice(0, p)
	};
}
var Dr = [
	73856093,
	19349663,
	83492791,
	2654435761,
	2246822519,
	3266489917,
	668265263,
	374761393,
	1181783497,
	3735928559,
	2028178513
];
function Or(e) {
	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), i = new Float32Array(t * 3), a = new Float32Array(t * 3), o = e.some((e) => e.mesh.uvs) ? new Float32Array(t * 2) : null, s = new Uint32Array(n), c = new U.Color(), l = 0, u = 0;
	for (let { mesh: t, color: n = 16777215 } of e) {
		let e = t.positions.length / 3;
		if (r.set(t.positions, l * 3), i.set(t.normals, l * 3), o && t.uvs && o.set(t.uvs, l * 2), t.colors) a.set(t.colors, l * 3);
		else {
			c.set(n);
			for (let t = 0; t < e; t++) a.set([
				c.r,
				c.g,
				c.b
			], (l + t) * 3);
		}
		for (let e = 0; e < t.indices.length; e++) s[u + e] = t.indices[e] + l;
		l += e, u += t.indices.length;
	}
	return o ? {
		positions: r,
		normals: i,
		colors: a,
		uvs: o,
		indices: s
	} : {
		positions: r,
		normals: i,
		colors: a,
		indices: s
	};
}
//#endregion
//#region src/core/import/fromObject3D.ts
var kr = Rt, Ar = /* @__PURE__ */ new WeakSet();
function jr(e) {
	let t = e;
	if (!t.isMesh) return "not a mesh";
	if (t.isVirtualMesh || t.isVirtualMeshPart) return "already a VirtualMesh";
	if (t.isSkinnedMesh) return "skinned";
	if (t.isBatchedMesh) return "batched";
	let n = t.geometry;
	if (!n?.attributes?.position || n.isInstancedBufferGeometry) return "unsupported geometry";
	let r = n.morphAttributes;
	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 || !br(e)) ? "material without a node equivalent" : null;
}
function Mr(e, t) {
	e.updateWorldMatrix(!0, !0);
	let n = /* @__PURE__ */ new Map(), r = [], i = [], a = new U.Matrix4(), o = new U.Matrix4(), s = new U.Color();
	e.traverse((e) => {
		if (!e.isMesh || Ar.has(e)) return;
		let c = e, l = jr(c) ?? (t && !t(c) ? "filtered out" : null);
		if (l) {
			i.push({
				object: c,
				reason: l
			});
			return;
		}
		let u = c.geometry, d = Array.isArray(c.material) ? c.material : [c.material], f = Nr(u, Array.isArray(c.material));
		if (f.length === 0) return;
		r.push(c);
		let p = c.isInstancedMesh ? c : null, m = p ? p.count : 1, h = Pr(c);
		for (let { start: e, count: t, materialIndex: r } of f) {
			let i = d[r];
			if (!i) continue;
			let l = i.vertexColors === !0 && u.attributes.color !== void 0, f = [
				u.id,
				e,
				t,
				i.uuid,
				c.castShadow,
				c.receiveShadow,
				h,
				c.renderOrder,
				c.layers.mask
			].join(":"), g = n.get(f);
			g || (g = {
				geometry: u,
				range: {
					start: e,
					count: t
				},
				material: i,
				matrices: /* @__PURE__ */ new Float32Array(),
				colors: null,
				instances: [],
				vertexColors: l,
				castShadow: c.castShadow,
				receiveShadow: c.receiveShadow,
				visible: h,
				renderOrder: c.renderOrder,
				layers: c.layers.mask,
				name: c.name,
				userData: { ...c.userData },
				matrixList: [],
				colorList: null
			}, n.set(f, g));
			for (let e = 0; e < m; e++) {
				p ? (p.getMatrixAt(e, a), o.multiplyMatrices(c.matrixWorld, a)) : o.copy(c.matrixWorld), g.matrixList.push(...o.elements);
				let t = !!p?.instanceColor;
				t && p.getColorAt(e, s), t && !g.colorList && (g.colorList = Array(g.instances.length * 4).fill(1)), g.colorList && (t ? g.colorList.push(s.r, s.g, s.b, 1) : g.colorList.push(1, 1, 1, 1)), g.instances.push({
					object: c,
					index: p ? e : -1
				});
			}
		}
	});
	let c = [];
	for (let { matrixList: e, colorList: t, ...r } of n.values()) r.matrices = Float32Array.from(e), r.colors = t ? Float32Array.from(t) : null, c.push(r);
	return {
		groups: c,
		meshes: r,
		skipped: i
	};
}
function Nr(e, t) {
	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 : [{
		start: 0,
		count: n,
		materialIndex: 0
	}], o = [];
	for (let e of a) {
		let t = Math.max(e.start, r), n = Math.min(e.start + e.count, i);
		n - t >= 3 && o.push({
			start: t,
			count: n - t,
			materialIndex: e.materialIndex ?? 0
		});
	}
	return o;
}
function Pr(e) {
	for (let t = e; t; t = t.parent) if (!t.visible) return !1;
	return !0;
}
var Fr = class {
	context;
	object = new U.Group();
	meshes = [];
	groups;
	skipped;
	stats = {
		sourceMeshes: 0,
		instances: 0,
		uniqueGeometries: 0,
		buildMs: 0
	};
	hidden = /* @__PURE__ */ new Map();
	detached = /* @__PURE__ */ new Map();
	constructor(e, t) {
		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);
	}
	hide(e, t) {
		let n = /* @__PURE__ */ new Set();
		for (let t of e) Ar.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());
		for (let e of n) for (; e !== t && e.children.length === 0 && e.parent && (e.type === "Group" || e.type === "Object3D");) {
			let t = e.parent;
			this.detached.set(e, t), t.remove(e), e = t;
		}
	}
	worldMatrixOf(e) {
		let t = this.detached.get(e);
		return t ? (e.updateMatrix(), e.matrixWorld.multiplyMatrices(this.worldMatrixOf(t), e.matrix)) : (e.updateWorldMatrix(!0, !1), e.matrixWorld);
	}
	syncTransforms() {
		let e = new U.Matrix4(), t = new U.Matrix4(), n = /* @__PURE__ */ new Set();
		this.groups.forEach((r, i) => {
			let a = this.meshes[i];
			r.instances.forEach(({ object: r, index: i }, o) => {
				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);
			}), a.commitInstances();
		});
	}
	dispose() {
		for (let e of this.meshes) e.dispose(this.context), e.material.dispose(), e.geometry.dispose();
		this.meshes.length = 0;
		for (let [e, t] of this.hidden) e.layers.mask = t, Ar.delete(e);
		this.hidden.clear();
		for (let [e, t] of this.detached) t.add(e), Ar.delete(e);
		this.detached.clear(), this.object.removeFromParent();
	}
};
async function Ir(e, t, n = {}) {
	let r = performance.now(), i = n.builder ?? kr, a = Mr(t, n.filter), o = new Fr(e, a), s = /* @__PURE__ */ new Map(), c = (e) => `${e.geometry.id}:${e.range.start}:${e.range.count}:${e.vertexColors}`;
	for (let e of o.groups) {
		let t = c(e);
		s.has(t) || s.set(t, {
			group: e,
			triangles: e.range.count / 3
		});
	}
	o.stats.uniqueGeometries = s.size;
	let l = [...s.values()].reduce((e, t) => e + t.triangles, 0) || 1, u = 0;
	for (let e of s.values()) {
		let { geometry: t, range: r, vertexColors: a } = e.group;
		e.data = await i(wr(t, {
			range: r,
			colors: a,
			normals: t.attributes.normal ? "keep" : "compute"
		}), {
			...n.build,
			onProgress: (t) => n.onProgress?.((u + t * e.triangles) / l)
		}), u += e.triangles;
	}
	let d = /* @__PURE__ */ new Map(), f = [], p = /* @__PURE__ */ new Set();
	for (let t of o.groups) {
		let r = Lr(t, n, d);
		if (!r) {
			for (let { object: e } of t.instances) p.add(e);
			continue;
		}
		let i = typeof n.mesh == "function" ? n.mesh(t) : n.mesh, a = e.createMesh(s.get(c(t)).data, r, {
			matrices: t.matrices,
			colors: t.colors ?? void 0
		}, i);
		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);
	}
	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;
}
function Lr(e, t, n) {
	let r = e.material, i = !!(r.normalMap && e.geometry.attributes.tangent && r.normalMap.flipY === !1), a = `${r.uuid}:${i}`;
	if (n.has(a)) return n.get(a);
	let o;
	if (t.material ? o = t.material(r, e) : (o = xr(r), o === r && (o = r.clone())), o && i) {
		let e = o.normalScale;
		e && (o.normalScale = e.clone().setY(-e.y));
	}
	return n.set(a, o), o;
}
//#endregion
//#region src/core/runtime/OcclusionCulling.ts
var Rr = 68, zr = 64, Br = 64, Vr = [], Hr = (e) => e.reduce((e, t) => e + t, 0) / e.length, Ur = P, Wr = N, Gr = class {
	enabled = !0;
	auto = !0;
	autoProbeFrames = 40;
	autoHoldFrames = 900;
	autoChoice = !1;
	phase = "hold";
	phaseFrames = this.autoHoldFrames - 120;
	samples = [];
	offMean = 0;
	lastTick = 0;
	resolutionScale = .5;
	maxSize;
	active = !1;
	activeNode = B(0, "uint");
	depthScene = new U.Scene();
	proxies = /* @__PURE__ */ new Map();
	projection;
	near;
	levelCapacity;
	levelOffsets = [];
	hzbAttribute;
	hzbWrite;
	hzbRead;
	buildNodes = [];
	renderTarget = null;
	width = 0;
	height = 0;
	levels = 0;
	bufferSize = new U.Vector2();
	constructor(e, t, n = 1024) {
		this.maxSize = Math.max(1, Math.min(32768, n)), this.projection = e, this.near = t;
		let r = this.maxSize, i = Rr, a = 0;
		for (; this.levelOffsets.push(i), i += r * r, a++, r !== 1;) r = Math.ceil(r / 2);
		this.levelCapacity = a, this.hzbAttribute = new U.StorageBufferAttribute(new Float32Array(i), 1), this.hzbWrite = R(this.hzbAttribute, "float", i), this.hzbRead = R(this.hzbAttribute, "float", i).toReadOnly();
	}
	occluded(e, t) {
		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 = Ur(o.div(i), o.div(a)).mul(u).sub(n.element(2).x), p = Wr(s.div(i), s.div(a)).mul(u).sub(n.element(2).x), m = Ur(c.div(i), c.div(a)).mul(d).sub(n.element(2).y), _ = Wr(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), b = i.lessThanEqual(this.near), C = this.hzbRead, w = C.element(1), T = C.element(2), E = x(0), D = g(S(f.mul(.5).add(.5).mul(w)), E, w.sub(1)), O = g(S(p.mul(.5).add(.5).mul(w)), E, w.sub(1)), k = g(S(x(.5).sub(_.mul(.5)).mul(T)), E, T.sub(1)), ee = g(S(x(.5).sub(m.mul(.5)).mul(T)), E, T.sub(1)), te = Wr(O.sub(D), ee.sub(k)).add(1), ne = Ur(h(A(te)), C.element(zr).sub(1)), j = z(ne).mul(4), M = y(ne), N = C.element(j), P = C.element(j.add(1)), re = C.element(j.add(2)), F = (e, t) => {
			let n = g(S(e.div(M)), E, P.sub(1)), r = g(S(t.div(M)), E, re.sub(1));
			return C.element(z(N.add(r.mul(P)).add(n)));
		}, ie = Wr(Wr(F(D, k), F(O, k)), Wr(F(D, ee), F(O, ee)));
		return b.not().and(v.lessThan(1)).and(v.greaterThan(ie.add(1e-6)));
	}
	tick(e) {
		let t = this.lastTick ? e - this.lastTick : 0;
		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 = Hr(this.samples), this.next("probeOn")) : this.phase === "probeOn" && this.samples.length >= this.autoProbeFrames ? (this.autoChoice = Hr(this.samples) < this.offMean * .97, this.next("hold")) : this.phase === "hold" && this.phaseFrames >= this.autoHoldFrames && this.next("probeOff"));
	}
	next(e) {
		this.phase = e, this.phaseFrames = 0, this.samples = [];
	}
	autoWanted() {
		return this.phase === "probeOn" || this.phase === "hold" && this.autoChoice;
	}
	proxyOf(e) {
		let t = this.proxies.get(e);
		t || (t = new U.Mesh(e.cameraGeometry, new U.MeshBasicNodeMaterial({ colorWrite: !1 })), t.frustumCulled = !1, this.depthScene.add(t), this.proxies.set(e, t));
		let n = t.material;
		return n.positionNode !== e.pool.positionNode && (n.positionNode = e.pool.positionNode, n.needsUpdate = !0), t;
	}
	unregisterMesh(e) {
		let t = this.proxies.get(e);
		t && (this.proxies.delete(e), t.removeFromParent(), t.material.dispose());
	}
	wantsFrame(e, t, n) {
		let r = e, i = t.isPerspectiveCamera && !r.reversedDepthBuffer && !r.logarithmicDepthBuffer;
		return this.enabled && i && (!this.auto || this.autoWanted());
	}
	beginFrame(e, t, n) {
		let r = !1;
		for (let e of n) {
			let t = e.visible && e.occluder && e.pool.hasCut && !!e.pool.positionNode;
			if (!t && !this.proxies.has(e)) continue;
			let n = this.proxyOf(e);
			n.visible = t, r ||= t;
		}
		if (this.active = r, this.activeNode.value = +!!r, !r) return Vr;
		e.getDrawingBufferSize(this.bufferSize);
		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));
		(a !== this.width || o !== this.height) && this.resize(a, o);
		let s = e.getRenderTarget(), c = e.getMRT();
		return e.setMRT(null), e.setRenderTarget(this.renderTarget), e.render(this.depthScene, t), e.setRenderTarget(s), e.setMRT(c), this.buildNodes;
	}
	resize(e, t) {
		let n = this.buildNodes;
		this.renderTarget?.dispose();
		let r = new U.DepthTexture(e, t);
		r.type = U.FloatType, this.renderTarget = new U.RenderTarget(e, t, {
			depthBuffer: !0,
			depthTexture: r
		}), this.width = e, this.height = t;
		let o = this.hzbAttribute.array;
		o.fill(0, 0, Rr);
		let c = e, l = t, u = 0;
		for (let e = 0; e < this.levelCapacity && (o[e * 4] = this.levelOffsets[e], o[e * 4 + 1] = c, o[e * 4 + 2] = l, u++, c !== 1 || l !== 1); e++) c = Math.max(1, Math.ceil(c / 2)), l = Math.max(1, Math.ceil(l / 2));
		this.levels = u, o[zr] = u, this.hzbAttribute.needsUpdate = !0;
		let d = pe(r), f = this.hzbWrite, p = i(() => {
			let e = T, t = z(f.element(1)), n = z(f.element(2));
			a(e.greaterThanEqual(t.mul(n)), () => {
				s();
			});
			let r = e.mod(t), i = e.div(t), o = z(f.element(0)).toVar();
			f.element(o.add(e)).assign(d.load(D(E(r), E(i))));
		})().compute(e * t, [Br]);
		this.buildNodes = [p], c = e, l = t;
		for (let e = 1; e < u; e++) c = Math.max(1, Math.ceil(c / 2)), l = Math.max(1, Math.ceil(l / 2)), this.buildNodes.push(i(() => {
			let t = T, n = z(f.element(e * 4)).toVar(), r = z(f.element(e * 4 + 1)), i = z(f.element(e * 4 + 2));
			a(t.greaterThanEqual(r.mul(i)), () => {
				s();
			});
			let o = t.mod(r), c = t.div(r), l = z(f.element((e - 1) * 4)).toVar(), u = z(f.element((e - 1) * 4 + 1)), d = z(f.element((e - 1) * 4 + 2)), p = o.mul(2), m = c.mul(2), h = Ur(p.add(1), u.sub(1)), g = Ur(m.add(1), d.sub(1)), _ = l.add(m.mul(u)), v = l.add(g.mul(u)), y = Wr(Wr(f.element(_.add(p)), f.element(_.add(h))), Wr(f.element(v.add(p)), f.element(v.add(h))));
			f.element(n.add(t)).assign(y);
		})().compute(c * l, [Br]));
		for (let e of n) e.dispose();
	}
	dispose() {
		this.renderTarget?.dispose(), this.renderTarget = null;
		for (let e of [...this.proxies.keys()]) this.unregisterMesh(e);
	}
}, Kr = 45, qr = 1.03, Jr = 1.01, Yr = new U.Vector3(), Xr = (e, t) => e * (t / .82) ** .25, Zr = class {
	viewMatrix = B(new U.Matrix4());
	projectionMatrix = B(new U.Matrix4());
	projScale = B(1);
	near = B(.1);
	errorThreshold = B(1);
	lodBlend = 2;
	lodBlendTemporal = !1;
	lodBlendMax = B(2);
	lodScaleLimit = B(64);
	triangleBudget = 0;
	thresholdRange = [.5, 3];
	maxErrorThreshold = 64;
	lastStats = null;
	statsInterval = 10;
	frameCount = 0;
	outOfBand = 0;
	thresholdTarget = null;
	thresholdWritten = NaN;
	statsThreshold = 1;
	statsPending = !1;
	frustumCulling = B(1, "uint");
	debugMode = B(0, "uint");
	minPixelRadius = B(.7);
	frustumPlanes = Array.from({ length: 6 }, () => B(new U.Vector4()));
	shadowSweep = B(new U.Vector3());
	autoShadowSweep = !0;
	shadowErrorScale = B(3);
	detectedSweep = new U.Vector3();
	detectedSweepFrame = -Infinity;
	occlusion = new Gr(this.projectionMatrix, this.near);
	freeze = !1;
	autoUpdate = !0;
	errorInCssPixels = !0;
	meshes = [];
	pools = [];
	capacity;
	maxPoolBytes;
	constructor(e = {}) {
		this.capacity = {
			triangles: e.maxTriangles ?? 1e7,
			shadowTriangles: e.maxShadowTriangles ?? 4e6,
			meshlets: Math.min(e.maxMeshlets ?? 1 << 20, 1 << 24)
		}, this.maxPoolBytes = e.maxPoolBytes ?? 125829120;
	}
	frustum = new U.Frustum();
	projScreen = new U.Matrix4();
	size = new U.Vector2();
	computeList = [];
	dispatchedPools = [];
	skippedFrames = 0;
	cutInputs = new Float64Array(Kr).fill(NaN);
	cutInputsScratch = new Float64Array(Kr);
	sceneHooks = /* @__PURE__ */ new WeakMap();
	autoCall = -1;
	autoCamera = null;
	manualCall = -1;
	manualCamera = null;
	updatingAuto = !1;
	add(e, t) {
		return Ir(this, e, t);
	}
	createMesh(e, t, n, r) {
		return new gr(this, e, t, n, r);
	}
	asyncCompile = !0;
	compilePool(e, t) {
		t.pipelineState = "compiling";
		let n = t.version, r = () => {
			t.version === n && (t.pipelineState = "ready", t.dirty = !0);
		};
		e.compileComputeAsync(t.computeNodes).then(r, r);
	}
	preparePools(e) {
		this.checkDeviceLimits(e);
		for (let t of this.pools) t.disabled || t.prepare(e);
		for (let e of this.meshes) e.syncPool();
	}
	checkedPools = /* @__PURE__ */ new WeakSet();
	checkDeviceLimits(e) {
		let t = e.backend.device;
		if (!t) return;
		let n = Math.min(t.limits.maxStorageBufferBindingSize, t.limits.maxBufferSize);
		for (let e of this.pools) {
			if (this.checkedPools.has(e) || (this.checkedPools.add(e), e.maxBytes <= n)) continue;
			e.disabled = !0;
			let t = this.meshes.filter((t) => t.pool === e);
			for (let e of t) e.visible = !1;
			let r = (e) => `${Math.round(e / 2 ** 20)} MB`;
			console.error(`three-virtual-geometry: ${t.map((e) => `"${e.name || "mesh"}"`).join(", ")} needs ${r(e.maxBytes)} in a single GPU buffer, but this device allows ${r(n)}, so it is not drawn. Create the renderer with new WebGPURenderer({ requiredLimits: await virtualGeometryLimits() }) to use the GPU's full limits, or use a lighter version of the mesh.`);
		}
	}
	async compileAsync(e, t, n) {
		this.preparePools(e);
		let r = this.pools.filter((e) => !e.disabled && e.pipelineState !== "ready");
		for (let e of r) e.pipelineState = "compiling";
		await Promise.all(r.map((t) => e.compileComputeAsync(t.computeNodes).catch(() => void 0)));
		for (let e of r) e.pipelineState = "ready", e.dirty = !0;
		await e.compileAsync(t, n);
	}
	noteShadowCamera(e) {
		if (this.detectedSweepFrame === this.frameCount) return;
		let t = e;
		if (!t.isOrthographicCamera) return;
		let n = Math.max(t.top - t.bottom, t.right - t.left) / t.zoom;
		e.getWorldDirection(this.detectedSweep).multiplyScalar(n), this.detectedSweepFrame = this.frameCount;
	}
	register(e, t) {
		let n = t.matrices.length / 16, r = tr.bytesOf(e.data), i = r > this.maxPoolBytes, a = i ? void 0 : this.pools.find((t) => !t.dedicated && t.fits(e.data, n));
		a || (a = new tr(this, this.capacity, i ? Math.ceil(r * 1.01) : this.maxPoolBytes), a.dedicated = i, this.pools.push(a)), e.pool = a, e.entry = a.add(e.data, t.matrices, t.colors, e.gpuToInput), a.ensureBuilt(), this.meshes.push(e), e.onBeforeRender = (e, t, n) => this.autoUpdateFor(e, t, n, !1);
	}
	autoUpdateFor(e, t, n, r) {
		if (!this.autoUpdate || this.meshes.length === 0 || t.overrideMaterial && t.overrideMaterial.isShadowPassMaterial) return;
		if (!r && t.isScene) {
			if (t.onBeforeRender === this.sceneHooks.get(t)) return;
			let e = t.onBeforeRender, n = this, r = function(t, r, i, ...a) {
				n.autoUpdateFor(t, r, i, !0), e.call(this, t, r, i, ...a);
			};
			t.onBeforeRender = r, this.sceneHooks.set(t, r);
		}
		let i = e.info.render.calls;
		if ((n !== this.autoCamera || i !== this.autoCall) && (n !== this.manualCamera || i !== this.manualCall + 1)) {
			this.autoCall = i, this.autoCamera = n, this.updatingAuto = !0;
			try {
				this.update(e, n);
			} finally {
				this.updatingAuto = !1;
			}
		}
	}
	unregister(e) {
		let t = this.meshes.indexOf(e);
		t !== -1 && (this.meshes.splice(t, 1), e.pool.remove(e.entry), this.occlusion.unregisterMesh(e));
	}
	dispose() {
		for (let e of [...this.meshes]) e.dispose(this);
		for (let e of this.pools) e.dispose();
		this.pools.length = 0, this.occlusion.dispose();
	}
	update(e, t) {
		if (this.updatingAuto || (this.manualCall = e.info.render.calls, this.manualCamera = t), this.freeze) return;
		this.occlusion.tick(performance.now()), this.stepThreshold();
		let n = Math.max(1, this.lodBlend);
		this.lodBlendMax.value !== n && (this.lodBlendMax.value = n);
		let r = this.lodBlendTemporal ? this.frameCount % 64 : 0;
		Qt.value !== r && (Qt.value = r);
		let i = Math.max(1, this.maxErrorThreshold / this.errorThreshold.value);
		this.lodScaleLimit.value !== i && (this.lodScaleLimit.value = i);
		let a = !!e.getMRT()?.outputNodes?.velocity;
		for (let e of this.meshes) e.setVelocityOutput(a), e.syncBlendPart();
		t.updateMatrixWorld(), this.viewMatrix.value.copy(t.matrixWorldInverse);
		let o = ye.projectionMatrix ?? t.projectionMatrix;
		this.projectionMatrix.value.equals(o) || this.projectionMatrix.value.copy(o), e.getDrawingBufferSize(this.size);
		let s = this.size.y / (this.errorInCssPixels ? e.getPixelRatio() : 1), c = o.elements[5] * s * .5;
		this.projScale.value !== c && (this.projScale.value = c), this.near.value !== t.near && (this.near.value = t.near), this.projScreen.multiplyMatrices(o, t.matrixWorldInverse), this.frustum.setFromProjectionMatrix(this.projScreen, U.WebGPUCoordinateSystem);
		for (let e = 0; e < 6; e++) {
			let { normal: t, constant: n } = this.frustum.planes[e], r = this.frustumPlanes[e].value;
			(r.x !== t.x || r.y !== t.y || r.z !== t.z || r.w !== n) && r.set(t.x, t.y, t.z, n);
		}
		if (this.autoShadowSweep) {
			let e = this.frameCount - this.detectedSweepFrame <= 2 ? this.detectedSweep : Yr;
			this.shadowSweep.value.equals(e) || this.shadowSweep.value.copy(e);
		}
		let l = this.occlusion.wantsFrame(e, t, this.frameCount);
		for (let e of this.meshes) e.pool.writeFlags(e.entry, {
			enabled: +!!e.visible,
			shadow: e.castShadow && this.frameCount - e.lastShadowFrame <= 2 ? 1 : 0,
			occlusion: l && e.occlusionCulling ? 1 : 0
		});
		if (this.cutInputsChanged(t, o, e.getPixelRatio())) for (let e of this.pools) e.dirty = !0;
		for (let e of this.pools) e.controllerActive && (e.dirty = !0);
		this.preparePools(e);
		let u = this.computeList;
		u.length = 0;
		let d = this.dispatchedPools;
		d.length = 0;
		for (let t of this.pools) if (!t.disabled && t.dirty && t.entries.length !== 0) {
			if (t.pipelineState !== "ready") {
				if (this.asyncCompile) {
					t.pipelineState === "none" && this.compilePool(e, t);
					continue;
				}
				t.pipelineState = "ready";
			}
			for (let e of t.computeNodes) u.push(e);
			d.push(t);
		}
		if (u.length > 0) {
			let n = l ? this.occlusion.beginFrame(e, t, this.meshes) : [];
			n.length && u.unshift(...n), e.compute(u);
			for (let e of d) e.dirty = !1, e.hasCut = !0;
		} else this.skippedFrames++;
		this.frameCount++;
		let f = this.thresholdTarget === null ? this.statsInterval : Math.min(2, this.statsInterval);
		this.meshes.length > 0 && !this.statsPending && this.frameCount % f === 0 && (this.statsPending = !0, this.statsThreshold = this.errorThreshold.value, this.readStats(e).then((e) => {
			this.lastStats = e, this.triangleBudget > 0 && this.adaptThreshold(e);
		}).finally(() => this.statsPending = !1));
	}
	cutInputsChanged(e, t, n) {
		let r = this.cutInputsScratch, i = 0;
		for (let t = 0; t < 16; t++) r[i++] = e.matrixWorldInverse.elements[t];
		for (let e = 0; e < 16; e++) r[i++] = t.elements[e];
		r[i++] = e.near, r[i++] = this.size.x, r[i++] = this.size.y, r[i++] = n, r[i++] = +!!this.errorInCssPixels, r[i++] = this.errorThreshold.value, r[i++] = this.lodBlend, r[i++] = this.minPixelRadius.value, r[i++] = this.frustumCulling.value, r[i++] = this.debugMode.value;
		let a = this.shadowSweep.value;
		r[i++] = a.x, r[i++] = a.y, r[i++] = a.z;
		for (let e = 0; e < Kr; e++) if (r[e] !== this.cutInputs[e]) return this.cutInputs.set(r), !0;
		return !1;
	}
	adaptThreshold(e) {
		let t = this.statsThreshold, n = this.errorThreshold.value, r = e.capacityUse;
		if (this.thresholdTarget !== null && this.thresholdTarget < n && r >= .75 && (this.thresholdTarget = null), e.drawnTriangles <= 0) return;
		let i = e.drawnTriangles / this.triangleBudget;
		if (Math.abs(i - 1) < .15) {
			this.outOfBand = 0;
			return;
		}
		if (++this.outOfBand < 2) return;
		let [a, o] = this.thresholdRange, s = Math.min(o, Math.max(a, t * Math.sqrt(i)));
		s < t && (s = Math.max(s, Xr(t, r))), this.glideTo(s);
	}
	glideTo(e) {
		this.thresholdTarget = e === this.errorThreshold.value ? null : e;
	}
	stepThreshold() {
		let e = this.errorThreshold.value;
		e !== this.thresholdWritten && !Number.isNaN(this.thresholdWritten) && (this.thresholdTarget = null);
		let t = this.thresholdTarget;
		if (t !== null) {
			let n = t > e ? Math.min(t, e * qr) : Math.max(t, e / Jr);
			this.errorThreshold.value = n, n === t && (this.thresholdTarget = null);
		}
		this.thresholdWritten = this.errorThreshold.value;
	}
	async readStats(e) {
		let t = {
			drawnMeshlets: 0,
			drawnTriangles: 0,
			fullDetailTriangles: 0,
			instances: 0,
			visibleInstances: 0,
			requestedTriangles: 0,
			overflow: !1,
			capacityUse: 0,
			occludedInstances: 0,
			shadowTriangles: 0,
			thresholdScale: 1
		};
		for (let e of this.meshes) e.visible && (t.fullDetailTriangles += e.fullDetailTriangles, t.instances += e.instanceCount);
		for (let n of this.pools) {
			if (!n.hasCut) continue;
			let r = await n.readCounters(e), i = n.capacity;
			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), t.thresholdScale = Math.max(t.thresholdScale, r.scale[0]), (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);
		}
		return t;
	}
};
//#endregion
//#region src/core/runtime/limits.ts
async function Qr(e = {}) {
	let t = typeof navigator < "u" ? navigator.gpu : void 0, n = t ? await t.requestAdapter({ powerPreference: e.powerPreference }).catch(() => null) : null;
	return n ? {
		maxStorageBufferBindingSize: n.limits.maxStorageBufferBindingSize,
		maxBufferSize: n.limits.maxBufferSize
	} : {};
}
//#endregion
export { Yt as LOD_FADE_STEPS, we as MAX_MESHLET_TRIANGLES, Te as MAX_MESHLET_VERTICES, Pt as VG_BUILD_VERSION, Oe as VG_DEBUG_MODES, ut as VG_FORMAT_VERSION, Zr as VirtualGeometry, Fr as VirtualGeometryImport, gr as VirtualMesh, J as VirtualMeshFormatError, mn as bindVirtualGeometryTextures, Ze as buildVirtualMesh, Rt as buildVirtualMeshCached, br as canConvertToNodeMaterial, zt as clearVirtualMeshCache, Mr as collectVirtualGeometryGroups, ht as decodeVirtualMesh, mt as encodeVirtualMesh, wr as fromBufferGeometry, cn as instanceGuaranteedRange, sn as instanceMeshletRange, gt as loadVirtualMesh, en as lodFadeRange, Or as mergeSources, ke as partitionMeshlets, nn as selectBlendCut, tn as selectCut, xr as toNodeMaterial, an as verifyCutCoverage, rn as verifyCutOverlap, wn as vgInstanceOrigin, pn as vgNormalMap, dn as vgTexture, ln as vgUv, yn as vgWorldNormal, Qr as virtualGeometryLimits, Bt as virtualMeshCacheKey, Ir as virtualMeshesFromObject3D };

//# sourceMappingURL=index.js.map