@voluma/vlam 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +60 -0
  3. package/THIRD_PARTY_NOTICES.md +86 -0
  4. package/dist/budget-governor.d.ts +154 -0
  5. package/dist/camera-budget-governor.d.ts +234 -0
  6. package/dist/chunk-cache-budget.d.ts +156 -0
  7. package/dist/chunk-fetch-scheduler.d.ts +168 -0
  8. package/dist/chunk-loader.d.ts +85 -0
  9. package/dist/compute-sorter.d.ts +131 -0
  10. package/dist/create-splat-renderer.d.ts +99 -0
  11. package/dist/dataset-source.d.ts +55 -0
  12. package/dist/depth-of-field.d.ts +73 -0
  13. package/dist/effects.d.ts +337 -0
  14. package/dist/effects.js +180 -0
  15. package/dist/effects.js.map +1 -0
  16. package/dist/formats/ksplat/index.d.ts +8 -0
  17. package/dist/formats/ksplat/parse-ksplat.d.ts +9 -0
  18. package/dist/formats/ksplat.js +167 -0
  19. package/dist/formats/ksplat.js.map +1 -0
  20. package/dist/formats/lcc/collision-mesh.d.ts +37 -0
  21. package/dist/formats/lcc/collision-partition.d.ts +35 -0
  22. package/dist/formats/lcc/index.d.ts +16 -0
  23. package/dist/formats/lcc/lcc.d.ts +28 -0
  24. package/dist/formats/lcc/lcc2-transform.d.ts +18 -0
  25. package/dist/formats/lcc/lcc2.d.ts +4 -0
  26. package/dist/formats/lcc/parse-collision-lci.d.ts +28 -0
  27. package/dist/formats/lcc/parse-lcc.d.ts +177 -0
  28. package/dist/formats/lcc/parse-mesh-ply.d.ts +21 -0
  29. package/dist/formats/lcc.js +969 -0
  30. package/dist/formats/lcc.js.map +1 -0
  31. package/dist/formats/ply/index.d.ts +12 -0
  32. package/dist/formats/ply/parse-compressed-ply.d.ts +16 -0
  33. package/dist/formats/ply/parse-splat-ply.d.ts +46 -0
  34. package/dist/formats/ply.js +230 -0
  35. package/dist/formats/ply.js.map +1 -0
  36. package/dist/formats/rad/frontier-worker-protocol.d.ts +177 -0
  37. package/dist/formats/rad/index.d.ts +10 -0
  38. package/dist/formats/rad/parse-rad.d.ts +88 -0
  39. package/dist/formats/rad/rad-column-decoders.d.ts +15 -0
  40. package/dist/formats/rad/rad-foveated-source.d.ts +71 -0
  41. package/dist/formats/rad/rad-parent-sizes.d.ts +45 -0
  42. package/dist/formats/rad/rad.d.ts +132 -0
  43. package/dist/formats/rad.js +1098 -0
  44. package/dist/formats/rad.js.map +1 -0
  45. package/dist/formats/sog/index.d.ts +9 -0
  46. package/dist/formats/sog/parse-sog.d.ts +45 -0
  47. package/dist/formats/sog.js +257 -0
  48. package/dist/formats/sog.js.map +1 -0
  49. package/dist/formats/splat/index.d.ts +8 -0
  50. package/dist/formats/splat/parse-splat.d.ts +10 -0
  51. package/dist/formats/splat.js +39 -0
  52. package/dist/formats/splat.js.map +1 -0
  53. package/dist/formats/spz/index.d.ts +8 -0
  54. package/dist/formats/spz/parse-spz.d.ts +10 -0
  55. package/dist/formats/spz.js +218 -0
  56. package/dist/formats/spz.js.map +1 -0
  57. package/dist/frontier-worker-CAnK_Cmu.js +566 -0
  58. package/dist/frontier-worker-CAnK_Cmu.js.map +1 -0
  59. package/dist/half-float-Cs4FDq8Q.js +30 -0
  60. package/dist/half-float-Cs4FDq8Q.js.map +1 -0
  61. package/dist/half-float.d.ts +15 -0
  62. package/dist/index.d.ts +54 -0
  63. package/dist/index.js +9054 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/load-scene.d.ts +50 -0
  66. package/dist/load-worker-protocol.d.ts +82 -0
  67. package/dist/loading-wLo8vRbA.js +102 -0
  68. package/dist/loading-wLo8vRbA.js.map +1 -0
  69. package/dist/loading.d.ts +150 -0
  70. package/dist/lod-manifest.d.ts +61 -0
  71. package/dist/lod-scheduler.d.ts +229 -0
  72. package/dist/lod-source.d.ts +207 -0
  73. package/dist/logging-BfPdd7NJ.js +19 -0
  74. package/dist/logging-BfPdd7NJ.js.map +1 -0
  75. package/dist/logging.d.ts +37 -0
  76. package/dist/one-shot-worker-G80btnth.js +664 -0
  77. package/dist/one-shot-worker-G80btnth.js.map +1 -0
  78. package/dist/orientation.d.ts +35 -0
  79. package/dist/ply-header-BwgExCn-.js +125 -0
  80. package/dist/ply-header-BwgExCn-.js.map +1 -0
  81. package/dist/ply-header.d.ts +87 -0
  82. package/dist/radix-sort.d.ts +28 -0
  83. package/dist/radix-sorter.d.ts +46 -0
  84. package/dist/relighting.d.ts +50 -0
  85. package/dist/selection-volume.d.ts +87 -0
  86. package/dist/sh-pack-D5wAe5gg.js +54 -0
  87. package/dist/sh-pack-D5wAe5gg.js.map +1 -0
  88. package/dist/sh-pack.d.ts +49 -0
  89. package/dist/sort-scheduler.d.ts +62 -0
  90. package/dist/sort-worker-protocol.d.ts +37 -0
  91. package/dist/sorter.d.ts +31 -0
  92. package/dist/source-transform.d.ts +57 -0
  93. package/dist/splat-budget-PSojLJPO.js +157 -0
  94. package/dist/splat-budget-PSojLJPO.js.map +1 -0
  95. package/dist/splat-budget.d.ts +404 -0
  96. package/dist/splat-data-BZM5dhhx.js +10 -0
  97. package/dist/splat-data-BZM5dhhx.js.map +1 -0
  98. package/dist/splat-data.d.ts +150 -0
  99. package/dist/splat-depth-pack.d.ts +39 -0
  100. package/dist/splat-mesh-material.d.ts +255 -0
  101. package/dist/splat-mesh-picking.d.ts +87 -0
  102. package/dist/splat-mesh-pool.d.ts +241 -0
  103. package/dist/splat-mesh-types-8QDjTbZO.js +390 -0
  104. package/dist/splat-mesh-types-8QDjTbZO.js.map +1 -0
  105. package/dist/splat-mesh-types.d.ts +390 -0
  106. package/dist/splat-mesh.d.ts +737 -0
  107. package/dist/splat-modifier-stack.d.ts +38 -0
  108. package/dist/splat-modifier.d.ts +156 -0
  109. package/dist/splat-partition.d.ts +37 -0
  110. package/dist/splat-query.d.ts +51 -0
  111. package/dist/splat-scene.d.ts +127 -0
  112. package/dist/splat-sort-bounds.d.ts +11 -0
  113. package/dist/static-lod-splat-mesh.d.ts +53 -0
  114. package/dist/static-lod-worker-D2fyqQZO.js +474 -0
  115. package/dist/static-lod-worker-D2fyqQZO.js.map +1 -0
  116. package/dist/static-lod-worker-protocol.d.ts +37 -0
  117. package/dist/static-lod.d.ts +24 -0
  118. package/dist/storage-attribute-mirror.d.ts +103 -0
  119. package/dist/streamed-splat-mesh-utils.d.ts +146 -0
  120. package/dist/streamed-splat-mesh.d.ts +985 -0
  121. package/dist/unified-splat-renderer.d.ts +205 -0
  122. package/dist/webgpu-limits.d.ts +133 -0
  123. package/dist/work-buffer-gather.d.ts +119 -0
  124. package/dist/work-buffer-material.d.ts +42 -0
  125. package/dist/worker-sorter.d.ts +57 -0
  126. package/dist/xr-view.d.ts +92 -0
  127. package/package.json +135 -21
