@kalyptos/narcissus 0.0.0 → 0.1.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.
- package/README.md +5 -0
- package/dist/cli/main.js +1 -1
- package/dist/{controls-5FaXzanr.js → controls-BCrDCO3z.js} +435 -379
- package/dist/element/index.js +1 -1
- package/dist/engine/gpu/buffers.d.ts +1 -0
- package/dist/engine/gpu/pool.d.ts +0 -1
- package/dist/engine/gpu/project.d.ts +1 -6
- package/dist/engine/gpu/sort.d.ts +1 -1
- package/dist/engine/plan/footprint.d.ts +4 -5
- package/dist/format/index.js +1 -1
- package/dist/{format-CxKTIugr.js → format-C3Vn0c2b.js} +75 -75
- package/dist/index.js +1 -1
- package/dist/{synthetic-BZcHRI1P.js → synthetic-BeGCzYIv.js} +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/{tools-DwOGah9N.js → tools-NykPVccD.js} +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as e, I as t, c as n, l as r, m as i, u as a } from "./format-
|
|
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
2
|
import { t as o } from "./ports-DZRKjdYD.js";
|
|
3
3
|
import { t as s } from "./http-DL7R39Nc.js";
|
|
4
4
|
//#region src/engine/gpu/layout.ts
|
|
@@ -56,22 +56,26 @@ var m = 19, h = 1024, g = class {
|
|
|
56
56
|
capacity;
|
|
57
57
|
#e;
|
|
58
58
|
#t = /* @__PURE__ */ new Map();
|
|
59
|
-
#n =
|
|
60
|
-
#r;
|
|
61
|
-
#i;
|
|
59
|
+
#n = null;
|
|
60
|
+
#r = null;
|
|
61
|
+
#i = /* @__PURE__ */ new Set();
|
|
62
62
|
#a;
|
|
63
|
-
#o
|
|
63
|
+
#o;
|
|
64
|
+
#s = 0;
|
|
65
|
+
#c;
|
|
66
|
+
#l = [
|
|
64
67
|
0,
|
|
65
68
|
0,
|
|
66
69
|
0
|
|
67
70
|
];
|
|
68
|
-
#s;
|
|
69
|
-
#c;
|
|
70
|
-
#l = new g();
|
|
71
71
|
#u;
|
|
72
72
|
#d;
|
|
73
73
|
#f = new g();
|
|
74
74
|
#p;
|
|
75
|
+
#m;
|
|
76
|
+
#h = new g();
|
|
77
|
+
#g;
|
|
78
|
+
#_ = [];
|
|
75
79
|
constructor(e, t) {
|
|
76
80
|
this.capacity = t, this.#e = e;
|
|
77
81
|
let n = this.slots, r = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC, i = (t, n) => e.createBuffer({
|
|
@@ -79,7 +83,7 @@ var m = 19, h = 1024, g = class {
|
|
|
79
83
|
size: n,
|
|
80
84
|
usage: r
|
|
81
85
|
});
|
|
82
|
-
this.geometry = i("pool geometry", t * 4 * 4), this.colour = i("pool colour", t * 3 * 4), this.pages = i("pool pages", n * 36 * 4), this.clusters = i("pool clusters", n * 12 * 4), this.list = i("pool list", n * 4), this.#
|
|
86
|
+
this.geometry = i("pool geometry", t * 4 * 4), this.colour = i("pool colour", t * 3 * 4), this.pages = i("pool pages", n * 36 * 4), this.clusters = i("pool clusters", n * 12 * 4), this.list = i("pool list", n * 4), 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
87
|
}
|
|
84
88
|
get slots() {
|
|
85
89
|
return this.capacity / 256;
|
|
@@ -101,65 +105,72 @@ var m = 19, h = 1024, g = class {
|
|
|
101
105
|
return this.#t.has(e);
|
|
102
106
|
}
|
|
103
107
|
*ids() {
|
|
104
|
-
for (let
|
|
108
|
+
for (let e = this.#n; e; e = e.next) e.page === null && (yield e.id);
|
|
105
109
|
}
|
|
106
110
|
add(e, n, r, i) {
|
|
107
111
|
if (this.#t.has(e)) return !0;
|
|
108
112
|
let a = c(n.count) / 256;
|
|
109
|
-
if (!this.#
|
|
110
|
-
let o = t.origin
|
|
111
|
-
|
|
113
|
+
if (!this.#b(a, i)) return !1;
|
|
114
|
+
let o = t.origin, s = {
|
|
115
|
+
id: e,
|
|
116
|
+
previous: null,
|
|
117
|
+
next: null,
|
|
112
118
|
page: n,
|
|
113
|
-
slots: this.#
|
|
114
|
-
|
|
119
|
+
slots: this.#w(a),
|
|
120
|
+
active: [],
|
|
121
|
+
mask: 0,
|
|
122
|
+
table: this.#c.pop(),
|
|
115
123
|
base: [
|
|
116
124
|
n.params[o] + r[0],
|
|
117
125
|
n.params[o + 1] + r[1],
|
|
118
126
|
n.params[o + 2]
|
|
119
127
|
],
|
|
120
128
|
factors: 0
|
|
121
|
-
}
|
|
129
|
+
};
|
|
130
|
+
return this.#t.set(e, s), this.#y(s), this.#i.add(e), !0;
|
|
122
131
|
}
|
|
123
132
|
remove(e) {
|
|
124
133
|
let t = this.#t.get(e);
|
|
125
134
|
if (t) {
|
|
126
|
-
this.#t.delete(e), this.#
|
|
127
|
-
for (let e of t.slots) this.#
|
|
128
|
-
this.#
|
|
135
|
+
this.#v(t), this.#t.delete(e), this.#i.delete(e);
|
|
136
|
+
for (let e of t.slots) this.#a[e] = 0;
|
|
137
|
+
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.#C(t, 0);
|
|
129
138
|
}
|
|
130
139
|
}
|
|
131
140
|
clear() {
|
|
132
141
|
for (let e of this.#t.keys()) this.remove(e);
|
|
133
142
|
}
|
|
134
143
|
get queued() {
|
|
135
|
-
return this.#
|
|
144
|
+
return this.#i.size;
|
|
136
145
|
}
|
|
137
146
|
upload(e) {
|
|
138
147
|
let t = 0;
|
|
139
|
-
for (let n of this.#
|
|
148
|
+
for (let n of this.#i) {
|
|
140
149
|
if (t >= e) break;
|
|
141
|
-
t += this.#
|
|
150
|
+
t += this.#x(this.#t.get(n)), this.#i.delete(n);
|
|
142
151
|
}
|
|
143
152
|
return t;
|
|
144
153
|
}
|
|
145
154
|
draw(e) {
|
|
146
|
-
let t = 0;
|
|
147
|
-
for (let { id:
|
|
148
|
-
let e = this.#t.get(
|
|
149
|
-
e
|
|
155
|
+
let t = 0, n = 0, r = !1;
|
|
156
|
+
for (let { id: i, factors: a } of e) {
|
|
157
|
+
let e = this.#t.get(i);
|
|
158
|
+
if (!e || e.page !== null) continue;
|
|
159
|
+
let o = e.active;
|
|
160
|
+
e.factors !== a && this.#C(e, a), r ||= o !== e.active, this.#y(e), r ||= this.#_[n] !== e, this.#_[n++] = e, r && this.#g.set(e.active, t), t += e.active.length;
|
|
150
161
|
}
|
|
151
|
-
this.listed = t;
|
|
152
|
-
let
|
|
153
|
-
this.#
|
|
162
|
+
r ||= this.#_.length !== n, this.#_.length = n, this.listed = t;
|
|
163
|
+
let i = this.#e.queue;
|
|
164
|
+
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);
|
|
154
165
|
}
|
|
155
166
|
setOrigin(e) {
|
|
156
|
-
this.#
|
|
167
|
+
this.#l = [
|
|
157
168
|
e[0],
|
|
158
169
|
e[1],
|
|
159
170
|
e[2]
|
|
160
171
|
];
|
|
161
|
-
for (let e of this.#t.values()) e.page === null && this.#
|
|
162
|
-
this.#e.queue.writeBuffer(this.pages, 0, this.#
|
|
172
|
+
for (let e of this.#t.values()) e.page === null && this.#S(e);
|
|
173
|
+
this.#e.queue.writeBuffer(this.pages, 0, this.#u), this.#f.clear();
|
|
163
174
|
}
|
|
164
175
|
destroy() {
|
|
165
176
|
let e = [
|
|
@@ -171,50 +182,77 @@ var m = 19, h = 1024, g = class {
|
|
|
171
182
|
];
|
|
172
183
|
for (let t of e) t.destroy();
|
|
173
184
|
}
|
|
174
|
-
#
|
|
175
|
-
|
|
185
|
+
#v(e) {
|
|
186
|
+
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;
|
|
187
|
+
}
|
|
188
|
+
#y(e) {
|
|
189
|
+
this.#r !== e && (this.#v(e), e.previous = this.#r, this.#r ? this.#r.next = e : this.#n = e, this.#r = e);
|
|
190
|
+
}
|
|
191
|
+
#b(e, t) {
|
|
192
|
+
let n = this.#o;
|
|
176
193
|
if (n >= e) return !0;
|
|
177
194
|
let r = [];
|
|
178
|
-
for (let
|
|
195
|
+
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);
|
|
179
196
|
if (n < e) return !1;
|
|
180
197
|
for (let e of r) this.remove(e);
|
|
181
198
|
return !0;
|
|
182
199
|
}
|
|
183
|
-
#
|
|
184
|
-
let n = e.page, { slots: r } = e, i = this.#e.queue, a = r.length, o = this.#
|
|
200
|
+
#x(e) {
|
|
201
|
+
let n = e.page, { slots: r } = e, i = this.#e.queue, a = r.length, o = this.#p, s = this.#m;
|
|
185
202
|
for (let t = 0; t < a; t++) {
|
|
186
203
|
let i = r[t] * 12;
|
|
187
|
-
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))
|
|
204
|
+
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));
|
|
205
|
+
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];
|
|
188
206
|
}
|
|
189
207
|
for (let e = 0; e < a;) {
|
|
190
208
|
let t = 1;
|
|
191
209
|
for (; e + t < a && r[e + t] === r[e] + t;) t++;
|
|
192
210
|
let o = e * 256, s = Math.min((e + t) * 256, n.count) - o, c = r[e] * 256;
|
|
193
|
-
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.#
|
|
211
|
+
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;
|
|
194
212
|
}
|
|
195
|
-
let c = e.table * 36, l = this.#
|
|
196
|
-
return l.fill(0, c, c + 36), this.#
|
|
213
|
+
let c = e.table * 36, l = this.#u, u = this.#d, d = n.params, [f, p, m] = n.quadrants;
|
|
214
|
+
return l.fill(0, c, c + 36), this.#S(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;
|
|
197
215
|
}
|
|
198
|
-
#
|
|
216
|
+
#S(e) {
|
|
199
217
|
let t = e.table * 36;
|
|
200
|
-
for (let n = 0; n < 3; n++) this.#
|
|
218
|
+
for (let n = 0; n < 3; n++) this.#d[t + n] = e.base[n] - this.#l[n];
|
|
201
219
|
}
|
|
202
|
-
#
|
|
220
|
+
#C(e, t) {
|
|
221
|
+
let n = 0;
|
|
222
|
+
for (let e = 0; e < 4; e++) t >>> 8 * e & 255 && (n |= 1 << e);
|
|
223
|
+
if (n !== e.mask) {
|
|
224
|
+
if (e.mask = n, n === 15 && this.#u[e.table * 36 + 3] > 0) e.active = e.slots;
|
|
225
|
+
else {
|
|
226
|
+
let t = [], r = e.table * 36, i = 0, a = -1;
|
|
227
|
+
for (let o = 0; o < 4; o++) {
|
|
228
|
+
let s = this.#u[r + (o === 3 ? 3 : 7 + 4 * o)];
|
|
229
|
+
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;
|
|
230
|
+
i = s;
|
|
231
|
+
}
|
|
232
|
+
e.active = t;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
203
235
|
e.factors = t;
|
|
204
|
-
let
|
|
205
|
-
this.#
|
|
206
|
-
}
|
|
207
|
-
#
|
|
208
|
-
let t = this.#
|
|
209
|
-
for (let r =
|
|
210
|
-
|
|
211
|
-
|
|
236
|
+
let r = e.table * 36 + m;
|
|
237
|
+
this.#u[r] = t, this.#f.mark(r, r + 1);
|
|
238
|
+
}
|
|
239
|
+
#w(e) {
|
|
240
|
+
let t = this.#a, n = -1;
|
|
241
|
+
for (let r = this.#s; r <= t.length - e;) {
|
|
242
|
+
let i = r;
|
|
243
|
+
for (; i < r + e && !t[i];) i++;
|
|
244
|
+
if (i === r + e) {
|
|
245
|
+
n = r;
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
if (r = t.indexOf(0, i + 1), r < 0) break;
|
|
212
249
|
}
|
|
213
250
|
let r = [];
|
|
214
251
|
if (n >= 0) for (let t = n; t < n + e; t++) r.push(t);
|
|
215
|
-
else for (let n =
|
|
252
|
+
else for (let n = this.#s; r.length < e; n = t.indexOf(0, n + 1)) r.push(n);
|
|
216
253
|
for (let e of r) t[e] = 1;
|
|
217
|
-
|
|
254
|
+
let i = t.indexOf(0, this.#s);
|
|
255
|
+
return this.#s = i < 0 ? t.length : i, this.#o -= e, r;
|
|
218
256
|
}
|
|
219
257
|
};
|
|
220
258
|
//#endregion
|
|
@@ -271,12 +309,14 @@ function T(e, t, n) {
|
|
|
271
309
|
r("work", (l.list + n) * 4, i | GPUBufferUsage.INDIRECT),
|
|
272
310
|
r("projected", t * 6 * 4, i),
|
|
273
311
|
r("sort", t * 16, i),
|
|
274
|
-
r("plugins", 256, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST)
|
|
275
|
-
|
|
312
|
+
r("plugins", 256, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST),
|
|
313
|
+
r("visible clusters", 4, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST)
|
|
314
|
+
], [o, s, c, u, d, f] = a;
|
|
276
315
|
return {
|
|
277
316
|
capacity: t,
|
|
278
317
|
uniforms: o,
|
|
279
318
|
work: s,
|
|
319
|
+
visible: f,
|
|
280
320
|
projected: c,
|
|
281
321
|
sort: u,
|
|
282
322
|
plugins: d,
|
|
@@ -306,7 +346,7 @@ function D(e, t, n, r) {
|
|
|
306
346
|
}
|
|
307
347
|
//#endregion
|
|
308
348
|
//#region src/engine/gpu/common.wgsl?raw
|
|
309
|
-
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
|
|
349
|
+
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 {
|
|
310
350
|
#e;
|
|
311
351
|
#t;
|
|
312
352
|
#n;
|
|
@@ -344,10 +384,10 @@ var O = "// shared by every engine pass; sizes and word offsets mirror format/sp
|
|
|
344
384
|
label: "cull",
|
|
345
385
|
timestampWrites: t
|
|
346
386
|
});
|
|
347
|
-
n.setBindGroup(0, this.#n), n.setPipeline(this.#t), n.dispatchWorkgroups(Math.ceil(this.#e.listed / A)), n.end();
|
|
387
|
+
n.setBindGroup(0, this.#n), n.setPipeline(this.#t), this.#e.listed && n.dispatchWorkgroups(Math.ceil(this.#e.listed / A)), n.end();
|
|
348
388
|
}
|
|
349
|
-
}, 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",
|
|
350
|
-
function
|
|
389
|
+
}, 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;
|
|
390
|
+
function ne(e) {
|
|
351
391
|
let t = new Uint32Array(e.length);
|
|
352
392
|
for (let n = 0; n < e.length; n++) {
|
|
353
393
|
let r = e[n];
|
|
@@ -355,7 +395,7 @@ function re(e) {
|
|
|
355
395
|
}
|
|
356
396
|
return new Float32Array(t.buffer);
|
|
357
397
|
}
|
|
358
|
-
var
|
|
398
|
+
var re = class {
|
|
359
399
|
#e;
|
|
360
400
|
#t;
|
|
361
401
|
#n;
|
|
@@ -385,7 +425,7 @@ var ie = class {
|
|
|
385
425
|
encode(e, t, n, r, i) {
|
|
386
426
|
let a = this.#e, o = this.#t, { listed: s } = o, c = r * r * 4, l = a.createBuffer({
|
|
387
427
|
label: "heights area",
|
|
388
|
-
size:
|
|
428
|
+
size: N,
|
|
389
429
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
390
430
|
}), u = a.createBuffer({
|
|
391
431
|
label: "heights",
|
|
@@ -395,14 +435,14 @@ var ie = class {
|
|
|
395
435
|
label: "heights readback",
|
|
396
436
|
size: c,
|
|
397
437
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
|
|
398
|
-
}), p = /* @__PURE__ */ new ArrayBuffer(
|
|
438
|
+
}), p = /* @__PURE__ */ new ArrayBuffer(N);
|
|
399
439
|
new Float32Array(p).set([
|
|
400
440
|
t,
|
|
401
441
|
n,
|
|
402
442
|
0,
|
|
403
443
|
0,
|
|
404
|
-
|
|
405
|
-
|
|
444
|
+
ee,
|
|
445
|
+
te
|
|
406
446
|
]), new Uint32Array(p).set([r, s], 2), a.queue.writeBuffer(l, 0, p);
|
|
407
447
|
let m = [
|
|
408
448
|
l,
|
|
@@ -415,11 +455,11 @@ var ie = class {
|
|
|
415
455
|
label: "heights",
|
|
416
456
|
timestampWrites: i
|
|
417
457
|
});
|
|
418
|
-
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(() =>
|
|
458
|
+
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(() => {
|
|
419
459
|
l.destroy(), u.destroy(), f.destroy();
|
|
420
460
|
});
|
|
421
461
|
}
|
|
422
|
-
},
|
|
462
|
+
}, 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 {
|
|
423
463
|
#e;
|
|
424
464
|
#t;
|
|
425
465
|
#n;
|
|
@@ -428,7 +468,7 @@ var ie = class {
|
|
|
428
468
|
constructor(e, t, n, r) {
|
|
429
469
|
let i = e.createShaderModule({
|
|
430
470
|
label: t,
|
|
431
|
-
code:
|
|
471
|
+
code: ie + n
|
|
432
472
|
});
|
|
433
473
|
this.#e = e, this.#t = t, this.#n = e.createRenderPipeline({
|
|
434
474
|
label: t,
|
|
@@ -463,15 +503,17 @@ var ie = class {
|
|
|
463
503
|
});
|
|
464
504
|
r.setPipeline(this.#n), r.setBindGroup(0, this.#i), r.draw(3), r.end();
|
|
465
505
|
}
|
|
466
|
-
},
|
|
506
|
+
}, 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 {
|
|
467
507
|
#e;
|
|
468
508
|
#t;
|
|
469
509
|
#n;
|
|
470
510
|
#r = [];
|
|
471
511
|
#i;
|
|
472
512
|
#a;
|
|
513
|
+
#o;
|
|
514
|
+
#s;
|
|
473
515
|
constructor(e, t, n) {
|
|
474
|
-
this.#e = e, this.#a = t;
|
|
516
|
+
this.#e = e, this.#a = t, this.#o = n.work, this.#s = n.visible;
|
|
475
517
|
let r = E(e, "project", GPUShaderStage.COMPUTE, [
|
|
476
518
|
"uniform",
|
|
477
519
|
"uniform",
|
|
@@ -481,7 +523,8 @@ var ie = class {
|
|
|
481
523
|
"read-only-storage",
|
|
482
524
|
"storage",
|
|
483
525
|
"storage",
|
|
484
|
-
"storage"
|
|
526
|
+
"storage",
|
|
527
|
+
"uniform"
|
|
485
528
|
]);
|
|
486
529
|
this.#t = e.createPipelineLayout({ bindGroupLayouts: [r] });
|
|
487
530
|
let i = [
|
|
@@ -493,27 +536,29 @@ var ie = class {
|
|
|
493
536
|
t.clusters,
|
|
494
537
|
n.work,
|
|
495
538
|
n.projected,
|
|
496
|
-
n.sort
|
|
539
|
+
n.sort,
|
|
540
|
+
n.visible
|
|
497
541
|
];
|
|
498
542
|
this.#i = D(e, "project", r, i);
|
|
499
543
|
}
|
|
500
544
|
hooks(e) {
|
|
501
545
|
this.#r = e, this.#n = void 0;
|
|
502
546
|
}
|
|
503
|
-
encode(e, t) {
|
|
504
|
-
|
|
547
|
+
encode(e, t, n) {
|
|
548
|
+
e.copyBufferToBuffer(this.#o, l.visible * 4, this.#s, 0, 4);
|
|
549
|
+
let r = Math.max(1, Math.min(128, this.#a.listed, t ? Math.max(32, Math.ceil(t / 16)) : 128)), i = e.beginComputePass({
|
|
505
550
|
label: "project",
|
|
506
|
-
timestampWrites:
|
|
551
|
+
timestampWrites: n
|
|
507
552
|
});
|
|
508
|
-
|
|
553
|
+
i.setPipeline(this.#n ??= this.#c()), i.setBindGroup(0, this.#i), i.dispatchWorkgroups(r), i.end();
|
|
509
554
|
}
|
|
510
|
-
#
|
|
555
|
+
#c() {
|
|
511
556
|
let e = this.#r, t = e.map(({ shade: e, slot: t }) => {
|
|
512
557
|
let n = Array.from({ length: e.uniforms }, (e, n) => `plugins[${t + n}]`);
|
|
513
558
|
return `\t${e.name}(s, array<vec4f, ${e.uniforms}>(${n.join(", ")}));`;
|
|
514
559
|
}), n = [
|
|
515
560
|
O,
|
|
516
|
-
|
|
561
|
+
ce,
|
|
517
562
|
...e.map(({ shade: e }) => e.wgsl),
|
|
518
563
|
"fn shade(s: ptr<function, Splat>) {",
|
|
519
564
|
...t,
|
|
@@ -531,10 +576,10 @@ var ie = class {
|
|
|
531
576
|
}
|
|
532
577
|
});
|
|
533
578
|
}
|
|
534
|
-
},
|
|
579
|
+
}, 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 = {
|
|
535
580
|
srcFactor: "one",
|
|
536
581
|
dstFactor: "one-minus-src-alpha"
|
|
537
|
-
},
|
|
582
|
+
}, me = class {
|
|
538
583
|
#e;
|
|
539
584
|
#t;
|
|
540
585
|
#n;
|
|
@@ -567,7 +612,7 @@ var ie = class {
|
|
|
567
612
|
]);
|
|
568
613
|
let a = e.createShaderModule({
|
|
569
614
|
label: "raster",
|
|
570
|
-
code: O +
|
|
615
|
+
code: O + ue
|
|
571
616
|
}), o = e.createPipelineLayout({ bindGroupLayouts: [i] }), s = (t, n) => e.createRenderPipeline({
|
|
572
617
|
label: `raster ${t}`,
|
|
573
618
|
layout: o,
|
|
@@ -579,10 +624,10 @@ var ie = class {
|
|
|
579
624
|
module: a,
|
|
580
625
|
entryPoint: "fs",
|
|
581
626
|
targets: [{
|
|
582
|
-
format:
|
|
627
|
+
format: de,
|
|
583
628
|
blend: {
|
|
584
|
-
color:
|
|
585
|
-
alpha:
|
|
629
|
+
color: pe,
|
|
630
|
+
alpha: pe
|
|
586
631
|
}
|
|
587
632
|
}]
|
|
588
633
|
},
|
|
@@ -590,7 +635,7 @@ var ie = class {
|
|
|
590
635
|
depthStencil: n
|
|
591
636
|
});
|
|
592
637
|
this.#n = s("Colour"), this.#r = s("Depth", {
|
|
593
|
-
format:
|
|
638
|
+
format: fe,
|
|
594
639
|
depthWriteEnabled: !0,
|
|
595
640
|
depthCompare: "always"
|
|
596
641
|
});
|
|
@@ -618,7 +663,7 @@ var ie = class {
|
|
|
618
663
|
this.#t.destroy();
|
|
619
664
|
}
|
|
620
665
|
};
|
|
621
|
-
function
|
|
666
|
+
function he(e, t, n, r, i, a, o) {
|
|
622
667
|
let { width: s, height: c } = n, l = Math.ceil(s * 2 / 256) * 256, u = e.createBuffer({
|
|
623
668
|
label: "pick",
|
|
624
669
|
size: l * c,
|
|
@@ -636,7 +681,7 @@ function ge(e, t, n, r, i, a, o) {
|
|
|
636
681
|
}
|
|
637
682
|
//#endregion
|
|
638
683
|
//#region src/engine/gpu/sort.wgsl?raw
|
|
639
|
-
var
|
|
684
|
+
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", _e = 1024, ve = 64, ye = 256, P = 3, F = 256, be = 32, xe = class {
|
|
640
685
|
keys;
|
|
641
686
|
values;
|
|
642
687
|
bytes;
|
|
@@ -646,25 +691,24 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
646
691
|
#r;
|
|
647
692
|
#i;
|
|
648
693
|
#a;
|
|
649
|
-
#o;
|
|
650
694
|
constructor(e, t) {
|
|
651
695
|
let { capacity: n } = t;
|
|
652
696
|
this.keys = n * 8, this.values = n * 12;
|
|
653
|
-
let r = Math.max(1, Math.ceil(n /
|
|
654
|
-
this.#a =
|
|
655
|
-
let i = (t, n, r) => e.createBuffer({
|
|
697
|
+
let r = Math.max(1, Math.ceil(n / _e));
|
|
698
|
+
this.#a = r;
|
|
699
|
+
let i = Math.ceil(r / ve), a = (t, n, r) => e.createBuffer({
|
|
656
700
|
label: t,
|
|
657
701
|
size: n,
|
|
658
702
|
usage: r
|
|
659
|
-
}),
|
|
703
|
+
}), o = GPUBufferUsage.STORAGE, s = a("sort params", P * F, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST), c = a("sort histograms", r * ye * 4, o), u = a("sort chunk sums", (i * ye + 1) * 4, o), d = a("sort state", 12, o);
|
|
660
704
|
this.#e = [
|
|
661
|
-
o,
|
|
662
705
|
s,
|
|
663
706
|
c,
|
|
664
|
-
u
|
|
707
|
+
u,
|
|
708
|
+
d
|
|
665
709
|
], this.bytes = this.#e.reduce((e, t) => e + t.size, 0);
|
|
666
|
-
let f = new Uint32Array(
|
|
667
|
-
for (let e = 0; e <
|
|
710
|
+
let f = new Uint32Array(P * F / 4);
|
|
711
|
+
for (let e = 0; e < P; e++) {
|
|
668
712
|
let [t, r] = e % 2 ? [2 * n, 0] : [0, 2 * n];
|
|
669
713
|
f.set([
|
|
670
714
|
8 * e,
|
|
@@ -673,9 +717,9 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
673
717
|
n,
|
|
674
718
|
l.projected,
|
|
675
719
|
l.drawArgs
|
|
676
|
-
], e *
|
|
720
|
+
], e * F / 4);
|
|
677
721
|
}
|
|
678
|
-
e.queue.writeBuffer(
|
|
722
|
+
e.queue.writeBuffer(s, 0, f);
|
|
679
723
|
let p = (e, t) => ({
|
|
680
724
|
binding: e,
|
|
681
725
|
visibility: GPUShaderStage.COMPUTE,
|
|
@@ -695,7 +739,7 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
695
739
|
]
|
|
696
740
|
}), g = e.createShaderModule({
|
|
697
741
|
label: "sort",
|
|
698
|
-
code: O +
|
|
742
|
+
code: O + ge
|
|
699
743
|
}), _ = (t, n) => e.createComputePipeline({
|
|
700
744
|
label: `sort ${t}`,
|
|
701
745
|
layout: e.createPipelineLayout({ bindGroupLayouts: [n] }),
|
|
@@ -712,9 +756,9 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
712
756
|
"scatter"
|
|
713
757
|
].map((e) => _(e, m));
|
|
714
758
|
let v = (e) => ({
|
|
715
|
-
buffer:
|
|
716
|
-
offset: e *
|
|
717
|
-
size:
|
|
759
|
+
buffer: s,
|
|
760
|
+
offset: e * F,
|
|
761
|
+
size: be
|
|
718
762
|
});
|
|
719
763
|
this.#r = e.createBindGroup({
|
|
720
764
|
label: "sort prepare",
|
|
@@ -726,14 +770,14 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
726
770
|
},
|
|
727
771
|
{
|
|
728
772
|
binding: 5,
|
|
729
|
-
resource: { buffer:
|
|
773
|
+
resource: { buffer: d }
|
|
730
774
|
},
|
|
731
775
|
{
|
|
732
776
|
binding: 6,
|
|
733
777
|
resource: { buffer: t.work }
|
|
734
778
|
}
|
|
735
779
|
]
|
|
736
|
-
}), this.#i = Array.from({ length:
|
|
780
|
+
}), this.#i = Array.from({ length: P }, (n, r) => e.createBindGroup({
|
|
737
781
|
label: `sort pass ${r}`,
|
|
738
782
|
layout: m,
|
|
739
783
|
entries: [
|
|
@@ -747,32 +791,32 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
747
791
|
},
|
|
748
792
|
{
|
|
749
793
|
binding: 2,
|
|
750
|
-
resource: { buffer:
|
|
794
|
+
resource: { buffer: c }
|
|
751
795
|
},
|
|
752
796
|
{
|
|
753
797
|
binding: 3,
|
|
754
|
-
resource: { buffer:
|
|
798
|
+
resource: { buffer: u }
|
|
755
799
|
},
|
|
756
800
|
{
|
|
757
801
|
binding: 4,
|
|
758
|
-
resource: { buffer:
|
|
802
|
+
resource: { buffer: d }
|
|
759
803
|
}
|
|
760
804
|
]
|
|
761
805
|
}));
|
|
762
806
|
}
|
|
763
|
-
encode(e, t) {
|
|
764
|
-
let [
|
|
807
|
+
encode(e, t, n, r) {
|
|
808
|
+
let [i, a, o, s, c] = this.#n, l = Math.max(1, Math.min(this.#a, Math.ceil(t / _e))), u = Math.max(l / 16, (n || t) / _e), f = d(Math.min(Math.ceil(l / 4), Math.ceil(u))), p = Math.ceil(l / ve), m = e.beginComputePass({
|
|
765
809
|
label: "sort",
|
|
766
|
-
timestampWrites:
|
|
810
|
+
timestampWrites: r
|
|
767
811
|
});
|
|
768
|
-
|
|
769
|
-
for (let e of this.#i)
|
|
770
|
-
|
|
812
|
+
m.setPipeline(this.#t), m.setBindGroup(0, this.#r), m.dispatchWorkgroups(1);
|
|
813
|
+
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);
|
|
814
|
+
m.end();
|
|
771
815
|
}
|
|
772
816
|
destroy() {
|
|
773
817
|
for (let e of this.#e) e.destroy();
|
|
774
818
|
}
|
|
775
|
-
},
|
|
819
|
+
}, Se = class {
|
|
776
820
|
ms = {};
|
|
777
821
|
#e;
|
|
778
822
|
#t;
|
|
@@ -799,7 +843,7 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
799
843
|
}
|
|
800
844
|
writes(e) {
|
|
801
845
|
let t = this.#t;
|
|
802
|
-
if (!t) return;
|
|
846
|
+
if (!t || this.#i) return;
|
|
803
847
|
let n = this.#e.indexOf(e);
|
|
804
848
|
return {
|
|
805
849
|
querySet: t,
|
|
@@ -823,14 +867,14 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
823
867
|
destroy() {
|
|
824
868
|
this.#t?.destroy(), this.#n?.destroy(), this.#r?.destroy();
|
|
825
869
|
}
|
|
826
|
-
},
|
|
870
|
+
}, Ce = [
|
|
827
871
|
"cull",
|
|
828
872
|
"project",
|
|
829
873
|
"sort",
|
|
830
874
|
"raster",
|
|
831
875
|
"heights",
|
|
832
876
|
"post"
|
|
833
|
-
],
|
|
877
|
+
], I = {
|
|
834
878
|
view: 0,
|
|
835
879
|
proj: 16,
|
|
836
880
|
viewProj: 32,
|
|
@@ -843,7 +887,7 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
843
887
|
far: 81,
|
|
844
888
|
lowPass: 82,
|
|
845
889
|
clusters: 83
|
|
846
|
-
},
|
|
890
|
+
}, we = class {
|
|
847
891
|
#e;
|
|
848
892
|
#t;
|
|
849
893
|
#n;
|
|
@@ -869,11 +913,12 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
869
913
|
#S;
|
|
870
914
|
#C = !1;
|
|
871
915
|
#w = 0;
|
|
916
|
+
#T = 0;
|
|
872
917
|
constructor(e, t, n, r) {
|
|
873
918
|
let { device: i } = e;
|
|
874
|
-
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
|
|
875
|
-
label: "
|
|
876
|
-
size: 4,
|
|
919
|
+
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 xe(i, this.#i), this.#c = new me(i, this.#i, this.#s), this.#u = new re(i, n), this.#d = new Se(i, e.timestamps, Ce), this.#S = i.createBuffer({
|
|
920
|
+
label: "counts readback",
|
|
921
|
+
size: (l.projected + 1) * 4,
|
|
877
922
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
|
|
878
923
|
}), this.#b = Math.max(1, t.canvas.width), this.#x = Math.max(1, t.canvas.height);
|
|
879
924
|
}
|
|
@@ -883,9 +928,9 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
883
928
|
shade: e,
|
|
884
929
|
slot: 0
|
|
885
930
|
};
|
|
886
|
-
return this.#g.push(t), this.#
|
|
931
|
+
return this.#g.push(t), this.#E(), () => {
|
|
887
932
|
let e = this.#g.indexOf(t);
|
|
888
|
-
e < 0 || (this.#g.splice(e, 1), this.#
|
|
933
|
+
e < 0 || (this.#g.splice(e, 1), this.#E());
|
|
889
934
|
};
|
|
890
935
|
}
|
|
891
936
|
post(e) {
|
|
@@ -899,16 +944,16 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
899
944
|
};
|
|
900
945
|
}
|
|
901
946
|
resize(e, t) {
|
|
902
|
-
(e !== this.#b || t !== this.#x) && (this.#b = e, this.#x = t, this.#
|
|
947
|
+
(e !== this.#b || t !== this.#x) && (this.#b = e, this.#x = t, this.#j());
|
|
903
948
|
}
|
|
904
949
|
render(e, t, n, r, i) {
|
|
905
|
-
let a = this.#e, o = this.#d, s = this.#_, c = this.#
|
|
906
|
-
this.#
|
|
950
|
+
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)];
|
|
951
|
+
this.#D(e, t);
|
|
907
952
|
let m = a.createCommandEncoder({ label: "frame" });
|
|
908
|
-
m.clearBuffer(this.#i.work, 0, l.list * 4), this.#a.encode(m, o.writes("cull")), this.#o.encode(m, o.writes("project")), this.#s.encode(m, o.writes("sort")), this.#c.encode(m, c, f, n, o.writes("raster"));
|
|
953
|
+
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"));
|
|
909
954
|
let h = d ? r.map(({ x: t, y: n, resolve: r }) => ({
|
|
910
955
|
resolve: r,
|
|
911
|
-
read:
|
|
956
|
+
read: he(a, m, d, t, n, e.near, e.far)
|
|
912
957
|
})) : [], g = i.map(({ x: e, y: t, cells: n, resolve: r }, i) => ({
|
|
913
958
|
resolve: r,
|
|
914
959
|
read: this.#u.encode(m, e, t, n, i ? void 0 : o.writes("heights"))
|
|
@@ -921,11 +966,11 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
921
966
|
} }).end();
|
|
922
967
|
}
|
|
923
968
|
let v = this.#t.getCurrentTexture().createView();
|
|
924
|
-
if (!s.length) this.#l ??=
|
|
969
|
+
if (!s.length) this.#l ??= se(a, this.#n), this.#l.encode(m, [c], v);
|
|
925
970
|
else {
|
|
926
971
|
let t = c;
|
|
927
972
|
s.forEach(({ post: n, pass: r }, i) => {
|
|
928
|
-
let a = i === s.length - 1 ? v : this.#
|
|
973
|
+
let a = i === s.length - 1 ? v : this.#k(p[i % 2]);
|
|
929
974
|
r.run(m, e, t, n.depth ? f : null, a), t = a;
|
|
930
975
|
});
|
|
931
976
|
}
|
|
@@ -938,7 +983,7 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
938
983
|
}
|
|
939
984
|
o.resolve(m);
|
|
940
985
|
let y = !this.#C;
|
|
941
|
-
y && m.copyBufferToBuffer(this.#i.work,
|
|
986
|
+
y && m.copyBufferToBuffer(this.#i.work, 0, this.#S, 0, this.#S.size), a.queue.submit([m.finish()]), o.read(), y && this.#M();
|
|
942
987
|
for (let { resolve: e, read: t } of h) t().then(e);
|
|
943
988
|
for (let { resolve: e, read: t } of g) t().then(e);
|
|
944
989
|
return a.queue.onSubmittedWorkDone();
|
|
@@ -955,20 +1000,20 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
955
1000
|
}
|
|
956
1001
|
destroy() {
|
|
957
1002
|
for (let { pass: e } of this.#_.splice(0)) e.destroy();
|
|
958
|
-
this.#
|
|
1003
|
+
this.#j(), this.#i.destroy(), this.#s.destroy(), this.#c.destroy(), this.#d.destroy(), this.#S.destroy();
|
|
959
1004
|
}
|
|
960
|
-
#
|
|
1005
|
+
#E() {
|
|
961
1006
|
let e = 0;
|
|
962
1007
|
for (let t of this.#g) t.slot = e, e += t.shade.uniforms;
|
|
963
1008
|
this.#o.hooks(this.#g);
|
|
964
1009
|
}
|
|
965
|
-
#
|
|
1010
|
+
#D(e, t) {
|
|
966
1011
|
let n = this.#f, [r, i] = [this.#b, this.#x];
|
|
967
|
-
n.set(e.view,
|
|
1012
|
+
n.set(e.view, I.view), n.set(e.proj, I.proj), n.set(S(this.#m, e.proj, e.view), I.viewProj), n.set(t, I.planes), n.set(e.camera.subarray(0, 3), I.camera), n[I.time] = e.time, n.set([r, i], I.viewport), n.set([e.proj[0] * r / 2, e.proj[5] * i / 2], I.focal), n[I.near] = e.near, n[I.far] = e.far, n[I.lowPass] = f, this.#p[I.clusters] = this.#r.listed, this.#e.queue.writeBuffer(this.#i.uniforms, 0, n);
|
|
968
1013
|
for (let { shade: t, slot: n } of this.#g) t.update(e, this.#h.subarray(n * 4, (n + t.uniforms) * 4));
|
|
969
|
-
this.#e.queue.writeBuffer(this.#i.plugins, 0, this.#h);
|
|
1014
|
+
this.#g.length && this.#e.queue.writeBuffer(this.#i.plugins, 0, this.#h);
|
|
970
1015
|
}
|
|
971
|
-
#
|
|
1016
|
+
#O(e, t) {
|
|
972
1017
|
let n = this.#v[e];
|
|
973
1018
|
return n || (n = this.#e.createTexture({
|
|
974
1019
|
label: e,
|
|
@@ -977,27 +1022,27 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
977
1022
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
|
|
978
1023
|
}), this.#v[e] = n), n;
|
|
979
1024
|
}
|
|
980
|
-
#
|
|
1025
|
+
#k(e) {
|
|
981
1026
|
let t = this.#y.get(e);
|
|
982
1027
|
return t || this.#y.set(e, t = e.createView()), t;
|
|
983
1028
|
}
|
|
984
|
-
#
|
|
985
|
-
if (n) return this.#
|
|
1029
|
+
#A(e, t, n) {
|
|
1030
|
+
if (n) return this.#O(e, t);
|
|
986
1031
|
this.#v[e]?.destroy(), delete this.#v[e];
|
|
987
1032
|
}
|
|
988
|
-
#
|
|
1033
|
+
#j() {
|
|
989
1034
|
for (let e of Object.values(this.#v)) e?.destroy();
|
|
990
1035
|
this.#v = {};
|
|
991
1036
|
}
|
|
992
|
-
#
|
|
1037
|
+
#M() {
|
|
993
1038
|
this.#C = !0;
|
|
994
1039
|
let e = this.#S;
|
|
995
1040
|
e.mapAsync(GPUMapMode.READ).then(() => {
|
|
996
|
-
let t = new Uint32Array(e.getMappedRange())
|
|
997
|
-
this.#w = Math.min(t, this.#i.capacity), e.unmap();
|
|
1041
|
+
let t = new Uint32Array(e.getMappedRange());
|
|
1042
|
+
this.#T = t[l.visible], this.#w = Math.min(t[l.projected], this.#i.capacity), e.unmap();
|
|
998
1043
|
}).catch(() => {}).finally(() => this.#C = !1);
|
|
999
1044
|
}
|
|
1000
|
-
},
|
|
1045
|
+
}, Te = [
|
|
1001
1046
|
[0, 1],
|
|
1002
1047
|
[0, -1],
|
|
1003
1048
|
[1, 1],
|
|
@@ -1005,9 +1050,9 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
|
|
|
1005
1050
|
[2, 0],
|
|
1006
1051
|
[2, -1]
|
|
1007
1052
|
];
|
|
1008
|
-
function
|
|
1053
|
+
function Ee(e, t) {
|
|
1009
1054
|
let n = (e, n) => t[n * 4 + e];
|
|
1010
|
-
return
|
|
1055
|
+
return Te.forEach(([t, r], i) => {
|
|
1011
1056
|
for (let a = 0; a < 4; a++) e[i * 4 + a] = r ? n(3, a) + r * n(t, a) : n(t, a);
|
|
1012
1057
|
let a = Math.hypot(e[i * 4], e[i * 4 + 1], e[i * 4 + 2]) || 1;
|
|
1013
1058
|
for (let t = 0; t < 4; t++) e[i * 4 + t] /= a;
|
|
@@ -1015,118 +1060,127 @@ function De(e, t) {
|
|
|
1015
1060
|
}
|
|
1016
1061
|
//#endregion
|
|
1017
1062
|
//#region src/engine/plan/footprint.ts
|
|
1063
|
+
var De = [
|
|
1064
|
+
0,
|
|
1065
|
+
0,
|
|
1066
|
+
0
|
|
1067
|
+
];
|
|
1018
1068
|
function Oe(e, t, n, r) {
|
|
1019
1069
|
let i = (e * e + e * t + t * t + n * n + n * r + r * r) / 3;
|
|
1020
1070
|
return 1 + 15 * Math.max(0, 1 - i) ** 2;
|
|
1021
1071
|
}
|
|
1022
1072
|
function ke(e, t, n, r, i, a, o, s = 1, c = {
|
|
1073
|
+
shown: !1,
|
|
1023
1074
|
pixels: 0,
|
|
1024
1075
|
weight: 1
|
|
1025
|
-
}) {
|
|
1026
|
-
let
|
|
1027
|
-
if (c.pixels = 0, c.weight = 1,
|
|
1028
|
-
let
|
|
1029
|
-
if (
|
|
1030
|
-
let
|
|
1031
|
-
|
|
1076
|
+
}, l = De) {
|
|
1077
|
+
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;
|
|
1078
|
+
if (c.pixels = 0, c.weight = 1, c.shown = !1, v + x < a || v - x > o) return c;
|
|
1079
|
+
let S = Math.max(a, v - x), C = Math.max(a, v + x), w = i * n / r;
|
|
1080
|
+
if (Math.abs(g) - y > s * w * C || Math.abs(_) - b > s * i * C) return c;
|
|
1081
|
+
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;
|
|
1082
|
+
if (E < -s || T > s || O < -s || D > s) return c;
|
|
1083
|
+
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);
|
|
1084
|
+
return N <= 0 || ee <= 0 || (c.shown = E > -1 && T < 1 && O > -1 && D < 1, c.pixels = N * n * r / 4, c.weight = Oe(k, A, j, M)), c;
|
|
1032
1085
|
}
|
|
1033
1086
|
//#endregion
|
|
1034
1087
|
//#region src/engine/plan/cut.ts
|
|
1035
|
-
var Ae = 1 / .8 ** 2, je =
|
|
1088
|
+
var Ae = 1 / .8 ** 2, je = 1.1, Me = class {
|
|
1036
1089
|
#e = /* @__PURE__ */ new Map();
|
|
1037
1090
|
#t = /* @__PURE__ */ new Map();
|
|
1038
|
-
#n =
|
|
1039
|
-
|
|
1091
|
+
#n = {
|
|
1092
|
+
shown: !1,
|
|
1040
1093
|
pixels: 0,
|
|
1041
1094
|
weight: 1
|
|
1042
1095
|
};
|
|
1043
1096
|
plan(e, t, n, r) {
|
|
1044
|
-
let { budget: i, capacity: a, now: o, predicted: s } = r, l = [], u =
|
|
1045
|
-
let
|
|
1046
|
-
l.push(e),
|
|
1047
|
-
let i = this.#e.get(
|
|
1048
|
-
|
|
1049
|
-
let
|
|
1050
|
-
(r < s * (a ? Ae : 1) ||
|
|
1051
|
-
page:
|
|
1052
|
-
shown:
|
|
1053
|
-
held:
|
|
1054
|
-
ratio:
|
|
1097
|
+
let { budget: i, capacity: a, now: o, predicted: s } = r, l = [], u = [], d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map(), p = e.wanted(), m = /* @__PURE__ */ new Map(), h = new Pe(), g = 0, _ = 0, v = (e) => {
|
|
1098
|
+
let t = e.page, r = t.row.count;
|
|
1099
|
+
l.push(t), u.push(+!!e.shown | (e.near ? 2 : 0)), _ += c(r), e.shown && (g += r);
|
|
1100
|
+
let i = this.#e.get(t.id), a = i !== void 0, s = e.pixels * e.weight, d = s / Math.max(1, r);
|
|
1101
|
+
p.length && e.pixels > 0 && m.set(t.id, d);
|
|
1102
|
+
let f = a && !e.shown && o - (this.#t.get(t.id) ?? -Infinity) <= 1500 ? i : null;
|
|
1103
|
+
(r < s * (a ? Ae : 1) || f !== null) && Ne(t, n) && h.push({
|
|
1104
|
+
page: t,
|
|
1105
|
+
shown: e.shown,
|
|
1106
|
+
held: f,
|
|
1107
|
+
ratio: d
|
|
1055
1108
|
});
|
|
1056
1109
|
};
|
|
1057
|
-
for (let n of e.roots) v(
|
|
1110
|
+
for (let n of e.roots) v(this.#r(n, t, s));
|
|
1058
1111
|
let y = !1;
|
|
1059
|
-
for (;
|
|
1060
|
-
let { page: e, shown: n, held: r } =
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
let
|
|
1070
|
-
|
|
1071
|
-
if (
|
|
1072
|
-
if (_ > 0 && (y || m + _ > i)) {
|
|
1112
|
+
for (; h.size;) {
|
|
1113
|
+
let { page: e, shown: n, held: r } = h.pop(), l = [], u = 0;
|
|
1114
|
+
for (let n = 0; n < e.children.length; n++) {
|
|
1115
|
+
let i = e.children[n];
|
|
1116
|
+
if (!i) continue;
|
|
1117
|
+
let a = this.#r(i, t, s);
|
|
1118
|
+
a.pixels <= 0 && !((r ?? 0) & 1 << n) || (l.push(a), u |= 1 << n);
|
|
1119
|
+
}
|
|
1120
|
+
if (!l.length) continue;
|
|
1121
|
+
let p = 0, m = n ? -e.row.count : 0;
|
|
1122
|
+
for (let e of l) p += c(e.page.row.count), e.shown && (m += e.page.row.count);
|
|
1123
|
+
if (_ + p > a) break;
|
|
1124
|
+
if (m > 0 && (y || g + m > i)) {
|
|
1073
1125
|
y = !0;
|
|
1074
1126
|
continue;
|
|
1075
1127
|
}
|
|
1076
|
-
|
|
1128
|
+
d.set(e.id, u);
|
|
1077
1129
|
let b = n ? o : this.#t.get(e.id);
|
|
1078
|
-
b !== void 0 &&
|
|
1079
|
-
for (let
|
|
1130
|
+
b !== void 0 && f.set(e.id, b), n && (g -= e.row.count);
|
|
1131
|
+
for (let e of l) v(e);
|
|
1132
|
+
}
|
|
1133
|
+
this.#e = d, this.#t = f;
|
|
1134
|
+
let b = [], x = [], S = new Set(d.keys()), C = 0;
|
|
1135
|
+
for (let e = 0; e < l.length; e++) {
|
|
1136
|
+
let t = l[e];
|
|
1137
|
+
d.has(t.id) || (b.push(t), S.add(t.id), n(t.id) || (u[e] & 1 && (C += t.row.count), x.push({
|
|
1138
|
+
page: t,
|
|
1139
|
+
near: !!(u[e] & 2)
|
|
1140
|
+
})));
|
|
1080
1141
|
}
|
|
1081
|
-
|
|
1082
|
-
let
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
e >= 0 && S.push({
|
|
1089
|
-
wanted: t,
|
|
1090
|
-
rank: e
|
|
1142
|
+
let w = [];
|
|
1143
|
+
for (let e of p) {
|
|
1144
|
+
let t = -1;
|
|
1145
|
+
for (let n of e.over) t = Math.max(t, m.get(n.id) ?? -1);
|
|
1146
|
+
t >= 0 && w.push({
|
|
1147
|
+
wanted: e,
|
|
1148
|
+
rank: t
|
|
1091
1149
|
});
|
|
1092
1150
|
}
|
|
1093
|
-
|
|
1094
|
-
let C = 0;
|
|
1095
|
-
for (let e of b) _.has(e.id) && !n(e.id) && (C += e.row.count);
|
|
1096
|
-
return {
|
|
1151
|
+
return w.sort((e, t) => t.rank - e.rank), {
|
|
1097
1152
|
cut: b,
|
|
1098
|
-
load:
|
|
1099
|
-
idx:
|
|
1100
|
-
keep:
|
|
1101
|
-
planned:
|
|
1153
|
+
load: x.filter(({ near: e }) => e || !s && C === 0).map(({ page: e }) => e),
|
|
1154
|
+
idx: w.map((e) => e.wanted),
|
|
1155
|
+
keep: S,
|
|
1156
|
+
planned: g,
|
|
1102
1157
|
missing: C
|
|
1103
1158
|
};
|
|
1104
1159
|
}
|
|
1105
|
-
#
|
|
1106
|
-
let r = this.#
|
|
1160
|
+
#r(e, t, n) {
|
|
1161
|
+
let r = this.#i(e, t, je), i = r.shown, { pixels: a, weight: o } = r, s = i;
|
|
1107
1162
|
if (n) {
|
|
1108
|
-
let t = this.#
|
|
1109
|
-
t.pixels >
|
|
1163
|
+
let t = this.#i(e, n, je);
|
|
1164
|
+
t.pixels > a && ({pixels: a, weight: o} = t), s ||= t.shown;
|
|
1110
1165
|
}
|
|
1111
1166
|
return {
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1167
|
+
page: e,
|
|
1168
|
+
shown: i,
|
|
1169
|
+
near: s,
|
|
1170
|
+
pixels: a,
|
|
1171
|
+
weight: o
|
|
1116
1172
|
};
|
|
1117
1173
|
}
|
|
1118
|
-
#
|
|
1119
|
-
let r =
|
|
1120
|
-
|
|
1121
|
-
let { width: i, height: a, tan: o, near: s, far: c } = t;
|
|
1122
|
-
return ke(r, t.view, i, a, o, s, c, n, this.#r);
|
|
1174
|
+
#i(e, t, n) {
|
|
1175
|
+
let { width: r, height: i, tan: a, near: o, far: s } = t;
|
|
1176
|
+
return ke(e.box, t.view, r, i, a, o, s, n, this.#n, t.origin);
|
|
1123
1177
|
}
|
|
1124
1178
|
};
|
|
1125
|
-
function
|
|
1179
|
+
function Ne(e, t) {
|
|
1126
1180
|
let { children: n } = e;
|
|
1127
|
-
return t(e.id) && !n.includes(void 0) && n.some((e) => e !== null);
|
|
1181
|
+
return e.g > 0 && t(e.id) && !n.includes(void 0) && n.some((e) => e !== null);
|
|
1128
1182
|
}
|
|
1129
|
-
var
|
|
1183
|
+
var Pe = class {
|
|
1130
1184
|
#e = [];
|
|
1131
1185
|
get size() {
|
|
1132
1186
|
return this.#e.length;
|
|
@@ -1136,68 +1190,67 @@ var Fe = class {
|
|
|
1136
1190
|
t.push(e);
|
|
1137
1191
|
let n = t.length - 1;
|
|
1138
1192
|
for (; n > 0;) {
|
|
1139
|
-
let
|
|
1140
|
-
if (!
|
|
1141
|
-
|
|
1193
|
+
let r = n - 1 >> 1;
|
|
1194
|
+
if (!L(e, t[r])) break;
|
|
1195
|
+
t[n] = t[r], n = r;
|
|
1142
1196
|
}
|
|
1197
|
+
t[n] = e;
|
|
1143
1198
|
}
|
|
1144
1199
|
pop() {
|
|
1145
1200
|
let e = this.#e, t = e[0], n = e.pop();
|
|
1146
1201
|
if (e.length) {
|
|
1147
|
-
e[0] = n;
|
|
1148
1202
|
let t = 0;
|
|
1149
|
-
for (
|
|
1150
|
-
let
|
|
1151
|
-
if (
|
|
1152
|
-
|
|
1203
|
+
for (; 2 * t + 1 < e.length;) {
|
|
1204
|
+
let r = 2 * t + 1;
|
|
1205
|
+
if (r + 1 < e.length && L(e[r + 1], e[r]) && r++, !L(e[r], n)) break;
|
|
1206
|
+
e[t] = e[r], t = r;
|
|
1153
1207
|
}
|
|
1208
|
+
e[t] = n;
|
|
1154
1209
|
}
|
|
1155
1210
|
return t;
|
|
1156
1211
|
}
|
|
1157
1212
|
};
|
|
1158
|
-
function
|
|
1213
|
+
function L(e, t) {
|
|
1159
1214
|
return e.shown === t.shown ? e.ratio > t.ratio : e.shown;
|
|
1160
1215
|
}
|
|
1161
|
-
var
|
|
1216
|
+
var R = .25, Fe = class {
|
|
1162
1217
|
#e = /* @__PURE__ */ new Map();
|
|
1163
1218
|
update(e, t, n, r) {
|
|
1164
|
-
let i = this.#e, a =
|
|
1165
|
-
for (let [e, r] of i) t(r.page.id) ? r.held
|
|
1166
|
-
let
|
|
1219
|
+
let i = this.#e, a = Ie(e, t), o = -1;
|
|
1220
|
+
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 = ze(r, n), r.start = null, r.held = !0))) : i.delete(e);
|
|
1221
|
+
let s = /* @__PURE__ */ new Set();
|
|
1167
1222
|
for (let [e, t] of a) {
|
|
1168
1223
|
let r = i.get(e);
|
|
1169
|
-
if (r) r.held && (r.held = !1, r.frozen < 255 && (r.start = n - r.frozen / 255 * 250,
|
|
1224
|
+
if (r) r.held && (r.held = !1, r.frozen < 255 && (r.start = n - r.frozen / 255 * 250, s.add(r)));
|
|
1170
1225
|
else {
|
|
1171
|
-
let r =
|
|
1172
|
-
i.set(e, r),
|
|
1226
|
+
let r = Le(t, e % 4, n);
|
|
1227
|
+
o = Math.max(o, r.level), i.set(e, r), s.add(r);
|
|
1173
1228
|
}
|
|
1174
1229
|
}
|
|
1175
|
-
let s = -1;
|
|
1176
|
-
for (let e of i.values()) s = Math.max(s, e.level);
|
|
1177
1230
|
let l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
|
|
1178
1231
|
for (let e of i.values()) if (e.held) {
|
|
1179
1232
|
l.set(e.cell, e);
|
|
1180
|
-
for (let t = e.level, n = e.col, r = e.row; t <=
|
|
1181
|
-
let i =
|
|
1233
|
+
for (let t = e.level, n = e.col, r = e.row; t <= o; t++, n >>= 1, r >>= 1) {
|
|
1234
|
+
let i = z(t, n, r), a = u.get(i);
|
|
1182
1235
|
a ? a.push(e) : u.set(i, [e]);
|
|
1183
1236
|
}
|
|
1184
1237
|
}
|
|
1185
1238
|
let d = (e) => {
|
|
1186
1239
|
let t = [...u.get(e.cell) ?? []];
|
|
1187
|
-
for (let n = e.level + 1, r = e.col >> 1, i = e.row >> 1; n <=
|
|
1188
|
-
let e = l.get(
|
|
1240
|
+
for (let n = e.level + 1, r = e.col >> 1, i = e.row >> 1; n <= o; n++, r >>= 1, i >>= 1) {
|
|
1241
|
+
let e = l.get(z(n, r, i));
|
|
1189
1242
|
e && t.push(e);
|
|
1190
1243
|
}
|
|
1191
1244
|
return t;
|
|
1192
1245
|
}, f = /* @__PURE__ */ new Set(), p = /* @__PURE__ */ new Set(), m = 0, h = 0, g = (e) => {
|
|
1193
1246
|
p.has(e) || (p.add(e), h += c(e.row.count));
|
|
1194
1247
|
};
|
|
1195
|
-
for (let e of i.values()) if (!(e.held || e.start === null ||
|
|
1248
|
+
for (let e of i.values()) if (!(e.held || e.start === null || s.has(e))) {
|
|
1196
1249
|
m += e.splats;
|
|
1197
1250
|
for (let t of d(e)) f.has(t) || (f.add(t), m += t.splats, g(t.page));
|
|
1198
1251
|
}
|
|
1199
|
-
let _ =
|
|
1200
|
-
for (let e of
|
|
1252
|
+
let _ = R * r;
|
|
1253
|
+
for (let e of s) {
|
|
1201
1254
|
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);
|
|
1202
1255
|
if (m + n > _ || h + i > _) e.start = null;
|
|
1203
1256
|
else {
|
|
@@ -1206,16 +1259,19 @@ var L = .25, Ie = class {
|
|
|
1206
1259
|
for (let e of r) g(e);
|
|
1207
1260
|
}
|
|
1208
1261
|
}
|
|
1209
|
-
for (let [e, t] of i) t.held && !f.has(t) && i.delete(e);
|
|
1210
1262
|
let v = /* @__PURE__ */ new Map(), y = !1;
|
|
1211
|
-
for (let e of i
|
|
1212
|
-
(
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1263
|
+
for (let [e, t] of i) {
|
|
1264
|
+
if (t.held && !f.has(t)) {
|
|
1265
|
+
i.delete(e);
|
|
1266
|
+
continue;
|
|
1267
|
+
}
|
|
1268
|
+
(t.held || t.start !== null) && (y = !0);
|
|
1269
|
+
let r = ze(t, n);
|
|
1270
|
+
if (!r) continue;
|
|
1271
|
+
let a = v.get(t.page.id);
|
|
1272
|
+
a ? a.factors = (a.factors | r << 8 * t.q) >>> 0 : v.set(t.page.id, {
|
|
1273
|
+
id: t.page.id,
|
|
1274
|
+
factors: r << 8 * t.q >>> 0
|
|
1219
1275
|
});
|
|
1220
1276
|
}
|
|
1221
1277
|
return {
|
|
@@ -1224,19 +1280,19 @@ var L = .25, Ie = class {
|
|
|
1224
1280
|
};
|
|
1225
1281
|
}
|
|
1226
1282
|
};
|
|
1227
|
-
function
|
|
1283
|
+
function Ie(e, t) {
|
|
1228
1284
|
let n = new Set(e), r = /* @__PURE__ */ new Set(), i = [];
|
|
1229
1285
|
for (let t of e) for (let e = t; e && !r.has(e); e = e.parent) r.add(e), e.parent || i.push(e);
|
|
1230
1286
|
let a = /* @__PURE__ */ new Map(), o = (e) => {
|
|
1231
1287
|
for (let i = 0; i < 4; i++) {
|
|
1232
1288
|
let s = e.children[i];
|
|
1233
|
-
s &&
|
|
1289
|
+
s && r.has(s) && t(s.id) ? o(s) : (s !== null || n.has(e)) && a.set(e.id * 4 + i, e);
|
|
1234
1290
|
}
|
|
1235
1291
|
};
|
|
1236
1292
|
for (let e of i) t(e.id) && o(e);
|
|
1237
1293
|
return a;
|
|
1238
1294
|
}
|
|
1239
|
-
function
|
|
1295
|
+
function Le(t, n, r) {
|
|
1240
1296
|
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);
|
|
1241
1297
|
return {
|
|
1242
1298
|
page: t,
|
|
@@ -1244,39 +1300,39 @@ function Re(t, n, r) {
|
|
|
1244
1300
|
level: a,
|
|
1245
1301
|
col: o,
|
|
1246
1302
|
row: s,
|
|
1247
|
-
cell:
|
|
1248
|
-
splats:
|
|
1303
|
+
cell: z(a, o, s),
|
|
1304
|
+
splats: Re(t.row, n),
|
|
1249
1305
|
start: r,
|
|
1250
1306
|
frozen: 0,
|
|
1251
1307
|
held: !1
|
|
1252
1308
|
};
|
|
1253
1309
|
}
|
|
1254
|
-
var
|
|
1255
|
-
function
|
|
1310
|
+
var z = (e, t, n) => ((e + 1) * 2 ** 21 + t) * 2 ** 21 + n;
|
|
1311
|
+
function Re({ count: e, quadrants: t }, n) {
|
|
1256
1312
|
return (n < 3 ? t[n] : e) - (n > 0 ? t[n - 1] : 0);
|
|
1257
1313
|
}
|
|
1258
|
-
function
|
|
1314
|
+
function ze(e, t) {
|
|
1259
1315
|
return e.held ? e.frozen : e.start === null ? 255 : Math.min(255, Math.round((t - e.start) / 250 * 255));
|
|
1260
1316
|
}
|
|
1261
1317
|
//#endregion
|
|
1262
1318
|
//#region src/engine/quality.ts
|
|
1263
|
-
var
|
|
1264
|
-
function
|
|
1265
|
-
return Math.min(n, Math.sqrt(
|
|
1319
|
+
var Be = 5e5, Ve = 2073600, He = [1, .85];
|
|
1320
|
+
function Ue(e, t, n, r) {
|
|
1321
|
+
return Math.min(n, Math.sqrt(Ve / Math.max(1, e * t))) * r;
|
|
1266
1322
|
}
|
|
1267
|
-
function
|
|
1323
|
+
function B(e, t) {
|
|
1268
1324
|
if (!e.length) return 0;
|
|
1269
1325
|
let n = [...e].sort((e, t) => e - t);
|
|
1270
1326
|
return n[Math.ceil(n.length * t) - 1];
|
|
1271
1327
|
}
|
|
1272
|
-
var
|
|
1328
|
+
var We = class {
|
|
1273
1329
|
#e = 0;
|
|
1274
1330
|
#t = [];
|
|
1275
1331
|
#n = -Infinity;
|
|
1276
1332
|
#r = 0;
|
|
1277
1333
|
#i = 0;
|
|
1278
1334
|
get scale() {
|
|
1279
|
-
return
|
|
1335
|
+
return He[this.#e];
|
|
1280
1336
|
}
|
|
1281
1337
|
full() {
|
|
1282
1338
|
this.#e = 0, this.#a();
|
|
@@ -1285,15 +1341,15 @@ var Ge = class {
|
|
|
1285
1341
|
this.#t = [], this.#r = 0, this.#i = 0, this.#n = -Infinity;
|
|
1286
1342
|
}
|
|
1287
1343
|
sample(e, t, n) {
|
|
1288
|
-
if (!n || t - this.#n > 250 || !Number.isFinite(e) || e <= 0) return this.#a(), this.#n = t, !1;
|
|
1344
|
+
if (!n || t - this.#n > Math.max(250, 2 * e) || !Number.isFinite(e) || e <= 0) return this.#a(), this.#n = t, !1;
|
|
1289
1345
|
let r = Math.max(0, t - this.#n);
|
|
1290
1346
|
if (this.#n = t, this.#t.push({
|
|
1291
1347
|
time: t,
|
|
1292
1348
|
ms: e
|
|
1293
|
-
}), this.#t = this.#t.filter((
|
|
1294
|
-
let i =
|
|
1349
|
+
}), this.#t = this.#t.filter((n) => t - n.time <= Math.max(1e3, 2 * e)), t - this.#t[0].time < 300) return !1;
|
|
1350
|
+
let i = B(this.#t.map((e) => e.ms), .9);
|
|
1295
1351
|
if (this.#r = i > 20 ? this.#r + r : 0, this.#i = i < 14 ? this.#i + r : 0, this.#r >= 2e3) {
|
|
1296
|
-
if (this.#e <
|
|
1352
|
+
if (this.#e < He.length - 1) this.#e++;
|
|
1297
1353
|
else return !1;
|
|
1298
1354
|
} else if (this.#i >= 5e3) {
|
|
1299
1355
|
if (this.#e > 0) this.#e--;
|
|
@@ -1301,7 +1357,7 @@ var Ge = class {
|
|
|
1301
1357
|
} else return !1;
|
|
1302
1358
|
return this.#a(), !0;
|
|
1303
1359
|
}
|
|
1304
|
-
},
|
|
1360
|
+
}, Ge = class {
|
|
1305
1361
|
#e;
|
|
1306
1362
|
#t = [];
|
|
1307
1363
|
#n = /* @__PURE__ */ new Set();
|
|
@@ -1380,12 +1436,12 @@ var Ge = class {
|
|
|
1380
1436
|
pages: o
|
|
1381
1437
|
};
|
|
1382
1438
|
}
|
|
1383
|
-
},
|
|
1439
|
+
}, Ke = {
|
|
1384
1440
|
idx: 8,
|
|
1385
1441
|
concurrency: 8,
|
|
1386
1442
|
gap: 65536,
|
|
1387
1443
|
span: 2097152
|
|
1388
|
-
},
|
|
1444
|
+
}, qe = 1e3, Je = 3e4, Ye = 1e3, Xe = 2e3, Ze = class {
|
|
1389
1445
|
#e;
|
|
1390
1446
|
#t;
|
|
1391
1447
|
#n;
|
|
@@ -1415,8 +1471,8 @@ var Ge = class {
|
|
|
1415
1471
|
#y = -Infinity;
|
|
1416
1472
|
#b = !1;
|
|
1417
1473
|
#x = !1;
|
|
1418
|
-
constructor(e, t, n, r, i, a =
|
|
1419
|
-
this.#e = e, this.#t = t, this.#n = n, this.#r = r, this.#i = i, this.#a = a, this.#o = new
|
|
1474
|
+
constructor(e, t, n, r, i, a = Ke) {
|
|
1475
|
+
this.#e = e, this.#t = t, this.#n = n, this.#r = r, this.#i = i, this.#a = a, this.#o = new Ge(a);
|
|
1420
1476
|
}
|
|
1421
1477
|
update(e, t, n) {
|
|
1422
1478
|
if (!this.#x) {
|
|
@@ -1483,7 +1539,7 @@ var Ge = class {
|
|
|
1483
1539
|
let n = this.#e.pages.get(e);
|
|
1484
1540
|
if (!n) return;
|
|
1485
1541
|
let { keep: r } = this.#s, i = this.#c;
|
|
1486
|
-
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 +
|
|
1542
|
+
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 + Ye), this.#A(e, Ye)), this.#r();
|
|
1487
1543
|
};
|
|
1488
1544
|
#E(e) {
|
|
1489
1545
|
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());
|
|
@@ -1497,7 +1553,7 @@ var Ge = class {
|
|
|
1497
1553
|
this.#b = !0, this.#i();
|
|
1498
1554
|
return;
|
|
1499
1555
|
}
|
|
1500
|
-
let n = this.#p.get(e), r = n ? Math.min(2 * n.delay,
|
|
1556
|
+
let n = this.#p.get(e), r = n ? Math.min(2 * n.delay, Je) : qe;
|
|
1501
1557
|
this.#p.set(e, {
|
|
1502
1558
|
delay: r,
|
|
1503
1559
|
until: this.#u + r
|
|
@@ -1518,11 +1574,11 @@ var Ge = class {
|
|
|
1518
1574
|
}
|
|
1519
1575
|
#M() {
|
|
1520
1576
|
let e = this.#u;
|
|
1521
|
-
if (e - this.#y <
|
|
1577
|
+
if (e - this.#y < Xe) return;
|
|
1522
1578
|
this.#y = e;
|
|
1523
1579
|
for (let e of this.#g) this.#n.holds(e) || this.#g.delete(e);
|
|
1524
1580
|
for (let [t, n] of this.#m) n <= e && this.#m.delete(t);
|
|
1525
|
-
for (let [t, n] of this.#_) e - n >=
|
|
1581
|
+
for (let [t, n] of this.#_) e - n >= Xe && this.#_.delete(t);
|
|
1526
1582
|
let { keep: t } = this.#s;
|
|
1527
1583
|
if (this.#e.pages.size <= 2 * (this.#g.size + t.size)) return;
|
|
1528
1584
|
let n = /* @__PURE__ */ new Set([
|
|
@@ -1547,7 +1603,7 @@ var Ge = class {
|
|
|
1547
1603
|
};
|
|
1548
1604
|
//#endregion
|
|
1549
1605
|
//#region src/engine/stream/remote.ts
|
|
1550
|
-
function
|
|
1606
|
+
function Qe(e, t) {
|
|
1551
1607
|
let n = /* @__PURE__ */ new Map();
|
|
1552
1608
|
return (r) => {
|
|
1553
1609
|
if ("unfetch" in r) return void n.get(r.unfetch)?.abort();
|
|
@@ -1570,29 +1626,29 @@ function $e(e, t) {
|
|
|
1570
1626
|
}
|
|
1571
1627
|
//#endregion
|
|
1572
1628
|
//#region src/engine/stream/worker.ts?worker&inline
|
|
1573
|
-
var et = "(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]}})();", tt = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", et], { type: "text/javascript;charset=utf-8" });
|
|
1574
|
-
function
|
|
1629
|
+
var $e = "(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]}})();", et = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", $e], { type: "text/javascript;charset=utf-8" });
|
|
1630
|
+
function tt(e) {
|
|
1575
1631
|
let t;
|
|
1576
1632
|
try {
|
|
1577
|
-
if (t =
|
|
1633
|
+
if (t = et && (self.URL || self.webkitURL).createObjectURL(et), !t) throw "";
|
|
1578
1634
|
let n = new Worker(t, { name: e?.name });
|
|
1579
1635
|
return n.addEventListener("error", () => {
|
|
1580
1636
|
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
1581
1637
|
}), n;
|
|
1582
1638
|
} catch {
|
|
1583
|
-
return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(
|
|
1639
|
+
return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent($e), { name: e?.name });
|
|
1584
1640
|
}
|
|
1585
1641
|
}
|
|
1586
1642
|
//#endregion
|
|
1587
1643
|
//#region src/engine/stream/loader.ts
|
|
1588
|
-
var
|
|
1644
|
+
var nt = class {
|
|
1589
1645
|
#e;
|
|
1590
1646
|
#t = /* @__PURE__ */ new Map();
|
|
1591
1647
|
#n = 0;
|
|
1592
1648
|
constructor(e) {
|
|
1593
1649
|
let { base: t, cache: n, source: r, workers: i } = e;
|
|
1594
1650
|
this.#e = Array.from({ length: i }, (e, a) => {
|
|
1595
|
-
let o = new
|
|
1651
|
+
let o = new tt(), s = { worker: o }, c = typeof r == "function" ? Qe(r, (e, t) => o.postMessage(e, t)) : void 0;
|
|
1596
1652
|
o.onmessage = ({ data: e }) => {
|
|
1597
1653
|
"id" in e ? this.#i(e) : c?.(e);
|
|
1598
1654
|
}, o.onerror = () => this.#a(s);
|
|
@@ -1616,8 +1672,8 @@ var rt = class {
|
|
|
1616
1672
|
return this.#r(this.#e[0], t);
|
|
1617
1673
|
}
|
|
1618
1674
|
batch(e, t, n) {
|
|
1619
|
-
if (t.aborted) return Promise.reject(
|
|
1620
|
-
let r = this.#e[
|
|
1675
|
+
if (t.aborted) return Promise.reject(V());
|
|
1676
|
+
let r = this.#e[rt(`${e.pack}#${e.window}`, this.#e.length)], i = {
|
|
1621
1677
|
type: "batch",
|
|
1622
1678
|
id: ++this.#n,
|
|
1623
1679
|
batch: e
|
|
@@ -1626,7 +1682,7 @@ var rt = class {
|
|
|
1626
1682
|
}
|
|
1627
1683
|
destroy() {
|
|
1628
1684
|
for (let { worker: e } of this.#e) e.terminate();
|
|
1629
|
-
for (let e of this.#t.values()) e.reject(
|
|
1685
|
+
for (let e of this.#t.values()) e.reject(V());
|
|
1630
1686
|
}
|
|
1631
1687
|
#r(e, t, n, r) {
|
|
1632
1688
|
if (e.error) return Promise.reject(e.error);
|
|
@@ -1638,7 +1694,7 @@ var rt = class {
|
|
|
1638
1694
|
s(), e.worker.postMessage({
|
|
1639
1695
|
type: "abort",
|
|
1640
1696
|
id: i
|
|
1641
|
-
}), o(
|
|
1697
|
+
}), o(V());
|
|
1642
1698
|
};
|
|
1643
1699
|
this.#t.set(i, {
|
|
1644
1700
|
slot: e,
|
|
@@ -1661,17 +1717,17 @@ var rt = class {
|
|
|
1661
1717
|
for (let t of this.#t.values()) t.slot === e && t.reject(e.error);
|
|
1662
1718
|
}
|
|
1663
1719
|
};
|
|
1664
|
-
function
|
|
1720
|
+
function rt(e, t) {
|
|
1665
1721
|
let n = 2166136261;
|
|
1666
1722
|
for (let t = 0; t < e.length; t++) n = Math.imul(n ^ e.charCodeAt(t), 16777619);
|
|
1667
1723
|
return (n >>> 0) % t;
|
|
1668
1724
|
}
|
|
1669
|
-
function
|
|
1725
|
+
function V() {
|
|
1670
1726
|
return new DOMException("The request was aborted.", "AbortError");
|
|
1671
1727
|
}
|
|
1672
1728
|
//#endregion
|
|
1673
1729
|
//#region src/engine/world/tree.ts
|
|
1674
|
-
var
|
|
1730
|
+
var H = (e, t, n) => (e * 256 + t) * 256 + n, it = class {
|
|
1675
1731
|
roots = [];
|
|
1676
1732
|
pages = /* @__PURE__ */ new Map();
|
|
1677
1733
|
units = /* @__PURE__ */ new Map();
|
|
@@ -1681,10 +1737,10 @@ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
|
|
|
1681
1737
|
#r = /* @__PURE__ */ new Map();
|
|
1682
1738
|
#i = /* @__PURE__ */ new Map();
|
|
1683
1739
|
constructor(e) {
|
|
1684
|
-
this.#e = new Set(e.roots.map(
|
|
1740
|
+
this.#e = new Set(e.roots.map(U)), this.#t = Math.max(...e.roots.map((e) => e.level));
|
|
1685
1741
|
}
|
|
1686
1742
|
add(e, t) {
|
|
1687
|
-
let n =
|
|
1743
|
+
let n = U(e), r = this.units.get(n);
|
|
1688
1744
|
if (r) return r;
|
|
1689
1745
|
let o = /* @__PURE__ */ new Map(), s = {
|
|
1690
1746
|
level: e.level,
|
|
@@ -1711,34 +1767,34 @@ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
|
|
|
1711
1767
|
null
|
|
1712
1768
|
]
|
|
1713
1769
|
};
|
|
1714
|
-
this.pages.set(r.id, r), s.pages.push(r), o.set(
|
|
1770
|
+
this.pages.set(r.id, r), s.pages.push(r), o.set(H(t.g, t.i, t.j), r);
|
|
1715
1771
|
}
|
|
1716
1772
|
this.units.set(n, s), this.#r.delete(n);
|
|
1717
1773
|
for (let t = e.level + 1; t <= this.#t; t++) {
|
|
1718
|
-
let n =
|
|
1774
|
+
let n = U(W(e, t));
|
|
1719
1775
|
this.#i.set(n, (this.#i.get(n) ?? 0) + 1);
|
|
1720
1776
|
}
|
|
1721
1777
|
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));
|
|
1722
1778
|
for (let e of s.pages) {
|
|
1723
1779
|
let { g: t, i: n, j: r } = e.row;
|
|
1724
|
-
c.has(t + 1) && (e.parent = o.get(
|
|
1780
|
+
c.has(t + 1) && (e.parent = o.get(H(t + 1, n >> 1, r >> 1)) ?? null);
|
|
1725
1781
|
for (let i = 0; i < 4; i++) {
|
|
1726
1782
|
let a = 2 * n + (i & 1), s = 2 * r + (i >> 1);
|
|
1727
|
-
c.has(t - 1) ? e.children[i] = o.get(
|
|
1783
|
+
c.has(t - 1) ? e.children[i] = o.get(H(t - 1, a, s)) ?? null : t === u && t > 0 && (e.children[i] = d.has((a >> 3) + 2 * (s >> 3)) ? void 0 : null);
|
|
1728
1784
|
}
|
|
1729
1785
|
}
|
|
1730
1786
|
if (this.#e.has(n)) for (let e of s.pages) e.g === l && this.roots.push(e);
|
|
1731
1787
|
else {
|
|
1732
|
-
let t = this.units.get(
|
|
1788
|
+
let t = this.units.get(U(W(e, e.level + 1)));
|
|
1733
1789
|
t && this.#o(t, s);
|
|
1734
1790
|
}
|
|
1735
1791
|
let f = a(s.idx);
|
|
1736
1792
|
for (let { key: t } of f) {
|
|
1737
|
-
let n = t.level === e.level - 1 ? this.units.get(
|
|
1793
|
+
let n = t.level === e.level - 1 ? this.units.get(U(t)) : void 0;
|
|
1738
1794
|
n && this.#o(s, n);
|
|
1739
1795
|
}
|
|
1740
1796
|
for (let { key: e, hash: t } of f) {
|
|
1741
|
-
let n =
|
|
1797
|
+
let n = U(e);
|
|
1742
1798
|
if (this.units.has(n)) continue;
|
|
1743
1799
|
let r = this.#r.get(n);
|
|
1744
1800
|
if (r && r.from <= s.level) continue;
|
|
@@ -1759,20 +1815,20 @@ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
|
|
|
1759
1815
|
}
|
|
1760
1816
|
ground(e, t) {
|
|
1761
1817
|
for (let n of this.roots) {
|
|
1762
|
-
let [r, i, a] =
|
|
1818
|
+
let [r, i, a] = at(n);
|
|
1763
1819
|
if (e < r || e >= r + a || t < i || t >= i + a) continue;
|
|
1764
1820
|
let o = n;
|
|
1765
1821
|
for (;;) {
|
|
1766
1822
|
let n = +(e >= r + a / 2), s = +(t >= i + a / 2), c = o.children[n + 2 * s];
|
|
1767
1823
|
if (!c) return o.box[2];
|
|
1768
|
-
o = c, [r, i, a] =
|
|
1824
|
+
o = c, [r, i, a] = at(o);
|
|
1769
1825
|
}
|
|
1770
1826
|
}
|
|
1771
1827
|
}
|
|
1772
1828
|
prune(e) {
|
|
1773
1829
|
let t = [], n = [...this.units.values()].sort((e, t) => e.level - t.level);
|
|
1774
1830
|
for (let r of n) {
|
|
1775
|
-
let n =
|
|
1831
|
+
let n = U(r);
|
|
1776
1832
|
if (this.#e.has(n) || this.#i.has(n) || r.pages.some((t) => e.has(t.id))) continue;
|
|
1777
1833
|
for (let e of r.pages) this.pages.delete(e.id), t.push(e.id);
|
|
1778
1834
|
let i = r.parent;
|
|
@@ -1782,7 +1838,7 @@ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
|
|
|
1782
1838
|
}
|
|
1783
1839
|
this.units.delete(n);
|
|
1784
1840
|
for (let e = r.level + 1; e <= this.#t; e++) {
|
|
1785
|
-
let t =
|
|
1841
|
+
let t = U(W(r, e)), n = this.#i.get(t) - 1;
|
|
1786
1842
|
n ? this.#i.set(t, n) : this.#i.delete(t);
|
|
1787
1843
|
}
|
|
1788
1844
|
for (let { key: e } of a(r.idx)) this.#a(e);
|
|
@@ -1791,12 +1847,12 @@ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
|
|
|
1791
1847
|
return t;
|
|
1792
1848
|
}
|
|
1793
1849
|
#a(e) {
|
|
1794
|
-
let t =
|
|
1850
|
+
let t = U(e);
|
|
1795
1851
|
this.#r.delete(t);
|
|
1796
1852
|
for (let n = e.level + 1; n <= e.level + 3; n++) {
|
|
1797
|
-
let r = this.units.get(
|
|
1853
|
+
let r = this.units.get(U(W(e, n)));
|
|
1798
1854
|
if (!r) continue;
|
|
1799
|
-
let o = a(r.idx).find((e) =>
|
|
1855
|
+
let o = a(r.idx).find((e) => U(e.key) === t);
|
|
1800
1856
|
if (!o) continue;
|
|
1801
1857
|
let s = {
|
|
1802
1858
|
level: e.level,
|
|
@@ -1818,23 +1874,23 @@ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
|
|
|
1818
1874
|
for (let n of this.#s(e, t)) n.children.fill(null);
|
|
1819
1875
|
for (let e of t.pages) {
|
|
1820
1876
|
if (e.g !== n) continue;
|
|
1821
|
-
let t = 8 * i + e.row.i, r = 8 * a + e.row.j, s = o.get(
|
|
1877
|
+
let t = 8 * i + e.row.i, r = 8 * a + e.row.j, s = o.get(H(n + 1, t >> 1, r >> 1)) ?? null;
|
|
1822
1878
|
e.parent = s, s && (s.children[(t & 1) + 2 * (r & 1)] = e);
|
|
1823
1879
|
}
|
|
1824
1880
|
}
|
|
1825
1881
|
#s(t, n) {
|
|
1826
1882
|
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 = [];
|
|
1827
1883
|
for (let e = o; e < o + s; e++) for (let n = a; n < a + s; n++) {
|
|
1828
|
-
let i = t.grid.get(
|
|
1884
|
+
let i = t.grid.get(H(r, n, e));
|
|
1829
1885
|
i && c.push(i);
|
|
1830
1886
|
}
|
|
1831
1887
|
return c;
|
|
1832
1888
|
}
|
|
1833
1889
|
};
|
|
1834
|
-
function
|
|
1890
|
+
function U(e) {
|
|
1835
1891
|
return `${e.level}/${e.e}/${e.n}`;
|
|
1836
1892
|
}
|
|
1837
|
-
function
|
|
1893
|
+
function W(e, t) {
|
|
1838
1894
|
let n = 250 * 2 ** t;
|
|
1839
1895
|
return {
|
|
1840
1896
|
level: t,
|
|
@@ -1842,7 +1898,7 @@ function U(e, t) {
|
|
|
1842
1898
|
n: Math.floor(e.n / n) * n
|
|
1843
1899
|
};
|
|
1844
1900
|
}
|
|
1845
|
-
function
|
|
1901
|
+
function at(t) {
|
|
1846
1902
|
let n = e * 2 ** t.g;
|
|
1847
1903
|
return [
|
|
1848
1904
|
t.unit.e + t.row.i * n,
|
|
@@ -1852,39 +1908,39 @@ function ot(t) {
|
|
|
1852
1908
|
}
|
|
1853
1909
|
//#endregion
|
|
1854
1910
|
//#region src/engine/engine.ts
|
|
1855
|
-
var
|
|
1911
|
+
var G = class extends Error {
|
|
1856
1912
|
constructor() {
|
|
1857
1913
|
super("This viewer needs WebGPU. Update to the latest Chrome, Edge, Safari or Firefox."), this.name = "NoWebGpu";
|
|
1858
1914
|
}
|
|
1859
1915
|
};
|
|
1860
|
-
async function
|
|
1916
|
+
async function ot(e, t) {
|
|
1861
1917
|
let n = await p();
|
|
1862
|
-
if (!n) throw new
|
|
1918
|
+
if (!n) throw new G();
|
|
1863
1919
|
let r = e.getContext("webgpu");
|
|
1864
|
-
if (!r) throw n.device.destroy(), new
|
|
1920
|
+
if (!r) throw n.device.destroy(), new G();
|
|
1865
1921
|
r.configure({
|
|
1866
1922
|
device: n.device,
|
|
1867
1923
|
format: n.format,
|
|
1868
1924
|
alphaMode: "opaque"
|
|
1869
1925
|
}), (t.cache ?? "opfs") === "opfs" && navigator.storage?.persist().catch(() => !1);
|
|
1870
1926
|
let { source: i = "http" } = t;
|
|
1871
|
-
return new Ot(e, n, r, t, i === "synthetic" ? (await import("./synthetic-
|
|
1927
|
+
return new Ot(e, n, r, t, i === "synthetic" ? (await import("./synthetic-BeGCzYIv.js")).synthetic() : i === "http" ? s : i);
|
|
1872
1928
|
}
|
|
1873
|
-
var
|
|
1874
|
-
function
|
|
1929
|
+
var K = .2, st = 25165824, ct = 2.5, lt = 1 + R, ut = 1024, dt = 2048, ft = 100, pt = 2, q = 300, mt = 100, ht = 250, gt = 300, _t = 1e3, vt = 400, yt = 5e3, bt = 60, J = Math.PI / 180, xt = "The viewer was closed.", St = "Another world was opened.";
|
|
1930
|
+
function Ct(e, t) {
|
|
1875
1931
|
let n = Math.min(t.maxStorageBufferBindingSize, t.maxBufferSize), r = (t, r) => {
|
|
1876
1932
|
let i = Math.ceil(e * t / 256) * 256;
|
|
1877
1933
|
return Math.min(i, Math.floor(n / r / 256) * 256);
|
|
1878
1934
|
};
|
|
1879
1935
|
return {
|
|
1880
|
-
pool: r(
|
|
1881
|
-
frame: r(
|
|
1936
|
+
pool: r(ct, 16),
|
|
1937
|
+
frame: r(lt, 24)
|
|
1882
1938
|
};
|
|
1883
1939
|
}
|
|
1884
1940
|
function wt(e, t) {
|
|
1885
1941
|
let [n, r, i] = t;
|
|
1886
|
-
if (Math.hypot(n - e[0], r - e[1], i - e[2]) <=
|
|
1887
|
-
let a = (e) => Math.round(e /
|
|
1942
|
+
if (Math.hypot(n - e[0], r - e[1], i - e[2]) <= dt) return e;
|
|
1943
|
+
let a = (e) => Math.round(e / ut) * ut;
|
|
1888
1944
|
return [
|
|
1889
1945
|
a(n),
|
|
1890
1946
|
a(r),
|
|
@@ -1911,7 +1967,7 @@ function Et(e, t) {
|
|
|
1911
1967
|
];
|
|
1912
1968
|
}
|
|
1913
1969
|
function Dt(e, t) {
|
|
1914
|
-
e.push(t), e.length >
|
|
1970
|
+
e.push(t), e.length > bt && e.shift();
|
|
1915
1971
|
}
|
|
1916
1972
|
var Ot = class {
|
|
1917
1973
|
#e;
|
|
@@ -1920,12 +1976,12 @@ var Ot = class {
|
|
|
1920
1976
|
#r;
|
|
1921
1977
|
#i;
|
|
1922
1978
|
#a;
|
|
1923
|
-
#o = new
|
|
1979
|
+
#o = new We();
|
|
1924
1980
|
#s;
|
|
1925
1981
|
#c;
|
|
1926
1982
|
#l;
|
|
1927
|
-
#u = new
|
|
1928
|
-
#d = new
|
|
1983
|
+
#u = new Me();
|
|
1984
|
+
#d = new Fe();
|
|
1929
1985
|
#f = (e) => this.#s.has(e);
|
|
1930
1986
|
#p = null;
|
|
1931
1987
|
#m = null;
|
|
@@ -1969,7 +2025,7 @@ var Ot = class {
|
|
|
1969
2025
|
#L = !1;
|
|
1970
2026
|
#R = !1;
|
|
1971
2027
|
#z = !1;
|
|
1972
|
-
#B =
|
|
2028
|
+
#B = [];
|
|
1973
2029
|
#V = -Infinity;
|
|
1974
2030
|
#H = -Infinity;
|
|
1975
2031
|
#U = -Infinity;
|
|
@@ -1991,8 +2047,8 @@ var Ot = class {
|
|
|
1991
2047
|
e.height,
|
|
1992
2048
|
1
|
|
1993
2049
|
], this.#k = [Math.max(1, e.width), Math.max(1, e.height)];
|
|
1994
|
-
let { pool: a, frame: o } =
|
|
1995
|
-
this.#s = new _(t.device, a), this.#c = new
|
|
2050
|
+
let { pool: a, frame: o } = Ct(this.#ne, t.device.limits);
|
|
2051
|
+
this.#s = new _(t.device, a), this.#c = new we(t, n, this.#s, o), this.#l = o, t.device.lost.then((e) => {
|
|
1996
2052
|
if (!this.#ee) {
|
|
1997
2053
|
this.#te = !0, cancelAnimationFrame(this.#A);
|
|
1998
2054
|
for (let t of this.#Z) t(e.message || e.reason);
|
|
@@ -2000,34 +2056,34 @@ var Ot = class {
|
|
|
2000
2056
|
});
|
|
2001
2057
|
}
|
|
2002
2058
|
async open(e) {
|
|
2003
|
-
if (this.#ee) throw Error(
|
|
2059
|
+
if (this.#ee) throw Error(xt);
|
|
2004
2060
|
let t = ++this.#_, i = () => {
|
|
2005
|
-
if (this.#ee) throw Error(
|
|
2006
|
-
if (t !== this.#_) throw Error(
|
|
2061
|
+
if (this.#ee) throw Error(xt);
|
|
2062
|
+
if (t !== this.#_) throw Error(St);
|
|
2007
2063
|
}, { cache: a = "opfs", source: o = "http" } = this.#r;
|
|
2008
2064
|
o === "http" && (e = new URL(e, document.baseURI).href);
|
|
2009
2065
|
let s = await this.#i(e, null), c = r(JSON.parse(new TextDecoder().decode(s)));
|
|
2010
2066
|
i();
|
|
2011
|
-
let l = new
|
|
2067
|
+
let l = new nt({
|
|
2012
2068
|
base: n(e),
|
|
2013
2069
|
workers: Math.min(6, Math.max(2, navigator.hardwareConcurrency - 2)),
|
|
2014
2070
|
cache: a,
|
|
2015
2071
|
source: o
|
|
2016
|
-
}), u = new
|
|
2072
|
+
}), u = new it(c);
|
|
2017
2073
|
try {
|
|
2018
2074
|
let e = await Promise.all(c.roots.map((e) => l.idx(e.idx)));
|
|
2019
2075
|
i(), e.forEach((e, t) => u.add(e, c.roots[t].idx));
|
|
2020
2076
|
} catch (e) {
|
|
2021
2077
|
throw l.destroy(), e;
|
|
2022
2078
|
}
|
|
2023
|
-
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
|
|
2079
|
+
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 Me(), this.#d = new Fe(), this.#s.clear(), this.#g = this.#ie(u, l), this.#I = !0, this.requestFrame(), c;
|
|
2024
2080
|
}
|
|
2025
2081
|
setCamera(e) {
|
|
2026
2082
|
if (this.#ee) return;
|
|
2027
2083
|
let t = performance.now(), n = t - this.#b, r = this.#y, i = this.#x;
|
|
2028
|
-
if (n >
|
|
2084
|
+
if (n > ht) i.fill(0);
|
|
2029
2085
|
else if (n > 0) {
|
|
2030
|
-
let t = 1 - Math.exp(-n /
|
|
2086
|
+
let t = 1 - Math.exp(-n / mt);
|
|
2031
2087
|
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]);
|
|
2032
2088
|
}
|
|
2033
2089
|
this.#b = t, this.#y = { ...e }, this.#F = !0, this.#$ || this.requestFrame();
|
|
@@ -2038,7 +2094,7 @@ var Ot = class {
|
|
|
2038
2094
|
...this.#a,
|
|
2039
2095
|
...e
|
|
2040
2096
|
};
|
|
2041
|
-
let { pool: t, frame: n } =
|
|
2097
|
+
let { pool: t, frame: n } = Ct(this.#ne, this.#t.device.limits);
|
|
2042
2098
|
(t > this.#s.capacity || n > this.#l) && this.#re(t, n), this.#I = !0, this.requestFrame();
|
|
2043
2099
|
}
|
|
2044
2100
|
resize(e, t, n) {
|
|
@@ -2075,8 +2131,8 @@ var Ot = class {
|
|
|
2075
2131
|
stats() {
|
|
2076
2132
|
let e = this.#s, t = this.#g, n = this.#c.stats();
|
|
2077
2133
|
return {
|
|
2078
|
-
frameMs:
|
|
2079
|
-
cpuMs:
|
|
2134
|
+
frameMs: B(this.#W, .5),
|
|
2135
|
+
cpuMs: B(this.#G, .5),
|
|
2080
2136
|
gpuMs: n.gpuMs,
|
|
2081
2137
|
passes: n.passes,
|
|
2082
2138
|
drawn: n.drawn,
|
|
@@ -2084,7 +2140,7 @@ var Ot = class {
|
|
|
2084
2140
|
missing: this.#N?.missing ?? 0,
|
|
2085
2141
|
pages: {
|
|
2086
2142
|
resident: Array.from(e.ids()).length,
|
|
2087
|
-
drawn: this.#B,
|
|
2143
|
+
drawn: this.#B.length,
|
|
2088
2144
|
loading: t?.loading ?? 0,
|
|
2089
2145
|
queued: t?.queued ?? 0
|
|
2090
2146
|
},
|
|
@@ -2114,7 +2170,7 @@ var Ot = class {
|
|
|
2114
2170
|
}
|
|
2115
2171
|
warm() {
|
|
2116
2172
|
let e = performance.now();
|
|
2117
|
-
e - this.#V <
|
|
2173
|
+
e - this.#V < _t || (this.#H = e + vt, this.requestFrame());
|
|
2118
2174
|
}
|
|
2119
2175
|
onFrame(e) {
|
|
2120
2176
|
return this.#Q.add(e), () => this.#Q.delete(e);
|
|
@@ -2150,26 +2206,26 @@ var Ot = class {
|
|
|
2150
2206
|
}
|
|
2151
2207
|
}
|
|
2152
2208
|
get #ne() {
|
|
2153
|
-
let e = Math.floor(
|
|
2209
|
+
let e = Math.floor(Ct(Infinity, this.#t.device.limits).frame / lt);
|
|
2154
2210
|
return Math.max(1, Math.min(this.#a.budget, e));
|
|
2155
2211
|
}
|
|
2156
2212
|
#re(e, t) {
|
|
2157
2213
|
this.#g?.destroy(), this.#g = null, this.#c.destroy(), this.#s.destroy(), this.#s = new _(this.#t.device, e), this.#s.setOrigin(this.#S);
|
|
2158
|
-
let n = new
|
|
2214
|
+
let n = new we(this.#t, this.#n, this.#s, t);
|
|
2159
2215
|
n.resize(...this.#k);
|
|
2160
2216
|
for (let e of this.#K) e.off = n.shade(e.hook);
|
|
2161
2217
|
for (let e of this.#q) e.off = n.post(e.hook);
|
|
2162
2218
|
this.#c = n, this.#l = t, this.#m && this.#h && (this.#g = this.#ie(this.#m, this.#h)), this.#N = null, this.#I = !0, this.requestFrame();
|
|
2163
2219
|
}
|
|
2164
2220
|
#ie(e, t) {
|
|
2165
|
-
return new
|
|
2221
|
+
return new Ze(e, t, this.#s, () => {
|
|
2166
2222
|
this.#R = !0, this.requestFrame();
|
|
2167
2223
|
}, this.#ae);
|
|
2168
2224
|
}
|
|
2169
2225
|
#ae = () => {
|
|
2170
2226
|
let e = this.#p, t = this.#m;
|
|
2171
2227
|
this.#v || this.#ee || e === null || (this.#v = !0, this.open(e).then(() => this.#v = !1, () => {
|
|
2172
|
-
this.#v = !1, this.#m === t && setTimeout(this.#ae,
|
|
2228
|
+
this.#v = !1, this.#m === t && setTimeout(this.#ae, yt);
|
|
2173
2229
|
}));
|
|
2174
2230
|
};
|
|
2175
2231
|
#oe(e, t, n) {
|
|
@@ -2183,12 +2239,12 @@ var Ot = class {
|
|
|
2183
2239
|
};
|
|
2184
2240
|
}
|
|
2185
2241
|
#se() {
|
|
2186
|
-
let [e, t, n] = this.#O, r =
|
|
2242
|
+
let [e, t, n] = this.#O, r = Ue(e, t, n, this.#o.scale), i = Math.max(1, Math.round(e * r)), a = Math.max(1, Math.round(t * r));
|
|
2187
2243
|
(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());
|
|
2188
2244
|
}
|
|
2189
2245
|
#ce = (e) => {
|
|
2190
2246
|
if (this.#A = 0, !(this.#ee || this.#te)) {
|
|
2191
|
-
if (this.#j >=
|
|
2247
|
+
if (this.#j >= pt) this.#M = !0;
|
|
2192
2248
|
else {
|
|
2193
2249
|
this.#$ = !0;
|
|
2194
2250
|
for (let t of this.#Q) t(e);
|
|
@@ -2208,36 +2264,36 @@ var Ot = class {
|
|
|
2208
2264
|
]);
|
|
2209
2265
|
l !== this.#S && (this.#S = l, r.setOrigin(l));
|
|
2210
2266
|
let u = Et(i, l);
|
|
2211
|
-
y(this.#C, u, i.yaw *
|
|
2267
|
+
y(this.#C, u, i.yaw * J, i.pitch * J), b(this.#w, i.fov * J, a / o, K, s);
|
|
2212
2268
|
let d = {
|
|
2213
2269
|
time: t,
|
|
2214
2270
|
width: a,
|
|
2215
2271
|
height: o,
|
|
2216
2272
|
view: new Float32Array(this.#C),
|
|
2217
2273
|
proj: new Float32Array(this.#w),
|
|
2218
|
-
near:
|
|
2274
|
+
near: K,
|
|
2219
2275
|
far: s,
|
|
2220
2276
|
camera: Float32Array.from(u),
|
|
2221
2277
|
origin: l
|
|
2222
2278
|
};
|
|
2223
|
-
|
|
2224
|
-
let f = this.#m, p = this.#g, m = this.#N;
|
|
2279
|
+
Ee(this.#D, S(this.#E, d.proj, d.view));
|
|
2280
|
+
let f = this.#m, p = this.#g, m = this.#R || this.#I || this.#z, h = this.#N, g = h;
|
|
2225
2281
|
if (f && p) {
|
|
2226
|
-
let e = !p.idle && t - this.#P >=
|
|
2227
|
-
(!
|
|
2282
|
+
let e = !p.idle && t - this.#P >= ft, n = this.#I || this.#R || this.#z || this.#L;
|
|
2283
|
+
(!g || c || e || n) && (g = this.#ue(f, t, c));
|
|
2228
2284
|
}
|
|
2229
|
-
let
|
|
2230
|
-
|
|
2231
|
-
let
|
|
2232
|
-
if (!this.#R && !this.#L && !
|
|
2285
|
+
let _ = this.#B, v = this.#z;
|
|
2286
|
+
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(st) > 0 && (this.#R = !0), (_ !== this.#B || this.#R) && r.draw(_), this.#z = v, this.#B = _;
|
|
2287
|
+
let x = this.#J.splice(0).map((e) => this.#fe(e, d)), C = this.#Y.splice(0).map((e) => this.#pe(e, l)), w = this.#c.render(d, this.#D, this.#r.sky, x, C), T = performance.now() - t;
|
|
2288
|
+
if (!this.#R && !this.#L && !v && r.queued === 0 && (!p || p.idle) && (!g || g.load.length === 0 && g.idx.length === 0) && this.#X.length) {
|
|
2233
2289
|
let e = this.#X.splice(0);
|
|
2234
|
-
|
|
2290
|
+
w.then(() => e.forEach((e) => e()));
|
|
2235
2291
|
}
|
|
2236
|
-
e && this.#me(t,
|
|
2237
|
-
let
|
|
2238
|
-
return (r.queued > 0 || this.#R || this.#L ||
|
|
2239
|
-
done:
|
|
2240
|
-
cpuMs:
|
|
2292
|
+
e && this.#me(t, T, c);
|
|
2293
|
+
let E = t < this.#H;
|
|
2294
|
+
return (r.queued > 0 || this.#R || this.#L || v || n.scale < 1 || E) && this.requestFrame(), {
|
|
2295
|
+
done: w,
|
|
2296
|
+
cpuMs: T
|
|
2241
2297
|
};
|
|
2242
2298
|
}
|
|
2243
2299
|
#ue(e, t, n) {
|
|
@@ -2245,15 +2301,15 @@ var Ot = class {
|
|
|
2245
2301
|
origin: this.#S,
|
|
2246
2302
|
width: a / s,
|
|
2247
2303
|
height: o / s,
|
|
2248
|
-
tan: Math.tan(r.fov *
|
|
2249
|
-
near:
|
|
2304
|
+
tan: Math.tan(r.fov * J / 2),
|
|
2305
|
+
near: K,
|
|
2250
2306
|
far: this.#a.viewDistance
|
|
2251
2307
|
}, u = {
|
|
2252
2308
|
...l,
|
|
2253
2309
|
view: this.#C
|
|
2254
2310
|
}, d = {
|
|
2255
2311
|
budget: c,
|
|
2256
|
-
capacity: i.capacity - Math.ceil(
|
|
2312
|
+
capacity: i.capacity - Math.ceil(R * c),
|
|
2257
2313
|
now: t,
|
|
2258
2314
|
predicted: n ? this.#de(l) : void 0
|
|
2259
2315
|
}, f = this.#u.plan(e, u, this.#f, d);
|
|
@@ -2263,13 +2319,13 @@ var Ot = class {
|
|
|
2263
2319
|
let t = this.#x;
|
|
2264
2320
|
if (t.every((e) => e === 0)) return;
|
|
2265
2321
|
let n = this.#y, r = [
|
|
2266
|
-
n.e + t[0] *
|
|
2267
|
-
n.n + t[1] *
|
|
2268
|
-
n.h + t[2] *
|
|
2322
|
+
n.e + t[0] * q - e.origin[0],
|
|
2323
|
+
n.n + t[1] * q - e.origin[1],
|
|
2324
|
+
n.h + t[2] * q - e.origin[2]
|
|
2269
2325
|
];
|
|
2270
2326
|
return {
|
|
2271
2327
|
...e,
|
|
2272
|
-
view: y(this.#T, r, n.yaw *
|
|
2328
|
+
view: y(this.#T, r, n.yaw * J, n.pitch * J)
|
|
2273
2329
|
};
|
|
2274
2330
|
}
|
|
2275
2331
|
#fe({ x: e, y: t, resolve: n }, r) {
|
|
@@ -2292,8 +2348,8 @@ var Ot = class {
|
|
|
2292
2348
|
};
|
|
2293
2349
|
}
|
|
2294
2350
|
#me(e, t, n) {
|
|
2295
|
-
let r = this.#o, i = e - this.#V <=
|
|
2296
|
-
|
|
2351
|
+
let r = this.#o, { gpuMs: i } = this.#c.stats(), a = e - this.#V <= Math.max(ht, 2 * i, 2 * t);
|
|
2352
|
+
a && Dt(this.#W, e - this.#V), Dt(this.#G, t), this.#V = e, r.sample(i, e, a && n) && this.#se(), n ? this.#U = e : r.scale < 1 && e - this.#U > gt && (r.full(), this.#se());
|
|
2297
2353
|
}
|
|
2298
2354
|
}, kt = 45, At = {
|
|
2299
2355
|
yaw: 0,
|
|
@@ -2630,4 +2686,4 @@ function $(e, t, n) {
|
|
|
2630
2686
|
e[0] += t, e[1] += n;
|
|
2631
2687
|
}
|
|
2632
2688
|
//#endregion
|
|
2633
|
-
export {
|
|
2689
|
+
export { ae as S, qt as _, Q as a, ot as b, Wt as c, Ht as d, Vt as f, Bt as g, It as h, Kt as i, Lt as l, Gt as m, kt as n, Z as o, Ft as p, Y as r, At as s, nn as t, Ut as u, zt as v, Be as x, G as y };
|