@kalyptos/narcissus 0.1.3 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2773 +0,0 @@
1
- import { F as e, I as t, c as n, l as r, m as i, u as a } from "./format-C3Vn0c2b.js";
2
- import { t as o } from "./ports-DZRKjdYD.js";
3
- import { t as s } from "./http-DL7R39Nc.js";
4
- //#region src/engine/gpu/layout.ts
5
- var c = (e) => Math.max(1, Math.ceil(e / 256)) * 256, l = {
6
- visible: 0,
7
- projected: 4,
8
- drawArgs: 8,
9
- list: 16
10
- }, u = 65535, d = (e) => [Math.min(e, u), Math.ceil(e / u)], f = .075;
11
- //#endregion
12
- //#region src/engine/gpu/device.ts
13
- async function p() {
14
- if (!navigator.gpu) return null;
15
- let e = await navigator.gpu.requestAdapter({ powerPreference: "high-performance" });
16
- if (!e) return null;
17
- let t = e.features.has("timestamp-query");
18
- return {
19
- device: await e.requestDevice({
20
- requiredFeatures: t ? ["timestamp-query"] : [],
21
- requiredLimits: {
22
- maxStorageBufferBindingSize: e.limits.maxStorageBufferBindingSize,
23
- maxBufferSize: e.limits.maxBufferSize
24
- }
25
- }),
26
- timestamps: t,
27
- format: navigator.gpu.getPreferredCanvasFormat()
28
- };
29
- }
30
- //#endregion
31
- //#region src/engine/gpu/pool.ts
32
- var m = 19, h = 1024, g = class {
33
- #e = [];
34
- mark(e, t) {
35
- this.#e.push([e, t]);
36
- }
37
- clear() {
38
- this.#e = [];
39
- }
40
- flush(e, t, n) {
41
- let r = this.#e.sort((e, t) => e[0] - t[0]);
42
- this.#e = [];
43
- for (let i = 0; i < r.length;) {
44
- let a = r[i][0], o = r[i++][1];
45
- for (; i < r.length && r[i][0] <= o + h;) o = Math.max(o, r[i++][1]);
46
- e.writeBuffer(t, a * 4, n, a, o - a);
47
- }
48
- }
49
- }, _ = class {
50
- geometry;
51
- colour;
52
- pages;
53
- clusters;
54
- list;
55
- listed = 0;
56
- capacity;
57
- #e;
58
- #t = /* @__PURE__ */ new Map();
59
- #n = null;
60
- #r = null;
61
- #i = /* @__PURE__ */ new Set();
62
- #a;
63
- #o;
64
- #s = 0;
65
- #c;
66
- #l = [
67
- 0,
68
- 0,
69
- 0
70
- ];
71
- #u;
72
- #d;
73
- #f = new g();
74
- #p;
75
- #m;
76
- #h = new g();
77
- #g;
78
- #_ = [];
79
- constructor(e, t) {
80
- this.capacity = t, this.#e = e;
81
- let n = this.slots;
82
- this.#y(), this.#a = new Uint8Array(n), this.#o = n, this.#c = Array.from({ length: n }, (e, t) => n - 1 - t), this.#u = new Uint32Array(n * 36), this.#d = new Float32Array(this.#u.buffer), this.#p = new Uint32Array(n * 12), this.#m = new Float32Array(this.#p.buffer), this.#g = new Uint32Array(n);
83
- }
84
- get slots() {
85
- return this.capacity / 256;
86
- }
87
- get bytes() {
88
- return this.#v().reduce((e, t) => e + t.size, 0);
89
- }
90
- has(e) {
91
- let t = this.#t.get(e);
92
- return t !== void 0 && t.page === null;
93
- }
94
- holds(e) {
95
- return this.#t.has(e);
96
- }
97
- *ids() {
98
- for (let e = this.#n; e; e = e.next) e.page === null && (yield e.id);
99
- }
100
- add(e, n, r, i) {
101
- if (this.#t.has(e)) return !0;
102
- let a = c(n.count) / 256;
103
- if (!this.#S(a, i)) return !1;
104
- let o = t.origin, s = {
105
- id: e,
106
- previous: null,
107
- next: null,
108
- page: n,
109
- slots: this.#E(a),
110
- active: [],
111
- mask: 0,
112
- table: this.#c.pop(),
113
- base: [
114
- n.params[o] + r[0],
115
- n.params[o + 1] + r[1],
116
- n.params[o + 2]
117
- ],
118
- factors: 0
119
- };
120
- return this.#t.set(e, s), this.#x(s), this.#i.add(e), !0;
121
- }
122
- remove(e) {
123
- let t = this.#t.get(e);
124
- if (t) {
125
- this.#b(t), this.#t.delete(e), this.#i.delete(e);
126
- for (let e of t.slots) this.#a[e] = 0;
127
- this.#s = Math.min(this.#s, t.slots[0]), this.#o += t.slots.length, this.#c.push(t.table), t.page === null && t.factors !== 0 && this.#T(t, 0);
128
- }
129
- }
130
- clear() {
131
- for (let e of this.#t.keys()) this.remove(e);
132
- }
133
- get queued() {
134
- return this.#i.size;
135
- }
136
- upload(e) {
137
- let t = 0;
138
- for (let n of this.#i) {
139
- if (t >= e) break;
140
- t += this.#C(this.#t.get(n)), this.#i.delete(n);
141
- }
142
- return t;
143
- }
144
- draw(e) {
145
- let t = 0, n = 0, r = !1;
146
- for (let { id: i, factors: a } of e) {
147
- let e = this.#t.get(i);
148
- if (!e || e.page !== null) continue;
149
- let o = e.active;
150
- e.factors !== a && this.#T(e, a), r ||= o !== e.active, this.#x(e), r ||= this.#_[n] !== e, this.#_[n++] = e, r && this.#g.set(e.active, t), t += e.active.length;
151
- }
152
- r ||= this.#_.length !== n, this.#_.length = n, this.listed = t;
153
- let i = this.#e.queue;
154
- this.#f.flush(i, this.pages, this.#u), this.#h.flush(i, this.clusters, this.#p), r && t && i.writeBuffer(this.list, 0, this.#g, 0, t);
155
- }
156
- setOrigin(e) {
157
- this.#l = [
158
- e[0],
159
- e[1],
160
- e[2]
161
- ];
162
- for (let e of this.#t.values()) e.page === null && this.#w(e);
163
- this.#e.queue.writeBuffer(this.pages, 0, this.#u), this.#f.clear();
164
- }
165
- grow(e) {
166
- if (e <= this.capacity) return;
167
- let t = this.slots, n = this.#v();
168
- this.capacity = e, this.#y();
169
- let r = this.#e.createCommandEncoder({ label: "pool grow" });
170
- this.#v().forEach((e, t) => r.copyBufferToBuffer(n[t], 0, e, 0, n[t].size)), this.#e.queue.submit([r.finish()]);
171
- for (let e of n) e.destroy();
172
- let i = this.slots, a = new Uint8Array(i);
173
- a.set(this.#a), this.#a = a, this.#o += i - t;
174
- for (let e = i - 1; e >= t; e--) this.#c.push(e);
175
- let o = new Uint32Array(i * 36);
176
- o.set(this.#u), this.#u = o, this.#d = new Float32Array(o.buffer);
177
- let s = new Uint32Array(i * 12);
178
- s.set(this.#p), this.#p = s, this.#m = new Float32Array(s.buffer);
179
- let c = new Uint32Array(i);
180
- c.set(this.#g), this.#g = c;
181
- }
182
- destroy() {
183
- for (let e of this.#v()) e.destroy();
184
- }
185
- #v() {
186
- return [
187
- this.geometry,
188
- this.colour,
189
- this.pages,
190
- this.clusters,
191
- this.list
192
- ];
193
- }
194
- #y() {
195
- let { capacity: e, slots: t } = this, n = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC, r = (e, t) => this.#e.createBuffer({
196
- label: e,
197
- size: t,
198
- usage: n
199
- });
200
- this.geometry = r("pool geometry", e * 4 * 4), this.colour = r("pool colour", e * 3 * 4), this.pages = r("pool pages", t * 36 * 4), this.clusters = r("pool clusters", t * 12 * 4), this.list = r("pool list", t * 4);
201
- }
202
- #b(e) {
203
- e.previous ? e.previous.next = e.next : this.#n === e && (this.#n = e.next), e.next ? e.next.previous = e.previous : this.#r === e && (this.#r = e.previous), e.previous = null, e.next = null;
204
- }
205
- #x(e) {
206
- this.#r !== e && (this.#b(e), e.previous = this.#r, this.#r ? this.#r.next = e : this.#n = e, this.#r = e);
207
- }
208
- #S(e, t) {
209
- let n = this.#o;
210
- if (n >= e) return !0;
211
- let r = [];
212
- for (let i = this.#n; i && !(!(i.page !== null || t(i.id)) && (r.push(i.id), n += i.slots.length, n >= e)); i = i.next);
213
- if (n < e) return !1;
214
- for (let e of r) this.remove(e);
215
- return !0;
216
- }
217
- #C(e) {
218
- let n = e.page, { slots: r } = e, i = this.#e.queue, a = r.length, o = this.#p, s = this.#m;
219
- for (let t = 0; t < a; t++) {
220
- let i = r[t] * 12;
221
- o.fill(0, i, i + 12), o[i] = e.table, o[i + 1] = r[t] * 256, o[i + 2] = t * 256, o[i + 3] = Math.max(0, Math.min(256, n.count - t * 256));
222
- for (let e = 0; e < 3; e++) s[i + 4 + e] = n.clusters[t * 6 + e], s[i + 8 + e] = n.clusters[t * 6 + 3 + e];
223
- }
224
- for (let e = 0; e < a;) {
225
- let t = 1;
226
- for (; e + t < a && r[e + t] === r[e] + t;) t++;
227
- let o = e * 256, s = Math.min((e + t) * 256, n.count) - o, c = r[e] * 256;
228
- i.writeBuffer(this.geometry, c * 4 * 4, n.geometry, o * 4, s * 4), i.writeBuffer(this.colour, c * 3 * 4, n.colour, o * 3, s * 3), this.#h.mark(r[e] * 12, (r[e] + t) * 12), e += t;
229
- }
230
- let c = e.table * 36, l = this.#u, u = this.#d, d = n.params, [f, p, m] = n.quadrants;
231
- return l.fill(0, c, c + 36), this.#w(e), l[c + 3] = n.count, u.set(d.subarray(t.step, t.step + 3), c + 4), l[c + 7] = f, u.set(d.subarray(t.scaleMin, t.scaleMin + 3), c + 8), l[c + 11] = p, u.set(d.subarray(t.scaleMax, t.scaleMax + 3), c + 12), l[c + 15] = m, u.set(d.subarray(t.dcMin, t.dcMin + 3), c + 16), u.set(d.subarray(t.dcMax, t.dcMax + 3), c + 20), u.set(d.subarray(t.shScale, t.shScale + 9), c + 24), this.#f.mark(c, c + 36), e.page = null, n.count * 7 * 4 + a * 12 * 4 + 144;
232
- }
233
- #w(e) {
234
- let t = e.table * 36;
235
- for (let n = 0; n < 3; n++) this.#d[t + n] = e.base[n] - this.#l[n];
236
- }
237
- #T(e, t) {
238
- let n = 0;
239
- for (let e = 0; e < 4; e++) t >>> 8 * e & 255 && (n |= 1 << e);
240
- if (n !== e.mask) {
241
- if (e.mask = n, n === 15 && this.#u[e.table * 36 + 3] > 0) e.active = e.slots;
242
- else {
243
- let t = [], r = e.table * 36, i = 0, a = -1;
244
- for (let o = 0; o < 4; o++) {
245
- let s = this.#u[r + (o === 3 ? 3 : 7 + 4 * o)];
246
- if (n & 1 << o && s > i) for (let n = Math.max(a + 1, Math.floor(i / 256)); n < Math.ceil(s / 256); n++) t.push(e.slots[n]), a = n;
247
- i = s;
248
- }
249
- e.active = t;
250
- }
251
- }
252
- e.factors = t;
253
- let r = e.table * 36 + m;
254
- this.#u[r] = t, this.#f.mark(r, r + 1);
255
- }
256
- #E(e) {
257
- let t = this.#a, n = -1;
258
- for (let r = this.#s; r <= t.length - e;) {
259
- let i = r;
260
- for (; i < r + e && !t[i];) i++;
261
- if (i === r + e) {
262
- n = r;
263
- break;
264
- }
265
- if (r = t.indexOf(0, i + 1), r < 0) break;
266
- }
267
- let r = [];
268
- if (n >= 0) for (let t = n; t < n + e; t++) r.push(t);
269
- else for (let n = this.#s; r.length < e; n = t.indexOf(0, n + 1)) r.push(n);
270
- for (let e of r) t[e] = 1;
271
- let i = t.indexOf(0, this.#s);
272
- return this.#s = i < 0 ? t.length : i, this.#o -= e, r;
273
- }
274
- };
275
- //#endregion
276
- //#region src/engine/math/mat4.ts
277
- function v(e, t) {
278
- let n = Math.cos(t);
279
- return [
280
- Math.sin(e) * n,
281
- Math.cos(e) * n,
282
- Math.sin(t)
283
- ];
284
- }
285
- function y(e, t, n, r) {
286
- let [i, a, o] = v(n, r), s = Math.cos(n), c = -Math.sin(n), l = c * o, u = -s * o, d = s * a - c * i;
287
- return e[0] = s, e[1] = l, e[2] = -i, e[3] = 0, e[4] = c, e[5] = u, e[6] = -a, e[7] = 0, e[8] = 0, e[9] = d, e[10] = -o, e[11] = 0, e[12] = -(s * t[0] + c * t[1]), e[13] = -(l * t[0] + u * t[1] + d * t[2]), e[14] = i * t[0] + a * t[1] + o * t[2], e[15] = 1, e;
288
- }
289
- function b(e, t, n, r, i) {
290
- let a = 1 / Math.tan(t / 2);
291
- return e.fill(0), e[0] = a / n, e[5] = a, e[10] = i / (r - i), e[11] = -1, e[14] = r * i / (r - i), e;
292
- }
293
- var x = /* @__PURE__ */ new Float64Array(16);
294
- function S(e, t, n) {
295
- for (let e = 0; e < 4; e++) for (let r = 0; r < 4; r++) {
296
- let i = 0;
297
- for (let a = 0; a < 4; a++) i += t[a * 4 + r] * n[e * 4 + a];
298
- x[e * 4 + r] = i;
299
- }
300
- return e.set(x), e;
301
- }
302
- function C(e, t) {
303
- let [n, r, i, a, o, s, c, l, u, d, f, p, m, h, g, _] = t, v = n * s - r * o, y = n * c - i * o, b = n * l - a * o, x = r * c - i * s, S = r * l - a * s, C = i * l - a * c, w = u * h - d * m, T = u * g - f * m, E = u * _ - p * m, D = d * g - f * h, O = d * _ - p * h, k = f * _ - p * g, A = v * k - y * O + b * D + x * E - S * T + C * w;
304
- if (!A) return null;
305
- let j = 1 / A;
306
- return e[0] = (s * k - c * O + l * D) * j, e[1] = (i * O - r * k - a * D) * j, e[2] = (h * C - g * S + _ * x) * j, e[3] = (f * S - d * C - p * x) * j, e[4] = (c * E - o * k - l * T) * j, e[5] = (n * k - i * E + a * T) * j, e[6] = (g * b - m * C - _ * y) * j, e[7] = (u * C - f * b + p * y) * j, e[8] = (o * O - s * E + l * w) * j, e[9] = (r * E - n * O - a * w) * j, e[10] = (m * S - h * b + _ * v) * j, e[11] = (d * b - u * S - p * v) * j, e[12] = (s * T - o * D - c * w) * j, e[13] = (n * D - r * T + i * w) * j, e[14] = (h * y - m * x - g * v) * j, e[15] = (u * x - d * y + f * v) * j, e;
307
- }
308
- function w(e, t) {
309
- let [n, r, i] = t;
310
- return [
311
- e[0] * n + e[4] * r + e[8] * i + e[12],
312
- e[1] * n + e[5] * r + e[9] * i + e[13],
313
- e[2] * n + e[6] * r + e[10] * i + e[14],
314
- e[3] * n + e[7] * r + e[11] * i + e[15]
315
- ];
316
- }
317
- //#endregion
318
- //#region src/engine/gpu/buffers.ts
319
- function T(e, t, n) {
320
- let r = (t, n, r) => e.createBuffer({
321
- label: t,
322
- size: n,
323
- usage: r
324
- }), i = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC, a = [
325
- r("frame uniforms", 336, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST),
326
- r("work", (l.list + n) * 4, i | GPUBufferUsage.INDIRECT),
327
- r("projected", t * 6 * 4, i),
328
- r("sort", t * 16, i),
329
- r("plugins", 256, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST),
330
- r("visible clusters", 4, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST)
331
- ], [o, s, c, u, d, f] = a;
332
- return {
333
- capacity: t,
334
- uniforms: o,
335
- work: s,
336
- visible: f,
337
- projected: c,
338
- sort: u,
339
- plugins: d,
340
- bytes: a.reduce((e, t) => e + t.size, 0),
341
- destroy: () => a.forEach((e) => e.destroy())
342
- };
343
- }
344
- function E(e, t, n, r) {
345
- return e.createBindGroupLayout({
346
- label: t,
347
- entries: r.map((e, t) => ({
348
- binding: t,
349
- visibility: n,
350
- buffer: { type: e }
351
- }))
352
- });
353
- }
354
- function D(e, t, n, r) {
355
- return e.createBindGroup({
356
- label: t,
357
- layout: n,
358
- entries: r.map((e, t) => ({
359
- binding: t,
360
- resource: { buffer: e }
361
- }))
362
- });
363
- }
364
- //#endregion
365
- //#region src/engine/gpu/common.wgsl?raw
366
- var O = "// shared by every engine pass; sizes and word offsets mirror format/spec.ts\n\nconst KEY_BITS: u32 = 24u;\n// word offsets in the work buffer, layout.ts WORK\nconst WORK_VISIBLE: u32 = 0u;\nconst WORK_PROJECTED: u32 = 4u;\nconst WORK_LIST: u32 = 16u;\n// workgroups a dispatch row holds\nconst GROUPS_X: u32 = 65535u;\nconst C0: f32 = 0.28209479177387814;\nconst C1: f32 = 0.4886025119029199;\n\n// floating-origin ENU frame; camera looks down -z of view space\nstruct FrameUniforms {\n view: mat4x4f,\n proj: mat4x4f,\n viewProj: mat4x4f,\n // inside when dot(plane.xyz, p) + plane.w >= 0\n planes: array<vec4f, 6>,\n camera: vec3f,\n time: f32,\n // render target pixels\n viewport: vec2f,\n focal: vec2f,\n near: f32,\n far: f32,\n lowPass: f32,\n // drawn cluster ids in the pool's list\n clusters: u32,\n}\n\n// one resident page; dc and sh ranges are after the colour correction\nstruct Page {\n origin: vec3f,\n count: u32,\n step: vec3f,\n q1: u32,\n scaleMin: vec3f,\n q2: u32,\n scaleMax: vec3f,\n q3: u32,\n dcMin: vec3f,\n // quadrant k opacity 0-255 at bits 8k\n factors: u32,\n dcMax: vec3f,\n pad: u32,\n shScale: array<vec4f, 3>,\n}\n\n// up to CLUSTER consecutive splats of one page in one pool slot\nstruct Cluster {\n page: u32,\n // first pool record\n slot: u32,\n // index in the page of its first splat\n first: u32,\n count: u32,\n // extents relative to the page origin\n boxMin: vec3f,\n pad0: u32,\n boxMax: vec3f,\n pad1: u32,\n}\n\n// a splat on screen; pixels with y up from the bottom-left of the target\nstruct Projected {\n centre: vec2f,\n // pack2x16float: 1-sigma major axis xy, 1-sigma minor axis xy\n axes: vec2u,\n // pack2x16float: r g, b opacity\n colour: vec2u,\n}\n\n// what a shade hook may change; position in the floating-origin frame, depth in view metres\nstruct Splat {\n position: vec3f,\n depth: f32,\n colour: vec3f,\n opacity: f32,\n scale: vec3f,\n}\n\n// the byte of word at bit, 0 to 1\nfn fraction(word: u32, bit: u32) -> f32 {\n return f32(extractBits(word, bit, 8u)) / 255.0;\n}\n\n// sigmas out to where a gaussian of opacity falls under 1/255, at most 3; the quad raster draws\nfn reach(opacity: f32) -> f32 {\n return min(3.0, sqrt(max(2.0 * log(255.0 * opacity), 0.0)));\n}\n", k = "// one thread per listed cluster\n\n@group(0) @binding(0) var<uniform> uniforms: FrameUniforms;\n@group(0) @binding(1) var<storage, read> pages: array<Page>;\n@group(0) @binding(2) var<storage, read> clusters: array<Cluster>;\n@group(0) @binding(3) var<storage, read> list: array<u32>;\n@group(0) @binding(4) var<storage, read_write> work: array<atomic<u32>>;\n\n// false only when the box lies wholly outside one plane\nfn inside(lo: vec3f, hi: vec3f) -> bool {\n for (var p = 0u; p < 6u; p++) {\n let plane = uniforms.planes[p];\n let corner = select(lo, hi, plane.xyz >= vec3f(0.0));\n if (dot(plane.xyz, corner) + plane.w < 0.0) {\n return false;\n }\n }\n return true;\n}\n\n@compute @workgroup_size(64)\nfn cull(@builtin(global_invocation_id) id: vec3u) {\n if (id.x >= uniforms.clusters) {\n return;\n }\n let slot = list[id.x];\n let cluster = clusters[slot];\n let page = pages[cluster.page];\n if (!inside(page.origin + cluster.boxMin, page.origin + cluster.boxMax)) {\n return;\n }\n atomicStore(&work[WORK_LIST + atomicAdd(&work[WORK_VISIBLE], 1u)], slot);\n}\n", A = 64, j = class {
367
- #e;
368
- #t;
369
- #n;
370
- constructor(e, t, n) {
371
- this.#e = t;
372
- let r = E(e, "cull", GPUShaderStage.COMPUTE, [
373
- "uniform",
374
- "read-only-storage",
375
- "read-only-storage",
376
- "read-only-storage",
377
- "storage"
378
- ]), i = e.createShaderModule({
379
- label: "cull",
380
- code: `${O}\n${k}`
381
- });
382
- this.#t = e.createComputePipeline({
383
- label: "cull",
384
- layout: e.createPipelineLayout({ bindGroupLayouts: [r] }),
385
- compute: {
386
- module: i,
387
- entryPoint: "cull"
388
- }
389
- });
390
- let a = [
391
- n.uniforms,
392
- t.pages,
393
- t.clusters,
394
- t.list,
395
- n.work
396
- ];
397
- this.#n = D(e, "cull", r, a);
398
- }
399
- encode(e, t) {
400
- let n = e.beginComputePass({
401
- label: "cull",
402
- timestampWrites: t
403
- });
404
- n.setBindGroup(0, this.#n), n.setPipeline(this.#t), this.#e.listed && n.dispatchWorkgroups(Math.ceil(this.#e.listed / A)), n.end();
405
- }
406
- }, M = "// the top of the solid drawn splats over a square of 1 m cells; one workgroup per listed cluster\n\nconst GROUP: u32 = 64u;\n\nstruct Area {\n // south-west corner, floating-origin frame\n corner: vec2f,\n cells: u32,\n clusters: u32,\n // least opacity and largest scale in metres of a splat that counts\n opacity: f32,\n scale: f32,\n}\n\n@group(0) @binding(0) var<uniform> area: Area;\n@group(0) @binding(1) var<storage, read> pages: array<Page>;\n@group(0) @binding(2) var<storage, read> clusters: array<Cluster>;\n@group(0) @binding(3) var<storage, read> list: array<u32>;\n@group(0) @binding(4) var<storage, read> geometry: array<vec4u>;\n@group(0) @binding(5) var<storage, read_write> tops: array<atomic<u32>>;\n\n// order-preserving bits of z, never 0, which marks an empty cell\nfn ordered(z: f32) -> u32 {\n let bits = bitcast<u32>(z);\n return select(bits | 0x80000000u, ~bits, z < 0.0);\n}\n\n@compute @workgroup_size(64)\nfn heights(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n let index = wid.y * GROUPS_X + wid.x;\n if (index >= area.clusters) {\n return;\n }\n let cluster = clusters[list[index]];\n let page = pages[cluster.page];\n let size = f32(area.cells);\n let lo = page.origin.xy + cluster.boxMin.xy - area.corner;\n let hi = page.origin.xy + cluster.boxMax.xy - area.corner;\n if (any(hi < vec2f(0.0)) || any(lo >= vec2f(size))) {\n return;\n }\n for (var k = t; k < cluster.count; k += GROUP) {\n let g = geometry[cluster.slot + k];\n let i = cluster.first + k;\n let quadrant = u32(i >= page.q1) + u32(i >= page.q2) + u32(i >= page.q3);\n let opacity = fraction(g.y, 16u) * fraction(page.factors, 8u * quadrant);\n let level = vec3f(fraction(g.z, 24u), fraction(g.w, 0u), fraction(g.w, 8u));\n let scale = exp(mix(page.scaleMin, page.scaleMax, level));\n if (opacity < area.opacity || max(scale.x, max(scale.y, scale.z)) > area.scale) {\n continue;\n }\n let q = vec3f(f32(g.x & 0xffffu), f32(g.x >> 16u), f32(g.y & 0xffffu));\n let p = page.origin + q * page.step;\n let cell = floor(p.xy - area.corner);\n if (any(cell < vec2f(0.0)) || any(cell >= vec2f(size))) {\n continue;\n }\n let c = vec2u(cell);\n atomicMax(&tops[c.y * area.cells + c.x], ordered(p.z));\n }\n}\n", N = 32, ee = .5, te = 1;
407
- function ne(e) {
408
- let t = new Uint32Array(e.length);
409
- for (let n = 0; n < e.length; n++) {
410
- let r = e[n];
411
- t[n] = r === 0 ? 2143289344 : r & 2147483648 ? r & 2147483647 : ~r >>> 0;
412
- }
413
- return new Float32Array(t.buffer);
414
- }
415
- var re = class {
416
- #e;
417
- #t;
418
- #n;
419
- #r;
420
- constructor(e, t) {
421
- this.#e = e, this.#t = t, this.#n = E(e, "heights", GPUShaderStage.COMPUTE, [
422
- "uniform",
423
- "read-only-storage",
424
- "read-only-storage",
425
- "read-only-storage",
426
- "read-only-storage",
427
- "storage"
428
- ]);
429
- let n = e.createShaderModule({
430
- label: "heights",
431
- code: `${O}\n${M}`
432
- });
433
- this.#r = e.createComputePipeline({
434
- label: "heights",
435
- layout: e.createPipelineLayout({ bindGroupLayouts: [this.#n] }),
436
- compute: {
437
- module: n,
438
- entryPoint: "heights"
439
- }
440
- });
441
- }
442
- encode(e, t, n, r, i) {
443
- let a = this.#e, o = this.#t, { listed: s } = o, c = r * r * 4, l = a.createBuffer({
444
- label: "heights area",
445
- size: N,
446
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
447
- }), u = a.createBuffer({
448
- label: "heights",
449
- size: c,
450
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
451
- }), f = a.createBuffer({
452
- label: "heights readback",
453
- size: c,
454
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
455
- }), p = /* @__PURE__ */ new ArrayBuffer(N);
456
- new Float32Array(p).set([
457
- t,
458
- n,
459
- 0,
460
- 0,
461
- ee,
462
- te
463
- ]), new Uint32Array(p).set([r, s], 2), a.queue.writeBuffer(l, 0, p);
464
- let m = [
465
- l,
466
- o.pages,
467
- o.clusters,
468
- o.list,
469
- o.geometry,
470
- u
471
- ], h = D(a, "heights", this.#n, m), g = e.beginComputePass({
472
- label: "heights",
473
- timestampWrites: i
474
- });
475
- return g.setPipeline(this.#r), g.setBindGroup(0, h), s > 0 && g.dispatchWorkgroups(...d(s)), g.end(), e.copyBufferToBuffer(u, 0, f, 0, c), () => f.mapAsync(GPUMapMode.READ).then(() => ne(new Uint32Array(f.getMappedRange())), () => null).finally(() => {
476
- l.destroy(), u.destroy(), f.destroy();
477
- });
478
- }
479
- }, ie = "@vertex\nfn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {\n // one triangle over the whole target\n let p = vec2f(f32((i << 1u) & 2u), f32(i & 2u));\n return vec4f(p * 2.0 - 1.0, 0.0, 1.0);\n}\n", ae = class {
480
- #e;
481
- #t;
482
- #n;
483
- #r = [];
484
- #i;
485
- constructor(e, t, n, r) {
486
- let i = e.createShaderModule({
487
- label: t,
488
- code: ie + n
489
- });
490
- this.#e = e, this.#t = t, this.#n = e.createRenderPipeline({
491
- label: t,
492
- layout: "auto",
493
- vertex: {
494
- module: i,
495
- entryPoint: "vs"
496
- },
497
- fragment: {
498
- module: i,
499
- entryPoint: "fs",
500
- targets: [{ format: r }]
501
- }
502
- });
503
- }
504
- encode(e, t, n) {
505
- (!this.#i || t.some((e, t) => e !== this.#r[t])) && (this.#r = t, this.#i = this.#e.createBindGroup({
506
- label: this.#t,
507
- layout: this.#n.getBindGroupLayout(0),
508
- entries: t.map((e, t) => ({
509
- binding: t,
510
- resource: e
511
- }))
512
- }));
513
- let r = e.beginRenderPass({
514
- label: this.#t,
515
- colorAttachments: [{
516
- view: n,
517
- loadOp: "clear",
518
- storeOp: "store"
519
- }]
520
- });
521
- r.setPipeline(this.#n), r.setBindGroup(0, this.#i), r.draw(3), r.end();
522
- }
523
- }, oe = "// the finished colour target onto the canvas, opaque\n\n@group(0) @binding(0) var scene: texture_2d<f32>;\n\n@fragment\nfn fs(@builtin(position) coord: vec4f) -> @location(0) vec4f {\n return vec4f(textureLoad(scene, vec2i(coord.xy), 0).rgb, 1.0);\n}\n", se = (e, t) => new ae(e, "present", oe, t), ce = "// workgroups loop over visible clusters, one thread per splat\n\n// ndc reach past the frustum, so splats centred just outside still cover the edge\nconst GUARD: f32 = 1.3;\n\n@group(0) @binding(0) var<uniform> uniforms: FrameUniforms;\n@group(0) @binding(1) var<uniform> plugins: array<vec4f, 16>;\n@group(0) @binding(2) var<storage, read> geometry: array<vec4u>;\n@group(0) @binding(3) var<storage, read> colours: array<u32>;\n@group(0) @binding(4) var<storage, read> pages: array<Page>;\n@group(0) @binding(5) var<storage, read> clusters: array<Cluster>;\n@group(0) @binding(6) var<storage, read_write> work: array<atomic<u32>>;\n@group(0) @binding(7) var<storage, read_write> projected: array<Projected>;\n// keys in [0, capacity), values in [capacity, 2 capacity)\n@group(0) @binding(8) var<storage, read_write> sort: array<u32>;\n\n@group(0) @binding(9) var<uniform> visible: u32;\nvar<workgroup> kept: atomic<u32>;\nvar<workgroup> base: u32;\n\n// i8 over 127, sign-extended by extractBits on i32\nfn code(word: u32, bit: u32) -> f32 {\n return f32(extractBits(i32(word), bit, 8u)) / 127.0;\n}\n\n// smallest three: w x y z with the largest at the stored index\nfn rotation(g: vec4u) -> vec4f {\n let v = (vec3f(fraction(g.z, 0u), fraction(g.z, 8u), fraction(g.z, 16u)) - 0.5) * sqrt(2.0);\n let big = sqrt(max(0.0, 1.0 - dot(v, v)));\n switch extractBits(g.y, 24u, 8u) {\n case 0u: {\n return normalize(vec4f(big, v));\n }\n case 1u: {\n return normalize(vec4f(v.x, big, v.yz));\n }\n case 2u: {\n return normalize(vec4f(v.xy, big, v.z));\n }\n default: {\n return normalize(vec4f(v, big));\n }\n }\n}\n\nfn rotate(q: vec4f) -> mat3x3f {\n let w = q.x;\n let x = q.y;\n let y = q.z;\n let z = q.w;\n return mat3x3f(\n 1.0 - 2.0 * (y * y + z * z), 2.0 * (x * y + w * z), 2.0 * (x * z - w * y),\n 2.0 * (x * y - w * z), 1.0 - 2.0 * (x * x + z * z), 2.0 * (y * z + w * x),\n 2.0 * (x * z + w * y), 2.0 * (y * z - w * x), 1.0 - 2.0 * (x * x + y * y)\n );\n}\n\n// false when splat t of the cluster cannot show; else its Projected and sort key\nfn shown(cluster: Cluster, t: u32, dest: ptr<function, Projected>, key: ptr<function, u32>) -> bool {\n let page = pages[cluster.page];\n let rec = cluster.slot + t;\n let g = geometry[rec];\n let w0 = colours[rec * 3u];\n let w1 = colours[rec * 3u + 1u];\n let w2 = colours[rec * 3u + 2u];\n let i = cluster.first + t;\n let quadrant = u32(i >= page.q1) + u32(i >= page.q2) + u32(i >= page.q3);\n\n // decode\n var s: Splat;\n let q = vec3f(f32(g.x & 0xffffu), f32(g.x >> 16u), f32(g.y & 0xffffu));\n s.position = page.origin + q * page.step;\n s.opacity = fraction(g.y, 16u) * fraction(page.factors, 8u * quadrant);\n let level = vec3f(fraction(g.z, 24u), fraction(g.w, 0u), fraction(g.w, 8u));\n s.scale = exp(mix(page.scaleMin, page.scaleMax, level));\n let dc = mix(page.dcMin, page.dcMax, vec3f(fraction(w0, 0u), fraction(w0, 8u), fraction(w0, 16u)));\n // sh[c][m] at 3c + m, gathered per m across the colours\n let k = page.shScale;\n let m0 = vec3f(code(w0, 24u), code(w1, 16u), code(w2, 8u)) * vec3f(k[0].x, k[0].w, k[1].z);\n let m1 = vec3f(code(w1, 0u), code(w1, 24u), code(w2, 16u)) * vec3f(k[0].y, k[1].x, k[1].w);\n let m2 = vec3f(code(w1, 8u), code(w2, 0u), code(w2, 24u)) * vec3f(k[0].z, k[1].y, k[2].x);\n let d = normalize(s.position - uniforms.camera);\n s.colour = max(0.5 + C0 * dc + C1 * (-d.y * m0 + d.z * m1 - d.x * m2), vec3f(0.0));\n s.depth = -(uniforms.view * vec4f(s.position, 1.0)).z;\n\n shade(&s);\n if (s.opacity < 1.0 / 255.0) {\n return false;\n }\n\n // project\n let viewPos = (uniforms.view * vec4f(s.position, 1.0)).xyz;\n let depth = -viewPos.z;\n if (depth < uniforms.near || depth > uniforms.far) {\n return false;\n }\n let clip = uniforms.proj * vec4f(viewPos, 1.0);\n let ndc = clip.xy / clip.w;\n if (any(abs(ndc) > vec2f(GUARD))) {\n return false;\n }\n\n // ewa: view-space covariance wm wm^T through the jacobian of the pixel projection\n let r = rotate(rotation(g));\n let m = mat3x3f(r[0] * s.scale.x, r[1] * s.scale.y, r[2] * s.scale.z);\n let w = mat3x3f(uniforms.view[0].xyz, uniforms.view[1].xyz, uniforms.view[2].xyz);\n let wm = w * m;\n let focal = uniforms.focal;\n let j0 = vec3f(focal.x / depth, 0.0, focal.x * viewPos.x / (depth * depth));\n let j1 = vec3f(0.0, focal.y / depth, focal.y * viewPos.y / (depth * depth));\n let u = j0 * wm;\n let v = j1 * wm;\n let a = dot(u, u) + uniforms.lowPass;\n let b = dot(u, v);\n let c = dot(v, v) + uniforms.lowPass;\n let mid = 0.5 * (a + c);\n let rad = length(vec2f(0.5 * (a - c), b));\n let major = sqrt(mid + rad);\n if (3.0 * major < 0.5) {\n return false;\n }\n let minor = sqrt(max(mid - rad, 0.0));\n let angle = 0.5 * atan2(2.0 * b, a - c);\n let axis = vec2f(cos(angle), sin(angle));\n // the quad raster draws; a centre inside the guard band can still miss the screen\n let centre = (ndc * 0.5 + 0.5) * uniforms.viewport;\n let extent = reach(s.opacity) * (abs(axis) * major + abs(axis.yx) * minor);\n if (any(centre + extent < vec2f(0.0)) || any(centre - extent > uniforms.viewport)) {\n return false;\n }\n\n *dest = Projected(\n centre,\n vec2u(pack2x16float(axis * major), pack2x16float(vec2f(-axis.y, axis.x) * minor)),\n vec2u(pack2x16float(s.colour.rg), pack2x16float(vec2f(s.colour.b, s.opacity)))\n );\n let span = clamp(log(depth / uniforms.near) / log(uniforms.far / uniforms.near), 0.0, 1.0);\n *key = u32((1.0 - span) * f32((1u << KEY_BITS) - 1u));\n return true;\n}\n\n@compute @workgroup_size(256)\nfn project(\n @builtin(workgroup_id) wid: vec3u,\n @builtin(num_workgroups) groups: vec3u,\n @builtin(local_invocation_index) t: u32\n) {\n for (var index = wid.y * groups.x + wid.x; index < visible; index += groups.x * groups.y) {\n let cluster = clusters[atomicLoad(&work[WORK_LIST + index])];\n var splat: Projected;\n var key = 0u;\n var keep = false;\n if (t < cluster.count) {\n keep = shown(cluster, t, &splat, &key);\n }\n\n // one global atomic per cluster\n var rank = 0u;\n if (keep) {\n rank = atomicAdd(&kept, 1u);\n }\n workgroupBarrier();\n if (t == 0u) {\n base = atomicAdd(&work[WORK_PROJECTED], atomicExchange(&kept, 0u));\n }\n let i = workgroupUniformLoad(&base) + rank;\n let capacity = arrayLength(&projected);\n if (keep && i < capacity) {\n projected[i] = splat;\n sort[i] = key;\n sort[capacity + i] = i;\n }\n }\n}\n", le = class {
524
- #e;
525
- #t;
526
- #n;
527
- #r = [];
528
- #i;
529
- #a;
530
- #o;
531
- #s;
532
- constructor(e, t, n) {
533
- this.#e = e, this.#a = t, this.#o = n.work, this.#s = n.visible;
534
- let r = E(e, "project", GPUShaderStage.COMPUTE, [
535
- "uniform",
536
- "uniform",
537
- "read-only-storage",
538
- "read-only-storage",
539
- "read-only-storage",
540
- "read-only-storage",
541
- "storage",
542
- "storage",
543
- "storage",
544
- "uniform"
545
- ]);
546
- this.#t = e.createPipelineLayout({ bindGroupLayouts: [r] });
547
- let i = [
548
- n.uniforms,
549
- n.plugins,
550
- t.geometry,
551
- t.colour,
552
- t.pages,
553
- t.clusters,
554
- n.work,
555
- n.projected,
556
- n.sort,
557
- n.visible
558
- ];
559
- this.#i = D(e, "project", r, i);
560
- }
561
- hooks(e) {
562
- this.#r = e, this.#n = void 0;
563
- }
564
- encode(e, t, n) {
565
- e.copyBufferToBuffer(this.#o, l.visible * 4, this.#s, 0, 4);
566
- let r = Math.max(1, Math.min(128, this.#a.listed, t ? Math.max(32, Math.ceil(t / 16)) : 128)), i = e.beginComputePass({
567
- label: "project",
568
- timestampWrites: n
569
- });
570
- i.setPipeline(this.#n ??= this.#c()), i.setBindGroup(0, this.#i), i.dispatchWorkgroups(r), i.end();
571
- }
572
- #c() {
573
- let e = this.#r, t = e.map(({ shade: e, slot: t }) => {
574
- let n = Array.from({ length: e.uniforms }, (e, n) => `plugins[${t + n}]`);
575
- return `\t${e.name}(s, array<vec4f, ${e.uniforms}>(${n.join(", ")}));`;
576
- }), n = [
577
- O,
578
- ce,
579
- ...e.map(({ shade: e }) => e.wgsl),
580
- "fn shade(s: ptr<function, Splat>) {",
581
- ...t,
582
- "}"
583
- ].join("\n"), r = this.#e.createShaderModule({
584
- label: "project",
585
- code: n
586
- });
587
- return this.#e.createComputePipeline({
588
- label: "project",
589
- layout: this.#t,
590
- compute: {
591
- module: r,
592
- entryPoint: "project"
593
- }
594
- });
595
- }
596
- }, ue = "// sorted splats as screen quads, premultiplied over what lies behind them\n\n// word offsets of the sorted keys and values in the sort buffer\nstruct Sorted {\n keys: u32,\n values: u32,\n}\n\nstruct Corner {\n @builtin(position) position: vec4f,\n // offset from the centre in sigmas\n @location(0) uv: vec2f,\n @location(1) colour: vec4f,\n}\n\n@group(0) @binding(0) var<uniform> frame: FrameUniforms;\n@group(0) @binding(1) var<storage, read> projected: array<Projected>;\n@group(0) @binding(2) var<storage, read> sort: array<u32>;\n@group(0) @binding(3) var<uniform> sorted: Sorted;\n\nfn corner(v: u32, i: u32) -> Corner {\n let p = projected[sort[sorted.values + i]];\n let major = unpack2x16float(p.axes.x);\n let minor = unpack2x16float(p.axes.y);\n let colour = vec4f(unpack2x16float(p.colour.x), unpack2x16float(p.colour.y));\n let r = reach(colour.a);\n let uv = vec2f(f32(v & 1u), f32(v >> 1u)) * 2.0 - 1.0;\n let pixel = p.centre + (major * uv.x + minor * uv.y) * r;\n return Corner(vec4f(pixel / frame.viewport * 2.0 - 1.0, 0.0, 1.0), uv * r, colour);\n}\n\nfn alpha(uv: vec2f, opacity: f32) -> f32 {\n return opacity * exp(-0.5 * dot(uv, uv));\n}\n\n@vertex\nfn vsColour(@builtin(vertex_index) v: u32, @builtin(instance_index) i: u32) -> Corner {\n return corner(v, i);\n}\n\n@vertex\nfn vsDepth(@builtin(vertex_index) v: u32, @builtin(instance_index) i: u32) -> Corner {\n var c = corner(v, i);\n // inverse of the key: the span from near to far in log depth\n c.position.z = 1.0 - f32(sort[sorted.keys + i]) / f32((1u << KEY_BITS) - 1u);\n return c;\n}\n\n@fragment\nfn fs(c: Corner) -> @location(0) vec4f {\n let a = alpha(c.uv, c.colour.a);\n if (a < 1.0 / 255.0) {\n discard;\n }\n return vec4f(c.colour.rgb * a, a);\n}\n", de = "rgb10a2unorm", fe = "depth16unorm", pe = {
597
- srcFactor: "one",
598
- dstFactor: "one-minus-src-alpha"
599
- }, me = class {
600
- #e;
601
- #t;
602
- #n;
603
- #r;
604
- #i;
605
- constructor(e, t, n) {
606
- this.#e = t.work, this.#t = e.createBuffer({
607
- label: "raster sorted",
608
- size: 16,
609
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
610
- });
611
- let r = new Uint32Array([
612
- n.keys / 4,
613
- n.values / 4,
614
- 0,
615
- 0
616
- ]);
617
- e.queue.writeBuffer(this.#t, 0, r);
618
- let i = E(e, "raster", GPUShaderStage.VERTEX, [
619
- "uniform",
620
- "read-only-storage",
621
- "read-only-storage",
622
- "uniform"
623
- ]);
624
- this.#i = D(e, "raster", i, [
625
- t.uniforms,
626
- t.projected,
627
- t.sort,
628
- this.#t
629
- ]);
630
- let a = e.createShaderModule({
631
- label: "raster",
632
- code: O + ue
633
- }), o = e.createPipelineLayout({ bindGroupLayouts: [i] }), s = (t, n) => e.createRenderPipeline({
634
- label: `raster ${t}`,
635
- layout: o,
636
- vertex: {
637
- module: a,
638
- entryPoint: `vs${t}`
639
- },
640
- fragment: {
641
- module: a,
642
- entryPoint: "fs",
643
- targets: [{
644
- format: de,
645
- blend: {
646
- color: pe,
647
- alpha: pe
648
- }
649
- }]
650
- },
651
- primitive: { topology: "triangle-strip" },
652
- depthStencil: n
653
- });
654
- this.#n = s("Colour"), this.#r = s("Depth", {
655
- format: fe,
656
- depthWriteEnabled: !0,
657
- depthCompare: "always"
658
- });
659
- }
660
- encode(e, t, n, r, i) {
661
- let a = e.beginRenderPass({
662
- label: "raster",
663
- colorAttachments: [{
664
- view: t,
665
- loadOp: "clear",
666
- clearValue: [...r, 1],
667
- storeOp: "store"
668
- }],
669
- depthStencilAttachment: n ? {
670
- view: n,
671
- depthClearValue: 1,
672
- depthLoadOp: "clear",
673
- depthStoreOp: "store"
674
- } : void 0,
675
- timestampWrites: i
676
- });
677
- a.setPipeline(n ? this.#r : this.#n), a.setBindGroup(0, this.#i), a.drawIndirect(this.#e, l.drawArgs * 4), a.end();
678
- }
679
- destroy() {
680
- this.#t.destroy();
681
- }
682
- };
683
- function he(e, t, n, r, i, a, o) {
684
- let { width: s, height: c } = n, l = Math.ceil(s * 2 / 256) * 256, u = e.createBuffer({
685
- label: "pick",
686
- size: l * c,
687
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
688
- });
689
- t.copyTextureToBuffer({ texture: n }, {
690
- buffer: u,
691
- bytesPerRow: l
692
- }, [s, c]);
693
- let d = (e, t) => Math.min(Math.max(Math.floor(e), 0), t - 1), f = d(i, c) * l / 2 + d(r, s);
694
- return () => u.mapAsync(GPUMapMode.READ).then(() => {
695
- let e = new Uint16Array(u.getMappedRange())[f] / 65535;
696
- return e < 1 ? a * (o / a) ** e : null;
697
- }, () => null).finally(() => u.destroy());
698
- }
699
- //#endregion
700
- //#region src/engine/gpu/sort.wgsl?raw
701
- var ge = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan, a stable scatter; no spin-waits\n\nconst THREADS: u32 = 128u;\nconst ITEMS: u32 = 8u;\nconst BLOCK: u32 = 1024u;\n// blocks per scan chunk\nconst CHUNK: u32 = 64u;\nconst DIGITS: u32 = 256u;\n\nstruct SortParams {\n shift: u32,\n // word offsets of the keys read and written; their values follow capacity words later\n src: u32,\n dst: u32,\n capacity: u32,\n // word offsets in the work buffer\n projected: u32,\n drawArgs: u32,\n}\n\nstruct SortState {\n count: u32,\n blocks: u32,\n chunks: u32,\n}\n\n@group(0) @binding(0) var<uniform> params: SortParams;\n@group(0) @binding(1) var<storage, read_write> data: array<u32>;\n// block-major: count, then exclusive global offset, of digit d in block b at b DIGITS + d\n@group(0) @binding(2) var<storage, read_write> hist: array<u32>;\n// chunk-major sums of hist, then their exclusive global offsets\n@group(0) @binding(3) var<storage, read_write> sums: array<u32>;\n@group(0) @binding(4) var<storage, read> state: SortState;\n@group(0) @binding(5) var<storage, read_write> stateOut: SortState;\n@group(0) @binding(6) var<storage, read_write> work: array<u32>;\n\nvar<workgroup> bins: array<atomic<u32>, DIGITS>;\nvar<workgroup> totals: array<u32, DIGITS>;\nvar<workgroup> bitValues: atomic<u32>;\nvar<workgroup> activeBits: u32;\nvar<workgroup> sk: array<u32, BLOCK>;\nvar<workgroup> sv: array<u32, BLOCK>;\n// three 10-bit counts; the fourth follows from the number of items\nvar<workgroup> counts: array<u32, THREADS * 2u>;\nvar<workgroup> tail: u32;\nvar<workgroup> starts: array<u32, DIGITS>;\nvar<workgroup> offsets: array<u32, DIGITS>;\n\nfn unpack(packed: u32, count: u32) -> vec4u {\n let a = packed & 1023u;\n let b = (packed >> 10u) & 1023u;\n let c = (packed >> 20u) & 1023u;\n return vec4u(a, b, c, count - a - b - c);\n}\n\nfn digit(key: u32) -> u32 {\n return (key >> params.shift) & 0xffu;\n}\n\n@compute @workgroup_size(1)\nfn prepare() {\n let count = min(work[params.projected], params.capacity);\n let blocks = (count + BLOCK - 1u) / BLOCK;\n work[params.drawArgs] = 4u;\n work[params.drawArgs + 1u] = count;\n work[params.drawArgs + 2u] = 0u;\n work[params.drawArgs + 3u] = 0u;\n stateOut = SortState(count, blocks, (blocks + CHUNK - 1u) / CHUNK);\n}\n\n@compute @workgroup_size(THREADS)\nfn histogram(\n @builtin(workgroup_id) wid: vec3u,\n @builtin(num_workgroups) groups: vec3u,\n @builtin(local_invocation_index) t: u32\n) {\n for (var block = wid.y * groups.x + wid.x; block < state.blocks; block += groups.x * groups.y) {\n let head = block * BLOCK;\n for (var k = 0u; k < ITEMS; k++) {\n let i = head + k * THREADS + t;\n if (i < state.count) {\n atomicAdd(&bins[digit(data[params.src + i])], 1u);\n }\n }\n workgroupBarrier();\n for (var d = t; d < DIGITS; d += THREADS) {\n hist[block * DIGITS + d] = atomicExchange(&bins[d], 0u);\n }\n workgroupBarrier();\n }\n}\n\n@compute @workgroup_size(DIGITS)\nfn reduce(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n let end = min((wid.x + 1u) * CHUNK, state.blocks);\n var sum = 0u;\n for (var b = wid.x * CHUNK; b < end; b++) {\n sum += hist[b * DIGITS + t];\n }\n sums[wid.x * DIGITS + t] = sum;\n}\n\n@compute @workgroup_size(DIGITS)\nfn top(@builtin(local_invocation_index) t: u32) {\n var run = 0u;\n for (var c = 0u; c < state.chunks; c++) {\n let x = sums[c * DIGITS + t];\n sums[c * DIGITS + t] = run;\n run += x;\n }\n totals[t] = run;\n // a bit varies only when both zero and one occur in nonempty digits\n if (run > 0u) {\n atomicOr(&bitValues, t | ((255u ^ t) << 8u));\n }\n workgroupBarrier();\n if (t == 0u) {\n let values = atomicLoad(&bitValues);\n sums[arrayLength(&sums) - 1u] = values & (values >> 8u);\n }\n for (var o = 1u; o < DIGITS; o *= 2u) {\n var x = 0u;\n if (t >= o) {\n x = totals[t - o];\n }\n workgroupBarrier();\n totals[t] += x;\n workgroupBarrier();\n }\n let base = totals[t] - run;\n for (var c = 0u; c < state.chunks; c++) {\n sums[c * DIGITS + t] += base;\n }\n}\n\n@compute @workgroup_size(DIGITS)\nfn down(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n let end = min((wid.x + 1u) * CHUNK, state.blocks);\n var run = sums[wid.x * DIGITS + t];\n for (var b = wid.x * CHUNK; b < end; b++) {\n let x = hist[b * DIGITS + t];\n hist[b * DIGITS + t] = run;\n run += x;\n }\n}\n\n@compute @workgroup_size(THREADS)\nfn scatter(\n @builtin(workgroup_id) wid: vec3u,\n @builtin(num_workgroups) groups: vec3u,\n @builtin(local_invocation_index) t: u32\n) {\n let first = wid.y * groups.x + wid.x;\n if (first >= state.blocks) {\n return;\n }\n if (t == 0u) {\n activeBits = sums[arrayLength(&sums) - 1u];\n }\n let bits = workgroupUniformLoad(&activeBits);\n for (var block = first; block < state.blocks; block += groups.x * groups.y) {\n let head = block * BLOCK;\n let valid = min(BLOCK, state.count - head);\n // padding has digit 255 at every shift, so it sorts behind the valid keys and is never written\n for (var k = 0u; k < ITEMS; k++) {\n let i = k * THREADS + t;\n var key = 0xffffffffu;\n var value = 0u;\n if (i < valid) {\n key = data[params.src + head + i];\n value = data[params.src + params.capacity + head + i];\n }\n sk[i] = key;\n sv[i] = value;\n }\n for (var d = t; d < DIGITS; d += THREADS) {\n offsets[d] = hist[block * DIGITS + d];\n }\n workgroupBarrier();\n\n // stable local sort by the digit, two bits a split; thread t owns positions t ITEMS + k\n for (var bit = 0u; bit < 8u; bit += 2u) {\n if ((bits & (3u << bit)) == 0u) {\n continue;\n }\n var keys: array<u32, ITEMS>;\n var values: array<u32, ITEMS>;\n var before: array<u32, ITEMS>;\n var mine = vec4u(0u);\n for (var k = 0u; k < ITEMS; k++) {\n keys[k] = sk[t * ITEMS + k];\n values[k] = sv[t * ITEMS + k];\n let b = (keys[k] >> (params.shift + bit)) & 3u;\n before[k] = mine[b];\n mine[b] += 1u;\n }\n counts[t] = mine.x | (mine.y << 10u) | (mine.z << 20u);\n if (t == THREADS - 1u) {\n tail = counts[t];\n }\n workgroupBarrier();\n // separate reads and writes need only one barrier per scan step\n var source = 0u;\n for (var o = 1u; o < THREADS; o *= 2u) {\n var x = counts[source + t];\n if (t >= o) {\n x += counts[source + t - o];\n }\n let dest = source ^ THREADS;\n counts[dest + t] = x;\n workgroupBarrier();\n source = dest;\n }\n // prefixes stop at 1016 items, so no count carries into its neighbour\n let total = unpack(counts[source + THREADS - 2u], BLOCK - ITEMS) + unpack(tail, ITEMS);\n var prior = vec4u(0u);\n if (t > 0u) {\n prior = unpack(counts[source + t - 1u], t * ITEMS);\n }\n let base = vec4u(0u, total.x, total.x + total.y, total.x + total.y + total.z);\n for (var k = 0u; k < ITEMS; k++) {\n let b = (keys[k] >> (params.shift + bit)) & 3u;\n let p = base[b] + prior[b] + before[k];\n sk[p] = keys[k];\n sv[p] = values[k];\n }\n workgroupBarrier();\n }\n\n for (var k = 0u; k < ITEMS; k++) {\n let i = t * ITEMS + k;\n let d = digit(sk[i]);\n if (i == 0u || digit(sk[i - 1u]) != d) {\n starts[d] = i;\n }\n }\n workgroupBarrier();\n for (var k = 0u; k < ITEMS; k++) {\n let i = k * THREADS + t;\n if (i < valid) {\n let d = digit(sk[i]);\n let slot = offsets[d] + i - starts[d];\n data[params.dst + slot] = sk[i];\n data[params.dst + params.capacity + slot] = sv[i];\n }\n }\n workgroupBarrier();\n }\n}\n", P = 1024, _e = 64, ve = 256, F = 3, I = 256, ye = 32, be = class {
702
- keys;
703
- values;
704
- bytes;
705
- #e;
706
- #t;
707
- #n;
708
- #r;
709
- #i;
710
- #a;
711
- constructor(e, t) {
712
- let { capacity: n } = t;
713
- this.keys = n * 8, this.values = n * 12;
714
- let r = Math.max(1, Math.ceil(n / P));
715
- this.#a = r;
716
- let i = Math.ceil(r / _e), a = (t, n, r) => e.createBuffer({
717
- label: t,
718
- size: n,
719
- usage: r
720
- }), o = GPUBufferUsage.STORAGE, s = a("sort params", F * I, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST), c = a("sort histograms", r * ve * 4, o), u = a("sort chunk sums", (i * ve + 1) * 4, o), d = a("sort state", 12, o);
721
- this.#e = [
722
- s,
723
- c,
724
- u,
725
- d
726
- ], this.bytes = this.#e.reduce((e, t) => e + t.size, 0);
727
- let f = new Uint32Array(F * I / 4);
728
- for (let e = 0; e < F; e++) {
729
- let [t, r] = e % 2 ? [2 * n, 0] : [0, 2 * n];
730
- f.set([
731
- 8 * e,
732
- t,
733
- r,
734
- n,
735
- l.projected,
736
- l.drawArgs
737
- ], e * I / 4);
738
- }
739
- e.queue.writeBuffer(s, 0, f);
740
- let p = (e, t) => ({
741
- binding: e,
742
- visibility: GPUShaderStage.COMPUTE,
743
- buffer: { type: t }
744
- }), m = E(e, "sort", GPUShaderStage.COMPUTE, [
745
- "uniform",
746
- "storage",
747
- "storage",
748
- "storage",
749
- "read-only-storage"
750
- ]), h = e.createBindGroupLayout({
751
- label: "sort prepare",
752
- entries: [
753
- p(0, "uniform"),
754
- p(5, "storage"),
755
- p(6, "storage")
756
- ]
757
- }), g = e.createShaderModule({
758
- label: "sort",
759
- code: O + ge
760
- }), _ = (t, n) => e.createComputePipeline({
761
- label: `sort ${t}`,
762
- layout: e.createPipelineLayout({ bindGroupLayouts: [n] }),
763
- compute: {
764
- module: g,
765
- entryPoint: t
766
- }
767
- });
768
- this.#t = _("prepare", h), this.#n = [
769
- "histogram",
770
- "reduce",
771
- "top",
772
- "down",
773
- "scatter"
774
- ].map((e) => _(e, m));
775
- let v = (e) => ({
776
- buffer: s,
777
- offset: e * I,
778
- size: ye
779
- });
780
- this.#r = e.createBindGroup({
781
- label: "sort prepare",
782
- layout: h,
783
- entries: [
784
- {
785
- binding: 0,
786
- resource: v(0)
787
- },
788
- {
789
- binding: 5,
790
- resource: { buffer: d }
791
- },
792
- {
793
- binding: 6,
794
- resource: { buffer: t.work }
795
- }
796
- ]
797
- }), this.#i = Array.from({ length: F }, (n, r) => e.createBindGroup({
798
- label: `sort pass ${r}`,
799
- layout: m,
800
- entries: [
801
- {
802
- binding: 0,
803
- resource: v(r)
804
- },
805
- {
806
- binding: 1,
807
- resource: { buffer: t.sort }
808
- },
809
- {
810
- binding: 2,
811
- resource: { buffer: c }
812
- },
813
- {
814
- binding: 3,
815
- resource: { buffer: u }
816
- },
817
- {
818
- binding: 4,
819
- resource: { buffer: d }
820
- }
821
- ]
822
- }));
823
- }
824
- encode(e, t, n, r) {
825
- let [i, a, o, s, c] = this.#n, l = Math.max(1, Math.min(this.#a, Math.ceil(t / P))), u = Math.max(l / 16, (n || t) / P), f = d(Math.min(Math.ceil(l / 4), Math.ceil(u))), p = Math.ceil(l / _e), m = e.beginComputePass({
826
- label: "sort",
827
- timestampWrites: r
828
- });
829
- m.setPipeline(this.#t), m.setBindGroup(0, this.#r), m.dispatchWorkgroups(1);
830
- for (let e of this.#i) m.setBindGroup(0, e), m.setPipeline(i), m.dispatchWorkgroups(...f), m.setPipeline(a), m.dispatchWorkgroups(p), m.setPipeline(o), m.dispatchWorkgroups(1), m.setPipeline(s), m.dispatchWorkgroups(p), m.setPipeline(c), m.dispatchWorkgroups(...f);
831
- m.end();
832
- }
833
- destroy() {
834
- for (let e of this.#e) e.destroy();
835
- }
836
- }, xe = class {
837
- ms = {};
838
- #e;
839
- #t;
840
- #n;
841
- #r;
842
- #i = !1;
843
- #a = !1;
844
- constructor(e, t, n) {
845
- if (this.#e = n, !t) return;
846
- let r = n.length * 2;
847
- this.#t = e.createQuerySet({
848
- label: "timing",
849
- type: "timestamp",
850
- count: r
851
- }), this.#n = e.createBuffer({
852
- label: "timing resolved",
853
- size: r * 8,
854
- usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC
855
- }), this.#r = e.createBuffer({
856
- label: "timing readback",
857
- size: r * 8,
858
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
859
- });
860
- }
861
- writes(e) {
862
- let t = this.#t;
863
- if (!t || this.#i) return;
864
- let n = this.#e.indexOf(e);
865
- return {
866
- querySet: t,
867
- beginningOfPassWriteIndex: 2 * n,
868
- endOfPassWriteIndex: 2 * n + 1
869
- };
870
- }
871
- resolve(e) {
872
- !this.#t || !this.#n || !this.#r || this.#i || (e.resolveQuerySet(this.#t, 0, this.#e.length * 2, this.#n, 0), e.copyBufferToBuffer(this.#n, 0, this.#r, 0, this.#r.size), this.#a = !0);
873
- }
874
- read() {
875
- let e = this.#r;
876
- !e || this.#i || !this.#a || (this.#i = !0, this.#a = !1, e.mapAsync(GPUMapMode.READ).then(() => {
877
- let t = new BigUint64Array(e.getMappedRange());
878
- this.#e.forEach((e, n) => {
879
- let [r, i] = [t[2 * n], t[2 * n + 1]];
880
- this.ms[e] = i > r ? Number(i - r) / 1e6 : 0;
881
- }), e.unmap();
882
- }).catch(() => {}).finally(() => this.#i = !1));
883
- }
884
- destroy() {
885
- this.#t?.destroy(), this.#n?.destroy(), this.#r?.destroy();
886
- }
887
- }, Se = [
888
- "cull",
889
- "project",
890
- "sort",
891
- "raster",
892
- "heights",
893
- "post"
894
- ], L = {
895
- view: 0,
896
- proj: 16,
897
- viewProj: 32,
898
- planes: 48,
899
- camera: 72,
900
- time: 75,
901
- viewport: 76,
902
- focal: 78,
903
- near: 80,
904
- far: 81,
905
- lowPass: 82,
906
- clusters: 83
907
- }, Ce = class {
908
- #e;
909
- #t;
910
- #n;
911
- #r;
912
- #i;
913
- #a;
914
- #o;
915
- #s;
916
- #c;
917
- #l;
918
- #u;
919
- #d;
920
- #f = /* @__PURE__ */ new Float32Array(84);
921
- #p = new Uint32Array(this.#f.buffer);
922
- #m = /* @__PURE__ */ new Float32Array(16);
923
- #h = /* @__PURE__ */ new Float32Array(64);
924
- #g = [];
925
- #_ = [];
926
- #v = {};
927
- #y = /* @__PURE__ */ new WeakMap();
928
- #b;
929
- #x;
930
- #S;
931
- #C = !1;
932
- #w = 0;
933
- #T = 0;
934
- constructor(e, t, n, r) {
935
- let { device: i } = e;
936
- this.#e = i, this.#t = t, this.#n = e.format, this.#r = n, this.#i = T(i, r, n.slots), this.#a = new j(i, n, this.#i), this.#o = new le(i, n, this.#i), this.#s = new be(i, this.#i), this.#c = new me(i, this.#i, this.#s), this.#u = new re(i, n), this.#d = new xe(i, e.timestamps, Se), this.#S = i.createBuffer({
937
- label: "counts readback",
938
- size: (l.projected + 1) * 4,
939
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
940
- }), this.#b = Math.max(1, t.canvas.width), this.#x = Math.max(1, t.canvas.height);
941
- }
942
- shade(e) {
943
- if (this.#g.reduce((e, { shade: t }) => e + t.uniforms, 0) + e.uniforms > 16) throw Error("Shade hooks may use 16 uniform slots in all.");
944
- let t = {
945
- shade: e,
946
- slot: 0
947
- };
948
- return this.#g.push(t), this.#E(), () => {
949
- let e = this.#g.indexOf(t);
950
- e < 0 || (this.#g.splice(e, 1), this.#E());
951
- };
952
- }
953
- post(e) {
954
- let t = {
955
- post: e,
956
- pass: e.setup(this.#e, this.#n)
957
- }, n = e.order ?? 0, r = this.#_.findIndex(({ post: e }) => (e.order ?? 0) > n);
958
- return this.#_.splice(r < 0 ? this.#_.length : r, 0, t), () => {
959
- let e = this.#_.indexOf(t);
960
- e < 0 || (this.#_.splice(e, 1), t.pass.destroy());
961
- };
962
- }
963
- resize(e, t) {
964
- (e !== this.#b || t !== this.#x) && (this.#b = e, this.#x = t, this.#j());
965
- }
966
- render(e, t, n, r, i) {
967
- let a = this.#e, o = this.#d, s = this.#_, c = this.#k(this.#O("colour", de)), u = r.length > 0 || s.some(({ post: e }) => e.depth), d = this.#A("depth", fe, u), f = d ? this.#k(d) : null, p = [this.#A("ping", this.#n, s.length > 1), this.#A("pong", this.#n, s.length > 2)];
968
- this.#D(e, t);
969
- let m = a.createCommandEncoder({ label: "frame" });
970
- m.clearBuffer(this.#i.work, 0, l.list * 4), this.#a.encode(m, o.writes("cull")), this.#o.encode(m, this.#T, o.writes("project")), this.#s.encode(m, this.#r.listed * 256, this.#w, o.writes("sort")), this.#c.encode(m, c, f, n, o.writes("raster"));
971
- let h = d ? r.map(({ x: t, y: n, resolve: r }) => ({
972
- resolve: r,
973
- read: he(a, m, d, t, n, e.near, e.far)
974
- })) : [], g = i.map(({ x: e, y: t, cells: n, resolve: r }, i) => ({
975
- resolve: r,
976
- read: this.#u.encode(m, e, t, n, i ? void 0 : o.writes("heights"))
977
- })), _ = o.writes("post");
978
- if (_) {
979
- let { querySet: e, beginningOfPassWriteIndex: t } = _;
980
- m.beginComputePass({ timestampWrites: {
981
- querySet: e,
982
- beginningOfPassWriteIndex: t
983
- } }).end();
984
- }
985
- let v = this.#t.getCurrentTexture().createView();
986
- if (!s.length) this.#l ??= se(a, this.#n), this.#l.encode(m, [c], v);
987
- else {
988
- let t = c;
989
- s.forEach(({ post: n, pass: r }, i) => {
990
- let a = i === s.length - 1 ? v : this.#k(p[i % 2]);
991
- r.run(m, e, t, n.depth ? f : null, a), t = a;
992
- });
993
- }
994
- if (_) {
995
- let { querySet: e, endOfPassWriteIndex: t } = _;
996
- m.beginComputePass({ timestampWrites: {
997
- querySet: e,
998
- endOfPassWriteIndex: t
999
- } }).end();
1000
- }
1001
- o.resolve(m);
1002
- let y = !this.#C;
1003
- y && m.copyBufferToBuffer(this.#i.work, 0, this.#S, 0, this.#S.size), a.queue.submit([m.finish()]), o.read(), y && this.#M();
1004
- for (let { resolve: e, read: t } of h) t().then(e);
1005
- for (let { resolve: e, read: t } of g) t().then(e);
1006
- return a.queue.onSubmittedWorkDone();
1007
- }
1008
- stats() {
1009
- let e = { ...this.#d.ms }, t = this.#i.bytes + this.#s.bytes;
1010
- for (let e of Object.values(this.#v)) e && (t += e.width * e.height * (e.format === "depth16unorm" ? 2 : 4));
1011
- return {
1012
- gpuMs: Object.values(e).reduce((e, t) => e + t, 0),
1013
- passes: e,
1014
- drawn: this.#w,
1015
- bytes: t
1016
- };
1017
- }
1018
- destroy() {
1019
- for (let { pass: e } of this.#_.splice(0)) e.destroy();
1020
- this.#j(), this.#i.destroy(), this.#s.destroy(), this.#c.destroy(), this.#d.destroy(), this.#S.destroy();
1021
- }
1022
- #E() {
1023
- let e = 0;
1024
- for (let t of this.#g) t.slot = e, e += t.shade.uniforms;
1025
- this.#o.hooks(this.#g);
1026
- }
1027
- #D(e, t) {
1028
- let n = this.#f, [r, i] = [this.#b, this.#x];
1029
- n.set(e.view, L.view), n.set(e.proj, L.proj), n.set(S(this.#m, e.proj, e.view), L.viewProj), n.set(t, L.planes), n.set(e.camera.subarray(0, 3), L.camera), n[L.time] = e.time, n.set([r, i], L.viewport), n.set([e.proj[0] * r / 2, e.proj[5] * i / 2], L.focal), n[L.near] = e.near, n[L.far] = e.far, n[L.lowPass] = f, this.#p[L.clusters] = this.#r.listed, this.#e.queue.writeBuffer(this.#i.uniforms, 0, n);
1030
- for (let { shade: t, slot: n } of this.#g) t.update(e, this.#h.subarray(n * 4, (n + t.uniforms) * 4));
1031
- this.#g.length && this.#e.queue.writeBuffer(this.#i.plugins, 0, this.#h);
1032
- }
1033
- #O(e, t) {
1034
- let n = this.#v[e];
1035
- return n || (n = this.#e.createTexture({
1036
- label: e,
1037
- size: [this.#b, this.#x],
1038
- format: t,
1039
- usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
1040
- }), this.#v[e] = n), n;
1041
- }
1042
- #k(e) {
1043
- let t = this.#y.get(e);
1044
- return t || this.#y.set(e, t = e.createView()), t;
1045
- }
1046
- #A(e, t, n) {
1047
- if (n) return this.#O(e, t);
1048
- this.#v[e]?.destroy(), delete this.#v[e];
1049
- }
1050
- #j() {
1051
- for (let e of Object.values(this.#v)) e?.destroy();
1052
- this.#v = {};
1053
- }
1054
- #M() {
1055
- this.#C = !0;
1056
- let e = this.#S;
1057
- e.mapAsync(GPUMapMode.READ).then(() => {
1058
- let t = new Uint32Array(e.getMappedRange());
1059
- this.#T = t[l.visible], this.#w = Math.min(t[l.projected], this.#i.capacity), e.unmap();
1060
- }).catch(() => {}).finally(() => this.#C = !1);
1061
- }
1062
- }, we = [
1063
- [0, 1],
1064
- [0, -1],
1065
- [1, 1],
1066
- [1, -1],
1067
- [2, 0],
1068
- [2, -1]
1069
- ];
1070
- function Te(e, t) {
1071
- let n = (e, n) => t[n * 4 + e];
1072
- return we.forEach(([t, r], i) => {
1073
- for (let a = 0; a < 4; a++) e[i * 4 + a] = r ? n(3, a) + r * n(t, a) : n(t, a);
1074
- let a = Math.hypot(e[i * 4], e[i * 4 + 1], e[i * 4 + 2]) || 1;
1075
- for (let t = 0; t < 4; t++) e[i * 4 + t] /= a;
1076
- }), e;
1077
- }
1078
- var Ee = class {
1079
- #e = /* @__PURE__ */ new Map();
1080
- update(e, t, n, r) {
1081
- let i = this.#e, a = De(e, t), o = -1;
1082
- for (let [e, r] of i) t(r.page.id) ? (o = Math.max(o, r.level), !r.held && (r.start !== null && n - r.start >= 250 && (r.start = null), a.has(e) || (r.frozen = z(r, n), r.start = null, r.out = null, r.covered = !1, r.held = !0))) : i.delete(e);
1083
- let s = /* @__PURE__ */ new Set();
1084
- for (let [e, t] of a) {
1085
- let r = i.get(e);
1086
- if (!r) {
1087
- let r = Oe(t, e % 4, n);
1088
- o = Math.max(o, r.level), i.set(e, r), s.add(r);
1089
- } else if (r.held) {
1090
- let e = z(r, n);
1091
- r.held = !1, r.out = null, e < 255 && (r.start = n - e / 255 * 250, s.add(r));
1092
- }
1093
- }
1094
- let l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
1095
- for (let e of i.values()) if (e.held) {
1096
- l.set(e.cell, e);
1097
- for (let t = e.level, n = e.col, r = e.row; t <= o; t++, n >>= 1, r >>= 1) {
1098
- let i = R(t, n, r), a = u.get(i);
1099
- a ? a.push(e) : u.set(i, [e]);
1100
- }
1101
- }
1102
- let d = (e) => {
1103
- let t = [...u.get(e.cell) ?? []];
1104
- for (let n = e.level + 1, r = e.col >> 1, i = e.row >> 1; n <= o; n++, r >>= 1, i >>= 1) {
1105
- let e = l.get(R(n, r, i));
1106
- e && t.push(e);
1107
- }
1108
- return t;
1109
- }, f = /* @__PURE__ */ new Set(), p = /* @__PURE__ */ new Set(), m = 0, h = 0, g = (e) => {
1110
- p.has(e) || (p.add(e), h += c(e.row.count));
1111
- };
1112
- for (let e of i.values()) if (!(e.held || e.start === null || s.has(e))) {
1113
- m += e.splats;
1114
- for (let t of d(e)) f.has(t) || (f.add(t), m += t.splats, g(t.page));
1115
- }
1116
- for (let e of i.values()) e.held && e.out !== null && !f.has(e) && (m += e.splats);
1117
- let _ = 1 * r;
1118
- for (let e of s) {
1119
- let t = d(e).filter((e) => !f.has(e)), n = t.reduce((e, t) => e + t.splats, e.splats), r = new Set(t.map((e) => e.page).filter((e) => !p.has(e))), i = [...r].reduce((e, t) => e + c(t.row.count), 0);
1120
- if (m + n > _ || h + i > _) e.start = null;
1121
- else {
1122
- m += n;
1123
- for (let e of t) f.add(e);
1124
- for (let e of r) g(e);
1125
- }
1126
- }
1127
- let v = /* @__PURE__ */ new Map(), y = !1;
1128
- for (let [e, t] of i) {
1129
- if (t.held && f.has(t)) t.out !== null && (t.frozen = z(t, n)), t.out = null, t.covered = !0;
1130
- else if (t.held && (t.covered && t.out === null && (t.out = n), !t.covered || z(t, n) === 0)) {
1131
- i.delete(e);
1132
- continue;
1133
- }
1134
- (t.held || t.start !== null) && (y = !0);
1135
- let r = z(t, n);
1136
- if (!r) continue;
1137
- let a = v.get(t.page.id);
1138
- a ? a.factors = (a.factors | r << 8 * t.q) >>> 0 : v.set(t.page.id, {
1139
- id: t.page.id,
1140
- factors: r << 8 * t.q >>> 0
1141
- });
1142
- }
1143
- return {
1144
- drawn: [...v.values()],
1145
- fading: y
1146
- };
1147
- }
1148
- };
1149
- function De(e, t) {
1150
- let n = new Set(e), r = /* @__PURE__ */ new Set(), i = [];
1151
- for (let t of e) for (let e = t; e && !r.has(e); e = e.parent) r.add(e), e.parent || i.push(e);
1152
- let a = /* @__PURE__ */ new Map(), o = (e) => {
1153
- for (let i = 0; i < 4; i++) {
1154
- let s = e.children[i];
1155
- s && r.has(s) && t(s.id) ? o(s) : (s !== null || n.has(e)) && a.set(e.id * 4 + i, e);
1156
- }
1157
- };
1158
- for (let e of i) t(e.id) && o(e);
1159
- return a;
1160
- }
1161
- function Oe(t, n, r) {
1162
- let i = e * 2 ** t.g, a = t.g - 1, o = 2 * (Math.round(t.unit.e / i) + t.row.i) + (n & 1), s = 2 * (Math.round(t.unit.n / i) + t.row.j) + (n >> 1);
1163
- return {
1164
- page: t,
1165
- q: n,
1166
- level: a,
1167
- col: o,
1168
- row: s,
1169
- cell: R(a, o, s),
1170
- splats: ke(t.row, n),
1171
- start: r,
1172
- frozen: 0,
1173
- out: null,
1174
- covered: !1,
1175
- held: !1
1176
- };
1177
- }
1178
- var R = (e, t, n) => ((e + 1) * 2 ** 21 + t) * 2 ** 21 + n;
1179
- function ke({ count: e, quadrants: t }, n) {
1180
- return (n < 3 ? t[n] : e) - (n > 0 ? t[n - 1] : 0);
1181
- }
1182
- function z(e, t) {
1183
- return e.held ? e.out === null ? e.frozen : Math.max(0, Math.round(e.frozen * (1 - (t - e.out) / 250))) : e.start === null ? 255 : Math.min(255, Math.round((t - e.start) / 250 * 255));
1184
- }
1185
- //#endregion
1186
- //#region src/engine/plan/footprint.ts
1187
- var Ae = [
1188
- 0,
1189
- 0,
1190
- 0
1191
- ];
1192
- function je(e, t, n, r) {
1193
- let i = (e * e + e * t + t * t + n * n + n * r + r * r) / 3;
1194
- return 1 + 15 * Math.max(0, 1 - i) ** 2;
1195
- }
1196
- function Me(e, t, n, r, i, a, o, s = 1, c = {
1197
- shown: !1,
1198
- pixels: 0,
1199
- weight: 1
1200
- }, l = Ae) {
1201
- let u = (e[0] + e[3]) / 2 - l[0], d = (e[1] + e[4]) / 2 - l[1], f = (e[2] + e[5]) / 2 - l[2], p = (e[3] - e[0]) / 2, m = (e[4] - e[1]) / 2, h = (e[5] - e[2]) / 2, g = t[0] * u + t[4] * d + t[8] * f + t[12], _ = t[1] * u + t[5] * d + t[9] * f + t[13], v = -(t[2] * u + t[6] * d + t[10] * f + t[14]), y = Math.abs(t[0]) * p + Math.abs(t[4]) * m + Math.abs(t[8]) * h, b = Math.abs(t[1]) * p + Math.abs(t[5]) * m + Math.abs(t[9]) * h, x = Math.abs(t[2]) * p + Math.abs(t[6]) * m + Math.abs(t[10]) * h;
1202
- if (c.pixels = 0, c.weight = 1, c.shown = !1, v + x < a || v - x > o) return c;
1203
- let S = Math.max(a, v - x), C = Math.max(a, v + x), w = i * n / r;
1204
- if (Math.abs(g) - y > s * w * C || Math.abs(_) - b > s * i * C) return c;
1205
- let T = Math.min((g - y) / S, (g - y) / C) / w, E = Math.max((g + y) / S, (g + y) / C) / w, D = Math.min((_ - b) / S, (_ - b) / C) / i, O = Math.max((_ + b) / S, (_ + b) / C) / i;
1206
- if (E < -s || T > s || O < -s || D > s) return c;
1207
- let k = Math.max(-s, T), A = Math.min(s, E), j = Math.max(-s, D), M = Math.min(s, O), N = (E - T) * (O - D), ee = (A - k) * (M - j);
1208
- return N <= 0 || ee <= 0 || (c.shown = E > -1 && T < 1 && O > -1 && D < 1, c.pixels = N * n * r / 4, c.weight = je(k, A, j, M)), c;
1209
- }
1210
- var B = /* @__PURE__ */ new Float64Array(6), Ne = {
1211
- shown: !1,
1212
- pixels: 0,
1213
- weight: 1
1214
- };
1215
- function Pe(e, [t, n, r], i, a, o, s, c, l, u = Ae) {
1216
- let d = r / 2, f = Math.max(0, t - e[0], n - e[1], e[3] - t - r, e[4] - n - r);
1217
- B[2] = e[2], B[5] = e[5];
1218
- let p = 0;
1219
- for (let r = 0; r < 4; r++) {
1220
- let m = t + (r & 1) * d, h = n + (r >> 1) * d;
1221
- B[0] = Math.max(e[0], m - f), B[1] = Math.max(e[1], h - f), B[3] = Math.min(e[3], m + d + f), B[4] = Math.min(e[4], h + d + f), !(B[0] > B[3] || B[1] > B[4]) && Me(B, i, a, o, s, c, l, 1, Ne, u).shown && (p |= 1 << r);
1222
- }
1223
- return p;
1224
- }
1225
- //#endregion
1226
- //#region src/engine/world/tree.ts
1227
- var V = (e, t, n) => (e * 256 + t) * 256 + n, Fe = class {
1228
- roots = [];
1229
- pages = /* @__PURE__ */ new Map();
1230
- units = /* @__PURE__ */ new Map();
1231
- #e;
1232
- #t;
1233
- #n = 0;
1234
- #r = /* @__PURE__ */ new Map();
1235
- #i = /* @__PURE__ */ new Map();
1236
- constructor(e) {
1237
- this.#e = new Set(e.roots.map(H)), this.#t = Math.max(...e.roots.map((e) => e.level));
1238
- }
1239
- add(e, t) {
1240
- let n = H(e), r = this.units.get(n);
1241
- if (r) return r;
1242
- let o = /* @__PURE__ */ new Map(), s = {
1243
- level: e.level,
1244
- e: e.e,
1245
- n: e.n,
1246
- idx: e,
1247
- path: t,
1248
- parent: null,
1249
- pages: [],
1250
- grid: o
1251
- };
1252
- for (let t of e.rows) {
1253
- let n = t.box, r = {
1254
- id: this.#n++,
1255
- unit: s,
1256
- row: t,
1257
- g: t.g,
1258
- box: Float64Array.of(e.e + n[0], e.n + n[1], n[2], e.e + n[3], e.n + n[4], n[5]),
1259
- parent: null,
1260
- children: [
1261
- null,
1262
- null,
1263
- null,
1264
- null
1265
- ]
1266
- };
1267
- this.pages.set(r.id, r), s.pages.push(r), o.set(V(t.g, t.i, t.j), r);
1268
- }
1269
- this.units.set(n, s), this.#r.delete(n);
1270
- for (let t = e.level + 1; t <= this.#t; t++) {
1271
- let n = H(U(e, t));
1272
- this.#i.set(n, (this.#i.get(n) ?? 0) + 1);
1273
- }
1274
- let c = new Set(e.rows.map((e) => e.g)), l = Math.max(...c), u = e.level === 0 ? 0 : e.level + 1, d = new Set(e.children.map((e) => e.quadrant));
1275
- for (let e of s.pages) {
1276
- let { g: t, i: n, j: r } = e.row;
1277
- c.has(t + 1) && (e.parent = o.get(V(t + 1, n >> 1, r >> 1)) ?? null);
1278
- for (let i = 0; i < 4; i++) {
1279
- let a = 2 * n + (i & 1), s = 2 * r + (i >> 1);
1280
- c.has(t - 1) ? e.children[i] = o.get(V(t - 1, a, s)) ?? null : t === u && t > 0 && (e.children[i] = d.has((a >> 3) + 2 * (s >> 3)) ? void 0 : null);
1281
- }
1282
- }
1283
- if (this.#e.has(n)) for (let e of s.pages) e.g === l && this.roots.push(e);
1284
- else {
1285
- let t = this.units.get(H(U(e, e.level + 1)));
1286
- t && this.#o(t, s);
1287
- }
1288
- let f = a(s.idx);
1289
- for (let { key: t } of f) {
1290
- let n = t.level === e.level - 1 ? this.units.get(H(t)) : void 0;
1291
- n && this.#o(s, n);
1292
- }
1293
- for (let { key: e, hash: t } of f) {
1294
- let n = H(e);
1295
- if (this.units.has(n)) continue;
1296
- let r = this.#r.get(n);
1297
- if (r && r.from <= s.level) continue;
1298
- let a = this.#s(s, e), o = {
1299
- ...e,
1300
- path: i(e, t, "idx"),
1301
- over: a
1302
- };
1303
- this.#r.set(n, {
1304
- wanted: o,
1305
- from: s.level
1306
- });
1307
- }
1308
- return s;
1309
- }
1310
- wanted() {
1311
- return Array.from(this.#r.values(), (e) => e.wanted);
1312
- }
1313
- ground(e, t) {
1314
- for (let n of this.roots) {
1315
- let [r, i, a] = W(n);
1316
- if (e < r || e >= r + a || t < i || t >= i + a) continue;
1317
- let o = n;
1318
- for (;;) {
1319
- let n = +(e >= r + a / 2), s = +(t >= i + a / 2), c = o.children[n + 2 * s];
1320
- if (!c) return o.box[2];
1321
- o = c, [r, i, a] = W(o);
1322
- }
1323
- }
1324
- }
1325
- async load(e, t, n) {
1326
- for (;;) {
1327
- let r = this.wanted().filter((n) => Ie(n, e, t));
1328
- if (r.length === 0) return;
1329
- (await Promise.all(r.map((e) => n(e.path)))).forEach((e, t) => this.add(e, r[t].path));
1330
- }
1331
- }
1332
- prune(e) {
1333
- let t = [], n = [...this.units.values()].sort((e, t) => e.level - t.level);
1334
- for (let r of n) {
1335
- let n = H(r);
1336
- if (this.#e.has(n) || this.#i.has(n) || r.pages.some((t) => e.has(t.id))) continue;
1337
- for (let e of r.pages) this.pages.delete(e.id), t.push(e.id);
1338
- let i = r.parent;
1339
- if (i) {
1340
- let e = 250 * 2 ** r.level, t = (r.e - i.e) / e, n = (r.n - i.n) / e, a = i.idx.children.some((e) => e.quadrant === t + 2 * n);
1341
- for (let e of this.#s(i, r)) e.children.fill(a ? void 0 : null);
1342
- }
1343
- this.units.delete(n);
1344
- for (let e = r.level + 1; e <= this.#t; e++) {
1345
- let t = H(U(r, e)), n = this.#i.get(t) - 1;
1346
- n ? this.#i.set(t, n) : this.#i.delete(t);
1347
- }
1348
- for (let { key: e } of a(r.idx)) this.#a(e);
1349
- this.#a(r);
1350
- }
1351
- return t;
1352
- }
1353
- #a(e) {
1354
- let t = H(e);
1355
- this.#r.delete(t);
1356
- for (let n = e.level + 1; n <= e.level + 3; n++) {
1357
- let r = this.units.get(H(U(e, n)));
1358
- if (!r) continue;
1359
- let o = a(r.idx).find((e) => H(e.key) === t);
1360
- if (!o) continue;
1361
- let s = {
1362
- level: e.level,
1363
- e: e.e,
1364
- n: e.n,
1365
- path: i(o.key, o.hash, "idx"),
1366
- over: this.#s(r, e)
1367
- };
1368
- this.#r.set(t, {
1369
- wanted: s,
1370
- from: r.level
1371
- });
1372
- return;
1373
- }
1374
- }
1375
- #o(e, t) {
1376
- t.parent = e;
1377
- let n = t.level + 1, r = 250 * 2 ** t.level, i = (t.e - e.e) / r, a = (t.n - e.n) / r, o = e.grid;
1378
- for (let n of this.#s(e, t)) n.children.fill(null);
1379
- for (let e of t.pages) {
1380
- if (e.g !== n) continue;
1381
- let t = 8 * i + e.row.i, r = 8 * a + e.row.j, s = o.get(V(n + 1, t >> 1, r >> 1)) ?? null;
1382
- e.parent = s, s && (s.children[(t & 1) + 2 * (r & 1)] = e);
1383
- }
1384
- }
1385
- #s(t, n) {
1386
- let r = t.level + 1, i = e * 2 ** r, a = (n.e - t.e) / i, o = (n.n - t.n) / i, s = 250 * 2 ** n.level / i, c = [];
1387
- for (let e = o; e < o + s; e++) for (let n = a; n < a + s; n++) {
1388
- let i = t.grid.get(V(r, n, e));
1389
- i && c.push(i);
1390
- }
1391
- return c;
1392
- }
1393
- };
1394
- function H(e) {
1395
- return `${e.level}/${e.e}/${e.n}`;
1396
- }
1397
- function U(e, t) {
1398
- let n = 250 * 2 ** t;
1399
- return {
1400
- level: t,
1401
- e: Math.floor(e.e / n) * n,
1402
- n: Math.floor(e.n / n) * n
1403
- };
1404
- }
1405
- function Ie(e, t, n) {
1406
- let r = 250 * 2 ** e.level;
1407
- return t >= e.e && t < e.e + r && n >= e.n && n < e.n + r;
1408
- }
1409
- function W(t) {
1410
- let n = e * 2 ** t.g;
1411
- return [
1412
- t.unit.e + t.row.i * n,
1413
- t.unit.n + t.row.j * n,
1414
- n
1415
- ];
1416
- }
1417
- //#endregion
1418
- //#region src/engine/plan/cut.ts
1419
- var Le = 1 / .8 ** 2, Re = 1.1, ze = class {
1420
- #e = /* @__PURE__ */ new Map();
1421
- #t = /* @__PURE__ */ new Map();
1422
- #n = {
1423
- shown: !1,
1424
- pixels: 0,
1425
- weight: 1
1426
- };
1427
- plan(e, t, n, r) {
1428
- let { budget: i, capacity: a, now: o, predicted: s } = r, l = [], u = [], d = [], f = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), m = e.wanted(), h = /* @__PURE__ */ new Map(), g = new He(), _ = 0, v = 0, y = (e) => {
1429
- let t = e.page, r = t.row.count;
1430
- l.push(t), u.push(e.visible), d.push(e.near), v += c(r), _ += e.visible;
1431
- let i = this.#e.get(t.id), a = i !== void 0, s = e.pixels * e.weight, f = s / Math.max(1, r);
1432
- m.length && e.pixels > 0 && h.set(t.id, f);
1433
- let p = a && !e.shown && o - (this.#t.get(t.id) ?? -Infinity) <= 1500 ? i : null;
1434
- (r < s * (a ? Le : 1) || p !== null) && Ve(t, n) && g.push({
1435
- page: t,
1436
- shown: e.shown,
1437
- held: p,
1438
- visible: e.visible,
1439
- ratio: f
1440
- });
1441
- };
1442
- for (let n of e.roots) y(this.#r(n, t, s));
1443
- let b = [];
1444
- for (; g.size;) {
1445
- let e = g.pop(), { page: n, shown: r, held: l } = e, u = [], d = 0;
1446
- for (let e = 0; e < n.children.length; e++) {
1447
- let r = n.children[e];
1448
- if (!r) continue;
1449
- let i = this.#r(r, t, s);
1450
- i.pixels <= 0 && !((l ?? 0) & 1 << e) || (u.push(i), d |= 1 << e);
1451
- }
1452
- if (!u.length) continue;
1453
- let m = 0, h = -e.visible;
1454
- for (let e of u) m += c(e.page.row.count), h += e.visible;
1455
- if (v + m > a) break;
1456
- if (h > 0 && (b.length || _ + h > i)) {
1457
- b.push(e);
1458
- continue;
1459
- }
1460
- if (h < 0) for (let e of b.splice(0)) g.push(e);
1461
- f.set(n.id, d);
1462
- let x = r ? o : this.#t.get(n.id);
1463
- x !== void 0 && p.set(n.id, x), _ -= e.visible;
1464
- for (let e of u) y(e);
1465
- }
1466
- this.#e = f, this.#t = p;
1467
- let x = [], S = [], C = new Set(f.keys()), w = 0;
1468
- for (let e = 0; e < l.length; e++) {
1469
- let t = l[e];
1470
- f.has(t.id) || (x.push(t), C.add(t.id), n(t.id) || (w += u[e], S.push({
1471
- page: t,
1472
- near: d[e]
1473
- })));
1474
- }
1475
- let T = [];
1476
- for (let e of m) {
1477
- let t = -1;
1478
- for (let n of e.over) t = Math.max(t, h.get(n.id) ?? -1);
1479
- t >= 0 && T.push({
1480
- wanted: e,
1481
- rank: t
1482
- });
1483
- }
1484
- return T.sort((e, t) => t.rank - e.rank), {
1485
- cut: x,
1486
- load: S.filter(({ near: e }) => e || !s && w === 0).map(({ page: e }) => e),
1487
- idx: T.map((e) => e.wanted),
1488
- keep: C,
1489
- planned: _,
1490
- missing: w
1491
- };
1492
- }
1493
- #r(e, t, n) {
1494
- let r = this.#i(e, t, Re), i = r.shown, { pixels: a, weight: o } = r, s = i;
1495
- if (n) {
1496
- let t = this.#i(e, n, Re);
1497
- t.pixels > a && ({pixels: a, weight: o} = t), s ||= t.shown;
1498
- }
1499
- return {
1500
- page: e,
1501
- shown: i,
1502
- near: s,
1503
- visible: i ? Be(e, t) : 0,
1504
- pixels: a,
1505
- weight: o
1506
- };
1507
- }
1508
- #i(e, t, n) {
1509
- let { width: r, height: i, tan: a, near: o, far: s } = t;
1510
- return Me(e.box, t.view, r, i, a, o, s, n, this.#n, t.origin);
1511
- }
1512
- };
1513
- function Be(e, t) {
1514
- let { width: n, height: r, tan: i, near: a, far: o, origin: s } = t, c = Pe(e.box, W(e), t.view, n, r, i, a, o, s), l = 0;
1515
- for (let t = 0; t < 4; t++) c & 1 << t && (l += ke(e.row, t));
1516
- return l;
1517
- }
1518
- function Ve(e, t) {
1519
- let { children: n } = e;
1520
- return e.g > 0 && t(e.id) && !n.includes(void 0) && n.some((e) => e !== null);
1521
- }
1522
- var He = class {
1523
- #e = [];
1524
- get size() {
1525
- return this.#e.length;
1526
- }
1527
- push(e) {
1528
- let t = this.#e;
1529
- t.push(e);
1530
- let n = t.length - 1;
1531
- for (; n > 0;) {
1532
- let r = n - 1 >> 1;
1533
- if (!G(e, t[r])) break;
1534
- t[n] = t[r], n = r;
1535
- }
1536
- t[n] = e;
1537
- }
1538
- pop() {
1539
- let e = this.#e, t = e[0], n = e.pop();
1540
- if (e.length) {
1541
- let t = 0;
1542
- for (; 2 * t + 1 < e.length;) {
1543
- let r = 2 * t + 1;
1544
- if (r + 1 < e.length && G(e[r + 1], e[r]) && r++, !G(e[r], n)) break;
1545
- e[t] = e[r], t = r;
1546
- }
1547
- e[t] = n;
1548
- }
1549
- return t;
1550
- }
1551
- };
1552
- function G(e, t) {
1553
- return e.shown === t.shown ? e.ratio > t.ratio : e.shown;
1554
- }
1555
- //#endregion
1556
- //#region src/engine/quality.ts
1557
- var Ue = 5e5, We = 2073600, Ge = [1, .85], Ke = 30, qe = 55, Je = 2e3, Ye = 5e3, Xe = 5e5, Ze = .9;
1558
- function Qe(e, t, n, r) {
1559
- return Math.min(n, Math.sqrt(We / Math.max(1, e * t))) * r;
1560
- }
1561
- function $e(e, t) {
1562
- if (!e.length) return 0;
1563
- let n = [...e].sort((e, t) => e - t);
1564
- return n[Math.ceil(n.length * t) - 1];
1565
- }
1566
- var et = class {
1567
- #e = 0;
1568
- #t;
1569
- #n;
1570
- #r;
1571
- #i = [];
1572
- #a = -Infinity;
1573
- #o = 0;
1574
- #s = 0;
1575
- constructor(e, [t, n] = [e, e]) {
1576
- this.#n = t, this.#r = Math.max(t, n), this.#t = Math.min(this.#r, Math.max(this.#n, e));
1577
- }
1578
- get scale() {
1579
- return Ge[this.#e];
1580
- }
1581
- get budget() {
1582
- return this.#t;
1583
- }
1584
- full() {
1585
- this.#e = 0, this.#c();
1586
- }
1587
- #c() {
1588
- this.#i = [], this.#o = 0, this.#s = 0, this.#a = -Infinity;
1589
- }
1590
- sample(e, t, n, r) {
1591
- if (!n || t - this.#a > Math.max(250, 2 * e) || !Number.isFinite(e) || e <= 0) return this.#c(), this.#a = t, !1;
1592
- let i = Math.max(0, t - this.#a);
1593
- if (this.#a = t, this.#i.push({
1594
- time: t,
1595
- ms: e
1596
- }), this.#i = this.#i.filter((n) => t - n.time <= Math.max(1e3, 2 * e)), t - this.#i[0].time < 300) return !1;
1597
- let a = this.#i.reduce((e, t) => e + t.ms, 0) / this.#i.length;
1598
- if (this.#o = a > 1e3 / Ke ? this.#o + i : 0, this.#s = a <= 1e3 / qe ? this.#s + i : 0, this.#o >= Je) {
1599
- let e = Math.floor(Math.min(.9, 1e3 / Ke / a) * this.#t);
1600
- if (this.#t > this.#n) this.#t = Math.max(this.#n, e);
1601
- else if (this.#e < Ge.length - 1) this.#e++;
1602
- else return !1;
1603
- } else if (this.#s >= Ye) {
1604
- if (this.#e > 0) this.#e--;
1605
- else if (this.#t < this.#r && r >= Ze * this.#t) this.#t = Math.min(this.#r, this.#t + Xe);
1606
- else return !1;
1607
- } else return !1;
1608
- return this.#c(), !0;
1609
- }
1610
- }, tt = class {
1611
- #e;
1612
- #t = [];
1613
- #n = /* @__PURE__ */ new Set();
1614
- #r = /* @__PURE__ */ new Set();
1615
- #i = /* @__PURE__ */ new Set();
1616
- #a = /* @__PURE__ */ new Map();
1617
- constructor(e) {
1618
- this.#e = e;
1619
- }
1620
- want(e) {
1621
- this.#t = e, this.#n = new Set(e.map((e) => e.id));
1622
- }
1623
- next() {
1624
- let e = [];
1625
- for (let t of this.#r) this.#i.has(t) || t.pages.some((e) => this.#n.has(e.id)) || (this.#i.add(t), e.push(t));
1626
- let t = [];
1627
- if (this.#r.size >= this.#e.concurrency) return {
1628
- start: t,
1629
- abort: e
1630
- };
1631
- let n = /* @__PURE__ */ new Map();
1632
- for (let e of this.#t) {
1633
- if (this.#a.has(e.id)) continue;
1634
- let t = n.get(e.pack);
1635
- t ? t.push(e) : n.set(e.pack, [e]);
1636
- }
1637
- for (let e of n.values()) e.sort((e, t) => e.offset - t.offset);
1638
- for (let e of this.#t) {
1639
- if (this.#r.size >= this.#e.concurrency) break;
1640
- if (this.#a.has(e.id)) continue;
1641
- let r = this.#o(e, n.get(e.pack));
1642
- for (let e of r.pages) this.#a.set(e.id, r);
1643
- this.#r.add(r), t.push(r);
1644
- }
1645
- return {
1646
- start: t,
1647
- abort: e
1648
- };
1649
- }
1650
- done(e) {
1651
- if (this.#r.delete(e)) {
1652
- this.#i.delete(e);
1653
- for (let t of e.pages) this.#a.get(t.id) === e && this.#a.delete(t.id);
1654
- }
1655
- }
1656
- get queued() {
1657
- let e = 0;
1658
- for (let t of this.#n) this.#a.has(t) || e++;
1659
- return e;
1660
- }
1661
- get loading() {
1662
- return this.#a.size;
1663
- }
1664
- #o(e, t) {
1665
- let { gap: n, span: r } = this.#e, i = Math.floor(e.offset / r), a = t.indexOf(e), o = [e], s = e.offset, c = e.offset + e.length;
1666
- for (let e = a + 1; e < t.length; e++) {
1667
- let a = t[e];
1668
- if (this.#a.has(a.id)) continue;
1669
- let l = Math.max(c, a.offset + a.length);
1670
- if (a.offset - c > n || l - s > r || Math.floor(a.offset / r) !== i) break;
1671
- o.push(a), c = l;
1672
- }
1673
- for (let e = a - 1; e >= 0; e--) {
1674
- let a = t[e];
1675
- if (!this.#a.has(a.id)) {
1676
- if (s - (a.offset + a.length) > n || c - a.offset > r || Math.floor(a.offset / r) !== i) break;
1677
- o.unshift(a), s = a.offset;
1678
- }
1679
- }
1680
- return {
1681
- pack: e.pack,
1682
- col: e.col,
1683
- start: s,
1684
- end: c,
1685
- window: i,
1686
- pages: o
1687
- };
1688
- }
1689
- }, nt = {
1690
- idx: 8,
1691
- concurrency: 8,
1692
- gap: 65536,
1693
- span: 2097152
1694
- }, rt = 1e3, it = 3e4, at = 1e3, ot = 2e3, st = class {
1695
- #e;
1696
- #t;
1697
- #n;
1698
- #r;
1699
- #i;
1700
- #a;
1701
- #o;
1702
- #s = {
1703
- cut: [],
1704
- load: [],
1705
- idx: [],
1706
- keep: /* @__PURE__ */ new Set(),
1707
- planned: 0,
1708
- missing: 0
1709
- };
1710
- #c = /* @__PURE__ */ new Set();
1711
- #l = [];
1712
- #u = 0;
1713
- #d = /* @__PURE__ */ new Set();
1714
- #f = /* @__PURE__ */ new Map();
1715
- #p = /* @__PURE__ */ new Map();
1716
- #m = /* @__PURE__ */ new Map();
1717
- #h = /* @__PURE__ */ new Map();
1718
- #g = /* @__PURE__ */ new Set();
1719
- #_ = /* @__PURE__ */ new Map();
1720
- #v = [];
1721
- #y = -Infinity;
1722
- #b = !1;
1723
- #x = !1;
1724
- constructor(e, t, n, r, i, a = nt) {
1725
- this.#e = e, this.#t = t, this.#n = n, this.#r = r, this.#i = i, this.#a = a, this.#o = new tt(a);
1726
- }
1727
- update(e, t, n) {
1728
- if (!this.#x) {
1729
- this.#s = e, this.#c = t, this.#u = n;
1730
- for (let e of this.#v) this.#_.set(e, n);
1731
- this.#v = [], this.#S(), this.#l = this.#C(), this.#o.want(this.#l), this.#w(), this.#M();
1732
- }
1733
- }
1734
- get loading() {
1735
- return this.#d.size + this.#f.size;
1736
- }
1737
- get queued() {
1738
- return this.#o.queued;
1739
- }
1740
- get idle() {
1741
- if (this.#d.size > 0 || this.#f.size > 0 || this.#n.queued > 0) return !1;
1742
- let { idx: e, load: t } = this.#s;
1743
- return e.length === 0 && t.every(({ id: e }) => this.#n.holds(e));
1744
- }
1745
- destroy() {
1746
- this.#x = !0;
1747
- for (let e of this.#f.values()) e.abort();
1748
- this.#f.clear(), this.#d.clear();
1749
- for (let e of this.#h.values()) clearTimeout(e);
1750
- this.#h.clear();
1751
- }
1752
- #S() {
1753
- if (!this.#b) for (let { path: e } of this.#s.idx) {
1754
- if (this.#d.size >= this.#a.idx) break;
1755
- this.#d.has(e) || this.#F(e) || (this.#d.add(e), this.#t.idx(e).then((t) => {
1756
- this.#x || (this.#d.delete(e), this.#k(e), this.#v.push(this.#e.add(t, e)), this.#r());
1757
- }, (t) => {
1758
- this.#x || (this.#d.delete(e), this.#O(e, t));
1759
- }));
1760
- }
1761
- }
1762
- #C() {
1763
- let e = [];
1764
- for (let { id: t, unit: n, row: r } of this.#s.load) {
1765
- let { idx: a } = n, o = i(n, a.pack, "pack");
1766
- if (!this.#N(t, o)) continue;
1767
- let s = a.col ? i(n, a.col, "col") : null;
1768
- e.push({
1769
- id: t,
1770
- pack: o,
1771
- col: s,
1772
- offset: r.offset,
1773
- length: r.length
1774
- });
1775
- }
1776
- return e;
1777
- }
1778
- #w() {
1779
- if (this.#b) return;
1780
- let { start: e, abort: t } = this.#o.next();
1781
- for (let e of t) this.#f.get(e)?.abort();
1782
- for (let t of e) {
1783
- let e = new AbortController();
1784
- this.#f.set(t, e), this.#t.batch(t, e.signal, this.#T).then(() => this.#E(t), (e) => this.#D(t, e));
1785
- }
1786
- }
1787
- #T = ({ id: e, page: t }) => {
1788
- if (this.#x) return;
1789
- let n = this.#e.pages.get(e);
1790
- if (!n) return;
1791
- let { keep: r } = this.#s, i = this.#c;
1792
- this.#n.add(e, t, [n.unit.e, n.unit.n], (e) => r.has(e) || i.has(e)) ? (this.#g.add(e), this.#m.delete(e) && this.#j(e)) : (this.#m.set(e, this.#u + at), this.#A(e, at)), this.#r();
1793
- };
1794
- #E(e) {
1795
- this.#x || (this.#f.delete(e), this.#k(e.pack), this.#l = this.#l.filter((e) => this.#N(e.id, e.pack)), this.#o.want(this.#l), this.#o.done(e), this.#w(), this.#r());
1796
- }
1797
- #D(e, t) {
1798
- this.#x || (this.#f.delete(e), this.#o.done(e), t instanceof DOMException && t.name === "AbortError" || this.#O(e.pack, t));
1799
- }
1800
- #O(e, t) {
1801
- if (t instanceof o) {
1802
- if (this.#b) return;
1803
- this.#b = !0, this.#i();
1804
- return;
1805
- }
1806
- let n = this.#p.get(e), r = n ? Math.min(2 * n.delay, it) : rt;
1807
- this.#p.set(e, {
1808
- delay: r,
1809
- until: this.#u + r
1810
- }), this.#A(e, r);
1811
- }
1812
- #k(e) {
1813
- this.#p.delete(e), this.#j(e);
1814
- }
1815
- #A(e, t) {
1816
- clearTimeout(this.#h.get(e));
1817
- let n = setTimeout(() => {
1818
- this.#h.delete(e), this.#r();
1819
- }, t);
1820
- this.#h.set(e, n);
1821
- }
1822
- #j(e) {
1823
- clearTimeout(this.#h.get(e)), this.#h.delete(e);
1824
- }
1825
- #M() {
1826
- let e = this.#u;
1827
- if (e - this.#y < ot) return;
1828
- this.#y = e;
1829
- for (let e of this.#g) this.#n.holds(e) || this.#g.delete(e);
1830
- for (let [t, n] of this.#m) n <= e && this.#m.delete(t);
1831
- for (let [t, n] of this.#_) e - n >= ot && this.#_.delete(t);
1832
- let { keep: t } = this.#s;
1833
- if (this.#e.pages.size <= 2 * (this.#g.size + t.size)) return;
1834
- let n = /* @__PURE__ */ new Set([
1835
- ...t,
1836
- ...this.#c,
1837
- ...this.#g
1838
- ]);
1839
- for (let e of this.#_.keys()) for (let { id: t } of e.pages) n.add(t);
1840
- for (let e of this.#e.prune(n)) this.#n.holds(e) && this.#n.remove(e);
1841
- }
1842
- #N(e, t) {
1843
- return !this.#e.pages.has(e) || this.#n.holds(e) ? !1 : !this.#P(e) && !this.#F(t);
1844
- }
1845
- #P(e) {
1846
- let t = this.#m.get(e);
1847
- return t !== void 0 && this.#u < t;
1848
- }
1849
- #F(e) {
1850
- let t = this.#p.get(e);
1851
- return t !== void 0 && this.#u < t.until;
1852
- }
1853
- };
1854
- //#endregion
1855
- //#region src/engine/stream/remote.ts
1856
- function ct(e, t) {
1857
- let n = /* @__PURE__ */ new Map();
1858
- return (r) => {
1859
- if ("unfetch" in r) return void n.get(r.unfetch)?.abort();
1860
- let i = r.fetch, a = new AbortController();
1861
- n.set(i, a), (async () => e(r.url, r.range, a.signal))().then((e) => {
1862
- let n = e.slice();
1863
- t({
1864
- fetched: i,
1865
- bytes: n
1866
- }, [n.buffer]);
1867
- }, (e) => {
1868
- let n = e instanceof Error ? e.message : String(e);
1869
- t({
1870
- fetched: i,
1871
- error: n,
1872
- missing: e instanceof o
1873
- }, []);
1874
- }).finally(() => n.delete(i));
1875
- };
1876
- }
1877
- //#endregion
1878
- //#region src/engine/stream/worker.ts?worker&inline
1879
- var lt = "(function(){var e=class extends Error{name=`Missing`};let t=async(t,n,r)=>{let i=await fetch(t,n?{signal:r,headers:{Range:`bytes=${n[0]}-${n[1]-1}`}}:{signal:r});if(i.status===404)throw new e(`http 404 for ${t}`);if(i.status!==200&&i.status!==206)throw Error(`http ${i.status} for ${t}`);let a=new Uint8Array(await i.arrayBuffer());return n&&i.status===200?a.slice(n[0],n[1]):a},n=.28209479177387814,r=15.625,i=`GMIX`,a={position:0,alpha:6,rotationIndex:7,rotation:8,scale:11,dc:14,label:17},o={origin:0,step:3,scaleMin:6,scaleMax:9,dcMin:12,dcMax:15,shScale:18};async function s(e,t){let n=new ReadableStream({start(t){t.enqueue(e),t.close()}}).pipeThrough(t);return new Uint8Array(await new Response(n).arrayBuffer())}function c(e){return s(e,new DecompressionStream(`deflate-raw`))}function l(e){return s(e,new CompressionStream(`deflate-raw`))}async function u(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength);if(e.length<8||String.fromCharCode(...e.subarray(0,4))!==t)throw Error(`not a ${n} file`);let i=r.getUint16(4,!0);if(i!==1)throw Error(`${n} version ${i}; narcissus reads 1`);let a;try{a=await c(e.subarray(8))}catch{throw Error(`${n} body is not a valid deflate stream`)}return new DataView(a.buffer,a.byteOffset,a.byteLength)}function d(e,t){let n=``;for(let r=0;r<8;r++){let i=e.getUint8(t+r);n+=i.toString(16).padStart(2,`0`)}return n}function f(e,t){let n=/* @__PURE__ */ new Float32Array(6);for(let r=0;r<6;r++)n[r]=e.getFloat32(t+20+4*r,!0);return{g:e.getUint8(t),i:e.getUint8(t+1),j:e.getUint8(t+2),count:e.getUint32(t+4,!0),quadrants:[e.getUint32(t+8,!0),e.getUint32(t+12,!0),e.getUint32(t+16,!0)],box:n,offset:e.getUint32(t+44,!0),length:e.getUint32(t+48,!0)}}async function p(e){let t=await u(e,i,`.idx`);if(t.byteLength<40)throw Error(`.idx header is cut off`);let n=t.getUint16(32,!0),r=t.getUint8(34),a=t.getUint16(36,!0),o=40+n*52+r*9+a*11;if(t.byteLength!==o)throw Error(`.idx holds ${t.byteLength} bytes, its counts need ${o}`);let s=d(t,24),c={level:t.getUint8(0),e:t.getInt32(4,!0),n:t.getInt32(8,!0),pack:d(t,12),packSize:t.getUint32(20,!0),col:s===`0000000000000000`?null:s,rows:[],children:[],descendants:[]},l=40;for(let e=0;e<n;e++,l+=52)c.rows.push(f(t,l));for(let e=0;e<r;e++,l+=9)c.children.push({quadrant:t.getUint8(l),idx:d(t,l+1)});for(let e=0;e<a;e++,l+=11)c.descendants.push({depth:t.getUint8(l),column:t.getUint8(l+1),row:t.getUint8(l+2),idx:d(t,l+3)});return c}function m(e,t,n){return`u/${e.level}/${e.e}/${e.n}.${t}.${n}`}let h=/(?:^|\\/)u\\/(\\d+)\\/(-?\\d+)\\/(-?\\d+)\\.([0-9a-f]{16})\\.(?:idx|pack|col)$/;function g(e){let t=h.exec(e);return t?{level:Number(t[1]),e:Number(t[2]),n:Number(t[3]),hash:t[4]}:null}async function _(e){let t=await u(e,`GMCL`,`.col`);if(t.byteLength<60)throw Error(`.col header is cut off`);let n=t.getUint16(0,!0),r=60+12*n*n;if(t.byteLength!==r)throw Error(`.col holds ${t.byteLength} bytes, ${n} nodes need ${r}`);let i=new Float32Array(12*n*n),a=60;for(let e=0;e<12;e++){let r=t.getFloat32(12+4*e,!0)/127;for(let o=0;o<n;o++){let s=0;for(let c=0;c<n;c++,a++)s=s+t.getInt8(a)<<24>>24,i[(e*n+o)*n+c]=s*r}}return{n,pitch:t.getFloat32(4,!0),margin:t.getFloat32(8,!0),values:i}}function v(e,t,n,r){let{n:i,pitch:a,margin:o,values:s}=e,c=i-1,l=Math.min(Math.max((t+o)/a-.5,0),c),u=Math.min(Math.max((n+o)/a-.5,0),c),d=Math.min(Math.floor(l),Math.max(c-1,0)),f=Math.min(Math.floor(u),Math.max(c-1,0)),p=Math.min(d+1,c),m=Math.min(f+1,c),h=l-d,g=u-f,_=(1-h)*(1-g),v=h*(1-g),y=(1-h)*g,b=h*g,x=i*i;for(let e=0,t=0;e<12;e++,t+=x)r[e]=s[t+f*i+d]*_+s[t+f*i+p]*v+s[t+m*i+d]*y+s[t+m*i+p]*b;return r}let y=Float64Array.from({length:256},(e,t)=>(t/255-.5)*Math.SQRT2);function b(e,t,n,r,i){let a=y[t],o=y[n],s=y[r];i[e]=Math.sqrt(Math.max(0,1-a*a-o*o-s*s)),i[e>0?0:1]=a,i[e>1?1:2]=o,i[e>2?2:3]=s}function x(e,t,n,r,i){let a=e[0],o=e[1],s=e[2],c=e[3],l=t*t,u=n*n,d=r*r,f=1-2*(s*s+c*c),p=2*(o*s-a*c),m=2*(o*c+a*s),h=2*(o*s+a*c),g=1-2*(o*o+c*c),_=2*(s*c-a*o),v=2*(o*c-a*s),y=2*(s*c+a*o),b=1-2*(o*o+s*s);i[0]=3*Math.sqrt(f*f*l+p*p*u+m*m*d),i[1]=3*Math.sqrt(h*h*l+g*g*u+_*_*d),i[2]=3*Math.sqrt(v*v*l+y*y*u+b*b*d)}function S(e){if(e.length<128)throw Error(`page payload is shorter than its header`);return new DataView(e.buffer,e.byteOffset,e.byteLength)}function C(e){let t=S(e),n=t.getUint32(0,!0),r=t.getUint16(16,!0),i=128+(17+(r>0?2:0))*n,a=i+r*9;if(e.length!==a)throw Error(`page payload holds ${e.length} bytes, its header needs ${a}`);return{view:t,count:n,k:r,book:i}}function w(e){return[e.getUint32(4,!0),e.getUint32(8,!0),e.getUint32(12,!0)]}function T(e,t){let{view:n,count:r,k:i,book:s}=C(e),c=/* @__PURE__ */ new Float32Array(27);for(let e=0;e<27;e++)c[e]=n.getFloat32(20+4*e,!0);i===0&&c.fill(0,o.shScale);let l=new Uint32Array(r*4),u=new Float32Array(Math.ceil(r/256)*6),d=/* @__PURE__ */ new Float64Array(768);for(let e=0;e<3;e++){let t=c[o.scaleMin+e],n=c[o.scaleMax+e]-t;for(let r=0;r<256;r++)d[e*256+r]=Math.exp(t+r/255*n)}let f=c[o.step],p=c[o.step+1],m=c[o.step+2],h=128+a.position*r,g=128+a.alpha*r,_=128+a.rotationIndex*r,v=128+a.rotation*r,y=128+a.scale*r,S=/* @__PURE__ */ new Float64Array(4),T=/* @__PURE__ */ new Float64Array(3),O=0,k=0,A=0;for(let t=0,n=0;n<r;t++){let i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,C=-1/0;for(let t=Math.min(n+256,r);n<t;n++){let t=e[h+n]|e[h+r+n]<<8;O=O+(t>>>1^-(t&1))&65535,t=e[h+2*r+n]|e[h+3*r+n]<<8,k=k+(t>>>1^-(t&1))&65535,t=e[h+4*r+n]|e[h+5*r+n]<<8,A=A+(t>>>1^-(t&1))&65535;let u=e[_+n],w=e[v+n],E=e[v+r+n],D=e[v+2*r+n],j=e[y+n],M=e[y+r+n],N=e[y+2*r+n],P=n*4;l[P]=O|k<<16,l[P+1]=A|e[g+n]<<16|u<<24,l[P+2]=w|E<<8|D<<16|j<<24,l[P+3]=M|N<<8,b(u,w,E,D,S),x(S,d[j],d[256+M],d[512+N],T);let F=O*f,I=k*p,L=A*m;i=Math.min(i,F-T[0]),a=Math.min(a,I-T[1]),o=Math.min(o,L-T[2]),s=Math.max(s,F+T[0]),c=Math.max(c,I+T[1]),C=Math.max(C,L+T[2])}u.set([i,a,o,s,c,C],t*6)}let j=t?D(e,r,i,s,l,c,t):E(e,r,i,s);return{count:r,quadrants:w(n),geometry:l,colour:j,params:c,clusters:u}}function E(e,t,n,r){let i=new Uint32Array(t*3),o=128+a.dc*t,s=128+a.label*t;for(let a=0;a<t;a++){let c=a*3;if(i[c]=e[o+a]|e[o+t+a]<<8|e[o+2*t+a]<<16,n===0)continue;let l=r+(e[s+a]|e[s+t+a]<<8)*9;i[c]|=e[l]<<24,i[c+1]=e[l+1]|e[l+2]<<8|e[l+3]<<16|e[l+4]<<24,i[c+2]=e[l+5]|e[l+6]<<8|e[l+7]<<16|e[l+8]<<24}return i}function D(e,t,r,i,s,c,l){let u=128+a.dc*t,d=128+a.label*t,f=new Int8Array(e.buffer,e.byteOffset+i,r*9),p=new Float32Array(t*3),m=new Float32Array(t*9),h=[1/0,1/0,1/0],g=[-1/0,-1/0,-1/0],_=/* @__PURE__ */ new Float32Array(9),y=/* @__PURE__ */ new Float32Array(12),b=c[o.origin],x=c[o.origin+1],S=c[o.step],C=c[o.step+1],w=/* @__PURE__ */ new Float64Array(768);for(let e=0;e<3;e++){let t=c[o.dcMin+e],n=c[o.dcMax+e]-t;for(let r=0;r<256;r++)w[e*256+r]=t+r/255*n}let T=new Float64Array(Math.max(r,1)*9);for(let e=0;e<r*9;e++)T[e]=f[e]/127*c[o.shScale+e%9];for(let i=0;i<t;i++){let a=s[i*4];v(l,b+(a&65535)*S,x+(a>>>16)*C,y);for(let r=0;r<3;r++){let a=i*3+r;p[a]=w[r*256+e[u+r*t+i]]+y[r]/n,h[r]=Math.min(h[r],p[a]),g[r]=Math.max(g[r],p[a])}let o=r>0?(e[d+i]|e[d+t+i]<<8)*9:0;for(let e=0;e<9;e++){let t=i*9+e;m[t]=T[o+e]+y[3+e],_[e]=Math.max(_[e],Math.abs(m[t]))}}for(let e=0;e<3;e++)c[o.dcMin+e]=t>0?h[e]:0,c[o.dcMax+e]=t>0?g[e]:0;c.set(_,o.shScale);let E=[0,1,2].map(e=>{let t=c[o.dcMax+e]-c[o.dcMin+e];return t>0?255/t:0}),D=Array.from(_,e=>e>0?127/e:0),O=[0,1,2].map(e=>c[o.dcMin+e]),k=new Uint32Array(t*3),A=new Uint8Array(k.buffer);for(let e=0;e<t;e++){let t=e*4*3;for(let n=0;n<3;n++){let r=Math.round((p[e*3+n]-O[n])*E[n]);A[t+n]=Math.min(255,Math.max(0,r))}for(let n=0;n<9;n++){let r=Math.round(m[e*9+n]*D[n]);A[t+3+n]=Math.min(127,Math.max(-127,r))}}return k}async function O(e,t){return p(await A(e,t))}async function*k(e,t,n,r){let i=t.col===null?null:M(e,t.col,n),a=await j(e,t,r),o=await i;for(let[e,n]of t.pages.entries()){let t=await c(a[e]);r?.throwIfAborted(),yield{id:n.id,page:T(t,o)}}}async function A(e,t){let n=await e.cache.get(t);if(n)return n;let r=await e.fetch(e.base+t,null);return e.cache.put(t,r),r}async function j(e,t,n){let r=t.pages.map(e=>`${t.pack}#${e.offset}+${e.length}`),i=await Promise.all(r.map(t=>e.cache.get(t)));if(n?.throwIfAborted(),i.every(e=>e!==void 0))return i;let a=await e.fetch(e.base+t.pack,[t.start,t.end],n);if(a.length!==t.end-t.start)throw Error(`${t.pack}: ${a.length} bytes for ${t.start}-${t.end}`);return t.pages.map((n,o)=>{let s=a.slice(n.offset-t.start,n.offset-t.start+n.length);return i[o]||e.cache.put(r[o],s),s})}function M(e,t,n){let r=n.get(t);if(r)n.delete(t);else{let i=A(e,t).then(_);i.catch(()=>{n.get(t)===i&&n.delete(t)}),r=i}if(n.set(t,r),n.size>64){let[e]=n.keys();n.delete(e)}return r}function N(e){let t=/* @__PURE__ */ new Map,n=0;return{async get(e){let n=t.get(e);return n&&(t.delete(e),t.set(e,n)),n},async put(r,i){let a=t.get(r);if(a&&(t.delete(r),n-=a.length),!(i.length>e)){t.set(r,i),n+=i.length;for(let[r,i]of t){if(n<=e)break;t.delete(r),n-=i.length}}}}}async function P(e,t){let n;try{n=await(await I()).getDirectoryHandle(String(t),{create:!0})}catch{return null}let r=/* @__PURE__ */ new Map,i=0,a=!1,o=(e,t)=>{i+=t-(r.get(e)??0),r.delete(e),r.set(e,t)},s=e=>{i-=r.get(e)??0,r.delete(e)},c=()=>{if(a)for(let[t,a]of r){if(i<=e)break;r.delete(t),i-=a,n.removeEntry(t).catch(()=>void 0)}};return z(n).then(e=>{let t=[...r];r.clear(),i=0;for(let{name:t,size:n}of e.sort((e,t)=>e.time-t.time))o(t,n);for(let[e,n]of t)o(e,n);a=!0,c()}),{async get(e){let t=encodeURIComponent(e);if(a&&!r.has(t))return;let i=await L(n,t);return i?o(t,i.length):s(t),i},async put(t,r){if(r.length===0||r.length>e)return;let i=encodeURIComponent(t);await R(n,i,r)&&(o(i,r.length),c())}}}async function F(e){let t=new Set(Array.from({length:e},(e,t)=>String(t)));try{let e=await I(),n=[];for await(let[r,i]of e.entries())(i.kind!==`directory`||!t.has(r))&&n.push(r);let r={recursive:!0};for(let t of n)await e.removeEntry(t,r).catch(()=>void 0)}catch{}}async function I(){return(await navigator.storage.getDirectory()).getDirectoryHandle(`cache`,{create:!0})}async function L(e,t){try{let n=await(await e.getFileHandle(t)).getFile();return n.size>0?new Uint8Array(await n.arrayBuffer()):void 0}catch{return}}async function R(e,t,n){let r;try{return r=await(await e.getFileHandle(t,{create:!0})).createWritable(),await r.write(n),await r.close(),!0}catch{return r?.abort().catch(()=>void 0),!1}}async function z(e){let t=[];try{for await(let[n,r]of e.entries()){if(r.kind!==`file`)continue;let e=await r.getFile().catch(()=>null);e&&t.push({name:n,size:e.size,time:e.lastModified})}}catch{}return t}function B(t){let n=/* @__PURE__ */ new Map,r=0;return{fetch:(i,a,o)=>new Promise((s,c)=>{if(o?.aborted)return c(o.reason);let l=++r,u=()=>{n.delete(l),t({unfetch:l}),c(o.reason)};n.set(l,t=>{o?.removeEventListener(`abort`,u),`bytes`in t?s(t.bytes):c(t.missing?new e(t.error):Error(t.error))}),o?.addEventListener(`abort`,u,{once:!0}),t({fetch:l,url:i,range:a})}),take(e){let t=n.get(e.fetched);n.delete(e.fetched),t?.(e)}}}let V=(e,t,n)=>Math.min(n,Math.max(t,e));function ee(e,t,n){return n>t?V(Math.round((e-t)/(n-t)*255),0,255):0}function te(e,t){return t>0?V(Math.round(e/t*127),-127,127):0}function H(e){return e&=1023,e=(e|e<<16)&50331903,e=(e|e<<8)&50393103,e=(e|e<<4)&51130563,(e|e<<2)&153391689}function ne(e,t,n){return H(e>>6)|H(t>>6)<<1|H(n>>6)<<2}function re(e,t){let n=/* @__PURE__ */ new Float32Array(9);for(let r=0;r<t;r++)for(let t=0;t<9;t++)n[t]=Math.max(n[t],Math.abs(e[r*9+t]));return n}function ie(e,t,n){let r=new Int8Array(t*9);for(let i=0;i<t;i++)for(let t=0;t<9;t++)r[i*9+t]=te(e[i*9+t],n[t]);let i=e=>r.subarray(e*9,(e+1)*9),a=/* @__PURE__ */ new Map,o=[],s=new Uint16Array(t);for(let e=0;e<t;e++){let t=i(e).join(),n=a.get(t);n===void 0&&(n=o.length,a.set(t,n),o.push(e)),s[e]=n}if(o.length>2048){let e=o.length/256,n=Array.from({length:256},(t,n)=>o[Math.floor(n*e)]);o.splice(0,o.length,...n);for(let e=0;e<t;e++){let t=1/0;for(let n=0;n<256;n++){let i=0;for(let t=0;t<9;t++)i+=(r[e*9+t]-r[o[n]*9+t])**2;i<t&&(t=i,s[e]=n)}}}let c=new Int8Array(o.length*9);return o.forEach((e,t)=>c.set(i(e),t*9)),{book:c,labels:s}}function ae(e,t){let{count:n,position:i,rotation:o,scale:s,alpha:c,dc:l,sh:u}=e,d=[1/0,1/0,1/0],f=[-1/0,-1/0,-1/0],p=[...d],m=[...f],h=[...d],g=[...f];for(let e=0;e<n;e++)for(let t=0;t<3;t++)d[t]=Math.min(d[t],i[e*3+t]),f[t]=Math.max(f[t],i[e*3+t]),p[t]=Math.min(p[t],s[e*3+t]),m[t]=Math.max(m[t],s[e*3+t]),h[t]=Math.min(h[t],l[e*3+t]),g[t]=Math.max(g[t],l[e*3+t]);let _=5e-4*2**t.g,v=Float32Array.from(d),y=Float32Array.from(d,(e,t)=>Math.max(_,(f[t]-e)/65535)),b=new Uint16Array(n*3);for(let e=0;e<n;e++)for(let t=0;t<3;t++){let n=(i[e*3+t]-v[t])/y[t];b[e*3+t]=V(Math.round(n),0,65535)}let S=r*2**t.g,C=(t.i+.5)*S,w=(t.j+.5)*S,T=new Uint8Array(n),E=new Float64Array(n);for(let e=0;e<n;e++){let t=+(i[e*3]>=C),n=+(i[e*3+1]>=w);T[e]=t+2*n,E[e]=T[e]*2**30+ne(b[e*3],b[e*3+1],b[e*3+2])}let D=Uint32Array.from({length:n},(e,t)=>t).sort((e,t)=>E[e]-E[t]),O=[0,0,0];for(let e=1;e<4;e++)O[e-1]=T.filter(t=>t<e).length;let k=u?re(u,n):/* @__PURE__ */ new Float32Array(9),{book:A,labels:j}=u?ie(u,n,k):{book:null,labels:null},M=A?A.length/9:0,N=17+(M>0?2:0),P=new Uint8Array(128+N*n+M*9),F=new DataView(P.buffer);F.setUint32(0,n,!0),O.forEach((e,t)=>F.setUint32(4+4*t,e,!0)),F.setUint16(16,M,!0),[...v,...y,...p,...m,...h,...g,...k].forEach((e,t)=>F.setFloat32(20+4*t,e,!0));let I=e=>128+e*n,L=new Float32Array([...d,...f]),R=/* @__PURE__ */ new Float64Array(4),z=/* @__PURE__ */ new Float64Array(3),B=[0,0,0];for(let e=0;e<n;e++){let t=D[e];for(let n=0;n<3;n++){let r=b[t*3+n]-B[n]<<16>>16,i=r<0?-2*r-1:2*r;B[n]=b[t*3+n],P[I(a.position+2*n)+e]=i&255,P[I(a.position+2*n+1)+e]=i>>8}P[I(a.alpha)+e]=V(Math.round(c[t]*255),0,255);let n=Math.hypot(...o.subarray(t*4,t*4+4));for(let e=0;e<4;e++)R[e]=o[t*4+e]/n;let r=0;for(let e=1;e<4;e++)Math.abs(R[e])>Math.abs(R[r])&&(r=e);let u=R[r]<0?-1:1;P[I(a.rotationIndex)+e]=r;for(let t=0,n=0;t<4;t++){if(t===r)continue;let i=Math.round((u*R[t]/Math.SQRT2+.5)*255);P[I(a.rotation+n++)+e]=V(i,0,255)}for(let n=0;n<3;n++)P[I(a.scale+n)+e]=ee(s[t*3+n],p[n],m[n]),P[I(a.dc+n)+e]=ee(l[t*3+n],h[n],g[n]);j&&(P[I(a.label)+e]=j[t]&255,P[I(a.label+1)+e]=j[t]>>8);let[d,f,_]=[0,1,2].map(e=>Math.exp(s[t*3+e]));x(R,d,f,_,z);for(let e=0;e<3;e++)L[e]=Math.min(L[e],i[t*3+e]-z[e]),L[3+e]=Math.max(L[3+e],i[t*3+e]+z[e])}return A&&P.set(new Uint8Array(A.buffer),I(N)),{payload:P,row:{g:t.g,i:t.i,j:t.j,count:n,quadrants:O,box:L,offset:0,length:0}}}function oe(e,t,n){e.setUint8(t,n.g),e.setUint8(t+1,n.i),e.setUint8(t+2,n.j),e.setUint32(t+4,n.count,!0),n.quadrants.forEach((n,r)=>e.setUint32(t+8+4*r,n,!0)),n.box.forEach((n,r)=>e.setFloat32(t+20+4*r,n,!0)),e.setUint32(t+44,n.offset,!0),e.setUint32(t+48,n.length,!0)}function se(e,t,n){for(let r=0;r<4;r++)e[t+r]=n.charCodeAt(r)}function U(e){return Uint8Array.from({length:8},(t,n)=>parseInt(e.slice(2*n,2*n+2),16))}async function ce(e,t){let n=await l(e),r=new Uint8Array(8+n.length);return se(r,0,t),new DataView(r.buffer).setUint16(4,1,!0),r.set(n,8),r}async function le(e){let{rows:t,children:n,descendants:r}=e,a=new Uint8Array(40+t.length*52+n.length*9+r.length*11),o=new DataView(a.buffer);o.setUint8(0,e.level),o.setInt32(4,e.e,!0),o.setInt32(8,e.n,!0),a.set(U(e.pack),12),o.setUint32(20,e.packSize,!0),e.col&&a.set(U(e.col),24),o.setUint16(32,t.length,!0),o.setUint8(34,n.length),o.setUint16(36,r.length,!0);let s=40;for(let e of t)oe(o,s,e),s+=52;for(let e of n)o.setUint8(s,e.quadrant),a.set(U(e.idx),s+1),s+=9;for(let e of r)o.setUint8(s,e.depth),o.setUint8(s+1,e.column),o.setUint8(s+2,e.row),a.set(U(e.idx),s+3),s+=11;return ce(a,i)}function ue(e){let t=3421674724,n=2216829733;for(let r=0;r<e.length;r++){n=(n^e[r])>>>0;let i=n*435;t=t*435+(n<<8>>>0)+Math.floor(i/4294967296)>>>0,n=i>>>0}return t.toString(16).padStart(8,`0`)+n.toString(16).padStart(8,`0`)}function de(e){return()=>{e=e+1831565813|0;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/2**32}}let W=16384,fe=1408,pe=65535,G=324121,me=.4,he=[[12,1/7e3,0,1/9e3,.7],[9,1/2300,1.1,1/3100,.4],[6,1/800,.3,1/1100,2],[3,1/150,.9,1/210,1.7]],ge=he.reduce((e,[t,n,,r])=>e+t*(n+r),0),_e=Float32Array.from({length:fe*9},(e,t)=>{let n=Math.floor(t/9),r=t%9,i=(n*(37+2*r)+11*r)%255-127;return r===0&&(i=n%255-127),r===1&&(i=20*Math.floor(n/255)-50),i/127*.04}),K=new TextEncoder,ve={version:1,crs:`synthetic`,height:`synthetic`,leaf:250,roots:[512e4,6144e3].map(e=>({level:12,e:0,n:e})).map(e=>({...e,idx:m(e,q(e,`idx`),`idx`)})),extent:{e:[44e4,9e5],n:[605e4,641e4],h:[0,80]}},ye=K.encode(JSON.stringify(ve));function be(){return async(t,n)=>{if(t.endsWith(`world.json`))return Se(ye,n);let r=g(t),i=t.slice(t.lastIndexOf(`.`)+1);if(!r||i!==`idx`&&i!==`pack`||!Ce(r)||r.hash!==q(r,i))throw new e(`no file ${t}`);return i===`idx`?Se(await ke(r),n):Ae(r,n,t)}}function xe(e,t){let n=30;for(let[r,i,a,o,s]of he)n+=r*Math.sin(i*e+a)*Math.sin(o*t+s);return n}function Se(e,t){return t?e.slice(t[0],t[1]):e.slice()}function q(e,t){return ue(K.encode(`${e.level}/${e.e}/${e.n}.${t}`))}function J(e,t,n){let{e:r,n:i}=ve.extent;return e<r[1]&&e+n>r[0]&&t<i[1]&&t+n>i[0]}function Ce({level:e,e:t,n}){let r=250*2**e;return e<=12&&t%r===0&&n%r===0&&J(t,n,r)}function we(e){return e===0?[1,0]:e===12?[16,15,14,13]:[e+1]}function Te(e){let t=0;for(let n=0;n<8;n++)t|=(e>>2*n&1)<<n;return t}function Ee(e){let t=[];for(let n of we(e.level)){let i=r*2**n,a=250*2**e.level/i;for(let r=0;r<a*a;r++){let a=Te(r),o=Te(r>>1);J(e.e+a*i,e.n+o*i,i)&&t.push({g:n,i:a,j:o})}}return t}function De(e,t){let n=e.level-t,r=250*2**n,i=[];for(let a=0;n>=0&&a<2**t;a++)for(let o=0;o<2**t;o++){let t={level:n,e:e.e+o*r,n:e.n+a*r};J(t.e,t.n,r)&&i.push({column:o,row:a,unit:t})}return i}function Oe(e,{g:t,i:n,j:i},a){let o=r*2**t,s=o/128,c=3*1.2*s,l=1.17*s,u=xe(e.e+(n+.5)*o,e.n+(i+.5)*o),d=ge*o/2,f=Float32Array.of(n*o-c,i*o-c,Math.max(0,u-d)-l,(n+1)*o+c,(i+1)*o+c,Math.min(60,u+d)+l),p=W/4;return{g:t,i:n,j:i,count:W,quadrants:[p,2*p,3*p],box:f,offset:a,length:G}}function ke(e){let t=Ee(e),n=[];for(let{column:t,row:r,unit:i}of De(e,1))n.push({quadrant:t+2*r,idx:q(i,`idx`)});let r=[];for(let t of[2,3])for(let{column:n,row:i,unit:a}of De(e,t))r.push({depth:t,column:n,row:i,idx:q(a,`idx`)});return le({level:e.level,e:e.e,n:e.n,pack:q(e,`pack`),packSize:t.length*324173+16,col:null,rows:t.map((t,n)=>Oe(e,t,n*G)),children:n,descendants:r})}function Ae(e,t,n){let r=Ee(e);if(!t||t[0]%G!=0||t[1]%G!=0||t[0]>=t[1]||t[1]>r.length*G)throw Error(`${n}: the synthetic world serves whole pages only`);let i=new Uint8Array(t[1]-t[0]);for(let n=0;n<i.length;n+=G)je(Ne(e,r[(t[0]+n)/G]),i,n);return i}function je(e,t,n){let r=n;for(let n=0;n<e.length;n+=pe){let i=Math.min(pe,e.length-n);t[r]=+(n+i===e.length),t[r+1]=i&255,t[r+2]=i>>8,t[r+3]=~i&255,t[r+4]=~i>>8&255,t.set(e.subarray(n,n+i),r+5),r+=5+i}}let Me=e=>de(parseInt(ue(K.encode(e)).slice(8),16));function Ne(e,{g:t,i,j:a}){let o=W,s=r*2**t/128,c=Me(`${e.level}/${e.e}/${e.n}/${t}/${i}/${a}`),l=new Float64Array(3*o),u=new Float32Array(4*o),d=new Float32Array(3*o),f=new Float32Array(o),p=new Float32Array(3*o),m=new Float32Array(9*o);for(let t=0;t<o;t++){let r=(i*128+t%128+.5+me*(2*c()-1))*s,o=(a*128+Math.floor(t/128)+.5+me*(2*c()-1))*s,h=xe(e.e+r,e.n+o);l[3*t]=r,l[3*t+1]=o,l[3*t+2]=h;let g=Math.PI*c(),_=.1/2*(2*c()-1);u[4*t]=Math.cos(g)*Math.cos(_),u[4*t+1]=Math.cos(g)*Math.sin(_),u[4*t+2]=Math.sin(g)*Math.sin(_),u[4*t+3]=Math.sin(g)*Math.cos(_);for(let e=0;e<2;e++)d[3*t+e]=Math.log(s*(.6+.6*c()));d[3*t+2]=Math.log(s*.15*(.5+.5*c())),f[t]=.35+.65*c();let v=h/60,y=.5+.5*Math.sin((e.e+r)/410)*Math.sin((e.n+o)/330);p[3*t]=(.32+.2*v+.1*y-.5)/n,p[3*t+1]=(.42+.15*y-.1*v-.5)/n,p[3*t+2]=(.25+.1*v+.04*c()-.5)/n;let b=t%fe;m.set(_e.subarray(9*b,9*(b+1)),9*t)}return ae({count:o,position:l,rotation:u,scale:d,alpha:f,dc:p,sh:m},{g:t,i,j:a}).payload}let Y=2**20,X=self,Z,Pe=/* @__PURE__ */ new Map,Q=/* @__PURE__ */ new Map,Fe=B(e=>X.postMessage(e,[]));X.onmessage=({data:e})=>{`fetched`in e?Fe.take(e):e.type===`init`?(Z=Ie(e),Z.catch(()=>void 0)):e.type===`abort`?Q.get(e.id)?.abort():Re(e)};async function Ie(e){return e.source===`synthetic`?{fetch:be(),cache:await $({...e,cache:`none`}),base:e.base}:{fetch:e.source===`page`?Fe.fetch:t,cache:await $(e),base:e.base}}async function $({cache:e,shard:t,shards:n}){return e===`memory`?N(256*Y):e===`none`?{get:async()=>void 0,put:async()=>void 0}:(t===0&&F(n),await P(await Le()/n,t)??N(256*Y))}async function Le(){try{let{quota:e}=await navigator.storage.estimate();return Math.min(4096*Y,e===void 0?1/0:e/2)}catch{return 4096*Y}}async function Re(t){let{id:n}=t,r=new AbortController;Q.set(n,r);try{if(!Z)throw Error(`stream worker used before init`);let e=await Z;if(t.type===`idx`)X.postMessage({id:n,value:await O(e,t.path)},[]);else{for await(let i of k(e,t.batch,Pe,r.signal))X.postMessage({id:n,page:i},ze(i));X.postMessage({id:n,done:!0},[])}}catch(t){let r=t instanceof Error?t.message:String(t);X.postMessage({id:n,error:r,missing:t instanceof e},[])}finally{Q.delete(n)}}function ze({page:e}){let t=/* @__PURE__ */ new Set;for(let n of[e.geometry,e.colour,e.params,e.clusters])t.add(n.buffer);return[...t]}})();", ut = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", lt], { type: "text/javascript;charset=utf-8" });
1880
- function dt(e) {
1881
- let t;
1882
- try {
1883
- if (t = ut && (self.URL || self.webkitURL).createObjectURL(ut), !t) throw "";
1884
- let n = new Worker(t, { name: e?.name });
1885
- return n.addEventListener("error", () => {
1886
- (self.URL || self.webkitURL).revokeObjectURL(t);
1887
- }), n;
1888
- } catch {
1889
- return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(lt), { name: e?.name });
1890
- }
1891
- }
1892
- //#endregion
1893
- //#region src/engine/stream/loader.ts
1894
- var ft = class {
1895
- #e;
1896
- #t = /* @__PURE__ */ new Map();
1897
- #n = 0;
1898
- constructor(e) {
1899
- let { base: t, cache: n, source: r, workers: i } = e;
1900
- this.#e = Array.from({ length: i }, (e, a) => {
1901
- let o = new dt(), s = { worker: o }, c = typeof r == "function" ? ct(r, (e, t) => o.postMessage(e, t)) : void 0;
1902
- o.onmessage = ({ data: e }) => {
1903
- "id" in e ? this.#i(e) : c?.(e);
1904
- }, o.onerror = () => this.#a(s);
1905
- let l = {
1906
- type: "init",
1907
- base: t,
1908
- cache: n,
1909
- source: typeof r == "function" ? "page" : r,
1910
- shard: a,
1911
- shards: i
1912
- };
1913
- return o.postMessage(l), s;
1914
- });
1915
- }
1916
- idx(e) {
1917
- let t = {
1918
- type: "idx",
1919
- id: ++this.#n,
1920
- path: e
1921
- };
1922
- return this.#r(this.#e[0], t);
1923
- }
1924
- batch(e, t, n) {
1925
- if (t.aborted) return Promise.reject(K());
1926
- let r = this.#e[pt(`${e.pack}#${e.window}`, this.#e.length)], i = {
1927
- type: "batch",
1928
- id: ++this.#n,
1929
- batch: e
1930
- };
1931
- return this.#r(r, i, t, n);
1932
- }
1933
- destroy() {
1934
- for (let { worker: e } of this.#e) e.terminate();
1935
- for (let e of this.#t.values()) e.reject(K());
1936
- }
1937
- #r(e, t, n, r) {
1938
- if (e.error) return Promise.reject(e.error);
1939
- let { id: i } = t;
1940
- return new Promise((a, o) => {
1941
- let s = () => {
1942
- this.#t.delete(i), n?.removeEventListener("abort", c);
1943
- }, c = () => {
1944
- s(), e.worker.postMessage({
1945
- type: "abort",
1946
- id: i
1947
- }), o(K());
1948
- };
1949
- this.#t.set(i, {
1950
- slot: e,
1951
- page: r,
1952
- resolve: (e) => {
1953
- s(), a(e);
1954
- },
1955
- reject: (e) => {
1956
- s(), o(e);
1957
- }
1958
- }), n?.addEventListener("abort", c, { once: !0 }), e.worker.postMessage(t);
1959
- });
1960
- }
1961
- #i(e) {
1962
- let t = this.#t.get(e.id);
1963
- t && ("page" in e ? t.page?.(e.page) : "error" in e ? t.reject(e.missing ? new o(e.error) : Error(e.error)) : t.resolve("value" in e ? e.value : void 0));
1964
- }
1965
- #a(e) {
1966
- e.error = /* @__PURE__ */ Error("a stream worker failed");
1967
- for (let t of this.#t.values()) t.slot === e && t.reject(e.error);
1968
- }
1969
- };
1970
- function pt(e, t) {
1971
- let n = 2166136261;
1972
- for (let t = 0; t < e.length; t++) n = Math.imul(n ^ e.charCodeAt(t), 16777619);
1973
- return (n >>> 0) % t;
1974
- }
1975
- function K() {
1976
- return new DOMException("The request was aborted.", "AbortError");
1977
- }
1978
- //#endregion
1979
- //#region src/engine/engine.ts
1980
- var mt = class extends Error {
1981
- constructor() {
1982
- super("This viewer needs WebGPU. Update to the latest Chrome, Edge, Safari or Firefox."), this.name = "NoWebGpu";
1983
- }
1984
- };
1985
- async function ht(e, t) {
1986
- let n = await p();
1987
- if (!n) throw new mt();
1988
- let r = e.getContext("webgpu");
1989
- if (!r) throw n.device.destroy(), new mt();
1990
- r.configure({
1991
- device: n.device,
1992
- format: n.format,
1993
- alphaMode: "opaque"
1994
- }), (t.cache ?? "opfs") === "opfs" && navigator.storage?.persist().catch(() => !1);
1995
- let { source: i = "http" } = t;
1996
- return new zt(e, n, r, t, i === "synthetic" ? (await import("./synthetic-BeGCzYIv.js")).synthetic() : i === "http" ? s : i);
1997
- }
1998
- var gt = .2, _t = 25165824, vt = 3.25, yt = 2, bt = 1024, xt = 2048, St = 100, Ct = 2, wt = 300, Tt = 100, Et = 250, Dt = 300, Ot = 1e3, kt = 400, At = 5e3, jt = 60, q = Math.PI / 180, Mt = "The viewer was closed.", Nt = "Another world was opened.";
1999
- function Pt(e, t) {
2000
- let n = Math.min(t.maxStorageBufferBindingSize, t.maxBufferSize), r = (t, r) => {
2001
- let i = Math.ceil(e * t / 256) * 256;
2002
- return Math.min(i, Math.floor(n / r / 256) * 256);
2003
- };
2004
- return {
2005
- pool: r(vt, 16),
2006
- frame: r(yt, 24)
2007
- };
2008
- }
2009
- function Ft(e, t) {
2010
- let [n, r, i] = t;
2011
- if (Math.hypot(n - e[0], r - e[1], i - e[2]) <= xt) return e;
2012
- let a = (e) => Math.round(e / bt) * bt;
2013
- return [
2014
- a(n),
2015
- a(r),
2016
- a(i)
2017
- ];
2018
- }
2019
- function It(e, t, n, r, i, a) {
2020
- let o = 2 * e[0] / t[0] - 1, s = 1 - 2 * e[1] / t[1], c = [
2021
- n * o / r[0],
2022
- n * s / r[5],
2023
- -n
2024
- ], [l, u, d] = w(C(/* @__PURE__ */ new Float64Array(16), i), c);
2025
- return [
2026
- l + a[0],
2027
- u + a[1],
2028
- d + a[2]
2029
- ];
2030
- }
2031
- function Lt(e, t) {
2032
- return [
2033
- e.e - t[0],
2034
- e.n - t[1],
2035
- e.h - t[2]
2036
- ];
2037
- }
2038
- function Rt(e, t) {
2039
- e.push(t), e.length > jt && e.shift();
2040
- }
2041
- var zt = class {
2042
- #e;
2043
- #t;
2044
- #n;
2045
- #r;
2046
- #i;
2047
- #a;
2048
- #o;
2049
- #s;
2050
- #c;
2051
- #l;
2052
- #u = new ze();
2053
- #d = new Ee();
2054
- #f = (e) => this.#s.has(e);
2055
- #p = null;
2056
- #m = null;
2057
- #h = null;
2058
- #g = null;
2059
- #_ = 0;
2060
- #v = !1;
2061
- #y = {
2062
- e: 0,
2063
- n: 0,
2064
- h: 0,
2065
- yaw: 0,
2066
- pitch: 0,
2067
- fov: 45
2068
- };
2069
- #b = -Infinity;
2070
- #x = [
2071
- 0,
2072
- 0,
2073
- 0
2074
- ];
2075
- #S = [
2076
- 0,
2077
- 0,
2078
- 0
2079
- ];
2080
- #C = /* @__PURE__ */ new Float64Array(16);
2081
- #w = /* @__PURE__ */ new Float64Array(16);
2082
- #T = /* @__PURE__ */ new Float64Array(16);
2083
- #E = /* @__PURE__ */ new Float64Array(16);
2084
- #D = /* @__PURE__ */ new Float32Array(24);
2085
- #O;
2086
- #k;
2087
- #A = 0;
2088
- #j = 0;
2089
- #M = !1;
2090
- #N = null;
2091
- #P = -Infinity;
2092
- #F = !0;
2093
- #I = !0;
2094
- #L = !1;
2095
- #R = !1;
2096
- #z = !1;
2097
- #B = [];
2098
- #V = -Infinity;
2099
- #H = -Infinity;
2100
- #U = -Infinity;
2101
- #W = [];
2102
- #G = [];
2103
- #K = [];
2104
- #q = [];
2105
- #J = [];
2106
- #Y = [];
2107
- #X = [];
2108
- #Z = /* @__PURE__ */ new Set();
2109
- #Q = /* @__PURE__ */ new Set();
2110
- #$ = !1;
2111
- #ee = !1;
2112
- #te = !1;
2113
- constructor(e, t, n, r, i) {
2114
- this.#e = e, this.#t = t, this.#n = n, this.#r = r, this.#i = i, this.#a = { ...r.settings }, this.#o = this.#re(), this.#O = [
2115
- e.width,
2116
- e.height,
2117
- 1
2118
- ], this.#k = [Math.max(1, e.width), Math.max(1, e.height)];
2119
- let { pool: a, frame: o } = Pt(this.#ne, t.device.limits);
2120
- this.#s = new _(t.device, a), this.#c = new Ce(t, n, this.#s, o), this.#l = o, t.device.lost.then((e) => {
2121
- if (!this.#ee) {
2122
- this.#te = !0, cancelAnimationFrame(this.#A);
2123
- for (let t of this.#Z) t(e.message || e.reason);
2124
- }
2125
- });
2126
- }
2127
- async open(e) {
2128
- if (this.#ee) throw Error(Mt);
2129
- let t = ++this.#_, i = () => {
2130
- if (this.#ee) throw Error(Mt);
2131
- if (t !== this.#_) throw Error(Nt);
2132
- }, { cache: a = "opfs", source: o = "http" } = this.#r;
2133
- o === "http" && (e = new URL(e, document.baseURI).href);
2134
- let s = await this.#i(e, null), c = r(JSON.parse(new TextDecoder().decode(s)));
2135
- i();
2136
- let l = new ft({
2137
- base: n(e),
2138
- workers: Math.min(6, Math.max(2, navigator.hardwareConcurrency - 2)),
2139
- cache: a,
2140
- source: o
2141
- }), u = new Fe(c);
2142
- try {
2143
- let e = await Promise.all(c.roots.map((e) => l.idx(e.idx)));
2144
- i(), e.forEach((e, t) => u.add(e, c.roots[t].idx));
2145
- } catch (e) {
2146
- throw l.destroy(), e;
2147
- }
2148
- return this.#g?.destroy(), this.#g = null, this.#h?.destroy(), this.#p = e, this.#m = u, this.#h = l, this.#N = null, this.#u = new ze(), this.#d = new Ee(), this.#s.clear(), this.#g = this.#oe(u, l), this.#I = !0, this.requestFrame(), c;
2149
- }
2150
- setCamera(e) {
2151
- if (this.#ee) return;
2152
- let t = performance.now(), n = t - this.#b, r = this.#y, i = this.#x;
2153
- if (n > Et) i.fill(0);
2154
- else if (n > 0) {
2155
- let t = 1 - Math.exp(-n / Tt);
2156
- i[0] += t * ((e.e - r.e) / n - i[0]), i[1] += t * ((e.n - r.n) / n - i[1]), i[2] += t * ((e.h - r.h) / n - i[2]);
2157
- }
2158
- this.#b = t, this.#y = { ...e }, this.#F = !0, this.#$ || this.requestFrame();
2159
- }
2160
- configure(e) {
2161
- if (this.#ee) return;
2162
- let { budget: t, budgetRange: n } = this.#a;
2163
- this.#a = {
2164
- ...this.#a,
2165
- ...e
2166
- };
2167
- let r = this.#a;
2168
- (r.budget !== t || !((e, t) => e?.join() === t?.join())(r.budgetRange, n)) && (this.#o = this.#re(), this.#le()), this.#ie();
2169
- }
2170
- resize(e, t, n) {
2171
- this.#ee || (this.#O = [
2172
- e,
2173
- t,
2174
- n
2175
- ], this.#le());
2176
- }
2177
- pick(e, t) {
2178
- if (this.#ee || this.#te) return Promise.resolve(null);
2179
- let [n, r] = this.#k, [i, a] = this.#O, o = e * n / Math.max(1, i), s = t * r / Math.max(1, a);
2180
- return new Promise((e) => {
2181
- this.#J.push({
2182
- x: o,
2183
- y: s,
2184
- resolve: e
2185
- }), this.requestFrame();
2186
- });
2187
- }
2188
- ground(e, t) {
2189
- return this.#m?.ground(e, t);
2190
- }
2191
- async groundAt(e, t) {
2192
- let n = this.#m, r = this.#h;
2193
- if (n && r) return await n.load(e, t, (e) => r.idx(e)), this.#R = !0, this.requestFrame(), n.ground(e, t);
2194
- }
2195
- heights(e, t, n) {
2196
- return this.#ee || this.#te ? Promise.resolve(null) : new Promise((r) => {
2197
- this.#Y.push({
2198
- west: e,
2199
- south: t,
2200
- cells: n,
2201
- resolve: r
2202
- }), this.requestFrame();
2203
- });
2204
- }
2205
- stats() {
2206
- let e = this.#s, t = this.#g, n = this.#c.stats();
2207
- return {
2208
- frameMs: $e(this.#W, .5),
2209
- cpuMs: $e(this.#G, .5),
2210
- gpuMs: n.gpuMs,
2211
- passes: n.passes,
2212
- drawn: n.drawn,
2213
- planned: this.#N?.planned ?? 0,
2214
- missing: this.#N?.missing ?? 0,
2215
- pages: {
2216
- resident: Array.from(e.ids()).length,
2217
- drawn: this.#B.length,
2218
- loading: t?.loading ?? 0,
2219
- queued: t?.queued ?? 0
2220
- },
2221
- memory: {
2222
- pool: e.bytes,
2223
- buffers: n.bytes
2224
- },
2225
- capacity: e.capacity,
2226
- budget: this.#ne,
2227
- scale: this.#o.scale,
2228
- loading: t !== null && !t.idle
2229
- };
2230
- }
2231
- idle() {
2232
- return this.#ee ? Promise.resolve() : new Promise((e) => {
2233
- this.#X.push(e), this.requestFrame();
2234
- });
2235
- }
2236
- use(e) {
2237
- if (this.#ee) return () => {};
2238
- let t = e({
2239
- shade: (e) => this.#ce(this.#K, e, this.#c.shade(e)),
2240
- post: (e) => this.#ce(this.#q, e, this.#c.post(e))
2241
- });
2242
- return () => {
2243
- this.#ee || t();
2244
- };
2245
- }
2246
- warm() {
2247
- let e = performance.now();
2248
- e - this.#V < Ot || (this.#H = e + kt, this.requestFrame());
2249
- }
2250
- onFrame(e) {
2251
- return this.#Q.add(e), () => this.#Q.delete(e);
2252
- }
2253
- onLost(e) {
2254
- return this.#Z.add(e), () => this.#Z.delete(e);
2255
- }
2256
- requestFrame() {
2257
- this.#ee || this.#te || this.#r.manual || this.#A || (this.#A = requestAnimationFrame(this.#ue));
2258
- }
2259
- async step() {
2260
- if (this.#ee || this.#te) return {
2261
- cpuMs: 0,
2262
- gpuMs: 0,
2263
- passes: {}
2264
- };
2265
- let { done: e, cpuMs: t } = this.#de(!1);
2266
- await e;
2267
- let { gpuMs: n, passes: r } = this.#c.stats();
2268
- return {
2269
- cpuMs: t,
2270
- gpuMs: n,
2271
- passes: r
2272
- };
2273
- }
2274
- destroy() {
2275
- if (!this.#ee) {
2276
- this.#ee = !0, cancelAnimationFrame(this.#A), this.#g?.destroy(), this.#h?.destroy(), this.#c.destroy(), this.#s.destroy();
2277
- for (let { resolve: e } of this.#J.splice(0)) e(null);
2278
- for (let { resolve: e } of this.#Y.splice(0)) e(null);
2279
- for (let e of this.#X.splice(0)) e();
2280
- this.#t.device.destroy();
2281
- }
2282
- }
2283
- get #ne() {
2284
- return this.#o.budget;
2285
- }
2286
- #re() {
2287
- let { budget: e, budgetRange: t = [e, e] } = this.#a, n = Math.floor(Pt(Infinity, this.#t.device.limits).frame / yt), r = (e) => Math.max(1, Math.min(e, n));
2288
- return new et(r(e), [r(t[0]), r(t[1])]);
2289
- }
2290
- #ie() {
2291
- let { pool: e, frame: t } = Pt(this.#ne, this.#t.device.limits);
2292
- (e > this.#s.capacity || t > this.#l) && this.#ae(e, t), this.#I = !0, this.requestFrame();
2293
- }
2294
- #ae(e, t) {
2295
- this.#s.grow(e), this.#c.destroy();
2296
- let n = new Ce(this.#t, this.#n, this.#s, t);
2297
- n.resize(...this.#k);
2298
- for (let e of this.#K) e.off = n.shade(e.hook);
2299
- for (let e of this.#q) e.off = n.post(e.hook);
2300
- this.#c = n, this.#l = t;
2301
- }
2302
- #oe(e, t) {
2303
- return new st(e, t, this.#s, () => {
2304
- this.#R = !0, this.requestFrame();
2305
- }, this.#se);
2306
- }
2307
- #se = () => {
2308
- let e = this.#p, t = this.#m;
2309
- this.#v || this.#ee || e === null || (this.#v = !0, this.open(e).then(() => this.#v = !1, () => {
2310
- this.#v = !1, this.#m === t && setTimeout(this.#se, At);
2311
- }));
2312
- };
2313
- #ce(e, t, n) {
2314
- let r = {
2315
- hook: t,
2316
- off: n
2317
- };
2318
- return e.push(r), this.requestFrame(), () => {
2319
- let t = e.indexOf(r);
2320
- this.#ee || t < 0 || (e.splice(t, 1), r.off(), this.requestFrame());
2321
- };
2322
- }
2323
- #le() {
2324
- let [e, t, n] = this.#O, r = Qe(e, t, n, this.#o.scale), i = Math.max(1, Math.round(e * r)), a = Math.max(1, Math.round(t * r));
2325
- (i !== this.#k[0] || a !== this.#k[1]) && (this.#k = [i, a], this.#e.width = i, this.#e.height = a, this.#c.resize(i, a), this.#I = !0, this.requestFrame());
2326
- }
2327
- #ue = (e) => {
2328
- if (this.#A = 0, !(this.#ee || this.#te)) {
2329
- if (this.#j >= Ct) this.#M = !0;
2330
- else {
2331
- this.#$ = !0;
2332
- for (let t of this.#Q) t(e);
2333
- this.#$ = !1, this.#j++, this.#de(!0).done.finally(() => {
2334
- this.#j--, this.#M && (this.#M = !1, this.requestFrame());
2335
- });
2336
- }
2337
- }
2338
- };
2339
- #de(e) {
2340
- let t = performance.now(), n = this.#o, r = this.#s, i = this.#y, [a, o] = this.#k, s = this.#a.viewDistance, c = this.#F;
2341
- this.#F = !1;
2342
- let l = Ft(this.#S, [
2343
- i.e,
2344
- i.n,
2345
- i.h
2346
- ]);
2347
- l !== this.#S && (this.#S = l, r.setOrigin(l));
2348
- let u = Lt(i, l);
2349
- y(this.#C, u, i.yaw * q, i.pitch * q), b(this.#w, i.fov * q, a / o, gt, s);
2350
- let d = {
2351
- time: t,
2352
- width: a,
2353
- height: o,
2354
- view: new Float32Array(this.#C),
2355
- proj: new Float32Array(this.#w),
2356
- near: gt,
2357
- far: s,
2358
- camera: Float32Array.from(u),
2359
- origin: l
2360
- };
2361
- Te(this.#D, S(this.#E, d.proj, d.view));
2362
- let f = this.#m, p = this.#g, m = this.#R || this.#I || this.#z, h = this.#N, g = h;
2363
- if (f && p) {
2364
- let e = !p.idle && t - this.#P >= St, n = this.#I || this.#R || this.#z || this.#L;
2365
- (!g || c || e || n) && (g = this.#fe(f, t, c));
2366
- }
2367
- let _ = this.#B, v = this.#z;
2368
- g && p && (g !== h && (m || !h || g.cut.length !== h.cut.length || g.cut.some((e, t) => e !== h.cut[t])) && ({drawn: _, fading: v} = this.#d.update(g.cut, this.#f, t, this.#ne)), p.update(g, new Set(_.map((e) => e.id)), t)), r.upload(_t) > 0 && (this.#R = !0), (_ !== this.#B || this.#R) && r.draw(_), this.#z = v, this.#B = _;
2369
- let x = this.#J.splice(0).map((e) => this.#me(e, d)), C = this.#Y.splice(0).map((e) => this.#he(e, l)), w = this.#c.render(d, this.#D, this.#r.sky, x, C), T = performance.now() - t;
2370
- if (!this.#R && !this.#L && !v && r.queued === 0 && (!p || p.idle) && (!g || g.load.length === 0 && g.idx.length === 0) && this.#X.length) {
2371
- let e = this.#X.splice(0);
2372
- w.then(() => e.forEach((e) => e()));
2373
- }
2374
- e && this.#ge(t, T, c);
2375
- let E = t < this.#H;
2376
- return (r.queued > 0 || this.#R || this.#L || v || n.scale < 1 || E) && this.requestFrame(), {
2377
- done: w,
2378
- cpuMs: T
2379
- };
2380
- }
2381
- #fe(e, t, n) {
2382
- let r = this.#y, i = this.#s, [a, o] = this.#k, s = this.#o.scale, c = this.#ne, l = {
2383
- origin: this.#S,
2384
- width: a / s,
2385
- height: o / s,
2386
- tan: Math.tan(r.fov * q / 2),
2387
- near: gt,
2388
- far: this.#a.viewDistance
2389
- }, u = {
2390
- ...l,
2391
- view: this.#C
2392
- }, d = {
2393
- budget: c,
2394
- capacity: i.capacity - Math.ceil(1 * c),
2395
- now: t,
2396
- predicted: n ? this.#pe(l) : void 0
2397
- }, f = this.#u.plan(e, u, this.#f, d);
2398
- return this.#N = f, this.#P = t, this.#I = !1, this.#L = d.predicted !== void 0, this.#R = !1, f;
2399
- }
2400
- #pe(e) {
2401
- let t = this.#x;
2402
- if (t.every((e) => e === 0)) return;
2403
- let n = this.#y, r = [
2404
- n.e + t[0] * wt - e.origin[0],
2405
- n.n + t[1] * wt - e.origin[1],
2406
- n.h + t[2] * wt - e.origin[2]
2407
- ];
2408
- return {
2409
- ...e,
2410
- view: y(this.#T, r, n.yaw * q, n.pitch * q)
2411
- };
2412
- }
2413
- #me({ x: e, y: t, resolve: n }, r) {
2414
- let i = this.#C.slice(), a = this.#S, o = [r.width, r.height], s = (n) => It([e, t], o, n, r.proj, i, a);
2415
- return {
2416
- x: e,
2417
- y: t,
2418
- resolve: (e) => n(e === null ? null : s(e))
2419
- };
2420
- }
2421
- #he({ west: e, south: t, cells: n, resolve: r }, i) {
2422
- return {
2423
- x: e - i[0],
2424
- y: t - i[1],
2425
- cells: n,
2426
- resolve: (e) => {
2427
- if (e) for (let t = 0; t < e.length; t++) e[t] += i[2];
2428
- r(e);
2429
- }
2430
- };
2431
- }
2432
- #ge(e, t, n) {
2433
- let r = this.#o, { gpuMs: i } = this.#c.stats(), a = e - this.#V, o = a <= Math.max(Et, 2 * i, 2 * t);
2434
- o && Rt(this.#W, a), Rt(this.#G, t), this.#V = e;
2435
- let s = r.budget;
2436
- r.sample(a, e, o && n, this.#N?.planned ?? 0) && (this.#le(), r.budget !== s && this.#ie()), n ? this.#U = e : r.scale < 1 && e - this.#U > Dt && (r.full(), this.#le());
2437
- }
2438
- }, Bt = 45, Vt = {
2439
- yaw: 0,
2440
- pitch: -35,
2441
- dist: 300
2442
- }, J = {
2443
- pitch: [-90, -20],
2444
- dist: [1, 2485],
2445
- clearance: 10,
2446
- floor: 50
2447
- }, Ht = .1, Y = Math.PI / 180, Ut = (e, [t, n]) => Math.min(n, Math.max(t, e)), Wt = (e) => (e % 360 + 360) % 360, Gt = (e, t) => (t - e + 540) % 360 - 180;
2448
- function Kt({ leaf: e, roots: t, extent: n }) {
2449
- let r = {
2450
- e: (n.e[0] + n.e[1]) / 2,
2451
- n: (n.n[0] + n.n[1]) / 2,
2452
- h: n.h[0]
2453
- }, i = r, a = Infinity;
2454
- for (let o of t) {
2455
- let t = e * 2 ** o.level, [s, c] = [Math.max(o.e, n.e[0]), Math.min(o.e + t, n.e[1])], [l, u] = [Math.max(o.n, n.n[0]), Math.min(o.n + t, n.n[1])], d = Math.hypot(Math.max(s - r.e, 0, r.e - c), Math.max(l - r.n, 0, r.n - u));
2456
- if (d === 0) return r;
2457
- d < a && (a = d, i = {
2458
- e: (s + c) / 2,
2459
- n: (l + u) / 2,
2460
- h: n.h[0]
2461
- });
2462
- }
2463
- return i;
2464
- }
2465
- function qt(e) {
2466
- let t = e.split(",");
2467
- if (t.length !== 6 || t.some((e) => e.trim() === "")) return null;
2468
- let [n, r, i, a, o, s] = t.map(Number);
2469
- return ![
2470
- n,
2471
- r,
2472
- i,
2473
- a,
2474
- o,
2475
- s
2476
- ].every(Number.isFinite) || s <= 0 ? null : {
2477
- e: n,
2478
- n: r,
2479
- h: i,
2480
- yaw: a,
2481
- pitch: o,
2482
- dist: s
2483
- };
2484
- }
2485
- function Jt(e) {
2486
- let t = (e, t) => +e.toFixed(t);
2487
- return [
2488
- t(e.e, 2),
2489
- t(e.n, 2),
2490
- t(e.h, 2),
2491
- t(e.yaw, 1),
2492
- t(e.pitch, 1),
2493
- t(e.dist, 1)
2494
- ].join(",");
2495
- }
2496
- function X(e, t, n = J) {
2497
- let r = {
2498
- e: e.e,
2499
- n: e.n,
2500
- h: e.h,
2501
- yaw: Wt(e.yaw),
2502
- pitch: Ut(e.pitch, n.pitch),
2503
- dist: Ut(e.dist, n.dist)
2504
- };
2505
- if (t) {
2506
- let e = Z(r), i = Math.max(n.floor, t(e.e, e.n) + n.clearance);
2507
- if (e.h < i) return {
2508
- ...Qt({
2509
- ...e,
2510
- h: i
2511
- }, r),
2512
- yaw: r.yaw
2513
- };
2514
- }
2515
- return r;
2516
- }
2517
- function Yt(e, t) {
2518
- let n = Math.cos(t * Y);
2519
- return {
2520
- e: Math.sin(e * Y) * n,
2521
- n: Math.cos(e * Y) * n,
2522
- h: Math.sin(t * Y)
2523
- };
2524
- }
2525
- function Z(e) {
2526
- let t = Yt(e.yaw, e.pitch);
2527
- return {
2528
- e: e.e - t.e * e.dist,
2529
- n: e.n - t.n * e.dist,
2530
- h: e.h - t.h * e.dist
2531
- };
2532
- }
2533
- function Xt(e) {
2534
- return {
2535
- ...Z(e),
2536
- yaw: e.yaw,
2537
- pitch: e.pitch,
2538
- fov: 45
2539
- };
2540
- }
2541
- function Zt(e, t, n) {
2542
- let r = Z(e), [i, a, o] = [
2543
- n.e - r.e,
2544
- n.n - r.n,
2545
- n.h - r.h
2546
- ], [s, c] = [Math.sin(e.yaw * Y), Math.cos(e.yaw * Y)], [l, u] = [Math.sin(e.pitch * Y), Math.cos(e.pitch * Y)], d = i * s + a * c, f = 2 * Math.tan(t * Y / 2) * (d * u + o * l);
2547
- return {
2548
- x: (i * c - a * s) / f,
2549
- y: (d * l - o * u) / f
2550
- };
2551
- }
2552
- function Qt(e, t) {
2553
- let [n, r, i] = [
2554
- t.e - e.e,
2555
- t.n - e.n,
2556
- t.h - e.h
2557
- ], a = Math.hypot(n, r, i);
2558
- return {
2559
- e: t.e,
2560
- n: t.n,
2561
- h: t.h,
2562
- yaw: Wt(Math.atan2(n, r) / Y),
2563
- pitch: Math.asin(i / a) / Y,
2564
- dist: a
2565
- };
2566
- }
2567
- function $t(e, t, n, r = J) {
2568
- let i = Z(e), a = X({
2569
- ...e,
2570
- yaw: t,
2571
- pitch: n
2572
- }, void 0, r), o = Yt(a.yaw, a.pitch);
2573
- return {
2574
- ...a,
2575
- e: i.e + o.e * a.dist,
2576
- n: i.n + o.n * a.dist,
2577
- h: i.h + o.h * a.dist
2578
- };
2579
- }
2580
- function en(e) {
2581
- return e.dist * Math.max(Math.sin(-e.pitch * Y), Ht);
2582
- }
2583
- function Q(e, t, n, r) {
2584
- let [i, a] = [Math.sin(e.yaw * Y), Math.cos(e.yaw * Y)];
2585
- return {
2586
- ...e,
2587
- e: e.e + t * a + n * i,
2588
- n: e.n - t * i + n * a,
2589
- h: e.h + r
2590
- };
2591
- }
2592
- function tn(e, t, n) {
2593
- return Q(e, t, n * e.dist / en(e), 0);
2594
- }
2595
- function nn(e, t, n) {
2596
- return {
2597
- e: e.e + (t.e - e.e) * n,
2598
- n: e.n + (t.n - e.n) * n,
2599
- h: e.h + (t.h - e.h) * n,
2600
- yaw: Wt(e.yaw + Gt(e.yaw, t.yaw) * n),
2601
- pitch: e.pitch + (t.pitch - e.pitch) * n,
2602
- dist: e.dist * (t.dist / e.dist) ** n
2603
- };
2604
- }
2605
- function rn(e, t) {
2606
- let n = e.dist * 1e-5;
2607
- return Math.abs(e.e - t.e) < n && Math.abs(e.n - t.n) < n && Math.abs(e.h - t.h) < n && Math.abs(e.dist - t.dist) < n && Math.abs(Gt(e.yaw, t.yaw)) < .001 && Math.abs(e.pitch - t.pitch) < .001;
2608
- }
2609
- //#endregion
2610
- //#region src/controls/controls.ts
2611
- var an = .2, on = .002, sn = .005, cn = .5, ln = .05;
2612
- function un(e, t) {
2613
- return 2 * e * Math.tan(45 * Math.PI / 360) / Math.max(1, t);
2614
- }
2615
- function dn(e) {
2616
- let t = (t) => +!!e.has(t);
2617
- return [
2618
- t("KeyD") - t("KeyA") + t("ArrowRight") - t("ArrowLeft"),
2619
- t("KeyW") - t("KeyS") + t("ArrowUp") - t("ArrowDown"),
2620
- t("KeyE") - t("KeyQ")
2621
- ];
2622
- }
2623
- function fn(e, t, n, r, i = J) {
2624
- return rn(e, t) ? t : X(nn(e, t, 1 - Math.exp(-n / ln)), r, i);
2625
- }
2626
- var pn = class {
2627
- #e;
2628
- #t;
2629
- #n;
2630
- #r;
2631
- #i = new AbortController();
2632
- #a = /* @__PURE__ */ new Map();
2633
- #o = /* @__PURE__ */ new Set();
2634
- #s = [0, 0];
2635
- #c = [0, 0];
2636
- #l = 0;
2637
- #u = !1;
2638
- #d;
2639
- #f;
2640
- #p = /* @__PURE__ */ new Set();
2641
- #m;
2642
- #h = null;
2643
- constructor(e, t, n, r, i = J) {
2644
- this.#e = e, this.#t = t, this.#n = n, this.#r = i, this.#d = this.#E(r), this.#f = this.#d, this.#m = t.onFrame(this.#T);
2645
- let a = this.#i.signal;
2646
- e.addEventListener("pointerdown", this.#g, { signal: a }), e.addEventListener("pointermove", this.#_, { signal: a });
2647
- for (let t of [
2648
- "pointerup",
2649
- "pointercancel",
2650
- "lostpointercapture"
2651
- ]) e.addEventListener(t, this.#v, { signal: a });
2652
- e.addEventListener("wheel", this.#y, {
2653
- passive: !1,
2654
- signal: a
2655
- }), e.addEventListener("dblclick", this.#S, { signal: a }), e.addEventListener("contextmenu", (e) => e.preventDefault(), { signal: a }), window.addEventListener("keydown", this.#b, { signal: a }), window.addEventListener("keyup", this.#x, { signal: a }), window.addEventListener("blur", () => this.#o.clear(), { signal: a }), this.#D();
2656
- }
2657
- get pose() {
2658
- return { ...this.#f };
2659
- }
2660
- onChange(e) {
2661
- return this.#p.add(e), () => this.#p.delete(e);
2662
- }
2663
- moveTo(e, t) {
2664
- let n = this.#d, r = Math.min(n.dist, Vt.dist);
2665
- this.#d = this.#E({
2666
- ...n,
2667
- e,
2668
- n: t,
2669
- h: this.#n(e, t),
2670
- dist: r
2671
- }), this.#w();
2672
- }
2673
- destroy() {
2674
- this.#i.abort(), this.#m(), this.#p.clear();
2675
- }
2676
- #g = (e) => {
2677
- this.#e.setPointerCapture(e.pointerId), this.#a.set(e.pointerId, {
2678
- x: e.clientX,
2679
- y: e.clientY
2680
- });
2681
- };
2682
- #_ = (e) => {
2683
- let t = this.#a.get(e.pointerId);
2684
- if (!t) return this.#t.warm();
2685
- let n = this.#C(), [r, i] = [e.clientX - t.x, e.clientY - t.y];
2686
- if (t.x = e.clientX, t.y = e.clientY, e.pointerType === "mouse") {
2687
- let t = !!(e.buttons & 1);
2688
- e.buttons & 6 || t && e.shiftKey ? $(this.#c, r, i) : t && $(this.#s, r, i);
2689
- } else if (n) {
2690
- let e = this.#C();
2691
- $(this.#c, e.x - n.x, e.y - n.y), this.#l += (n.d - e.d) * sn;
2692
- } else $(this.#s, r, i);
2693
- this.#w();
2694
- };
2695
- #v = (e) => {
2696
- this.#a.delete(e.pointerId);
2697
- };
2698
- #y = (e) => {
2699
- e.preventDefault(), this.#l += e.deltaY * on, this.#w();
2700
- };
2701
- #b = (e) => {
2702
- e.code === "KeyF" && !e.repeat && (this.#u = !this.#u), this.#o.add(e.code), this.#u && this.#w();
2703
- };
2704
- #x = (e) => {
2705
- this.#o.delete(e.code);
2706
- };
2707
- #S = async (e) => {
2708
- let t = await this.#t.pick(e.offsetX, e.offsetY);
2709
- if (!t || this.#i.signal.aborted) return;
2710
- let [n, r, i] = t;
2711
- this.#d = X(Qt(Z(this.#f), {
2712
- e: n,
2713
- n: r,
2714
- h: i
2715
- }), void 0, this.#r), this.#w();
2716
- };
2717
- #C() {
2718
- if (this.#a.size < 2) return null;
2719
- let [e, t] = this.#a.values();
2720
- return {
2721
- x: (e.x + t.x) / 2,
2722
- y: (e.y + t.y) / 2,
2723
- d: Math.hypot(e.x - t.x, e.y - t.y)
2724
- };
2725
- }
2726
- #w() {
2727
- this.#i.signal.aborted || this.#t.requestFrame();
2728
- }
2729
- #T = (e) => {
2730
- let t = this.#h === null ? 1 / 60 : Math.min(.1, (e - this.#h) / 1e3);
2731
- this.#h = e;
2732
- let n = this.#d, [r, i] = this.#c;
2733
- if (r || i) {
2734
- let e = un(n.dist, this.#e.clientHeight);
2735
- n = tn(n, -r * e, i * e);
2736
- }
2737
- let [a, o] = this.#s;
2738
- if (a || o) {
2739
- let [e, t] = [n.yaw + a * an, n.pitch - o * an];
2740
- n = this.#u ? $t(n, e, t, this.#r) : X({
2741
- ...n,
2742
- yaw: e,
2743
- pitch: t
2744
- }, void 0, this.#r);
2745
- }
2746
- this.#l && (n = X({
2747
- ...n,
2748
- dist: n.dist * Math.exp(this.#l)
2749
- }, void 0, this.#r)), this.#c = [0, 0], this.#s = [0, 0], this.#l = 0;
2750
- let [s, c, l] = dn(this.#o), u = this.#u && (s !== 0 || l !== 0 || c !== 0);
2751
- if (u) {
2752
- let e = cn * en(n) * t;
2753
- n = Q(n, s * e, c * e, l * e);
2754
- }
2755
- let d = this.#f;
2756
- if (d !== n) {
2757
- this.#d = n = this.#E(n), this.#f = fn(d, n, t, this.#n, this.#r), this.#D();
2758
- for (let e of this.#p) e();
2759
- }
2760
- u || this.#f !== this.#d ? this.#w() : this.#h = null;
2761
- };
2762
- #E(e) {
2763
- return X(e, this.#n, this.#r);
2764
- }
2765
- #D() {
2766
- this.#t.setCamera(Xt(this.#f));
2767
- }
2768
- };
2769
- function $(e, t, n) {
2770
- e[0] += t, e[1] += n;
2771
- }
2772
- //#endregion
2773
- export { ae as S, rn as _, Z as a, ht as b, Q as c, $t as d, Qt as f, Zt as g, qt as h, nn as i, Jt as l, tn as m, Bt as n, X as o, Kt as p, J as r, Vt as s, pn as t, en as u, Xt as v, Ue as x, mt as y };