@@ -0,0 +1,474 @@
1
+ const a = `var at = Object.defineProperty;
2
+ var it = (t, n, o) => n in t ? at(t, n, { enumerable: !0, configurable: !0, writable: !0, value: o }) : t[n] = o;
3
+ var Z = (t, n, o) => it(t, typeof n != "symbol" ? n + "" : n, o);
4
+ const lt = {
5
+ coneFov0: 90,
6
+ coneFov: 120,
7
+ coneFoveate: 0.4,
8
+ behindFoveate: 0.2
9
+ };
10
+ function rt(t, n, o = lt) {
11
+ return {
12
+ origin: t,
13
+ ...n ? { forward: n } : {},
14
+ coneDot0: o.coneFov0 > 0 ? Math.cos(0.5 * o.coneFov0 * Math.PI / 180) : 1,
15
+ coneDot: o.coneFov > 0 ? Math.cos(0.5 * o.coneFov * Math.PI / 180) : 1,
16
+ coneFoveate: o.coneFoveate,
17
+ behindFoveate: o.behindFoveate
18
+ };
19
+ }
20
+ function ht(t, n, o, s, e, i = Number.POSITIVE_INFINITY) {
21
+ const c = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map(), l = new ft(), p = s.origin.x, h = s.origin.y, f = s.origin.z, r = s.forward, a = (r == null ? void 0 : r.x) ?? 0, M = (r == null ? void 0 : r.y) ?? 0, b = (r == null ? void 0 : r.z) ?? 0, N = r !== void 0, { coneDot0: S, coneDot: v, coneFoveate: F, behindFoveate: A } = s, R = (y) => {
22
+ const d = Math.floor(y / o), m = t.get(d);
23
+ return !m || !m.radTree ? null : { data: m, local: y - d * o };
24
+ }, D = (y, d) => {
25
+ let m = c.get(y);
26
+ m || (m = [], c.set(y, m)), m.push(d);
27
+ }, V = (y, d) => {
28
+ const m = y.positions, P = d * 3, E = m[P] - p, C = m[P + 1] - h, O = m[P + 2] - f, x = Math.sqrt(E * E + C * C + O * O) || 1e-6, U = y.radTree.size[d] / x;
29
+ if (!N) return U;
30
+ const I = E * a + C * M + O * b;
31
+ if (I <= 0) return U * A;
32
+ const T = I / x;
33
+ if (T >= S) return U;
34
+ if (T >= v) {
35
+ const L = (T - v) / (S - v);
36
+ return U * (F + (1 - F) * L);
37
+ }
38
+ return U * (A + (F - A) * (T / v));
39
+ };
40
+ let _ = 0;
41
+ const $ = /* @__PURE__ */ new Set();
42
+ for (const y of n) {
43
+ if ($.has(y)) continue;
44
+ const d = R(y);
45
+ d && ($.add(y), l.push(y, V(d.data, d.local)), _++);
46
+ }
47
+ let k = !1;
48
+ for (; l.size > 0; ) {
49
+ const y = l.peekPriority();
50
+ if (y <= e) break;
51
+ const d = l.peek(), m = R(d);
52
+ if (!m) {
53
+ l.pop(), _--;
54
+ continue;
55
+ }
56
+ const P = Math.floor(d / o), E = m.data.radTree, C = E.childCount[m.local];
57
+ if (C === 0) {
58
+ l.pop(), D(P, m.local);
59
+ continue;
60
+ }
61
+ const O = _ - 1 + C;
62
+ if (O > i) {
63
+ k = !0;
64
+ break;
65
+ }
66
+ l.pop();
67
+ const x = E.childStart[m.local], U = Math.floor(x / o), I = Math.floor((x + C - 1) / o);
68
+ let T = !0;
69
+ for (let L = U; L <= I; L++)
70
+ t.has(L) || (T = !1, y > (u.get(L) ?? 0) && u.set(L, y));
71
+ if (!T) {
72
+ D(P, m.local);
73
+ continue;
74
+ }
75
+ for (let L = 0; L < C; L++) {
76
+ const K = x + L, X = R(K), Q = V(X.data, X.local);
77
+ Q <= e ? D(Math.floor(K / o), X.local) : l.push(K, Q);
78
+ }
79
+ _ = O;
80
+ }
81
+ let w = !1;
82
+ for (; l.size > 0; ) {
83
+ const y = l.pop(), d = Math.floor(y / o), m = y - d * o;
84
+ if (D(d, m), !w) {
85
+ const P = t.get(d), E = P == null ? void 0 : P.radTree, C = E ? E.childCount[m] : 0;
86
+ if (C > 0) {
87
+ const O = E.childStart[m], x = Math.floor(O / o), U = Math.floor((O + C - 1) / o);
88
+ let I = !0;
89
+ for (let T = x; T <= U && I; T++)
90
+ t.has(T) || (I = !1);
91
+ I && (w = !0);
92
+ }
93
+ }
94
+ }
95
+ const G = /* @__PURE__ */ new Map();
96
+ let Y = 0;
97
+ for (const [y, d] of c)
98
+ G.set(y, Uint32Array.from(d)), Y += d.length;
99
+ return { selection: G, count: Y, touched: u, budgetClamped: k, refinable: w };
100
+ }
101
+ class ft {
102
+ constructor() {
103
+ Z(this, "items", []);
104
+ // global indices
105
+ Z(this, "prio", []);
106
+ }
107
+ get size() {
108
+ return this.items.length;
109
+ }
110
+ /** Largest-priority item, without removing it. Undefined when empty. */
111
+ peek() {
112
+ return this.items[0];
113
+ }
114
+ /** Priority of {@link peek}. */
115
+ peekPriority() {
116
+ return this.prio[0];
117
+ }
118
+ push(n, o) {
119
+ const s = this.items, e = this.prio;
120
+ let i = s.length;
121
+ for (s.push(n), e.push(o); i > 0; ) {
122
+ const c = i - 1 >> 1;
123
+ if (e[c] >= o) break;
124
+ s[i] = s[c], e[i] = e[c], s[c] = n, e[c] = o, i = c;
125
+ }
126
+ }
127
+ pop() {
128
+ const n = this.items, o = this.prio, s = n[0], e = n.pop(), i = o.pop();
129
+ if (n.length > 0) {
130
+ n[0] = e, o[0] = i;
131
+ const c = n.length;
132
+ let u = 0;
133
+ for (; ; ) {
134
+ const l = 2 * u + 1, p = l + 1;
135
+ let h = u;
136
+ if (l < c && o[l] > o[h] && (h = l), p < c && o[p] > o[h] && (h = p), h === u) break;
137
+ const f = n[u], r = o[u];
138
+ n[u] = n[h], o[u] = o[h], n[h] = f, o[h] = r, u = h;
139
+ }
140
+ }
141
+ return s;
142
+ }
143
+ }
144
+ function nt(t) {
145
+ return [0, 3, 8, 15][t] ?? 0;
146
+ }
147
+ const ot = 10, z = 1 << ot, q = 1e-18, st = (t, n) => {
148
+ const o = n * 6, s = t[o], e = t[o + 1], i = t[o + 2], c = t[o + 3], u = t[o + 4], l = t[o + 5];
149
+ return s * (c * l - u * u) - e * (e * l - u * i) + i * (e * u - c * i);
150
+ }, pt = (t, n, o) => {
151
+ const s = t[o * 4 + 3] / 255, e = Math.sqrt(Math.max(q, st(n, o)));
152
+ return Math.max(q, s * e);
153
+ }, et = (t, n) => {
154
+ const o = n * 6, s = t[o] + t[o + 3] + t[o + 5];
155
+ return 2 * Math.sqrt(Math.max(q, s));
156
+ }, W = (t) => {
157
+ let n = t & 1023;
158
+ return n = (n | n << 16) & 50331903, n = (n | n << 8) & 50393103, n = (n | n << 4) & 51130563, n = (n | n << 2) & 153391689, n >>> 0;
159
+ }, ut = (t, n, o) => (W(t) | W(n) << 1 | W(o) << 2) >>> 0, dt = (t, n) => {
160
+ const o = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY], s = [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY];
161
+ for (let p = 0; p < n; p++) {
162
+ const h = p * 3;
163
+ for (let f = 0; f < 3; f++) {
164
+ const r = t[h + f];
165
+ o[f] = Math.min(o[f], r), s[f] = Math.max(s[f], r);
166
+ }
167
+ }
168
+ let e = new Uint32Array(n), i = new Uint32Array(n), c = new Uint32Array(n), u = new Uint32Array(n);
169
+ const l = o.map(
170
+ (p, h) => (z - 1) / Math.max(1e-12, s[h] - p)
171
+ );
172
+ for (let p = 0; p < n; p++) {
173
+ const h = p * 3, f = Math.max(
174
+ 0,
175
+ Math.min(
176
+ z - 1,
177
+ Math.floor((t[h] - o[0]) * l[0])
178
+ )
179
+ ), r = Math.max(
180
+ 0,
181
+ Math.min(
182
+ z - 1,
183
+ Math.floor((t[h + 1] - o[1]) * l[1])
184
+ )
185
+ ), a = Math.max(
186
+ 0,
187
+ Math.min(
188
+ z - 1,
189
+ Math.floor((t[h + 2] - o[2]) * l[2])
190
+ )
191
+ );
192
+ e[p] = p, c[p] = ut(f, r, a);
193
+ }
194
+ for (let p = 0; p < 30; p += ot) {
195
+ const h = new Uint32Array(z);
196
+ for (let r = 0; r < n; r++) {
197
+ const a = c[r] >>> p & z - 1;
198
+ h[a] = h[a] + 1;
199
+ }
200
+ let f = 0;
201
+ for (let r = 0; r < h.length; r++) {
202
+ const a = h[r];
203
+ h[r] = f, f += a;
204
+ }
205
+ for (let r = 0; r < n; r++) {
206
+ const a = c[r], M = a >>> p & z - 1, b = h[M];
207
+ h[M] = b + 1, u[b] = a, i[b] = e[r];
208
+ }
209
+ [c, u] = [u, c], [e, i] = [i, e];
210
+ }
211
+ return e;
212
+ };
213
+ function J(t) {
214
+ if (!Number.isSafeInteger(t.count) || t.count < 0)
215
+ throw new RangeError(
216
+ \`Static LOD source count must be a non-negative safe integer; received \${t.count}.\`
217
+ );
218
+ const n = [
219
+ ["positions", t.positions.length, t.count * 3],
220
+ ["colors", t.colors.length, t.count * 4],
221
+ ["covariances", t.covariances.length, t.count * 6]
222
+ ];
223
+ t.sh && n.push(["sh.labels", t.sh.labels.length, t.count]);
224
+ for (const [e, i, c] of n)
225
+ if (i !== c)
226
+ throw new RangeError(
227
+ \`Static LOD source is structurally inconsistent: \${e} has \${i} entries; expected \${c} for \${t.count} splats.\`
228
+ );
229
+ if (!t.shPacked) return;
230
+ const o = nt(t.shPacked.bands), s = t.count * o;
231
+ if (t.shPacked.packed.length !== s)
232
+ throw new RangeError(
233
+ \`Static LOD source is structurally inconsistent: shPacked.packed has \${t.shPacked.packed.length} words; expected \${s} (\${t.count} splats × \${o} coefficients for \${t.shPacked.bands} SH bands).\`
234
+ );
235
+ }
236
+ const B = (t) => t.shPacked ? nt(t.shPacked.bands) : 0, mt = (t, n) => ({
237
+ count: t,
238
+ positions: new Float32Array(t * 3),
239
+ colors: new Uint8Array(t * 4),
240
+ covariances: new Float32Array(t * 6),
241
+ masses: new Float64Array(t),
242
+ sizes: new Float32Array(t),
243
+ ...n.sh ? { shLabels: new Uint32Array(t) } : {},
244
+ ...n.shPacked ? {
245
+ shPacked: new Uint32Array(t * B(n)),
246
+ packedStride: B(n)
247
+ } : {},
248
+ dominant: new Uint32Array(t)
249
+ }), g = (t, n, o, s) => {
250
+ if (o.positions.set(
251
+ t.positions.subarray(n * 3, n * 3 + 3),
252
+ s * 3
253
+ ), o.colors.set(t.colors.subarray(n * 4, n * 4 + 4), s * 4), o.covariances.set(
254
+ t.covariances.subarray(n * 6, n * 6 + 6),
255
+ s * 6
256
+ ), o.masses[s] = pt(t.colors, t.covariances, n), o.sizes[s] = et(t.covariances, n), o.dominant[s] = n, o.shLabels && t.sh && (o.shLabels[s] = t.sh.labels[n]), o.shPacked && t.shPacked) {
257
+ const e = B(t);
258
+ o.shPacked.set(
259
+ t.shPacked.packed.subarray(n * e, (n + 1) * e),
260
+ s * e
261
+ );
262
+ }
263
+ }, ct = (t, n, o, s, e) => {
264
+ let i = 0, c = n, u = -1;
265
+ const l = [0, 0, 0], p = [0, 0, 0];
266
+ for (let a = n; a < o; a++) {
267
+ const M = t.masses[a];
268
+ i += M, M > u && (u = M, c = a);
269
+ for (let b = 0; b < 3; b++)
270
+ l[b] = l[b] + t.positions[a * 3 + b] * M, p[b] = p[b] + t.colors[a * 4 + b] * M;
271
+ }
272
+ const h = Math.max(i, q);
273
+ for (let a = 0; a < 3; a++)
274
+ l[a] = l[a] / h, s.positions[e * 3 + a] = l[a], s.colors[e * 4 + a] = Math.max(
275
+ 0,
276
+ Math.min(255, Math.round(p[a] / h))
277
+ );
278
+ const f = [0, 0, 0, 0, 0, 0];
279
+ for (let a = n; a < o; a++) {
280
+ const M = t.masses[a], b = t.positions[a * 3] - l[0], N = t.positions[a * 3 + 1] - l[1], S = t.positions[a * 3 + 2] - l[2], v = a * 6;
281
+ f[0] = f[0] + (t.covariances[v] + b * b) * M, f[1] = f[1] + (t.covariances[v + 1] + b * N) * M, f[2] = f[2] + (t.covariances[v + 2] + b * S) * M, f[3] = f[3] + (t.covariances[v + 3] + N * N) * M, f[4] = f[4] + (t.covariances[v + 4] + N * S) * M, f[5] = f[5] + (t.covariances[v + 5] + S * S) * M;
282
+ }
283
+ for (let a = 0; a < 6; a++)
284
+ s.covariances[e * 6 + a] = f[a] / h;
285
+ s.masses[e] = i;
286
+ const r = Math.sqrt(
287
+ Math.max(q, st(s.covariances, e))
288
+ );
289
+ if (s.colors[e * 4 + 3] = Math.max(
290
+ 0,
291
+ Math.min(255, Math.round(i / r * 255))
292
+ ), s.sizes[e] = et(s.covariances, e), s.dominant[e] = t.dominant[c], s.shLabels && t.shLabels && (s.shLabels[e] = t.shLabels[c]), s.shPacked && t.shPacked) {
293
+ const a = t.packedStride;
294
+ if (a === void 0) throw new Error("Static LOD packed-SH stride is unavailable.");
295
+ s.shPacked.set(
296
+ t.shPacked.subarray(c * a, (c + 1) * a),
297
+ e * a
298
+ );
299
+ }
300
+ }, bt = (t, n, o) => {
301
+ if (o.count === t.count) {
302
+ for (let i = 0; i < t.count; i++)
303
+ g(t, n[i], o, i);
304
+ return;
305
+ }
306
+ const s = Math.ceil(t.count / o.count), e = mt(s, t);
307
+ for (let i = 0; i < o.count; i++) {
308
+ const c = Math.floor(i * t.count / o.count), u = Math.max(c + 1, Math.floor((i + 1) * t.count / o.count));
309
+ e.count = u - c;
310
+ for (let l = 0; l < e.count; l++)
311
+ g(t, n[c + l], e, l);
312
+ ct(e, 0, e.count, o, i);
313
+ }
314
+ }, yt = (t, n) => {
315
+ for (let o = 0; o < n.count; o++)
316
+ ct(t, o * 2, Math.min(t.count, o * 2 + 2), n, o);
317
+ };
318
+ function Mt(t, n, o) {
319
+ var $;
320
+ if (!Number.isFinite(n) || n < 1)
321
+ throw new RangeError("Static LOD maxBudget must be a positive finite number.");
322
+ if (J(t), t.count === 0)
323
+ return { data: t, contentSplatCount: 0, finestSplatCount: 0, roots: new Uint32Array() };
324
+ const s = Math.max(1, Math.min(t.count, Math.floor(n)));
325
+ o == null || o({ completed: 0, total: t.count });
326
+ const e = dt(t.positions, t.count), i = [s];
327
+ for (; (i.at(-1) ?? 0) > 1; )
328
+ i.push(Math.ceil(i.at(-1) / 2));
329
+ const c = i.reduce((k, w) => k + w, 0), u = new Float32Array(c * 3), l = new Uint8Array(c * 4), p = new Float32Array(c * 6), h = new Float64Array(c), f = new Uint32Array(c), r = new Uint16Array(c), a = new Uint32Array(c), M = new Float32Array(c), b = t.sh ? new Uint32Array(c) : void 0, N = B(t), S = t.shPacked ? new Uint32Array(c * N) : void 0, v = [];
330
+ let F = 0;
331
+ const A = i.map((k) => {
332
+ v.push(F);
333
+ const w = F;
334
+ return F += k, {
335
+ count: k,
336
+ positions: u.subarray(w * 3, F * 3),
337
+ colors: l.subarray(w * 4, F * 4),
338
+ covariances: p.subarray(w * 6, F * 6),
339
+ masses: h.subarray(w, F),
340
+ sizes: M.subarray(w, F),
341
+ ...b ? { shLabels: b.subarray(w, F) } : {},
342
+ ...S ? {
343
+ shPacked: S.subarray(w * N, F * N),
344
+ packedStride: N
345
+ } : {},
346
+ dominant: f.subarray(w, F)
347
+ };
348
+ });
349
+ bt(t, e, A[0]), o == null || o({ completed: Math.floor(t.count * 0.6), total: t.count });
350
+ for (let k = 1; k < A.length; k++)
351
+ yt(A[k - 1], A[k]);
352
+ for (let k = 1; k < A.length; k++) {
353
+ const w = A[k], G = A[k - 1], Y = v[k], y = v[k - 1];
354
+ for (let d = 0; d < w.count; d++) {
355
+ const m = Math.min(2, G.count - d * 2);
356
+ r[Y + d] = m, a[Y + d] = y + d * 2;
357
+ }
358
+ }
359
+ const R = { childCount: r, childStart: a, size: M }, D = t.sh && b ? { ...t.sh, labels: b } : void 0, V = t.shPacked && S ? { ...t.shPacked, packed: S } : void 0, _ = {
360
+ count: c,
361
+ positions: u,
362
+ colors: l,
363
+ covariances: p,
364
+ ...D ? { sh: D } : {},
365
+ ...V ? { shPacked: V } : {},
366
+ ...t.antialias === void 0 ? {} : { antialias: t.antialias },
367
+ ...t.sourceFormat === void 0 ? {} : { sourceFormat: t.sourceFormat },
368
+ radTree: R
369
+ };
370
+ return o == null || o({ completed: t.count, total: t.count }), {
371
+ data: _,
372
+ contentSplatCount: t.count,
373
+ finestSplatCount: (($ = A[0]) == null ? void 0 : $.count) ?? 0,
374
+ roots: Uint32Array.of(c - 1)
375
+ };
376
+ }
377
+ let H, tt = new Uint32Array();
378
+ const kt = (t) => (J(t), {
379
+ count: t.count,
380
+ positions: t.positions.slice(),
381
+ colors: t.colors.slice(),
382
+ covariances: t.covariances.slice(),
383
+ ...t.sh ? { sh: { ...t.sh, labels: t.sh.labels.slice() } } : {},
384
+ ...t.shPacked ? { shPacked: { ...t.shPacked, packed: t.shPacked.packed.slice() } } : {},
385
+ ...t.antialias === void 0 ? {} : { antialias: t.antialias },
386
+ ...t.sourceFormat === void 0 ? {} : { sourceFormat: t.sourceFormat }
387
+ });
388
+ function wt(t, n) {
389
+ try {
390
+ if (t.type === "build") {
391
+ J(t.source);
392
+ const e = Mt(t.source, t.maxBudget, (i) => {
393
+ n({ type: "progress", progress: i });
394
+ });
395
+ if (!e.data.radTree) throw new Error("Static LOD builder did not produce a hierarchy.");
396
+ H = e.data, tt = new Uint32Array(e.roots), n({
397
+ type: "built",
398
+ data: kt(e.data),
399
+ contentSplatCount: e.contentSplatCount,
400
+ finestSplatCount: e.finestSplatCount
401
+ });
402
+ return;
403
+ }
404
+ if (!H) throw new Error("Static LOD selection requested before build completed.");
405
+ const o = rt(
406
+ { x: t.cameraLocal[0], y: t.cameraLocal[1], z: t.cameraLocal[2] },
407
+ { x: t.cameraForward[0], y: t.cameraForward[1], z: t.cameraForward[2] }
408
+ ), s = ht(
409
+ /* @__PURE__ */ new Map([[0, H]]),
410
+ [...tt],
411
+ H.count,
412
+ o,
413
+ 0,
414
+ t.budget
415
+ );
416
+ n({
417
+ type: "selection",
418
+ sequence: t.sequence,
419
+ indices: Uint32Array.from(s.selection.get(0) ?? [])
420
+ });
421
+ } catch (o) {
422
+ n({ type: "error", message: o instanceof Error ? o.message : String(o) });
423
+ }
424
+ }
425
+ const vt = (t) => {
426
+ const n = [
427
+ t.positions.buffer,
428
+ t.colors.buffer,
429
+ t.covariances.buffer
430
+ ];
431
+ return t.sh && n.push(t.sh.labels.buffer), t.shPacked && n.push(t.shPacked.packed.buffer), n;
432
+ }, j = (t, n = []) => {
433
+ self.postMessage(t, n);
434
+ };
435
+ self.onmessage = (t) => {
436
+ wt(t.data, (n) => {
437
+ if (n.type === "built") {
438
+ j(n, vt(n.data));
439
+ return;
440
+ }
441
+ if (n.type === "selection") {
442
+ j(n, [n.indices.buffer]);
443
+ return;
444
+ }
445
+ j(n);
446
+ });
447
+ };
448
+ //# sourceMappingURL=static-lod-worker-BFIwsvQc.js.map
449
+ `, o = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", a], { type: "text/javascript;charset=utf-8" });
450
+ function r(n) {
451
+ let t;
452
+ try {
453
+ if (t = o && (self.URL || self.webkitURL).createObjectURL(o), !t) throw "";
454
+ const e = new Worker(t, {
455
+ type: "module",
456
+ name: n == null ? void 0 : n.name
457
+ });
458
+ return e.addEventListener("error", () => {
459
+ (self.URL || self.webkitURL).revokeObjectURL(t);
460
+ }), e;
461
+ } catch {
462
+ return new Worker(
463
+ "data:text/javascript;charset=utf-8," + encodeURIComponent(a),
464
+ {
465
+ type: "module",
466
+ name: n == null ? void 0 : n.name
467
+ }
468
+ );
469
+ }
470
+ }
471
+ export {
472
+ r as default
473
+ };
474
+ //# sourceMappingURL=static-lod-worker-D2fyqQZO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-lod-worker-D2fyqQZO.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,37 @@
1
+ import type { SplatData } from './splat-data';
2
+ import type { StaticLodBuildProgress } from './static-lod';
3
+ export interface StaticLodBuildRequest {
4
+ readonly type: 'build';
5
+ readonly source: SplatData;
6
+ readonly maxBudget: number;
7
+ }
8
+ export interface StaticLodSelectRequest {
9
+ readonly type: 'select';
10
+ readonly sequence: number;
11
+ readonly budget: number;
12
+ readonly cameraLocal: readonly [number, number, number];
13
+ readonly cameraForward: readonly [number, number, number];
14
+ }
15
+ export type StaticLodWorkerRequest = StaticLodBuildRequest | StaticLodSelectRequest;
16
+ export interface StaticLodProgressResponse {
17
+ readonly type: 'progress';
18
+ readonly progress: StaticLodBuildProgress;
19
+ }
20
+ export interface StaticLodBuiltResponse {
21
+ readonly type: 'built';
22
+ /** Full hierarchy for a one-time GPU upload; selection later remaps active indices. */
23
+ readonly data: SplatData;
24
+ readonly contentSplatCount: number;
25
+ readonly finestSplatCount: number;
26
+ }
27
+ export interface StaticLodSelectionResponse {
28
+ readonly type: 'selection';
29
+ readonly sequence: number;
30
+ /** Pool indices into the resident hierarchy (not gathered splat attributes). */
31
+ readonly indices: Uint32Array;
32
+ }
33
+ export interface StaticLodErrorResponse {
34
+ readonly type: 'error';
35
+ readonly message: string;
36
+ }
37
+ export type StaticLodWorkerResponse = StaticLodProgressResponse | StaticLodBuiltResponse | StaticLodSelectionResponse | StaticLodErrorResponse;
@@ -0,0 +1,24 @@
1
+ import type { SplatData } from './splat-data';
2
+ /** Progress emitted while a static scene is spatially ordered and merged. */
3
+ export interface StaticLodBuildProgress {
4
+ readonly completed: number;
5
+ readonly total: number;
6
+ }
7
+ /** Result consumed by {@link StaticLodSplatMesh}. */
8
+ export interface StaticLodBuildResult {
9
+ readonly data: SplatData;
10
+ readonly contentSplatCount: number;
11
+ readonly finestSplatCount: number;
12
+ readonly roots: Uint32Array;
13
+ }
14
+ /** Validates the worker-owned shape before a hierarchy copies its typed arrays. */
15
+ export declare function validateStaticLodSource(data: SplatData): void;
16
+ /**
17
+ * Builds a deterministic, coverage-preserving binary splat hierarchy.
18
+ *
19
+ * Parents use Gaussian-mixture moment matching. The finest retained level is
20
+ * capped before the hierarchy is materialized. The resident pool holds the
21
+ * full tree (~2× that ceiling: finest + parents) so camera cuts can remap
22
+ * active indices without rewriting splat attributes.
23
+ */
24
+ export declare function buildStaticLod(source: SplatData, maxBudget: number, onProgress?: (progress: StaticLodBuildProgress) => void): StaticLodBuildResult;
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Frees the JS-heap mirror of storage buffers only the GPU ever reads.
3
+ *
4
+ * ## The gap
5
+ *
6
+ * Every `THREE.StorageBufferAttribute` is constructed around a JS typed array,
7
+ * and three's WebGPU backend never releases it. `WebGPUAttributeUtils`'s
8
+ * `createAttribute` copies the array into a `mappedAtCreation` GPU buffer,
9
+ * unmaps it, stores the buffer - and never calls `bufferAttribute
10
+ * .onUploadCallback()`, the hook that exists for exactly this and that the
11
+ * legacy WebGL renderer does call (`WebGLAttributes.js`). So a buffer of N
12
+ * slots costs N bytes on the GPU *and the same again on the JS heap,
13
+ * permanently*, even when nothing ever reads the CPU copy back.
14
+ *
15
+ * For VLAM that is not a rounding error. The unified work buffer alone is
16
+ * 72 B/slot, gathered entirely on the GPU and never read back - at a 10M-slot
17
+ * scene that is ~720 MB of JS heap holding zeroes, next to the ~720 MB of GPU
18
+ * memory doing the actual work. Add the sort scratch and it is most of a
19
+ * gigabyte that no on-screen number accounts for.
20
+ *
21
+ * ## Why replacing `.array` is safe
22
+ *
23
+ * Four properties of three 0.185 hold simultaneously, and this module is only
24
+ * correct while they all do:
25
+ *
26
+ * 1. `createAttribute` is guarded by `if (buffer === undefined)` - once the GPU
27
+ * buffer exists, every later call short-circuits without reading `.array`.
28
+ * 2. `updateAttribute` *does* re-read `.array`, but `Attributes.update` only
29
+ * reaches it when `data.version < attribute.version` or the attribute uses
30
+ * `DynamicDrawUsage`. VLAM sets neither on the buffers released here - which
31
+ * is what {@link StorageMirrorReleaser}'s drift guard verifies at runtime.
32
+ * 3. The vertex-layout paths read `.array.constructor` and
33
+ * `.array.BYTES_PER_ELEMENT`, never the contents - and only for *geometry*
34
+ * attributes, which these are not. Both survive a zero-length array of the
35
+ * same constructor.
36
+ * 4. Device loss is terminal: `Renderer._onDeviceLost` sets a flag and every
37
+ * later render/compute returns early. There is no re-upload-from-`.array`
38
+ * path to break.
39
+ *
40
+ * A zero-length array rather than a detached buffer, deliberately: if a future
41
+ * change ever does bump `version` on a released attribute, a zero-length array
42
+ * degrades to a legal 0-byte `writeBuffer` (silent, and caught by the drift
43
+ * guard) where a detached one would throw inside the render loop.
44
+ *
45
+ * Peak memory is unchanged - the array has to exist for the upload copy. Only
46
+ * steady state improves, which is the number that was hurting.
47
+ *
48
+ * ## Relationship to `releaseRendererAttributes`
49
+ *
50
+ * They are complements, and compose in either order.
51
+ * `releaseRendererAttributes` frees the **GPU** buffer at dispose; this frees
52
+ * the **CPU** mirror during the first frame. If dispose somehow ran first, the
53
+ * upload probe simply reports "not uploaded" and the mirror is never released -
54
+ * fail-safe.
55
+ *
56
+ * Upstream fix: a one-line `bufferAttribute.onUploadCallback()` in
57
+ * `WebGPUAttributeUtils.createAttribute` would make the documented
58
+ * `BufferAttribute.onUpload()` contract work on WebGPU, and this module would
59
+ * become a shim for older three.
60
+ */
61
+ import type * as THREE from 'three/webgpu';
62
+ /**
63
+ * Drops the JS mirrors of storage attributes three has already uploaded.
64
+ *
65
+ * Owners construct one over the attributes they own **outright** and call
66
+ * {@link release} after each dispatch; it settles on the first frame and costs
67
+ * one WeakMap probe per pending attribute until then. Attributes the owner only
68
+ * borrows (a mesh's `splatIndex`/`sourceIndex` passed into a sorter) must never
69
+ * be handed to it - the same ownership line `releaseRendererAttributes` draws.
70
+ *
71
+ * Only pass attributes that are written from the CPU *at most once*, at
72
+ * construction. Anything the CPU rewrites per frame will silently stop
73
+ * uploading; the drift guard turns that into a warning rather than a mystery.
74
+ */
75
+ export declare class StorageMirrorReleaser {
76
+ private readonly pending;
77
+ /** Released attributes and the `version` they carried when released. */
78
+ private readonly released;
79
+ private releasedBytesValue;
80
+ private warnedDrift;
81
+ constructor(attributes: readonly THREE.BufferAttribute[]);
82
+ /** Nothing left to release. */
83
+ get settled(): boolean;
84
+ /** Bytes still mirrored on the JS heap. */
85
+ get pendingBytes(): number;
86
+ /** Bytes freed so far. Diagnostic. */
87
+ get releasedBytes(): number;
88
+ /**
89
+ * Releases every pending mirror three has uploaded, and checks the ones
90
+ * already released for version drift. Idempotent and cheap once settled.
91
+ *
92
+ * @returns Bytes freed by this call.
93
+ */
94
+ release(renderer: THREE.WebGPURenderer): number;
95
+ /**
96
+ * A released attribute whose `version` moved means someone added a CPU write
97
+ * to a buffer this class promised was GPU-only. Three would then upload the
98
+ * zero-length array - a legal no-op - and the data would simply never reach
99
+ * the GPU. Warn once, so that failure is visible rather than a silent wrong
100
+ * render.
101
+ */
102
+ private checkDrift;
103
+ }