@voluma/vlam 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/budget-governor.d.ts +4 -4
- package/dist/camera-budget-governor.d.ts +11 -11
- package/dist/chunk-cache-budget.d.ts +5 -5
- package/dist/chunk-fetch-scheduler.d.ts +4 -4
- package/dist/chunk-loader-DlNwggfG.js +1859 -0
- package/dist/chunk-loader-DlNwggfG.js.map +1 -0
- package/dist/chunk-loader.d.ts +2 -2
- package/dist/compute-sorter.d.ts +1 -1
- package/dist/effects.d.ts +11 -10
- package/dist/effects.js.map +1 -1
- package/dist/formats/ksplat/index.d.ts +1 -1
- package/dist/formats/lcc/collision-mesh.d.ts +2 -2
- package/dist/formats/lcc.js +17 -16
- package/dist/formats/lcc.js.map +1 -1
- package/dist/formats/ply/index.d.ts +1 -1
- package/dist/formats/ply/parse-splat-ply.d.ts +2 -2
- package/dist/formats/ply.js +1 -1
- package/dist/formats/ply.js.map +1 -1
- package/dist/formats/rad/index.d.ts +1 -1
- package/dist/formats/rad/parse-rad.d.ts +1 -1
- package/dist/formats/rad/rad.d.ts +2 -2
- package/dist/formats/rad.js +3 -3
- package/dist/formats/rad.js.map +1 -1
- package/dist/formats/sog/index.d.ts +1 -1
- package/dist/formats/sog/parse-sog.d.ts +4 -4
- package/dist/formats/sog.js.map +1 -1
- package/dist/formats/splat/index.d.ts +1 -1
- package/dist/formats/spz/index.d.ts +1 -1
- package/dist/index.d.ts +16 -25
- package/dist/index.js +253 -9047
- package/dist/index.js.map +1 -1
- package/dist/{load-scene.d.ts → load-splat-data.d.ts} +15 -13
- package/dist/loaders.d.ts +15 -0
- package/dist/loaders.js +26 -0
- package/dist/loaders.js.map +1 -0
- package/dist/loading-wLo8vRbA.js.map +1 -1
- package/dist/loading.d.ts +8 -8
- package/dist/{splat-mesh-types-CTN_duw2.js → lod-scheduler-B0a_uBlv.js} +133 -140
- package/dist/lod-scheduler-B0a_uBlv.js.map +1 -0
- package/dist/lod-scheduler.d.ts +1 -1
- package/dist/lod-source.d.ts +5 -5
- package/dist/{splat-scene.d.ts → merged-splat-mesh.d.ts} +14 -15
- package/dist/orientation.d.ts +7 -7
- package/dist/{ply-header-BwgExCn-.js → ply-header-B9WllbPg.js} +3 -3
- package/dist/{ply-header-BwgExCn-.js.map → ply-header-B9WllbPg.js.map} +1 -1
- package/dist/radix-sorter-R0FCSqKu.js +178 -0
- package/dist/radix-sorter-R0FCSqKu.js.map +1 -0
- package/dist/relighting-CSQF3UcL.js +969 -0
- package/dist/relighting-CSQF3UcL.js.map +1 -0
- package/dist/relighting.d.ts +1 -1
- package/dist/selection.d.ts +13 -0
- package/dist/selection.js +137 -0
- package/dist/selection.js.map +1 -0
- package/dist/source-transform.d.ts +4 -4
- package/dist/{splat-budget-DXew_86c.js → splat-budget-DuVZspPQ.js} +7 -7
- package/dist/{splat-budget-DXew_86c.js.map → splat-budget-DuVZspPQ.js.map} +1 -1
- package/dist/splat-budget.d.ts +1 -1
- package/dist/splat-data-BZM5dhhx.js.map +1 -1
- package/dist/splat-data.d.ts +4 -4
- package/dist/splat-mesh-aQdcWA6v.js +1942 -0
- package/dist/splat-mesh-aQdcWA6v.js.map +1 -0
- package/dist/splat-mesh-material.d.ts +2 -2
- package/dist/splat-mesh-types-BZIko-_9.js +18 -0
- package/dist/splat-mesh-types-BZIko-_9.js.map +1 -0
- package/dist/splat-mesh-types.d.ts +14 -8
- package/dist/splat-mesh.d.ts +4 -4
- package/dist/splat-modifier.d.ts +5 -5
- package/dist/splat-partition.d.ts +1 -1
- package/dist/static-lod-entry.d.ts +12 -0
- package/dist/static-lod-splat-mesh.d.ts +2 -2
- package/dist/{static-lod-worker-D2fyqQZO.js → static-lod-worker-DktKnJkR.js} +46 -46
- package/dist/{static-lod-worker-D2fyqQZO.js.map → static-lod-worker-DktKnJkR.js.map} +1 -1
- package/dist/static-lod.js +148 -0
- package/dist/static-lod.js.map +1 -0
- package/dist/streamed-splat-mesh.d.ts +21 -27
- package/dist/streaming.d.ts +23 -0
- package/dist/streaming.js +2877 -0
- package/dist/streaming.js.map +1 -0
- package/dist/{unified-splat-renderer.d.ts → unified-splat-mesh.d.ts} +10 -10
- package/dist/unified-work-buffer.d.ts +66 -0
- package/dist/unified.d.ts +11 -0
- package/dist/unified.js +738 -0
- package/dist/unified.js.map +1 -0
- package/dist/webgpu-limits-Y3CI_6_6.js +43 -0
- package/dist/webgpu-limits-Y3CI_6_6.js.map +1 -0
- package/dist/webgpu-limits.d.ts +0 -59
- package/dist/work-buffer-gather.d.ts +1 -1
- package/package.json +24 -4
- package/dist/splat-mesh-types-CTN_duw2.js.map +0 -1
|
@@ -0,0 +1,1859 @@
|
|
|
1
|
+
var g = Object.defineProperty;
|
|
2
|
+
var E = (o, t, n) => t in o ? g(o, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : o[t] = n;
|
|
3
|
+
var a = (o, t, n) => E(o, typeof t != "symbol" ? t + "" : t, n);
|
|
4
|
+
import { r as _, s as m, b as A, c, d as k, S as x, e as R } from "./loading-wLo8vRbA.js";
|
|
5
|
+
const y = `var bt = Object.defineProperty;
|
|
6
|
+
var gt = (e, t, r) => t in e ? bt(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
|
|
7
|
+
var K = (e, t, r) => gt(e, typeof t != "symbol" ? t + "" : t, r);
|
|
8
|
+
const Et = [2047, 1023, 2047];
|
|
9
|
+
function P(e) {
|
|
10
|
+
return [0, 3, 8, 15][e] ?? 0;
|
|
11
|
+
}
|
|
12
|
+
function Ae(e, t, r, n) {
|
|
13
|
+
const s = P(r);
|
|
14
|
+
let o = n ?? 0;
|
|
15
|
+
if (n === void 0)
|
|
16
|
+
for (const c of e) o = Math.max(o, Math.abs(c));
|
|
17
|
+
const a = {
|
|
18
|
+
min: [-o, -o, -o],
|
|
19
|
+
max: [o, o, o]
|
|
20
|
+
}, h = new Uint32Array(t * s), i = o || 1;
|
|
21
|
+
for (let c = 0; c < h.length; c++) {
|
|
22
|
+
const f = c * 3, l = (m, b) => Math.min(b, Math.max(0, Math.round((m / i + 1) * 0.5 * b))), d = l(e[f], 2047), u = l(e[f + 1], 1023), y = l(e[f + 2], 2047);
|
|
23
|
+
h[c] = (d | u << 11 | y << 21) >>> 0;
|
|
24
|
+
}
|
|
25
|
+
return { bands: r, packed: h, range: a };
|
|
26
|
+
}
|
|
27
|
+
function _t(e, t, r) {
|
|
28
|
+
const n = P(r), s = P(e.bands), o = e.paletteWidth, a = new Float32Array(t * n * 3);
|
|
29
|
+
for (let h = 0; h < t; h++) {
|
|
30
|
+
const i = e.labels[h], c = i % 64 * s, f = Math.floor(i / 64);
|
|
31
|
+
if (c + s > o || (f * o + c + s) * 4 > e.palette.length)
|
|
32
|
+
throw new Error(\`packPaletteSh: splat \${h} has SH label \${i} outside the palette.\`);
|
|
33
|
+
const l = Math.min(n, s);
|
|
34
|
+
for (let d = 0; d < l; d++) {
|
|
35
|
+
const u = (f * o + c + d) * 4, y = (h * n + d) * 3;
|
|
36
|
+
a[y] = e.palette[u], a[y + 1] = e.palette[u + 1], a[y + 2] = e.palette[u + 2];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return Ae(a, t, r);
|
|
40
|
+
}
|
|
41
|
+
function At(e) {
|
|
42
|
+
const t = (r, n, s) => {
|
|
43
|
+
if (n === r) return 0;
|
|
44
|
+
const o = (0 - r) / (n - r);
|
|
45
|
+
return Math.max(0, Math.min(s, Math.round(o * s)));
|
|
46
|
+
};
|
|
47
|
+
return (t(e.min[0], e.max[0], 2047) | t(e.min[1], e.max[1], 1023) << 11 | t(e.min[2], e.max[2], 2047) << 21) >>> 0;
|
|
48
|
+
}
|
|
49
|
+
function Rt(e, t) {
|
|
50
|
+
return e.min[0] === t.min[0] && e.min[1] === t.min[1] && e.min[2] === t.min[2] && e.max[0] === t.max[0] && e.max[1] === t.max[1] && e.max[2] === t.max[2];
|
|
51
|
+
}
|
|
52
|
+
function St(e, t, r) {
|
|
53
|
+
return e + (t - e) * r;
|
|
54
|
+
}
|
|
55
|
+
function xt(e, t, r) {
|
|
56
|
+
const n = [e & 2047, e >>> 11 & 1023, e >>> 21 & 2047];
|
|
57
|
+
let s = 0, o = 0;
|
|
58
|
+
for (let a = 0; a < 3; a++) {
|
|
59
|
+
const h = Et[a], i = St(
|
|
60
|
+
t.min[a],
|
|
61
|
+
t.max[a],
|
|
62
|
+
n[a] / h
|
|
63
|
+
), c = r.min[a], f = r.max[a], l = f === c ? 0 : (i - c) / (f - c), d = Math.max(0, Math.min(h, Math.round(l * h)));
|
|
64
|
+
s |= d << o, o += a === 0 ? 11 : 10;
|
|
65
|
+
}
|
|
66
|
+
return s >>> 0;
|
|
67
|
+
}
|
|
68
|
+
const Be = 0.28209479177387814;
|
|
69
|
+
function te(e, t, r, n, s, o, a, h, i) {
|
|
70
|
+
const c = Math.hypot(o, a, h, i) || 1, f = o / c, l = a / c, d = h / c, u = i / c, y = (1 - 2 * (d * d + u * u)) * r, m = 2 * (l * d - f * u) * n, b = 2 * (l * u + f * d) * s, _ = 2 * (l * d + f * u) * r, w = (1 - 2 * (l * l + u * u)) * n, p = 2 * (d * u - f * l) * s, A = 2 * (l * u - f * d) * r, g = 2 * (d * u + f * l) * n, E = (1 - 2 * (l * l + d * d)) * s;
|
|
71
|
+
e[t * 6 + 0] = y * y + m * m + b * b, e[t * 6 + 1] = y * _ + m * w + b * p, e[t * 6 + 2] = y * A + m * g + b * E, e[t * 6 + 3] = _ * _ + w * w + p * p, e[t * 6 + 4] = _ * A + w * g + p * E, e[t * 6 + 5] = A * A + g * g + E * E;
|
|
72
|
+
}
|
|
73
|
+
const ue = {
|
|
74
|
+
float: 4,
|
|
75
|
+
float32: 4,
|
|
76
|
+
double: 8,
|
|
77
|
+
float64: 8,
|
|
78
|
+
int: 4,
|
|
79
|
+
int32: 4,
|
|
80
|
+
uint: 4,
|
|
81
|
+
uint32: 4,
|
|
82
|
+
short: 2,
|
|
83
|
+
int16: 2,
|
|
84
|
+
ushort: 2,
|
|
85
|
+
uint16: 2,
|
|
86
|
+
char: 1,
|
|
87
|
+
int8: 1,
|
|
88
|
+
uchar: 1,
|
|
89
|
+
uint8: 1
|
|
90
|
+
};
|
|
91
|
+
function qe(e) {
|
|
92
|
+
const t = new Uint8Array(e, 0, Math.min(e.byteLength, 65536)), r = new TextDecoder("ascii").decode(t), n = /end_header\\r?\\n/.exec(r);
|
|
93
|
+
if (!/^ply\\r?\\n/.test(r))
|
|
94
|
+
throw new Error('Not a PLY file (missing "ply" magic).');
|
|
95
|
+
if (!n)
|
|
96
|
+
throw new Error(
|
|
97
|
+
'Unsupported PLY file: no "end_header" within the first 64 KiB - the header exceeds the supported window, or the file is truncated.'
|
|
98
|
+
);
|
|
99
|
+
if (!r.includes("format binary_little_endian 1.0"))
|
|
100
|
+
throw new Error("Unsupported PLY format; expected binary_little_endian 1.0.");
|
|
101
|
+
const s = [];
|
|
102
|
+
for (const i of r.slice(0, n.index).split(\`
|
|
103
|
+
\`)) {
|
|
104
|
+
const c = i.trim().split(/\\s+/);
|
|
105
|
+
if (c[0] === "element") {
|
|
106
|
+
const f = c[1], l = Number(c[2]);
|
|
107
|
+
if (f === void 0) throw new Error(\`Malformed PLY element: "\${i.trim()}"\`);
|
|
108
|
+
if (!Number.isSafeInteger(l) || l < 0)
|
|
109
|
+
throw new Error(\`Invalid PLY \${f} count: \${c[2]}.\`);
|
|
110
|
+
s.push({
|
|
111
|
+
name: f,
|
|
112
|
+
count: l,
|
|
113
|
+
properties: /* @__PURE__ */ new Map(),
|
|
114
|
+
propertyNames: [],
|
|
115
|
+
listProperties: /* @__PURE__ */ new Map(),
|
|
116
|
+
stride: 0,
|
|
117
|
+
hasListProperty: !1
|
|
118
|
+
});
|
|
119
|
+
} else if (c[0] === "property") {
|
|
120
|
+
const f = s[s.length - 1];
|
|
121
|
+
if (!f) throw new Error(\`PLY property declared before any element: "\${i.trim()}"\`);
|
|
122
|
+
if (c[1] === "list") {
|
|
123
|
+
const y = c[2] ?? "", m = c[3] ?? "", b = c[4];
|
|
124
|
+
if (ue[y] === void 0 || ue[m] === void 0 || b === void 0)
|
|
125
|
+
throw new Error(\`Unsupported PLY property: "\${i.trim()}"\`);
|
|
126
|
+
if (f.properties.has(b) || f.listProperties.has(b))
|
|
127
|
+
throw new Error(\`Duplicate PLY property "\${b}" in element "\${f.name}".\`);
|
|
128
|
+
f.listProperties.set(b, { countType: y, itemType: m }), f.hasListProperty = !0;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const l = c[1] ?? "", d = ue[l], u = c[2];
|
|
132
|
+
if (d === void 0 || u === void 0)
|
|
133
|
+
throw new Error(\`Unsupported PLY property: "\${i.trim()}"\`);
|
|
134
|
+
if (f.properties.has(u) || f.listProperties.has(u))
|
|
135
|
+
throw new Error(\`Duplicate PLY property "\${u}" in element "\${f.name}".\`);
|
|
136
|
+
f.properties.set(u, { type: l, offset: f.stride }), f.propertyNames.push(u), f.stride += d;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
let o = n.index + n[0].length, a = !0;
|
|
140
|
+
const h = [];
|
|
141
|
+
for (const i of s)
|
|
142
|
+
h.push({
|
|
143
|
+
name: i.name,
|
|
144
|
+
count: i.count,
|
|
145
|
+
properties: i.properties,
|
|
146
|
+
propertyNames: i.propertyNames,
|
|
147
|
+
listProperties: i.listProperties,
|
|
148
|
+
stride: i.stride,
|
|
149
|
+
offset: a ? o : -1,
|
|
150
|
+
hasListProperty: i.hasListProperty
|
|
151
|
+
}), i.hasListProperty ? a = !1 : o += i.count * i.stride;
|
|
152
|
+
return {
|
|
153
|
+
elements: h,
|
|
154
|
+
element: (i) => h.find((c) => c.name === i)
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function J(e, t) {
|
|
158
|
+
if (e.offset < 0)
|
|
159
|
+
throw new Error(
|
|
160
|
+
\`Unsupported PLY layout: element "\${e.name}" follows a list property, so its position cannot be determined.\`
|
|
161
|
+
);
|
|
162
|
+
const r = e.offset + e.count * e.stride;
|
|
163
|
+
if (r > t)
|
|
164
|
+
throw new Error(
|
|
165
|
+
\`Truncated PLY file: element "\${e.name}" needs \${r} bytes but the file is \${t}.\`
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
function D(e, t) {
|
|
169
|
+
const r = e.properties.get(t);
|
|
170
|
+
if (!r)
|
|
171
|
+
throw new Error(\`PLY element "\${e.name}" is missing property "\${t}".\`);
|
|
172
|
+
return r.offset;
|
|
173
|
+
}
|
|
174
|
+
function W(e, t, r, n) {
|
|
175
|
+
for (const s of t) {
|
|
176
|
+
const o = e.properties.get(s);
|
|
177
|
+
if (!o)
|
|
178
|
+
throw new Error(\`\${n}: missing property "\${s}".\`);
|
|
179
|
+
if (!r.includes(o.type))
|
|
180
|
+
throw new Error(
|
|
181
|
+
\`Unsupported PLY property type for "\${s}": expected \${r.join(" or ")}, got \${o.type}.\`
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const ae = 256, Ct = [
|
|
186
|
+
"min_x",
|
|
187
|
+
"min_y",
|
|
188
|
+
"min_z",
|
|
189
|
+
"max_x",
|
|
190
|
+
"max_y",
|
|
191
|
+
"max_z",
|
|
192
|
+
"min_scale_x",
|
|
193
|
+
"min_scale_y",
|
|
194
|
+
"min_scale_z",
|
|
195
|
+
"max_scale_x",
|
|
196
|
+
"max_scale_y",
|
|
197
|
+
"max_scale_z"
|
|
198
|
+
], vt = ["min_r", "min_g", "min_b", "max_r", "max_g", "max_b"], kt = [
|
|
199
|
+
"packed_position",
|
|
200
|
+
"packed_rotation",
|
|
201
|
+
"packed_scale",
|
|
202
|
+
"packed_color"
|
|
203
|
+
], Le = { 1: 3, 2: 8, 3: 15 }, we = -4, ye = 4;
|
|
204
|
+
function ze(e) {
|
|
205
|
+
const t = e.element("vertex");
|
|
206
|
+
return t !== void 0 && t.properties.has("packed_position");
|
|
207
|
+
}
|
|
208
|
+
function C(e, t) {
|
|
209
|
+
const r = (1 << t) - 1;
|
|
210
|
+
return (e & r) / r;
|
|
211
|
+
}
|
|
212
|
+
function M(e, t, r) {
|
|
213
|
+
return e + (t - e) * r;
|
|
214
|
+
}
|
|
215
|
+
function Ye(e, t) {
|
|
216
|
+
const r = t.element("chunk"), n = t.element("vertex");
|
|
217
|
+
if (!r || !n)
|
|
218
|
+
throw new Error('Compressed PLY is missing its "chunk" or "vertex" element.');
|
|
219
|
+
W(n, kt, ["uint", "uint32"], "Compressed PLY vertex"), W(r, Ct, ["float", "float32"], "Compressed PLY chunk");
|
|
220
|
+
const s = r.properties.has("min_r");
|
|
221
|
+
s && W(
|
|
222
|
+
r,
|
|
223
|
+
vt,
|
|
224
|
+
["float", "float32"],
|
|
225
|
+
"Compressed PLY chunk"
|
|
226
|
+
), J(r, e.byteLength), J(n, e.byteLength);
|
|
227
|
+
const o = n.count, a = Math.ceil(o / ae);
|
|
228
|
+
if (r.count < a)
|
|
229
|
+
throw new Error(
|
|
230
|
+
\`Compressed PLY declares \${r.count} chunks, too few for \${o} splats (needs \${a} at \${ae} splats per chunk).\`
|
|
231
|
+
);
|
|
232
|
+
const h = new DataView(e, r.offset), i = new DataView(e, n.offset), c = (w, p) => h.getFloat32(w * r.stride + D(r, p), !0), f = D(n, "packed_position"), l = D(n, "packed_rotation"), d = D(n, "packed_scale"), u = D(n, "packed_color"), y = new Float32Array(o * 3), m = new Uint8Array(o * 4), b = new Float32Array(o * 6);
|
|
233
|
+
for (let w = 0; w < a; w++) {
|
|
234
|
+
const p = c(w, "min_x"), A = c(w, "min_y"), g = c(w, "min_z"), E = c(w, "max_x"), v = c(w, "max_y"), U = c(w, "max_z"), T = c(w, "min_scale_x"), F = c(w, "min_scale_y"), N = c(w, "min_scale_z"), V = c(w, "max_scale_x"), S = c(w, "max_scale_y"), X = c(w, "max_scale_z"), B = s ? c(w, "min_r") : 0, j = s ? c(w, "min_g") : 0, k = s ? c(w, "min_b") : 0, x = s ? c(w, "max_r") : 1, Z = s ? c(w, "max_g") : 1, re = s ? c(w, "max_b") : 1, xe = w * ae, ht = Math.min(xe + ae, o);
|
|
235
|
+
for (let L = xe; L < ht; L++) {
|
|
236
|
+
const ne = L * n.stride, le = i.getUint32(ne + f, !0);
|
|
237
|
+
y[L * 3 + 0] = M(p, E, C(le >>> 21, 11)), y[L * 3 + 1] = M(A, v, C(le >>> 11, 10)), y[L * 3 + 2] = M(g, U, C(le, 11));
|
|
238
|
+
const oe = i.getUint32(ne + u, !0), Ce = C(oe >>> 24, 8), ve = C(oe >>> 16, 8), ke = C(oe >>> 8, 8), ft = C(oe, 8);
|
|
239
|
+
m[L * 4 + 0] = ie(s ? M(B, x, Ce) : Ce), m[L * 4 + 1] = ie(s ? M(j, Z, ve) : ve), m[L * 4 + 2] = ie(s ? M(k, re, ke) : ke), m[L * 4 + 3] = ie(ft);
|
|
240
|
+
const de = i.getUint32(ne + d, !0), lt = Math.exp(M(T, V, C(de >>> 21, 11))), dt = Math.exp(M(F, S, C(de >>> 11, 10))), ut = Math.exp(M(N, X, C(de, 11))), q = i.getUint32(ne + l, !0), z = (C(q >>> 20, 10) - 0.5) * Math.SQRT2, Y = (C(q >>> 10, 10) - 0.5) * Math.SQRT2, G = (C(q, 10) - 0.5) * Math.SQRT2, se = Math.sqrt(Math.max(0, 1 - (z * z + Y * Y + G * G))), [wt, yt, mt, pt] = q >>> 30 ? q >>> 30 === 1 ? [z, se, Y, G] : q >>> 30 === 2 ? [z, Y, se, G] : [z, Y, G, se] : [se, z, Y, G];
|
|
241
|
+
te(b, L, lt, dt, ut, wt, yt, mt, pt);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const _ = Lt(e, t, o);
|
|
245
|
+
return { count: o, positions: y, colors: m, covariances: b, ..._ ? { shPacked: _ } : {} };
|
|
246
|
+
}
|
|
247
|
+
function ie(e) {
|
|
248
|
+
return Math.max(0, Math.min(255, Math.round(e * 255)));
|
|
249
|
+
}
|
|
250
|
+
function Lt(e, t, r) {
|
|
251
|
+
const n = t.element("sh");
|
|
252
|
+
if (!n || n.count === 0) return;
|
|
253
|
+
if (n.count !== r)
|
|
254
|
+
throw new Error(\`Compressed PLY "sh" element has \${n.count} records for \${r} splats.\`);
|
|
255
|
+
const s = n.propertyNames.length / 3, o = Number(
|
|
256
|
+
Object.keys(Le).find((f) => Le[Number(f)] === s)
|
|
257
|
+
);
|
|
258
|
+
if (!o)
|
|
259
|
+
throw new Error(
|
|
260
|
+
\`Compressed PLY "sh" element has \${n.propertyNames.length} properties, which is not 3, 8 or 15 coefficients across three channels.\`
|
|
261
|
+
);
|
|
262
|
+
const a = Array.from({ length: s * 3 }, (f, l) => \`f_rest_\${l}\`);
|
|
263
|
+
W(n, a, ["uchar", "uint8"], "Compressed PLY sh"), J(n, e.byteLength);
|
|
264
|
+
const h = new Uint8Array(e, n.offset), i = a.map((f) => D(n, f)), c = new Uint32Array(r * s);
|
|
265
|
+
for (let f = 0; f < r; f++) {
|
|
266
|
+
const l = f * n.stride;
|
|
267
|
+
for (let d = 0; d < s; d++) {
|
|
268
|
+
const u = h[l + i[d]] / 255, y = h[l + i[s + d]] / 255, m = h[l + i[2 * s + d]] / 255;
|
|
269
|
+
c[f * s + d] = (Math.round(u * 2047) | Math.round(y * 1023) << 11 | Math.round(m * 2047) << 21) >>> 0;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
bands: o,
|
|
274
|
+
packed: c,
|
|
275
|
+
range: { min: [we, we, we], max: [ye, ye, ye] }
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
const $t = 100;
|
|
279
|
+
function Ut(e, t = $t) {
|
|
280
|
+
let r = -1 / 0;
|
|
281
|
+
return (n, s) => {
|
|
282
|
+
const o = s > 0 && n >= s, a = Dt();
|
|
283
|
+
!o && a - r < t || (r = a, e(n, s));
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
class $e extends Error {
|
|
287
|
+
constructor(r, n) {
|
|
288
|
+
super(r, { cause: n.cause });
|
|
289
|
+
K(this, "phase");
|
|
290
|
+
K(this, "url");
|
|
291
|
+
K(this, "status");
|
|
292
|
+
K(this, "retryable");
|
|
293
|
+
this.name = "SplatLoadError", this.phase = n.phase, this.url = n.url, this.status = n.status, this.retryable = n.retryable;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
function Re(e, t) {
|
|
297
|
+
return {
|
|
298
|
+
...e != null && e.headers ? { headers: { ...e.headers } } : {},
|
|
299
|
+
...e != null && e.credentials ? { credentials: e.credentials } : {},
|
|
300
|
+
...e != null && e.mode ? { mode: e.mode } : {},
|
|
301
|
+
...e != null && e.cache ? { cache: e.cache } : {},
|
|
302
|
+
...t ? { signal: t } : {}
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
const Mt = 2 ** 31;
|
|
306
|
+
function Pt(e) {
|
|
307
|
+
return \`\${(e / 1e9).toFixed(1)} GB\`;
|
|
308
|
+
}
|
|
309
|
+
async function Ge(e) {
|
|
310
|
+
if (e.size > Mt)
|
|
311
|
+
throw new Error(
|
|
312
|
+
\`\${e.name} is \${Pt(e.size)}. A browser cannot read more than 2 GB of a file at once, and this format has to be decoded in one piece. Convert it to SOG (npx @playcanvas/splat-transform in.ply out.sog) or a compressed .ply.\`
|
|
313
|
+
);
|
|
314
|
+
try {
|
|
315
|
+
return await e.arrayBuffer();
|
|
316
|
+
} catch (t) {
|
|
317
|
+
throw $(t) ? t : t instanceof Error && t.name === "NotReadableError" ? new Error(
|
|
318
|
+
\`\${e.name} could not be read. It may have been moved, renamed or changed since it was dropped, or it may be on a drive the browser cannot reach.\`,
|
|
319
|
+
{ cause: t }
|
|
320
|
+
) : t;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function $(e) {
|
|
324
|
+
return e instanceof Error && e.name === "AbortError";
|
|
325
|
+
}
|
|
326
|
+
function R(e, t) {
|
|
327
|
+
if (e instanceof $e) return e;
|
|
328
|
+
const r = e instanceof Error ? e.message : String(e);
|
|
329
|
+
return new $e(r, {
|
|
330
|
+
...t,
|
|
331
|
+
retryable: Ft(t.status, t.phase),
|
|
332
|
+
cause: e
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
function Tt(e) {
|
|
336
|
+
return {
|
|
337
|
+
name: e.name,
|
|
338
|
+
message: e.message,
|
|
339
|
+
phase: e.phase,
|
|
340
|
+
url: e.url,
|
|
341
|
+
...e.status === void 0 ? {} : { status: e.status },
|
|
342
|
+
retryable: e.retryable
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
function Dt() {
|
|
346
|
+
var e;
|
|
347
|
+
return ((e = globalThis.performance) == null ? void 0 : e.now()) ?? Date.now();
|
|
348
|
+
}
|
|
349
|
+
function Ft(e, t) {
|
|
350
|
+
return e !== void 0 ? e === 408 || e === 425 || e === 429 || e >= 500 : t === "fetch" || t === "manifest" || t === "worker";
|
|
351
|
+
}
|
|
352
|
+
const Nt = [
|
|
353
|
+
"x",
|
|
354
|
+
"y",
|
|
355
|
+
"z",
|
|
356
|
+
"f_dc_0",
|
|
357
|
+
"f_dc_1",
|
|
358
|
+
"f_dc_2",
|
|
359
|
+
"opacity",
|
|
360
|
+
"scale_0",
|
|
361
|
+
"scale_1",
|
|
362
|
+
"scale_2",
|
|
363
|
+
"rot_0",
|
|
364
|
+
"rot_1",
|
|
365
|
+
"rot_2",
|
|
366
|
+
"rot_3"
|
|
367
|
+
], Ot = { 3: 1, 8: 2, 15: 3 };
|
|
368
|
+
function It(e) {
|
|
369
|
+
return 1 / (1 + Math.exp(-e));
|
|
370
|
+
}
|
|
371
|
+
function Bt(e) {
|
|
372
|
+
const t = qe(e);
|
|
373
|
+
if (ze(t)) return Ye(e, t);
|
|
374
|
+
const r = He(t);
|
|
375
|
+
J(r, e.byteLength);
|
|
376
|
+
const n = Xe(r.count), s = We(r), o = s ? new Float32Array(r.count * s.coefficients * 3) : null;
|
|
377
|
+
return Ze(
|
|
378
|
+
new DataView(e, r.offset),
|
|
379
|
+
je(r),
|
|
380
|
+
r.stride,
|
|
381
|
+
0,
|
|
382
|
+
0,
|
|
383
|
+
r.count,
|
|
384
|
+
n
|
|
385
|
+
), s && o && Ke(
|
|
386
|
+
new DataView(e, r.offset),
|
|
387
|
+
r.stride,
|
|
388
|
+
0,
|
|
389
|
+
0,
|
|
390
|
+
r.count,
|
|
391
|
+
s,
|
|
392
|
+
o
|
|
393
|
+
), Ve(r.count, n, s, o);
|
|
394
|
+
}
|
|
395
|
+
const qt = 64 * 1024 * 1024, zt = 64 * 1024;
|
|
396
|
+
async function Yt(e, t = {}) {
|
|
397
|
+
const { signal: r, onProgress: n } = t, s = t.windowBytes ?? qt, o = await e.slice(0, Math.min(e.size, zt)).arrayBuffer(), a = qe(o);
|
|
398
|
+
if (ze(a)) return Ye(await Ge(e), a);
|
|
399
|
+
const h = He(a);
|
|
400
|
+
J(h, e.size), r == null || r.throwIfAborted();
|
|
401
|
+
const i = h.count, c = h.stride, f = Xe(i), l = je(h), d = We(h), u = d ? new Float32Array(i * d.coefficients * 3) : null, y = Math.max(1, Math.floor(s / c)), m = i * c;
|
|
402
|
+
n == null || n(0, m);
|
|
403
|
+
for (let b = 0; b < i; b += y) {
|
|
404
|
+
r == null || r.throwIfAborted();
|
|
405
|
+
const _ = Math.min(b + y, i), w = e.slice(h.offset + b * c, h.offset + _ * c), p = new DataView(await w.arrayBuffer());
|
|
406
|
+
Ze(p, l, c, b, b, _, f), d && u && Ke(p, c, b, b, _, d, u), n == null || n(_ * c, m);
|
|
407
|
+
}
|
|
408
|
+
return Ve(i, f, d, u);
|
|
409
|
+
}
|
|
410
|
+
function He(e) {
|
|
411
|
+
const t = e.element("vertex");
|
|
412
|
+
if (!t) throw new Error('PLY file is not a Gaussian splat file: no "vertex" element.');
|
|
413
|
+
return W(
|
|
414
|
+
t,
|
|
415
|
+
Nt,
|
|
416
|
+
["float", "float32"],
|
|
417
|
+
"PLY file is not a Gaussian splat file"
|
|
418
|
+
), t;
|
|
419
|
+
}
|
|
420
|
+
function We(e) {
|
|
421
|
+
const t = e.propertyNames.filter((a) => a.startsWith("f_rest_"));
|
|
422
|
+
if (t.length === 0) return null;
|
|
423
|
+
if (t.length % 3 !== 0)
|
|
424
|
+
throw new Error(
|
|
425
|
+
\`PLY vertex has \${t.length} f_rest_* properties, which is not divisible by three.\`
|
|
426
|
+
);
|
|
427
|
+
const r = t.length / 3, n = Ot[r];
|
|
428
|
+
if (!n)
|
|
429
|
+
throw new Error(
|
|
430
|
+
\`PLY vertex has \${r} SH coefficients per channel; expected 3, 8 or 15.\`
|
|
431
|
+
);
|
|
432
|
+
const s = Array.from({ length: r * 3 }, (a, h) => \`f_rest_\${h}\`);
|
|
433
|
+
W(e, s, ["float", "float32"], "PLY f_rest");
|
|
434
|
+
const o = s.map((a) => D(e, a));
|
|
435
|
+
return { bands: n, coefficients: r, offsets: o };
|
|
436
|
+
}
|
|
437
|
+
function Ve(e, t, r, n) {
|
|
438
|
+
const s = r && n ? Ae(n, e, r.bands) : void 0;
|
|
439
|
+
return { count: e, ...t, ...s ? { shPacked: s } : {} };
|
|
440
|
+
}
|
|
441
|
+
function Xe(e) {
|
|
442
|
+
return {
|
|
443
|
+
positions: new Float32Array(e * 3),
|
|
444
|
+
colors: new Uint8Array(e * 4),
|
|
445
|
+
covariances: new Float32Array(e * 6)
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
function je(e) {
|
|
449
|
+
const t = (r) => D(e, r);
|
|
450
|
+
return {
|
|
451
|
+
x: t("x"),
|
|
452
|
+
y: t("y"),
|
|
453
|
+
z: t("z"),
|
|
454
|
+
r: t("f_dc_0"),
|
|
455
|
+
g: t("f_dc_1"),
|
|
456
|
+
b: t("f_dc_2"),
|
|
457
|
+
alpha: t("opacity"),
|
|
458
|
+
s0: t("scale_0"),
|
|
459
|
+
s1: t("scale_1"),
|
|
460
|
+
s2: t("scale_2"),
|
|
461
|
+
q0: t("rot_0"),
|
|
462
|
+
q1: t("rot_1"),
|
|
463
|
+
q2: t("rot_2"),
|
|
464
|
+
q3: t("rot_3")
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
function Ze(e, t, r, n, s, o, a) {
|
|
468
|
+
const { positions: h, colors: i, covariances: c } = a;
|
|
469
|
+
for (let f = s; f < o; f++) {
|
|
470
|
+
const l = (f - n) * r, d = (y) => e.getFloat32(l + y, !0);
|
|
471
|
+
h[f * 3 + 0] = d(t.x), h[f * 3 + 1] = d(t.y), h[f * 3 + 2] = d(t.z);
|
|
472
|
+
const u = (y) => Math.max(0, Math.min(255, Math.round((0.5 + Be * y) * 255)));
|
|
473
|
+
i[f * 4 + 0] = u(d(t.r)), i[f * 4 + 1] = u(d(t.g)), i[f * 4 + 2] = u(d(t.b)), i[f * 4 + 3] = Math.round(It(d(t.alpha)) * 255), te(
|
|
474
|
+
c,
|
|
475
|
+
f,
|
|
476
|
+
Math.exp(d(t.s0)),
|
|
477
|
+
Math.exp(d(t.s1)),
|
|
478
|
+
Math.exp(d(t.s2)),
|
|
479
|
+
d(t.q0),
|
|
480
|
+
d(t.q1),
|
|
481
|
+
d(t.q2),
|
|
482
|
+
d(t.q3)
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
function Ke(e, t, r, n, s, o, a) {
|
|
487
|
+
const { coefficients: h, offsets: i } = o;
|
|
488
|
+
for (let c = n; c < s; c++) {
|
|
489
|
+
const f = (c - r) * t, l = c * h * 3;
|
|
490
|
+
for (let d = 0; d < h; d++)
|
|
491
|
+
a[l + d * 3 + 0] = e.getFloat32(f + i[d], !0), a[l + d * 3 + 1] = e.getFloat32(f + i[h + d], !0), a[l + d * 3 + 2] = e.getFloat32(
|
|
492
|
+
f + i[2 * h + d],
|
|
493
|
+
!0
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
const Ue = 1 << 24;
|
|
498
|
+
async function Gt(e, t = {}) {
|
|
499
|
+
const r = jt(e);
|
|
500
|
+
return Qe(async (n) => {
|
|
501
|
+
const s = r.get(n);
|
|
502
|
+
if (!s) throw new Error(\`SOG bundle is missing "\${n}".\`);
|
|
503
|
+
return s();
|
|
504
|
+
}, t.signal);
|
|
505
|
+
}
|
|
506
|
+
async function Ht(e, t = {}) {
|
|
507
|
+
const r = e.endsWith("/") ? e : \`\${e}/\`;
|
|
508
|
+
return Qe(async (n) => {
|
|
509
|
+
var h;
|
|
510
|
+
Vt(n);
|
|
511
|
+
const s = (h = t.files) == null ? void 0 : h[n];
|
|
512
|
+
if (t.files && s === void 0)
|
|
513
|
+
throw new Error(\`SOG chunk is missing "\${n}".\`);
|
|
514
|
+
const o = s === void 0 ? new URL(n, r) : new URL(s);
|
|
515
|
+
let a;
|
|
516
|
+
try {
|
|
517
|
+
a = await fetch(o, Re(t.request, t.signal));
|
|
518
|
+
} catch (i) {
|
|
519
|
+
throw $(i) ? i : R(i, { phase: "fetch", url: o.href });
|
|
520
|
+
}
|
|
521
|
+
if (!a.ok)
|
|
522
|
+
throw R(new Error(\`Failed to load \${o.href}: HTTP \${a.status}\`), {
|
|
523
|
+
phase: "fetch",
|
|
524
|
+
url: o.href,
|
|
525
|
+
status: a.status
|
|
526
|
+
});
|
|
527
|
+
return new Uint8Array(await a.arrayBuffer());
|
|
528
|
+
}, t.signal);
|
|
529
|
+
}
|
|
530
|
+
async function Qe(e, t) {
|
|
531
|
+
const r = JSON.parse(new TextDecoder().decode(await e("meta.json")));
|
|
532
|
+
Wt(r), t == null || t.throwIfAborted();
|
|
533
|
+
const [n, s, o, a, h] = await Promise.all([
|
|
534
|
+
e(r.means.files[0] ?? "means_l.webp").then(O),
|
|
535
|
+
e(r.means.files[1] ?? "means_u.webp").then(O),
|
|
536
|
+
e(r.quats.files[0] ?? "quats.webp").then(O),
|
|
537
|
+
e(r.scales.files[0] ?? "scales.webp").then(O),
|
|
538
|
+
e(r.sh0.files[0] ?? "sh0.webp").then(O)
|
|
539
|
+
]);
|
|
540
|
+
t == null || t.throwIfAborted();
|
|
541
|
+
const i = r.count;
|
|
542
|
+
H(n, "means_l", i), H(s, "means_u", i), H(o, "quats", i), H(a, "scales", i), H(h, "sh0", i);
|
|
543
|
+
const c = new Float32Array(i * 3), f = new Uint8Array(i * 4), l = new Float32Array(i * 6), { mins: d, maxs: u } = r.means, y = (w) => Math.sign(w) * (Math.exp(Math.abs(w)) - 1), m = (w) => (w / 255 - 0.5) * Math.SQRT2, b = (w) => Math.max(0, Math.min(255, Math.round((0.5 + w * Be) * 255)));
|
|
544
|
+
for (let w = 0; w < i; w++) {
|
|
545
|
+
t && (w & 65535) === 0 && w > 0 && (await new Promise((S) => setTimeout(S, 0)), t.throwIfAborted());
|
|
546
|
+
const p = w * 4;
|
|
547
|
+
for (let S = 0; S < 3; S++) {
|
|
548
|
+
const X = (s.data[p + S] << 8 | n.data[p + S]) / 65535, B = d[S], j = u[S];
|
|
549
|
+
c[w * 3 + S] = y(B + (j - B) * X);
|
|
550
|
+
}
|
|
551
|
+
f[p + 0] = b(r.sh0.codebook[h.data[p + 0]]), f[p + 1] = b(r.sh0.codebook[h.data[p + 1]]), f[p + 2] = b(r.sh0.codebook[h.data[p + 2]]), f[p + 3] = h.data[p + 3];
|
|
552
|
+
const A = m(o.data[p + 0]), g = m(o.data[p + 1]), E = m(o.data[p + 2]), v = Math.sqrt(Math.max(0, 1 - (A * A + g * g + E * E))), U = o.data[p + 3] - 252, [T, F, N, V] = U === 0 ? [v, A, g, E] : U === 1 ? [A, v, g, E] : U === 2 ? [A, g, v, E] : [A, g, E, v];
|
|
553
|
+
te(
|
|
554
|
+
l,
|
|
555
|
+
w,
|
|
556
|
+
Math.exp(r.scales.codebook[a.data[p + 0]]),
|
|
557
|
+
Math.exp(r.scales.codebook[a.data[p + 1]]),
|
|
558
|
+
Math.exp(r.scales.codebook[a.data[p + 2]]),
|
|
559
|
+
T,
|
|
560
|
+
F,
|
|
561
|
+
N,
|
|
562
|
+
V
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
t == null || t.throwIfAborted();
|
|
566
|
+
const _ = r.shN ? await Xt(r.shN, i, e) : void 0;
|
|
567
|
+
return { count: i, positions: c, colors: f, covariances: l, sh: _, antialias: r.antialias === !0 };
|
|
568
|
+
}
|
|
569
|
+
function Wt(e) {
|
|
570
|
+
var t, r, n, s;
|
|
571
|
+
if (e.version !== 2) throw new Error(\`Unsupported SOG version: \${e.version}.\`);
|
|
572
|
+
if (!Number.isSafeInteger(e.count) || e.count < 0)
|
|
573
|
+
throw new Error(\`SOG meta.json declares an invalid splat count: \${e.count}.\`);
|
|
574
|
+
if (e.count > Ue)
|
|
575
|
+
throw new Error(
|
|
576
|
+
\`SOG meta.json declares \${e.count} splats, above the supported maximum of \${Ue}.\`
|
|
577
|
+
);
|
|
578
|
+
if (Me((t = e.means) == null ? void 0 : t.mins, "means.mins"), Me((r = e.means) == null ? void 0 : r.maxs, "means.maxs"), me((n = e.scales) == null ? void 0 : n.codebook, "scales"), me((s = e.sh0) == null ? void 0 : s.codebook, "sh0"), e.shN) {
|
|
579
|
+
me(e.shN.codebook, "shN");
|
|
580
|
+
const o = e.shN.bands;
|
|
581
|
+
if (!Number.isInteger(o) || o < 1 || o > 3)
|
|
582
|
+
throw new Error(\`SOG meta.json declares an invalid shN band count: \${o}.\`);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
function Me(e, t) {
|
|
586
|
+
if (!Array.isArray(e) || e.length !== 3 || e.some((r) => typeof r != "number" || !Number.isFinite(r)))
|
|
587
|
+
throw new Error(\`SOG meta.json: "\${t}" must be an array of 3 finite numbers.\`);
|
|
588
|
+
}
|
|
589
|
+
function me(e, t) {
|
|
590
|
+
if (!Array.isArray(e) || e.length < 256)
|
|
591
|
+
throw new Error(\`SOG meta.json: the "\${t}" codebook must contain at least 256 entries.\`);
|
|
592
|
+
for (const r of e)
|
|
593
|
+
if (typeof r != "number" || !Number.isFinite(r))
|
|
594
|
+
throw new Error(\`SOG meta.json: the "\${t}" codebook contains a non-finite entry.\`);
|
|
595
|
+
}
|
|
596
|
+
function H(e, t, r) {
|
|
597
|
+
if (r > e.width * e.height)
|
|
598
|
+
throw new Error(
|
|
599
|
+
\`SOG "\${t}" image (\${e.width}×\${e.height}) holds fewer than the declared \${r} splats.\`
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
function Vt(e) {
|
|
603
|
+
if (typeof e != "string" || e.length === 0 || /^[a-z][a-z0-9+.-]*:/i.test(e) || e.startsWith("/") || e.includes("\\\\") || e.split("/").some((r) => r === ".."))
|
|
604
|
+
throw new Error(\`SOG meta.json references a file outside its directory: "\${e}".\`);
|
|
605
|
+
}
|
|
606
|
+
async function Xt(e, t, r) {
|
|
607
|
+
const [n, s] = await Promise.all([
|
|
608
|
+
r(e.files[0] ?? "shN_centroids.webp").then(O),
|
|
609
|
+
r(e.files[1] ?? "shN_labels.webp").then(O)
|
|
610
|
+
]);
|
|
611
|
+
H(s, "shN labels", t);
|
|
612
|
+
const o = e.bands === 1 ? 3 : e.bands === 2 ? 8 : 15, a = new Uint32Array(t);
|
|
613
|
+
for (let i = 0; i < t; i++) {
|
|
614
|
+
const c = s.data[i * 4] | s.data[i * 4 + 1] << 8, f = Math.floor(c / 64), l = c % 64 * o;
|
|
615
|
+
if (f >= n.height || l + o > n.width)
|
|
616
|
+
throw new Error(
|
|
617
|
+
\`SOG shN label \${c} (splat \${i}) lies outside the \${n.width}×\${n.height} centroids palette.\`
|
|
618
|
+
);
|
|
619
|
+
a[i] = c;
|
|
620
|
+
}
|
|
621
|
+
const h = new Float32Array(n.width * n.height * 4);
|
|
622
|
+
for (let i = 0; i < n.width * n.height; i++)
|
|
623
|
+
h[i * 4 + 0] = e.codebook[n.data[i * 4 + 0]], h[i * 4 + 1] = e.codebook[n.data[i * 4 + 1]], h[i * 4 + 2] = e.codebook[n.data[i * 4 + 2]];
|
|
624
|
+
return {
|
|
625
|
+
bands: e.bands,
|
|
626
|
+
labels: a,
|
|
627
|
+
palette: h,
|
|
628
|
+
paletteWidth: n.width,
|
|
629
|
+
paletteHeight: n.height
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
function jt(e) {
|
|
633
|
+
const t = new DataView(e), r = new Uint8Array(e);
|
|
634
|
+
let n = -1;
|
|
635
|
+
const s = Math.max(0, e.byteLength - 65557);
|
|
636
|
+
for (let i = e.byteLength - 22; i >= s && !(i < 0); i--)
|
|
637
|
+
if (t.getUint32(i, !0) === 101010256) {
|
|
638
|
+
n = i;
|
|
639
|
+
break;
|
|
640
|
+
}
|
|
641
|
+
if (n < 0) throw new Error("Not a ZIP archive (no end-of-central-directory record).");
|
|
642
|
+
const o = t.getUint16(n + 10, !0);
|
|
643
|
+
let a = t.getUint32(n + 16, !0);
|
|
644
|
+
const h = /* @__PURE__ */ new Map();
|
|
645
|
+
for (let i = 0; i < o; i++) {
|
|
646
|
+
if (a < 0 || a + 46 > e.byteLength)
|
|
647
|
+
throw new Error("Corrupt ZIP central directory.");
|
|
648
|
+
if (t.getUint32(a, !0) !== 33639248)
|
|
649
|
+
throw new Error("Corrupt ZIP central directory.");
|
|
650
|
+
const c = t.getUint16(a + 10, !0), f = t.getUint32(a + 20, !0), l = t.getUint16(a + 28, !0), d = t.getUint16(a + 30, !0), u = t.getUint16(a + 32, !0), y = t.getUint32(a + 42, !0);
|
|
651
|
+
if (a + 46 + l > e.byteLength)
|
|
652
|
+
throw new Error("Corrupt ZIP central directory.");
|
|
653
|
+
const m = new TextDecoder().decode(r.subarray(a + 46, a + 46 + l));
|
|
654
|
+
a += 46 + l + d + u, h.set(m, async () => {
|
|
655
|
+
if (y + 30 > e.byteLength)
|
|
656
|
+
throw new Error(\`Corrupt ZIP entry "\${m}": local header extends past the archive.\`);
|
|
657
|
+
const b = t.getUint16(y + 26, !0), _ = t.getUint16(y + 28, !0), w = y + 30 + b + _;
|
|
658
|
+
if (w + f > e.byteLength)
|
|
659
|
+
throw new Error(\`Corrupt ZIP entry "\${m}": data extends past the archive.\`);
|
|
660
|
+
const p = r.subarray(w, w + f);
|
|
661
|
+
if (c === 0) return p;
|
|
662
|
+
if (c === 8) {
|
|
663
|
+
const A = new Blob([p]).stream().pipeThrough(new DecompressionStream("deflate-raw"));
|
|
664
|
+
return new Uint8Array(await new Response(A).arrayBuffer());
|
|
665
|
+
}
|
|
666
|
+
throw new Error(\`Unsupported ZIP compression method \${c} for "\${m}".\`);
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
return h;
|
|
670
|
+
}
|
|
671
|
+
let ce;
|
|
672
|
+
function Zt() {
|
|
673
|
+
if (!("OffscreenCanvas" in globalThis) || !("createImageBitmap" in globalThis)) return;
|
|
674
|
+
if (ce && !ce.isContextLost()) return ce;
|
|
675
|
+
const t = new OffscreenCanvas(1, 1).getContext("webgl2", {
|
|
676
|
+
alpha: !1,
|
|
677
|
+
antialias: !1,
|
|
678
|
+
depth: !1,
|
|
679
|
+
premultipliedAlpha: !1,
|
|
680
|
+
preserveDrawingBuffer: !0,
|
|
681
|
+
stencil: !1
|
|
682
|
+
});
|
|
683
|
+
if (t)
|
|
684
|
+
return ce = t, t;
|
|
685
|
+
}
|
|
686
|
+
async function Kt(e, t) {
|
|
687
|
+
const r = e, n = await createImageBitmap(new Blob([r], { type: "image/webp" }), {
|
|
688
|
+
colorSpaceConversion: "none",
|
|
689
|
+
premultiplyAlpha: "none"
|
|
690
|
+
}), s = t.createTexture(), o = t.createFramebuffer();
|
|
691
|
+
if (!s || !o)
|
|
692
|
+
throw n.close(), new Error("Could not allocate a WebGL texture for SOG WebP decoding.");
|
|
693
|
+
try {
|
|
694
|
+
if (t.bindTexture(t.TEXTURE_2D, s), t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL, !1), t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL, !1), t.pixelStorei(t.UNPACK_COLORSPACE_CONVERSION_WEBGL, t.NONE), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MIN_FILTER, t.NEAREST), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MAG_FILTER, t.NEAREST), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_S, t.CLAMP_TO_EDGE), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_T, t.CLAMP_TO_EDGE), t.texImage2D(
|
|
695
|
+
t.TEXTURE_2D,
|
|
696
|
+
0,
|
|
697
|
+
t.RGBA,
|
|
698
|
+
t.RGBA,
|
|
699
|
+
t.UNSIGNED_BYTE,
|
|
700
|
+
n
|
|
701
|
+
), t.bindFramebuffer(t.FRAMEBUFFER, o), t.framebufferTexture2D(
|
|
702
|
+
t.FRAMEBUFFER,
|
|
703
|
+
t.COLOR_ATTACHMENT0,
|
|
704
|
+
t.TEXTURE_2D,
|
|
705
|
+
s,
|
|
706
|
+
0
|
|
707
|
+
), t.checkFramebufferStatus(t.FRAMEBUFFER) !== t.FRAMEBUFFER_COMPLETE)
|
|
708
|
+
throw new Error("Could not read the decoded SOG WebP texture.");
|
|
709
|
+
const a = new Uint8Array(n.width * n.height * 4);
|
|
710
|
+
return t.readPixels(
|
|
711
|
+
0,
|
|
712
|
+
0,
|
|
713
|
+
n.width,
|
|
714
|
+
n.height,
|
|
715
|
+
t.RGBA,
|
|
716
|
+
t.UNSIGNED_BYTE,
|
|
717
|
+
a
|
|
718
|
+
), { width: n.width, height: n.height, data: a };
|
|
719
|
+
} finally {
|
|
720
|
+
t.bindFramebuffer(t.FRAMEBUFFER, null), t.bindTexture(t.TEXTURE_2D, null), t.deleteFramebuffer(o), t.deleteTexture(s), n.close();
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
async function O(e) {
|
|
724
|
+
const t = Zt();
|
|
725
|
+
if (t) return Kt(e, t);
|
|
726
|
+
if ("ImageDecoder" in globalThis) {
|
|
727
|
+
const h = new ImageDecoder({
|
|
728
|
+
data: e,
|
|
729
|
+
type: "image/webp",
|
|
730
|
+
colorSpaceConversion: "none"
|
|
731
|
+
}), { image: i } = await h.decode(), c = i.codedWidth, f = i.codedHeight, l = new Uint8Array(c * f * 4);
|
|
732
|
+
return await i.copyTo(l, { format: "RGBA" }), i.close(), h.close(), { width: c, height: f, data: l };
|
|
733
|
+
}
|
|
734
|
+
const r = e, n = await createImageBitmap(new Blob([r], { type: "image/webp" }), {
|
|
735
|
+
premultiplyAlpha: "none",
|
|
736
|
+
colorSpaceConversion: "none"
|
|
737
|
+
}), o = new OffscreenCanvas(n.width, n.height).getContext("2d");
|
|
738
|
+
if (!o) throw new Error("Could not create a 2D canvas context.");
|
|
739
|
+
o.drawImage(n, 0, 0);
|
|
740
|
+
const a = o.getImageData(0, 0, n.width, n.height);
|
|
741
|
+
return n.close(), {
|
|
742
|
+
width: a.width,
|
|
743
|
+
height: a.height,
|
|
744
|
+
data: new Uint8Array(a.data.buffer)
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
function Se(e) {
|
|
748
|
+
const t = e & 32768 ? -1 : 1, r = e >>> 10 & 31, n = e & 1023;
|
|
749
|
+
return r === 0 ? t * 2 ** -14 * (n / 1024) : r === 31 ? n === 0 ? t * (1 / 0) : Number.NaN : t * 2 ** (r - 15) * (1 + n / 1024);
|
|
750
|
+
}
|
|
751
|
+
const Qt = new Float32Array(1);
|
|
752
|
+
new Uint32Array(Qt.buffer);
|
|
753
|
+
function Jt(e) {
|
|
754
|
+
return e.encoding === "f32" ? 4 : e.encoding === "f16" ? 2 : 1;
|
|
755
|
+
}
|
|
756
|
+
function pe(e) {
|
|
757
|
+
if (e.min === void 0 || e.max === void 0)
|
|
758
|
+
throw new Error(\`RAD "\${e.property}" (\${e.encoding}) is missing its min/max range.\`);
|
|
759
|
+
return { min: e.min, max: e.max };
|
|
760
|
+
}
|
|
761
|
+
function Pe(e) {
|
|
762
|
+
if (e.max === void 0)
|
|
763
|
+
throw new Error(\`RAD "\${e.property}" (\${e.encoding}) is missing its max range.\`);
|
|
764
|
+
return e.max;
|
|
765
|
+
}
|
|
766
|
+
function I(e, t, r, n, s) {
|
|
767
|
+
if (e.byteLength < n * r * s)
|
|
768
|
+
throw new Error(
|
|
769
|
+
\`RAD "\${t.property}" column holds \${e.byteLength} bytes, fewer than the \${n * r * s} its declared \${n} splats need.\`
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
function Q(e, t, r, n) {
|
|
773
|
+
switch (I(e, t, r, n, Jt(t)), t.encoding) {
|
|
774
|
+
case "f32":
|
|
775
|
+
return Je(e, r, n);
|
|
776
|
+
case "f16":
|
|
777
|
+
return et(e, r, n);
|
|
778
|
+
case "f32_lebytes":
|
|
779
|
+
return or(e, r, n);
|
|
780
|
+
case "f16_lebytes":
|
|
781
|
+
return sr(e, r, n);
|
|
782
|
+
case "r8": {
|
|
783
|
+
const { min: s, max: o } = pe(t);
|
|
784
|
+
return ar(e, r, n, s, o);
|
|
785
|
+
}
|
|
786
|
+
case "r8_delta": {
|
|
787
|
+
const { min: s, max: o } = pe(t);
|
|
788
|
+
return ir(e, r, n, s, o);
|
|
789
|
+
}
|
|
790
|
+
case "s8":
|
|
791
|
+
return cr(e, r, n, Pe(t));
|
|
792
|
+
case "s8_delta":
|
|
793
|
+
return hr(e, r, n, Pe(t));
|
|
794
|
+
case "ln_0r8": {
|
|
795
|
+
const { min: s, max: o } = pe(t);
|
|
796
|
+
return fr(e, r, n, s, o);
|
|
797
|
+
}
|
|
798
|
+
case "ln_f16":
|
|
799
|
+
return lr(e, r, n);
|
|
800
|
+
default:
|
|
801
|
+
throw new Error(\`Unsupported RAD "\${t.property}" encoding "\${t.encoding}".\`);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
function er(e, t, r) {
|
|
805
|
+
if (t.encoding === "oct88r8")
|
|
806
|
+
return I(e, t, 3, r, 1), dr(e, r);
|
|
807
|
+
(t.encoding === "f32" || t.encoding === "f16") && I(e, t, 3, r, t.encoding === "f32" ? 4 : 2);
|
|
808
|
+
const n = t.encoding === "f32" ? Je(e, 3, r) : t.encoding === "f16" ? et(e, 3, r) : void 0;
|
|
809
|
+
if (!n) throw new Error(\`Unsupported RAD orientation encoding "\${t.encoding}".\`);
|
|
810
|
+
const s = new Float32Array(r * 4);
|
|
811
|
+
for (let o = 0; o < r; o++) {
|
|
812
|
+
const a = n[o * 3 + 0], h = n[o * 3 + 1], i = n[o * 3 + 2];
|
|
813
|
+
s[o * 4 + 0] = a, s[o * 4 + 1] = h, s[o * 4 + 2] = i, s[o * 4 + 3] = Math.sqrt(Math.max(0, 1 - a * a - h * h - i * i));
|
|
814
|
+
}
|
|
815
|
+
return s;
|
|
816
|
+
}
|
|
817
|
+
function tr(e, t, r) {
|
|
818
|
+
if (t.encoding !== "u16")
|
|
819
|
+
throw new Error(\`Unsupported RAD child_count encoding "\${t.encoding}".\`);
|
|
820
|
+
return I(e, t, 1, r, 2), tt(e, r);
|
|
821
|
+
}
|
|
822
|
+
function rr(e, t, r) {
|
|
823
|
+
if (t.encoding !== "u32")
|
|
824
|
+
throw new Error(\`Unsupported RAD child_start encoding "\${t.encoding}".\`);
|
|
825
|
+
return I(e, t, 1, r, 4), rt(e, r);
|
|
826
|
+
}
|
|
827
|
+
const Te = new DataView(new ArrayBuffer(4));
|
|
828
|
+
function nr(e) {
|
|
829
|
+
return Te.setUint32(0, e, !0), Te.getFloat32(0, !0);
|
|
830
|
+
}
|
|
831
|
+
function Je(e, t, r) {
|
|
832
|
+
const n = new DataView(e.buffer, e.byteOffset, e.byteLength), s = new Float32Array(r * t);
|
|
833
|
+
for (let o = 0; o < r; o++) {
|
|
834
|
+
let a = o * 4;
|
|
835
|
+
for (let h = 0; h < t; h++)
|
|
836
|
+
s[o * t + h] = n.getFloat32(a, !0), a += r * 4;
|
|
837
|
+
}
|
|
838
|
+
return s;
|
|
839
|
+
}
|
|
840
|
+
function et(e, t, r) {
|
|
841
|
+
const n = new DataView(e.buffer, e.byteOffset, e.byteLength), s = new Float32Array(r * t);
|
|
842
|
+
for (let o = 0; o < r; o++) {
|
|
843
|
+
let a = o * 2;
|
|
844
|
+
for (let h = 0; h < t; h++)
|
|
845
|
+
s[o * t + h] = Se(n.getUint16(a, !0)), a += r * 2;
|
|
846
|
+
}
|
|
847
|
+
return s;
|
|
848
|
+
}
|
|
849
|
+
function or(e, t, r) {
|
|
850
|
+
const n = r * t, s = new Float32Array(r * t);
|
|
851
|
+
for (let o = 0; o < r; o++)
|
|
852
|
+
for (let a = 0; a < t; a++) {
|
|
853
|
+
const h = r * a + o, i = (e[h] | e[h + n] << 8 | e[h + n * 2] << 16 | e[h + n * 3] << 24) >>> 0;
|
|
854
|
+
s[o * t + a] = nr(i);
|
|
855
|
+
}
|
|
856
|
+
return s;
|
|
857
|
+
}
|
|
858
|
+
function sr(e, t, r) {
|
|
859
|
+
const n = r * t, s = new Float32Array(r * t);
|
|
860
|
+
for (let o = 0; o < r; o++)
|
|
861
|
+
for (let a = 0; a < t; a++) {
|
|
862
|
+
const h = r * a + o, i = e[h] | e[h + n] << 8;
|
|
863
|
+
s[o * t + a] = Se(i);
|
|
864
|
+
}
|
|
865
|
+
return s;
|
|
866
|
+
}
|
|
867
|
+
function ar(e, t, r, n, s) {
|
|
868
|
+
const o = new Float32Array(r * t), a = s - n;
|
|
869
|
+
for (let h = 0; h < r; h++) {
|
|
870
|
+
let i = h;
|
|
871
|
+
for (let c = 0; c < t; c++)
|
|
872
|
+
o[h * t + c] = e[i] / 255 * a + n, i += r;
|
|
873
|
+
}
|
|
874
|
+
return o;
|
|
875
|
+
}
|
|
876
|
+
function ir(e, t, r, n, s) {
|
|
877
|
+
const o = new Float32Array(r * t), a = s - n, h = new Uint8Array(t);
|
|
878
|
+
for (let i = 0; i < r; i++) {
|
|
879
|
+
let c = i;
|
|
880
|
+
for (let f = 0; f < t; f++) {
|
|
881
|
+
const l = h[f] + e[c] & 255;
|
|
882
|
+
h[f] = l, o[i * t + f] = l / 255 * a + n, c += r;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
return o;
|
|
886
|
+
}
|
|
887
|
+
function cr(e, t, r, n) {
|
|
888
|
+
const s = new Float32Array(r * t);
|
|
889
|
+
for (let o = 0; o < r; o++) {
|
|
890
|
+
let a = o;
|
|
891
|
+
for (let h = 0; h < t; h++) {
|
|
892
|
+
const i = e[a], c = i >= 128 ? i - 256 : i;
|
|
893
|
+
s[o * t + h] = c / 127 * n, a += r;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
return s;
|
|
897
|
+
}
|
|
898
|
+
function hr(e, t, r, n) {
|
|
899
|
+
const s = new Float32Array(r * t), o = new Uint8Array(t);
|
|
900
|
+
for (let a = 0; a < r; a++) {
|
|
901
|
+
let h = a;
|
|
902
|
+
for (let i = 0; i < t; i++) {
|
|
903
|
+
const c = o[i] + e[h] & 255;
|
|
904
|
+
o[i] = c;
|
|
905
|
+
const f = c >= 128 ? c - 256 : c;
|
|
906
|
+
s[a * t + i] = f / 127 * n, h += r;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
return s;
|
|
910
|
+
}
|
|
911
|
+
function fr(e, t, r, n, s) {
|
|
912
|
+
const o = new Float32Array(r * t), a = (s - n) / 254;
|
|
913
|
+
for (let h = 0; h < r; h++) {
|
|
914
|
+
let i = h;
|
|
915
|
+
for (let c = 0; c < t; c++) {
|
|
916
|
+
const f = e[i];
|
|
917
|
+
o[h * t + c] = f === 0 ? 0 : Math.exp(n + (f - 1) * a), i += r;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
return o;
|
|
921
|
+
}
|
|
922
|
+
function lr(e, t, r) {
|
|
923
|
+
const n = new DataView(e.buffer, e.byteOffset, e.byteLength), s = new Float32Array(r * t);
|
|
924
|
+
for (let o = 0; o < r; o++) {
|
|
925
|
+
let a = o * 2;
|
|
926
|
+
for (let h = 0; h < t; h++)
|
|
927
|
+
s[o * t + h] = Math.exp(Se(n.getUint16(a, !0))), a += r * 2;
|
|
928
|
+
}
|
|
929
|
+
return s;
|
|
930
|
+
}
|
|
931
|
+
function dr(e, t) {
|
|
932
|
+
const r = new Float32Array(t * 4);
|
|
933
|
+
for (let n = 0; n < t; n++) {
|
|
934
|
+
const s = n * 3, o = e[s], a = e[s + 1], h = e[s + 2];
|
|
935
|
+
let i = o / 255 * 2 - 1, c = a / 255 * 2 - 1;
|
|
936
|
+
const f = 1 - Math.abs(i) - Math.abs(c), l = Math.max(-f, 0);
|
|
937
|
+
i = i >= 0 ? i - l : i + l, c = c >= 0 ? c - l : c + l;
|
|
938
|
+
const d = Math.hypot(i, c, f) || 1, u = h / 255 * 0.5 * Math.PI, y = Math.sin(u), m = Math.cos(u);
|
|
939
|
+
r[n * 4 + 0] = i / d * y, r[n * 4 + 1] = c / d * y, r[n * 4 + 2] = f / d * y, r[n * 4 + 3] = m;
|
|
940
|
+
}
|
|
941
|
+
return r;
|
|
942
|
+
}
|
|
943
|
+
function tt(e, t) {
|
|
944
|
+
const r = new DataView(e.buffer, e.byteOffset, e.byteLength), n = new Uint16Array(t);
|
|
945
|
+
for (let s = 0; s < t; s++) n[s] = r.getUint16(s * 2, !0);
|
|
946
|
+
return n;
|
|
947
|
+
}
|
|
948
|
+
function rt(e, t) {
|
|
949
|
+
const r = new DataView(e.buffer, e.byteOffset, e.byteLength), n = new Uint32Array(t);
|
|
950
|
+
for (let s = 0; s < t; s++) n[s] = r.getUint32(s * 4, !0);
|
|
951
|
+
return n;
|
|
952
|
+
}
|
|
953
|
+
const ur = 809779538, nt = 1128546642, ee = 1 << 24;
|
|
954
|
+
function ot(e, t) {
|
|
955
|
+
if (!Number.isSafeInteger(e) || e < 0)
|
|
956
|
+
throw new Error(\`Invalid RAD \${t} splat count: \${e}.\`);
|
|
957
|
+
}
|
|
958
|
+
function wr(e, t) {
|
|
959
|
+
if (ot(e, t), e > ee)
|
|
960
|
+
throw new Error(
|
|
961
|
+
\`RAD \${t} declares \${e} splats, above the supported maximum of \${ee}.\`
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
async function yr(e) {
|
|
965
|
+
var c;
|
|
966
|
+
const t = new Uint8Array(e);
|
|
967
|
+
if (t.byteLength < 8) throw new Error("Truncated RAD file.");
|
|
968
|
+
if (new DataView(t.buffer, t.byteOffset, t.byteLength).getUint32(0, !0) === nt)
|
|
969
|
+
return De([await be(t, 0)]);
|
|
970
|
+
const { meta: s, chunksStart: o } = mr(e);
|
|
971
|
+
if (s.count > ee)
|
|
972
|
+
throw new Error(
|
|
973
|
+
\`RAD header declares \${s.count} splats, above the supported maximum of \${ee} for a one-shot decode; load this file as a streamed scene instead.\`
|
|
974
|
+
);
|
|
975
|
+
const a = [];
|
|
976
|
+
let h, i;
|
|
977
|
+
for (const [f, l] of s.chunks.entries()) {
|
|
978
|
+
if (l.filename !== void 0)
|
|
979
|
+
throw new Error(
|
|
980
|
+
\`RAD chunk \${f} is an external .radc file ("\${l.filename}"); one-shot loading only supports a single self-contained .rad file.\`
|
|
981
|
+
);
|
|
982
|
+
const d = o + l.offset;
|
|
983
|
+
if (d + l.bytes > t.byteLength)
|
|
984
|
+
throw new Error(\`RAD chunk \${f} extends past the file.\`);
|
|
985
|
+
const u = await be(t, d, !0, h, i);
|
|
986
|
+
h ?? (h = u.shCodebook), i ?? (i = (c = u.shPacked) == null ? void 0 : c.range.max[0]), a.push(u);
|
|
987
|
+
}
|
|
988
|
+
return De(a);
|
|
989
|
+
}
|
|
990
|
+
function mr(e) {
|
|
991
|
+
const t = new Uint8Array(e);
|
|
992
|
+
if (t.byteLength < 8) throw new Error("Truncated RAD file.");
|
|
993
|
+
const r = new DataView(t.buffer, t.byteOffset, t.byteLength), n = r.getUint32(0, !0);
|
|
994
|
+
if (n !== ur)
|
|
995
|
+
throw new Error(\`Not a RAD file (magic 0x\${n.toString(16).padStart(8, "0")}).\`);
|
|
996
|
+
const s = r.getUint32(4, !0);
|
|
997
|
+
if (t.byteLength < 8 + s) throw new Error("Truncated RAD header.");
|
|
998
|
+
const o = JSON.parse(at(t, 8, s));
|
|
999
|
+
if (o.version !== 1) throw new Error(\`Unsupported RAD version \${o.version}.\`);
|
|
1000
|
+
if (o.type !== "gsplat") throw new Error(\`Unsupported RAD type "\${o.type}".\`);
|
|
1001
|
+
if (ot(o.count, "header"), !Array.isArray(o.chunks)) throw new Error("RAD header is missing its chunk list.");
|
|
1002
|
+
const a = o.chunks;
|
|
1003
|
+
for (const [h, i] of a.entries())
|
|
1004
|
+
if (!Number.isSafeInteger(i == null ? void 0 : i.offset) || i.offset < 0 || !Number.isSafeInteger(i == null ? void 0 : i.bytes) || i.bytes < 0)
|
|
1005
|
+
throw new Error(\`RAD chunk \${h} declares an invalid byte range.\`);
|
|
1006
|
+
if (o.chunkSize !== void 0) {
|
|
1007
|
+
if (!Number.isSafeInteger(o.chunkSize) || o.chunkSize <= 0 || o.chunkSize > ee)
|
|
1008
|
+
throw new Error(\`Invalid RAD chunk size: \${o.chunkSize}.\`);
|
|
1009
|
+
if (o.count > o.chunkSize * a.length)
|
|
1010
|
+
throw new Error(
|
|
1011
|
+
\`RAD header declares \${o.count} splats, more than its \${a.length} chunks of \${o.chunkSize} can hold.\`
|
|
1012
|
+
);
|
|
1013
|
+
}
|
|
1014
|
+
return { meta: o, chunksStart: 8 + st(s) };
|
|
1015
|
+
}
|
|
1016
|
+
async function pr(e, t, r, n = !0) {
|
|
1017
|
+
const s = await be(new Uint8Array(e), 0, !0, t, r);
|
|
1018
|
+
return br(s, n);
|
|
1019
|
+
}
|
|
1020
|
+
function br(e, t) {
|
|
1021
|
+
const { count: r } = e, n = new Float32Array(r * 3), s = new Uint8Array(r * 4), o = new Float32Array(r * 6);
|
|
1022
|
+
if (!e.childCount || !e.childStart) {
|
|
1023
|
+
for (let u = 0; u < r; u++) ge(e, u, u, n, s, o);
|
|
1024
|
+
return {
|
|
1025
|
+
count: r,
|
|
1026
|
+
positions: n,
|
|
1027
|
+
colors: s,
|
|
1028
|
+
covariances: o,
|
|
1029
|
+
...e.shPacked ? { shPacked: e.shPacked } : {},
|
|
1030
|
+
...e.shCodebook ? { radShCodebook: e.shCodebook } : {}
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
const a = e.childCount, h = e.childStart, i = t ? _r(a, h, r) : Er(r), c = Ar(e.shPacked, i), f = new Uint16Array(r), l = new Uint32Array(r), d = new Float32Array(r);
|
|
1034
|
+
for (let u = 0; u < r; u++) {
|
|
1035
|
+
const y = i[u];
|
|
1036
|
+
ge(e, y, u, n, s, o), f[u] = a[y], l[u] = h[y], d[u] = gr(e.alpha[y], e.scale, y);
|
|
1037
|
+
}
|
|
1038
|
+
return {
|
|
1039
|
+
count: r,
|
|
1040
|
+
positions: n,
|
|
1041
|
+
colors: s,
|
|
1042
|
+
covariances: o,
|
|
1043
|
+
radTree: { childCount: f, childStart: l, size: d },
|
|
1044
|
+
...c ? { shPacked: c } : {},
|
|
1045
|
+
...e.shCodebook ? { radShCodebook: e.shCodebook } : {}
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
function gr(e, t, r) {
|
|
1049
|
+
const n = (t[r * 3] + t[r * 3 + 1] + t[r * 3 + 2]) / 3;
|
|
1050
|
+
return 2 * (Math.max(e, 1) * 4 - 3) * n;
|
|
1051
|
+
}
|
|
1052
|
+
function Er(e) {
|
|
1053
|
+
const t = new Uint32Array(e);
|
|
1054
|
+
for (let r = 0; r < e; r++) t[r] = r;
|
|
1055
|
+
return t;
|
|
1056
|
+
}
|
|
1057
|
+
function _r(e, t, r) {
|
|
1058
|
+
const n = new Uint32Array(r);
|
|
1059
|
+
for (let o = 0; o < r; o++) n[o] = o;
|
|
1060
|
+
const s = (o) => e[o] === 0 ? Number.MAX_SAFE_INTEGER : t[o];
|
|
1061
|
+
return n.sort((o, a) => s(a) - s(o));
|
|
1062
|
+
}
|
|
1063
|
+
async function be(e, t, r, n, s) {
|
|
1064
|
+
const o = new DataView(e.buffer, e.byteOffset, e.byteLength), a = o.getUint32(t, !0);
|
|
1065
|
+
if (a !== nt)
|
|
1066
|
+
throw new Error(\`Not a RAD chunk (magic 0x\${a.toString(16).padStart(8, "0")}).\`);
|
|
1067
|
+
const h = o.getUint32(t + 4, !0), i = t + 8 + st(h), c = JSON.parse(at(e, t + 8, h));
|
|
1068
|
+
if (c.version !== 1)
|
|
1069
|
+
throw new Error(\`Unsupported RAD chunk version \${c.version}.\`);
|
|
1070
|
+
const f = Number(o.getBigUint64(i, !0)), l = i + 8;
|
|
1071
|
+
if (l + f > e.byteLength)
|
|
1072
|
+
throw new Error("RAD chunk payload extends past the file.");
|
|
1073
|
+
const { count: d } = c;
|
|
1074
|
+
wr(d, "chunk");
|
|
1075
|
+
const u = c.lodTree ?? !1;
|
|
1076
|
+
if (!Array.isArray(c.properties))
|
|
1077
|
+
throw new Error("RAD chunk metadata is missing its property list.");
|
|
1078
|
+
const y = c.properties, m = new Map(y.map((k) => [k.property, k])), b = async (k) => {
|
|
1079
|
+
const x = m.get(k);
|
|
1080
|
+
if (!x) return;
|
|
1081
|
+
if (!Number.isSafeInteger(x.offset) || x.offset < 0 || !Number.isSafeInteger(x.bytes) || x.bytes < 0)
|
|
1082
|
+
throw new Error(\`RAD property "\${k}" declares an invalid byte range.\`);
|
|
1083
|
+
const Z = l + x.offset;
|
|
1084
|
+
if (x.offset + x.bytes > f || Z + x.bytes > e.byteLength)
|
|
1085
|
+
throw new Error(\`RAD property "\${k}" extends past its chunk.\`);
|
|
1086
|
+
const re = e.subarray(Z, Z + x.bytes);
|
|
1087
|
+
return x.compression === void 0 ? re : Lr(re);
|
|
1088
|
+
}, _ = u, w = [
|
|
1089
|
+
"center",
|
|
1090
|
+
"alpha",
|
|
1091
|
+
"rgb",
|
|
1092
|
+
"scales",
|
|
1093
|
+
"orientation",
|
|
1094
|
+
..._ ? ["child_count", "child_start"] : [void 0, void 0],
|
|
1095
|
+
"sh1",
|
|
1096
|
+
"sh2",
|
|
1097
|
+
"sh3",
|
|
1098
|
+
"sh_label",
|
|
1099
|
+
"sh1_code",
|
|
1100
|
+
"sh2_code",
|
|
1101
|
+
"sh3_code"
|
|
1102
|
+
], [
|
|
1103
|
+
p,
|
|
1104
|
+
A,
|
|
1105
|
+
g,
|
|
1106
|
+
E,
|
|
1107
|
+
v,
|
|
1108
|
+
U,
|
|
1109
|
+
T,
|
|
1110
|
+
F,
|
|
1111
|
+
N,
|
|
1112
|
+
V,
|
|
1113
|
+
S,
|
|
1114
|
+
X,
|
|
1115
|
+
B,
|
|
1116
|
+
j
|
|
1117
|
+
] = await Promise.all(
|
|
1118
|
+
w.map((k) => k === void 0 ? Promise.resolve(void 0) : b(k))
|
|
1119
|
+
);
|
|
1120
|
+
if (!p) throw new Error('RAD chunk is missing its "center" property.');
|
|
1121
|
+
if (!A) throw new Error('RAD chunk is missing its "alpha" property.');
|
|
1122
|
+
if (!g) throw new Error('RAD chunk is missing its "rgb" property.');
|
|
1123
|
+
if (!E) throw new Error('RAD chunk is missing its "scales" property.');
|
|
1124
|
+
if (!v) throw new Error('RAD chunk is missing its "orientation" property.');
|
|
1125
|
+
return {
|
|
1126
|
+
count: d,
|
|
1127
|
+
lodTree: u,
|
|
1128
|
+
center: Q(p, m.get("center"), 3, d),
|
|
1129
|
+
alpha: Q(A, m.get("alpha"), 1, d),
|
|
1130
|
+
rgb: Q(g, m.get("rgb"), 3, d),
|
|
1131
|
+
scale: Q(E, m.get("scales"), 3, d),
|
|
1132
|
+
quat: er(v, m.get("orientation"), d),
|
|
1133
|
+
..._ && U ? { childCount: tr(U, m.get("child_count"), d) } : {},
|
|
1134
|
+
..._ && T ? { childStart: rr(T, m.get("child_start"), d) } : {},
|
|
1135
|
+
...Rr({
|
|
1136
|
+
count: d,
|
|
1137
|
+
byName: m,
|
|
1138
|
+
sh1Raw: F,
|
|
1139
|
+
sh2Raw: N,
|
|
1140
|
+
sh3Raw: V,
|
|
1141
|
+
shLabelRaw: S,
|
|
1142
|
+
sh1CodeRaw: X,
|
|
1143
|
+
sh2CodeRaw: B,
|
|
1144
|
+
sh3CodeRaw: j,
|
|
1145
|
+
knownShCodebook: n,
|
|
1146
|
+
knownShExtent: s
|
|
1147
|
+
})
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
function De(e) {
|
|
1151
|
+
var i;
|
|
1152
|
+
let t = 0;
|
|
1153
|
+
for (const c of e)
|
|
1154
|
+
t += c.childCount ? kr(c.childCount) : c.count;
|
|
1155
|
+
if (t === 0) throw new Error("RAD file has no leaf splats.");
|
|
1156
|
+
const r = new Float32Array(t * 3), n = new Uint8Array(t * 4), s = new Float32Array(t * 6), o = (i = e.find((c) => c.shPacked)) == null ? void 0 : i.shPacked, a = o ? new Uint32Array(t * P(o.bands)) : void 0;
|
|
1157
|
+
a && o && a.fill(At(o.range));
|
|
1158
|
+
let h = 0;
|
|
1159
|
+
for (const c of e)
|
|
1160
|
+
for (let f = 0; f < c.count; f++)
|
|
1161
|
+
if (!(c.childCount && c.childCount[f] !== 0)) {
|
|
1162
|
+
if (ge(c, f, h, r, n, s), a && c.shPacked) {
|
|
1163
|
+
const l = P(o.bands);
|
|
1164
|
+
a.set(c.shPacked.packed.subarray(f * l, (f + 1) * l), h * l);
|
|
1165
|
+
}
|
|
1166
|
+
h++;
|
|
1167
|
+
}
|
|
1168
|
+
return {
|
|
1169
|
+
count: t,
|
|
1170
|
+
positions: r,
|
|
1171
|
+
colors: n,
|
|
1172
|
+
covariances: s,
|
|
1173
|
+
...o && a ? { shPacked: { ...o, packed: a } } : {}
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
function Ar(e, t) {
|
|
1177
|
+
if (!e) return;
|
|
1178
|
+
const r = P(e.bands), n = new Uint32Array(e.packed.length);
|
|
1179
|
+
for (let s = 0; s < t.length; s++) {
|
|
1180
|
+
const o = t[s];
|
|
1181
|
+
n.set(e.packed.subarray(o * r, (o + 1) * r), s * r);
|
|
1182
|
+
}
|
|
1183
|
+
return { ...e, packed: n };
|
|
1184
|
+
}
|
|
1185
|
+
function Rr(e) {
|
|
1186
|
+
const t = [e.sh1Raw, e.sh2Raw, e.sh3Raw], r = [e.sh1CodeRaw, e.sh2CodeRaw, e.sh3CodeRaw], n = t.reduce((c, f, l) => f ? l + 1 : c, 0), s = r.reduce((c, f, l) => f ? l + 1 : c, 0);
|
|
1187
|
+
if (n === 0 && s === 0 && !e.shLabelRaw) return {};
|
|
1188
|
+
if (n > 0 && s > 0)
|
|
1189
|
+
throw new Error("RAD chunk mixes direct and codebook SH columns.");
|
|
1190
|
+
let o, a, h, i;
|
|
1191
|
+
if (n > 0)
|
|
1192
|
+
a = n, o = Fe(t, e.byName, e.count, a), i = Sr(e.byName, a) ?? e.knownShExtent;
|
|
1193
|
+
else {
|
|
1194
|
+
if (h = e.knownShCodebook, !h && s > 0) {
|
|
1195
|
+
a = s;
|
|
1196
|
+
const l = xr(
|
|
1197
|
+
r[s - 1],
|
|
1198
|
+
e.byName.get(\`sh\${s}_code\`)
|
|
1199
|
+
);
|
|
1200
|
+
h = {
|
|
1201
|
+
bands: a,
|
|
1202
|
+
count: l,
|
|
1203
|
+
coefficients: Fe(r, e.byName, l, a, "_code")
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
if (!h) throw new Error("RAD SH labels require the codebook stored in chunk zero.");
|
|
1207
|
+
if (!e.shLabelRaw)
|
|
1208
|
+
throw new Error('RAD SH codebook chunk is missing its "sh_label" property.');
|
|
1209
|
+
a = h.bands;
|
|
1210
|
+
const c = vr(e.shLabelRaw, e.byName.get("sh_label"), e.count);
|
|
1211
|
+
o = new Float32Array(e.count * P(a) * 3);
|
|
1212
|
+
const f = P(a) * 3;
|
|
1213
|
+
for (let l = 0; l < e.count; l++) {
|
|
1214
|
+
const d = c[l];
|
|
1215
|
+
if (d >= h.count)
|
|
1216
|
+
throw new Error(\`RAD SH label \${d} exceeds its \${h.count}-entry codebook.\`);
|
|
1217
|
+
o.set(
|
|
1218
|
+
h.coefficients.subarray(d * f, (d + 1) * f),
|
|
1219
|
+
l * f
|
|
1220
|
+
);
|
|
1221
|
+
}
|
|
1222
|
+
i = 0;
|
|
1223
|
+
for (const l of h.coefficients) i = Math.max(i, Math.abs(l));
|
|
1224
|
+
}
|
|
1225
|
+
return {
|
|
1226
|
+
shPacked: Ae(o, e.count, a, i),
|
|
1227
|
+
...h ? { shCodebook: h } : {}
|
|
1228
|
+
};
|
|
1229
|
+
}
|
|
1230
|
+
function Sr(e, t, r = "") {
|
|
1231
|
+
let n = 0;
|
|
1232
|
+
for (let s = 1; s <= t; s++) {
|
|
1233
|
+
const o = e.get(\`sh\${s}\${r}\`);
|
|
1234
|
+
if (!o) return;
|
|
1235
|
+
let a;
|
|
1236
|
+
switch (o.encoding) {
|
|
1237
|
+
case "s8":
|
|
1238
|
+
case "s8_delta":
|
|
1239
|
+
if (o.max === void 0) return;
|
|
1240
|
+
a = Math.abs(o.max);
|
|
1241
|
+
break;
|
|
1242
|
+
case "r8":
|
|
1243
|
+
case "r8_delta":
|
|
1244
|
+
if (o.min === void 0 || o.max === void 0) return;
|
|
1245
|
+
a = Math.max(Math.abs(o.min), Math.abs(o.max));
|
|
1246
|
+
break;
|
|
1247
|
+
default:
|
|
1248
|
+
return;
|
|
1249
|
+
}
|
|
1250
|
+
n = Math.max(n, a);
|
|
1251
|
+
}
|
|
1252
|
+
return n;
|
|
1253
|
+
}
|
|
1254
|
+
function Fe(e, t, r, n, s = "") {
|
|
1255
|
+
const o = P(n), a = new Float32Array(r * o * 3);
|
|
1256
|
+
let h = 0;
|
|
1257
|
+
for (let i = 1; i <= n; i++) {
|
|
1258
|
+
const c = e[i - 1], f = t.get(\`sh\${i}\${s}\`);
|
|
1259
|
+
if (!c || !f) throw new Error(\`RAD SH is missing its "sh\${i}\${s}" column.\`);
|
|
1260
|
+
const l = i === 1 ? 9 : i === 2 ? 15 : 21, d = Q(c, f, l, r);
|
|
1261
|
+
for (let u = 0; u < r; u++) {
|
|
1262
|
+
const y = (u * o + h) * 3;
|
|
1263
|
+
for (let m = 0; m < l; m++) a[y + m] = d[u * l + m];
|
|
1264
|
+
}
|
|
1265
|
+
h += l / 3;
|
|
1266
|
+
}
|
|
1267
|
+
return a;
|
|
1268
|
+
}
|
|
1269
|
+
function xr(e, t) {
|
|
1270
|
+
const r = t.property.startsWith("sh1") ? 9 : t.property.startsWith("sh2") ? 15 : 21, n = Cr(t);
|
|
1271
|
+
if (e.byteLength % (r * n) !== 0)
|
|
1272
|
+
throw new Error(\`RAD "\${t.property}" has an invalid SH column length.\`);
|
|
1273
|
+
return e.byteLength / (r * n);
|
|
1274
|
+
}
|
|
1275
|
+
function Cr(e) {
|
|
1276
|
+
switch (e.encoding) {
|
|
1277
|
+
case "f32":
|
|
1278
|
+
case "f32_lebytes":
|
|
1279
|
+
return 4;
|
|
1280
|
+
case "f16":
|
|
1281
|
+
case "f16_lebytes":
|
|
1282
|
+
case "ln_f16":
|
|
1283
|
+
return 2;
|
|
1284
|
+
case "r8":
|
|
1285
|
+
case "r8_delta":
|
|
1286
|
+
case "s8":
|
|
1287
|
+
case "s8_delta":
|
|
1288
|
+
case "ln_0r8":
|
|
1289
|
+
return 1;
|
|
1290
|
+
default:
|
|
1291
|
+
throw new Error(\`Unsupported RAD "\${e.property}" encoding "\${e.encoding}".\`);
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
function vr(e, t, r) {
|
|
1295
|
+
if (t.encoding === "u16")
|
|
1296
|
+
return I(e, t, 1, r, 2), Uint32Array.from(tt(e, r));
|
|
1297
|
+
if (t.encoding === "u32")
|
|
1298
|
+
return I(e, t, 1, r, 4), rt(e, r);
|
|
1299
|
+
throw new Error(\`Unsupported RAD sh_label encoding "\${t.encoding}".\`);
|
|
1300
|
+
}
|
|
1301
|
+
function ge(e, t, r, n, s, o) {
|
|
1302
|
+
const a = e.alpha[t];
|
|
1303
|
+
n[r * 3 + 0] = e.center[t * 3 + 0], n[r * 3 + 1] = e.center[t * 3 + 1], n[r * 3 + 2] = e.center[t * 3 + 2], s[r * 4 + 0] = he(e.rgb[t * 3 + 0] * 255), s[r * 4 + 1] = he(e.rgb[t * 3 + 1] * 255), s[r * 4 + 2] = he(e.rgb[t * 3 + 2] * 255), s[r * 4 + 3] = he(a * 0.5 * 255), te(
|
|
1304
|
+
o,
|
|
1305
|
+
r,
|
|
1306
|
+
e.scale[t * 3 + 0],
|
|
1307
|
+
e.scale[t * 3 + 1],
|
|
1308
|
+
e.scale[t * 3 + 2],
|
|
1309
|
+
e.quat[t * 4 + 3],
|
|
1310
|
+
// w
|
|
1311
|
+
e.quat[t * 4 + 0],
|
|
1312
|
+
// x
|
|
1313
|
+
e.quat[t * 4 + 1],
|
|
1314
|
+
// y
|
|
1315
|
+
e.quat[t * 4 + 2]
|
|
1316
|
+
// z
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
function kr(e) {
|
|
1320
|
+
let t = 0;
|
|
1321
|
+
for (const r of e) r === 0 && t++;
|
|
1322
|
+
return t;
|
|
1323
|
+
}
|
|
1324
|
+
function he(e) {
|
|
1325
|
+
return Math.max(0, Math.min(255, Math.round(e)));
|
|
1326
|
+
}
|
|
1327
|
+
function st(e) {
|
|
1328
|
+
return e + 7 & -8;
|
|
1329
|
+
}
|
|
1330
|
+
function at(e, t, r) {
|
|
1331
|
+
return new TextDecoder().decode(e.subarray(t, t + r));
|
|
1332
|
+
}
|
|
1333
|
+
async function Lr(e) {
|
|
1334
|
+
if (typeof DecompressionStream > "u")
|
|
1335
|
+
throw new Error("This runtime does not provide decompression required for RAD files.");
|
|
1336
|
+
const t = e[0] === 31 && e[1] === 139 ? "gzip" : e[0] === 120 ? "deflate" : "deflate-raw", r = new Uint8Array(e.byteLength);
|
|
1337
|
+
r.set(e);
|
|
1338
|
+
const n = new Blob([r.buffer]).stream().pipeThrough(new DecompressionStream(t));
|
|
1339
|
+
return new Uint8Array(await new Response(n).arrayBuffer());
|
|
1340
|
+
}
|
|
1341
|
+
const fe = 32, Ee = 64, Ne = 1 << 24;
|
|
1342
|
+
function $r(e) {
|
|
1343
|
+
return e === 1 ? 3 : e === 2 ? 8 : 15;
|
|
1344
|
+
}
|
|
1345
|
+
function Ur(e) {
|
|
1346
|
+
const t = e >>> 30 & 3, r = [0, 0, 0, 0];
|
|
1347
|
+
let n = 0;
|
|
1348
|
+
for (let o = 0; o < 4; o++) {
|
|
1349
|
+
if (o === t) continue;
|
|
1350
|
+
const a = e >>> 10 * n & 1023;
|
|
1351
|
+
r[o] = (a - 511) * Mr, n++;
|
|
1352
|
+
}
|
|
1353
|
+
const s = r[0] ** 2 + r[1] ** 2 + r[2] ** 2 + r[3] ** 2;
|
|
1354
|
+
return r[t] = Math.sqrt(Math.max(0, 1 - s)), [r[3], r[0], r[1], r[2]];
|
|
1355
|
+
}
|
|
1356
|
+
const Mr = 1 / (511 * Math.SQRT2);
|
|
1357
|
+
async function Pr(e, t, r, n) {
|
|
1358
|
+
var A;
|
|
1359
|
+
const s = t.stride;
|
|
1360
|
+
if (s !== fe && s !== fe + Ee)
|
|
1361
|
+
throw new Error(\`LCC chunk declares an unsupported \${s}-byte record.\`);
|
|
1362
|
+
if (((A = t.sh) == null ? void 0 : A.source) === "inline" && s === fe)
|
|
1363
|
+
throw new Error("LCC chunk asks for inline SH but its records have no room for it.");
|
|
1364
|
+
if (e.byteLength % s !== 0)
|
|
1365
|
+
throw new Error(
|
|
1366
|
+
\`LCC chunk is \${e.byteLength} bytes, not a multiple of the \${s}-byte record.\`
|
|
1367
|
+
);
|
|
1368
|
+
const o = e.byteLength / s;
|
|
1369
|
+
if (o > Ne)
|
|
1370
|
+
throw new Error(
|
|
1371
|
+
\`LCC chunk holds \${o} splats, above the supported maximum of \${Ne}.\`
|
|
1372
|
+
);
|
|
1373
|
+
const a = new DataView(e), h = new Float32Array(o * 3), i = new Uint8Array(o * 4), c = new Float32Array(o * 6), f = new Uint8Array(e), { min: l, max: d } = t.scale, u = l[0], y = l[1], m = l[2], b = d[0] - l[0], _ = d[1] - l[1], w = d[2] - l[2];
|
|
1374
|
+
for (let g = 0; g < o; g++) {
|
|
1375
|
+
n && (g & 65535) === 0 && g > 0 && (await new Promise((N) => setTimeout(N, 0)), n.throwIfAborted());
|
|
1376
|
+
const E = g * s;
|
|
1377
|
+
h[g * 3 + 0] = a.getFloat32(E, !0), h[g * 3 + 1] = a.getFloat32(E + 4, !0), h[g * 3 + 2] = a.getFloat32(E + 8, !0), i[g * 4 + 0] = f[E + 12], i[g * 4 + 1] = f[E + 13], i[g * 4 + 2] = f[E + 14], i[g * 4 + 3] = f[E + 15];
|
|
1378
|
+
const [v, U, T, F] = Ur(a.getUint32(E + 22, !0));
|
|
1379
|
+
te(
|
|
1380
|
+
c,
|
|
1381
|
+
g,
|
|
1382
|
+
u + b * (a.getUint16(E + 16, !0) / 65535),
|
|
1383
|
+
y + _ * (a.getUint16(E + 18, !0) / 65535),
|
|
1384
|
+
m + w * (a.getUint16(E + 20, !0) / 65535),
|
|
1385
|
+
v,
|
|
1386
|
+
U,
|
|
1387
|
+
T,
|
|
1388
|
+
F
|
|
1389
|
+
);
|
|
1390
|
+
}
|
|
1391
|
+
n == null || n.throwIfAborted();
|
|
1392
|
+
const p = t.sh ? Tr(e, r, t.sh, o, s) : void 0;
|
|
1393
|
+
return {
|
|
1394
|
+
count: o,
|
|
1395
|
+
positions: h,
|
|
1396
|
+
colors: i,
|
|
1397
|
+
covariances: c,
|
|
1398
|
+
...p ? { shPacked: p } : {}
|
|
1399
|
+
};
|
|
1400
|
+
}
|
|
1401
|
+
function Tr(e, t, r, n, s) {
|
|
1402
|
+
const o = $r(r.bands), a = new Uint32Array(n * o);
|
|
1403
|
+
if (r.source === "inline") {
|
|
1404
|
+
const c = new DataView(e);
|
|
1405
|
+
for (let f = 0; f < n; f++) {
|
|
1406
|
+
const l = f * s + fe;
|
|
1407
|
+
for (let d = 0; d < o; d++)
|
|
1408
|
+
a[f * o + d] = c.getUint32(l + d * 4, !0);
|
|
1409
|
+
}
|
|
1410
|
+
return Oe(a, r);
|
|
1411
|
+
}
|
|
1412
|
+
if (!t) throw new Error("LCC chunk expected shcoef.bin bytes but none were fetched.");
|
|
1413
|
+
const h = n * Ee;
|
|
1414
|
+
if (t.byteLength !== h)
|
|
1415
|
+
throw new Error(
|
|
1416
|
+
\`LCC shcoef.bin range is \${t.byteLength} bytes; expected \${h} for \${n} splats.\`
|
|
1417
|
+
);
|
|
1418
|
+
const i = new DataView(t);
|
|
1419
|
+
for (let c = 0; c < n; c++) {
|
|
1420
|
+
const f = c * Ee;
|
|
1421
|
+
for (let l = 0; l < o; l++)
|
|
1422
|
+
a[c * o + l] = i.getUint32(f + l * 4, !0);
|
|
1423
|
+
}
|
|
1424
|
+
return Oe(a, r);
|
|
1425
|
+
}
|
|
1426
|
+
function Oe(e, t) {
|
|
1427
|
+
const r = t.requantizeTo;
|
|
1428
|
+
if (!r || Rt(t.range, r))
|
|
1429
|
+
return { bands: t.bands, packed: e, range: t.range };
|
|
1430
|
+
for (let n = 0; n < e.length; n++)
|
|
1431
|
+
e[n] = xt(e[n], t.range, r);
|
|
1432
|
+
return { bands: t.bands, packed: e, range: r };
|
|
1433
|
+
}
|
|
1434
|
+
function it(e) {
|
|
1435
|
+
const t = e.indexOf("#");
|
|
1436
|
+
return t < 0 ? e : e.slice(0, t);
|
|
1437
|
+
}
|
|
1438
|
+
async function _e(e, t, r, n, s) {
|
|
1439
|
+
const o = Re(n, s);
|
|
1440
|
+
let a;
|
|
1441
|
+
try {
|
|
1442
|
+
a = await fetch(e, {
|
|
1443
|
+
...o,
|
|
1444
|
+
headers: { ...(n == null ? void 0 : n.headers) ?? {}, Range: \`bytes=\${t}-\${t + r - 1}\` }
|
|
1445
|
+
});
|
|
1446
|
+
} catch (i) {
|
|
1447
|
+
throw $(i) ? i : R(i, { phase: "fetch", url: e });
|
|
1448
|
+
}
|
|
1449
|
+
if (!a.ok)
|
|
1450
|
+
throw R(new Error(\`Failed to load \${e}: HTTP \${a.status}\`), {
|
|
1451
|
+
phase: "fetch",
|
|
1452
|
+
url: e,
|
|
1453
|
+
status: a.status
|
|
1454
|
+
});
|
|
1455
|
+
if (a.status !== 206)
|
|
1456
|
+
throw R(
|
|
1457
|
+
new Error(
|
|
1458
|
+
\`\${e} ignored a Range request (HTTP \${a.status}); LCC streaming needs a server that answers 206 Partial Content.\`
|
|
1459
|
+
),
|
|
1460
|
+
{ phase: "fetch", url: e, status: a.status }
|
|
1461
|
+
);
|
|
1462
|
+
let h;
|
|
1463
|
+
try {
|
|
1464
|
+
h = await a.arrayBuffer();
|
|
1465
|
+
} catch (i) {
|
|
1466
|
+
throw $(i) ? i : R(i, { phase: "fetch", url: e });
|
|
1467
|
+
}
|
|
1468
|
+
if (h.byteLength !== r)
|
|
1469
|
+
throw R(
|
|
1470
|
+
new Error(\`\${e} returned \${h.byteLength} bytes for a \${r}-byte range.\`),
|
|
1471
|
+
{ phase: "fetch", url: e }
|
|
1472
|
+
);
|
|
1473
|
+
return h;
|
|
1474
|
+
}
|
|
1475
|
+
async function ct(e, t, r, n) {
|
|
1476
|
+
let s;
|
|
1477
|
+
try {
|
|
1478
|
+
s = await fetch(e, Re(t, r));
|
|
1479
|
+
} catch (o) {
|
|
1480
|
+
throw $(o) ? o : R(o, { phase: "fetch", url: e });
|
|
1481
|
+
}
|
|
1482
|
+
if (!s.ok)
|
|
1483
|
+
throw R(new Error(\`Failed to load \${e}: HTTP \${s.status}\`), {
|
|
1484
|
+
phase: "fetch",
|
|
1485
|
+
url: e,
|
|
1486
|
+
status: s.status
|
|
1487
|
+
});
|
|
1488
|
+
try {
|
|
1489
|
+
return !n || !s.body ? await s.arrayBuffer() : await Dr(s, n);
|
|
1490
|
+
} catch (o) {
|
|
1491
|
+
throw $(o) ? o : R(o, { phase: "fetch", url: e });
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
async function Dr(e, t) {
|
|
1495
|
+
const r = Number(e.headers.get("Content-Length")), n = Number.isSafeInteger(r) && r > 0 ? r : 0, s = e.body.getReader(), o = [], a = n > 0 ? new Uint8Array(n) : null;
|
|
1496
|
+
let h = 0;
|
|
1497
|
+
for (t(0, n); ; ) {
|
|
1498
|
+
const { done: f, value: l } = await s.read();
|
|
1499
|
+
if (f) break;
|
|
1500
|
+
if (a) {
|
|
1501
|
+
if (h + l.byteLength > n)
|
|
1502
|
+
throw new Error(\`Response body is longer than its Content-Length of \${n} bytes.\`);
|
|
1503
|
+
a.set(l, h);
|
|
1504
|
+
} else
|
|
1505
|
+
o.push(l);
|
|
1506
|
+
h += l.byteLength, t(h, n);
|
|
1507
|
+
}
|
|
1508
|
+
if (a) {
|
|
1509
|
+
if (h !== n)
|
|
1510
|
+
throw new Error(\`Response body ended at \${h} bytes, short of its \${n}-byte length.\`);
|
|
1511
|
+
return a.buffer;
|
|
1512
|
+
}
|
|
1513
|
+
const i = new Uint8Array(h);
|
|
1514
|
+
let c = 0;
|
|
1515
|
+
for (const f of o)
|
|
1516
|
+
i.set(f, c), c += f.byteLength;
|
|
1517
|
+
return i.buffer;
|
|
1518
|
+
}
|
|
1519
|
+
function Fr(e) {
|
|
1520
|
+
const t = /* @__PURE__ */ new Map();
|
|
1521
|
+
self.onmessage = async (r) => {
|
|
1522
|
+
var i;
|
|
1523
|
+
const n = self, s = r.data;
|
|
1524
|
+
if (s.type === "cancel") {
|
|
1525
|
+
(i = t.get(s.id)) == null || i.abort();
|
|
1526
|
+
return;
|
|
1527
|
+
}
|
|
1528
|
+
const o = new AbortController();
|
|
1529
|
+
t.set(s.id, o);
|
|
1530
|
+
const a = s.source.from === "url" ? s.source.url : s.source.file.name, h = s.progress ? Ut((c, f) => {
|
|
1531
|
+
const l = { type: "progress", id: s.id, loaded: c, total: f };
|
|
1532
|
+
n.postMessage(l);
|
|
1533
|
+
}) : void 0;
|
|
1534
|
+
try {
|
|
1535
|
+
const c = await e(s, o.signal, h), f = [c.positions.buffer, c.colors.buffer, c.covariances.buffer];
|
|
1536
|
+
c.sh && f.push(c.sh.labels.buffer, c.sh.palette.buffer), c.shPacked && f.push(c.shPacked.packed.buffer), c.radTree && f.push(
|
|
1537
|
+
c.radTree.childCount.buffer,
|
|
1538
|
+
c.radTree.childStart.buffer,
|
|
1539
|
+
c.radTree.size.buffer
|
|
1540
|
+
);
|
|
1541
|
+
const l = { type: "result", id: s.id, ok: !0, data: c };
|
|
1542
|
+
n.postMessage(l, f);
|
|
1543
|
+
} catch (c) {
|
|
1544
|
+
const f = {
|
|
1545
|
+
type: "result",
|
|
1546
|
+
id: s.id,
|
|
1547
|
+
ok: !1,
|
|
1548
|
+
error: Tt(R(c, { phase: "worker", url: a })),
|
|
1549
|
+
cancelled: o.signal.aborted || $(c)
|
|
1550
|
+
};
|
|
1551
|
+
n.postMessage(f);
|
|
1552
|
+
} finally {
|
|
1553
|
+
t.delete(s.id);
|
|
1554
|
+
}
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
Fr(
|
|
1558
|
+
(e, t, r) => Nr(
|
|
1559
|
+
e.source,
|
|
1560
|
+
e.format,
|
|
1561
|
+
t,
|
|
1562
|
+
e.lcc,
|
|
1563
|
+
e.rad,
|
|
1564
|
+
e.files,
|
|
1565
|
+
e.sog,
|
|
1566
|
+
r
|
|
1567
|
+
)
|
|
1568
|
+
);
|
|
1569
|
+
async function Nr(e, t, r, n, s, o, a, h) {
|
|
1570
|
+
if (e.from === "url" && e.kind === "directory") {
|
|
1571
|
+
const f = await Ht(e.url, {
|
|
1572
|
+
signal: r,
|
|
1573
|
+
...e.request ? { request: e.request } : {},
|
|
1574
|
+
...o ? { files: o } : {}
|
|
1575
|
+
});
|
|
1576
|
+
return a ? Ie(f, a.packShBands) : f;
|
|
1577
|
+
}
|
|
1578
|
+
if (t === "lcc-bin") {
|
|
1579
|
+
if (e.from !== "url") throw new Error("LCC chunks must be loaded from a URL.");
|
|
1580
|
+
if (!n) throw new Error("LCC chunk request is missing its byte range.");
|
|
1581
|
+
return Or(e, n, r);
|
|
1582
|
+
}
|
|
1583
|
+
if (t === "rad-chunk") {
|
|
1584
|
+
if (e.from !== "url") throw new Error("RAD chunks must be loaded from a URL.");
|
|
1585
|
+
if (!s) throw new Error("RAD chunk request is missing its byte range.");
|
|
1586
|
+
return Ir(e, s, r);
|
|
1587
|
+
}
|
|
1588
|
+
const i = e.from === "url" ? e.url : e.file.name;
|
|
1589
|
+
if (e.from === "file" && t === "ply")
|
|
1590
|
+
try {
|
|
1591
|
+
return await Yt(e.file, {
|
|
1592
|
+
signal: r,
|
|
1593
|
+
...h ? { onProgress: h } : {}
|
|
1594
|
+
});
|
|
1595
|
+
} catch (f) {
|
|
1596
|
+
throw $(f) ? f : R(f, { phase: "decode", url: i });
|
|
1597
|
+
}
|
|
1598
|
+
const c = e.from === "url" ? await ct(e.url, e.request, r, h) : await Ge(e.file);
|
|
1599
|
+
try {
|
|
1600
|
+
switch (t) {
|
|
1601
|
+
case "ply":
|
|
1602
|
+
return Bt(c);
|
|
1603
|
+
case "sog": {
|
|
1604
|
+
const f = await Gt(c, { signal: r });
|
|
1605
|
+
return a ? Ie(f, a.packShBands) : f;
|
|
1606
|
+
}
|
|
1607
|
+
case "rad":
|
|
1608
|
+
return yr(c);
|
|
1609
|
+
// \`ChunkLoader\` routes spz/splat/ksplat to the one-shot worker; reaching
|
|
1610
|
+
// this worker with one of them means the routing table lost an entry.
|
|
1611
|
+
default:
|
|
1612
|
+
throw new Error(\`The streaming worker does not decode \${t}.\`);
|
|
1613
|
+
}
|
|
1614
|
+
} catch (f) {
|
|
1615
|
+
throw $(f) ? f : R(f, { phase: "decode", url: i });
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
function Ie(e, t) {
|
|
1619
|
+
if (!e.sh) return e;
|
|
1620
|
+
const r = _t(e.sh, e.count, t), { sh: n, ...s } = e;
|
|
1621
|
+
return { ...s, shPacked: r };
|
|
1622
|
+
}
|
|
1623
|
+
async function Or(e, t, r) {
|
|
1624
|
+
var h;
|
|
1625
|
+
const n = it(e.url), s = ((h = t.sh) == null ? void 0 : h.source) === "sidecar" ? t.sh : void 0, [o, a] = await Promise.all([
|
|
1626
|
+
_e(n, t.start, t.length, e.request, r),
|
|
1627
|
+
(s == null ? void 0 : s.url) === void 0 ? Promise.resolve(void 0) : (
|
|
1628
|
+
// shcoef.bin holds 64 bytes per splat against data.bin's 32, aligned
|
|
1629
|
+
// 2:1, so this chunk's SH is exactly its doubled byte range.
|
|
1630
|
+
_e(s.url, t.start * 2, t.length * 2, e.request, r)
|
|
1631
|
+
)
|
|
1632
|
+
]);
|
|
1633
|
+
try {
|
|
1634
|
+
return await Pr(o, t, a, r);
|
|
1635
|
+
} catch (i) {
|
|
1636
|
+
throw $(i) ? i : R(i, { phase: "decode", url: n });
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
async function Ir(e, t, r) {
|
|
1640
|
+
const n = it(e.url), s = t.start !== void 0 && t.length !== void 0 ? await _e(n, t.start, t.length, e.request, r) : await ct(n, e.request, r);
|
|
1641
|
+
try {
|
|
1642
|
+
return await pr(s, t.shCodebook, t.shExtent, t.reorder ?? !0);
|
|
1643
|
+
} catch (o) {
|
|
1644
|
+
throw $(o) ? o : R(o, { phase: "decode", url: n });
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
//# sourceMappingURL=load-worker-CQhCbUGy.js.map
|
|
1648
|
+
`, d = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", y], { type: "text/javascript;charset=utf-8" });
|
|
1649
|
+
function U(o) {
|
|
1650
|
+
let t;
|
|
1651
|
+
try {
|
|
1652
|
+
if (t = d && (self.URL || self.webkitURL).createObjectURL(d), !t) throw "";
|
|
1653
|
+
const n = new Worker(t, {
|
|
1654
|
+
type: "module",
|
|
1655
|
+
name: o == null ? void 0 : o.name
|
|
1656
|
+
});
|
|
1657
|
+
return n.addEventListener("error", () => {
|
|
1658
|
+
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
1659
|
+
}), n;
|
|
1660
|
+
} catch {
|
|
1661
|
+
return new Worker(
|
|
1662
|
+
"data:text/javascript;charset=utf-8," + encodeURIComponent(y),
|
|
1663
|
+
{
|
|
1664
|
+
type: "module",
|
|
1665
|
+
name: o == null ? void 0 : o.name
|
|
1666
|
+
}
|
|
1667
|
+
);
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
const $ = /* @__PURE__ */ new Set(["spz", "splat", "ksplat"]);
|
|
1671
|
+
class w {
|
|
1672
|
+
constructor(t) {
|
|
1673
|
+
a(this, "nextRequestId", 0);
|
|
1674
|
+
a(this, "pending", /* @__PURE__ */ new Map());
|
|
1675
|
+
a(this, "disposed", !1);
|
|
1676
|
+
/** Terminal worker failure; subsequent loads reject instead of hanging. */
|
|
1677
|
+
a(this, "workerFailure", null);
|
|
1678
|
+
this.worker = t, this.worker.onmessage = (n) => {
|
|
1679
|
+
var r, s;
|
|
1680
|
+
const e = this.pending.get(n.data.id);
|
|
1681
|
+
if (e) {
|
|
1682
|
+
if (n.data.type === "progress") {
|
|
1683
|
+
(r = e.onProgress) == null || r.call(e, n.data.loaded, n.data.total);
|
|
1684
|
+
return;
|
|
1685
|
+
}
|
|
1686
|
+
this.pending.delete(n.data.id), (s = e.removeAbortListener) == null || s.call(e), n.data.ok ? e.resolve(n.data.data) : n.data.cancelled ? e.reject(c("Chunk load was cancelled.")) : e.reject(k(n.data.error));
|
|
1687
|
+
}
|
|
1688
|
+
}, this.worker.onerror = (n) => {
|
|
1689
|
+
if (this.workerFailure) return;
|
|
1690
|
+
const e = n && typeof n == "object" && "message" in n && typeof n.message == "string" ? n.message : "", r = new x(
|
|
1691
|
+
e ? `Chunk loading worker failed. ${e}` : "Chunk loading worker failed.",
|
|
1692
|
+
{ phase: "worker", url: "", retryable: !1 }
|
|
1693
|
+
);
|
|
1694
|
+
this.workerFailure = r, this.worker.terminate(), this.rejectAll(r);
|
|
1695
|
+
};
|
|
1696
|
+
}
|
|
1697
|
+
/** Posts one load to this worker and tracks its pending promise. */
|
|
1698
|
+
request(t, n, e) {
|
|
1699
|
+
if (this.disposed) return Promise.reject(c("ChunkLoader has been disposed."));
|
|
1700
|
+
if (n != null && n.aborted) return Promise.reject(c("Chunk load was cancelled."));
|
|
1701
|
+
if (this.workerFailure) return Promise.reject(this.workerFailure);
|
|
1702
|
+
const r = this.nextRequestId++, s = new Promise((h, i) => {
|
|
1703
|
+
this.pending.set(r, { resolve: h, reject: i, ...e ? { onProgress: e } : {} });
|
|
1704
|
+
});
|
|
1705
|
+
if (n) {
|
|
1706
|
+
const h = () => {
|
|
1707
|
+
const f = this.pending.get(r);
|
|
1708
|
+
if (!f) return;
|
|
1709
|
+
this.pending.delete(r);
|
|
1710
|
+
const u = { type: "cancel", id: r };
|
|
1711
|
+
this.disposed || this.worker.postMessage(u), f.reject(c("Chunk load was cancelled."));
|
|
1712
|
+
};
|
|
1713
|
+
n.addEventListener("abort", h, { once: !0 });
|
|
1714
|
+
const i = this.pending.get(r);
|
|
1715
|
+
i && (i.removeAbortListener = () => n.removeEventListener("abort", h));
|
|
1716
|
+
}
|
|
1717
|
+
const l = { ...t, id: r };
|
|
1718
|
+
return this.worker.postMessage(l), s;
|
|
1719
|
+
}
|
|
1720
|
+
/** Terminates this worker and rejects its in-flight requests. */
|
|
1721
|
+
dispose() {
|
|
1722
|
+
this.disposed || (this.disposed = !0, this.worker.terminate(), this.rejectAll(c("ChunkLoader has been disposed.")));
|
|
1723
|
+
}
|
|
1724
|
+
rejectAll(t) {
|
|
1725
|
+
var n;
|
|
1726
|
+
for (const e of this.pending.values())
|
|
1727
|
+
(n = e.removeAbortListener) == null || n.call(e), e.reject(t);
|
|
1728
|
+
this.pending.clear();
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
class S {
|
|
1732
|
+
constructor() {
|
|
1733
|
+
a(this, "streaming", new w(new U()));
|
|
1734
|
+
/** The in-flight construction; `null` until a one-shot format is requested. */
|
|
1735
|
+
a(this, "oneShot", null);
|
|
1736
|
+
/** The constructed one-shot client, so `dispose` does not have to await. */
|
|
1737
|
+
a(this, "oneShotClient", null);
|
|
1738
|
+
a(this, "disposed", !1);
|
|
1739
|
+
}
|
|
1740
|
+
/**
|
|
1741
|
+
* Fetches and decodes one scene file or chunk directory.
|
|
1742
|
+
*
|
|
1743
|
+
* @param url - Scene URL, absolute or relative to the page.
|
|
1744
|
+
* @param options.kind - 'file' (default) selects a parser by extension;
|
|
1745
|
+
* 'directory' decodes an unbundled SOG chunk directory.
|
|
1746
|
+
* @param options.format - Explicit parser; `lcc-bin` additionally needs
|
|
1747
|
+
* `options.lcc` to say which byte range of the file to fetch.
|
|
1748
|
+
* @param options.signal - Abort signal for cancellation; the returned
|
|
1749
|
+
* promise then rejects with a `DOMException` named `AbortError`.
|
|
1750
|
+
* @param options.lcc - Byte-range plumbing for `lcc-bin`. This path exists
|
|
1751
|
+
* for {@link StreamedSplatMesh} and is **not** part of the stable surface;
|
|
1752
|
+
* the type is nameable as `LccChunkParams` on `@voluma/vlam/formats/lcc`.
|
|
1753
|
+
* @param options.rad - Byte-range plumbing for `rad-chunk`, on the same
|
|
1754
|
+
* footing; the type is `RadChunkRangeRequest` on `@voluma/vlam/formats/rad`.
|
|
1755
|
+
* @throws Rejects only with {@link SplatLoadError} (resolve, fetch, decode or
|
|
1756
|
+
* worker failures - `error.phase` says which; a worker that cannot start at
|
|
1757
|
+
* all, e.g. under a CSP that blocks `blob:` workers, reports
|
|
1758
|
+
* `phase: 'worker'`) or an `Error` named `AbortError` (cancellation or
|
|
1759
|
+
* {@link dispose}).
|
|
1760
|
+
*/
|
|
1761
|
+
// `async` so a URL or format that will not resolve rejects the returned
|
|
1762
|
+
// promise rather than throwing synchronously into the caller.
|
|
1763
|
+
async load(t, n = {}) {
|
|
1764
|
+
const e = n.kind ?? "file", r = _(t, n.baseUrl).href, s = v(r, e, n.format ?? "auto"), l = await this.request(
|
|
1765
|
+
{
|
|
1766
|
+
from: "url",
|
|
1767
|
+
url: r,
|
|
1768
|
+
kind: e,
|
|
1769
|
+
...n.request ? { request: n.request } : {}
|
|
1770
|
+
},
|
|
1771
|
+
s,
|
|
1772
|
+
n.signal,
|
|
1773
|
+
n.lcc,
|
|
1774
|
+
n.rad,
|
|
1775
|
+
n.files,
|
|
1776
|
+
n.sog,
|
|
1777
|
+
n.onProgress
|
|
1778
|
+
);
|
|
1779
|
+
return p(l, s);
|
|
1780
|
+
}
|
|
1781
|
+
/**
|
|
1782
|
+
* Decodes a local file (from a file input or a drop) in the worker - the
|
|
1783
|
+
* bytes are read worker-side, so a multi-million-splat decode still never
|
|
1784
|
+
* blocks the main thread.
|
|
1785
|
+
*
|
|
1786
|
+
* Only self-contained files are supported: `.ply`, `.spz`, `.splat`,
|
|
1787
|
+
* `.ksplat` and bundled `.sog`. An unbundled SOG directory needs sibling
|
|
1788
|
+
* fetches and so requires {@link load} with `kind: 'directory'`.
|
|
1789
|
+
*
|
|
1790
|
+
* @param file - The file; its name selects the parser unless `format` is given.
|
|
1791
|
+
* @throws Rejects only with {@link SplatLoadError} (unknown extension, read
|
|
1792
|
+
* or decode failures) or an `Error` named `AbortError` (cancellation or
|
|
1793
|
+
* {@link dispose}).
|
|
1794
|
+
*/
|
|
1795
|
+
// `async` so an unknown extension rejects the returned promise rather than
|
|
1796
|
+
// throwing synchronously into the caller.
|
|
1797
|
+
async loadFile(t, n = {}) {
|
|
1798
|
+
const e = n.format ?? "auto", r = e === "auto" ? m(A(t.name), t.name) : e, s = await this.request(
|
|
1799
|
+
{ from: "file", file: t },
|
|
1800
|
+
r,
|
|
1801
|
+
n.signal,
|
|
1802
|
+
void 0,
|
|
1803
|
+
void 0,
|
|
1804
|
+
void 0,
|
|
1805
|
+
void 0,
|
|
1806
|
+
n.onProgress
|
|
1807
|
+
);
|
|
1808
|
+
return p(s, r);
|
|
1809
|
+
}
|
|
1810
|
+
/** Routes one load to the worker that owns its format. */
|
|
1811
|
+
request(t, n, e, r, s, l, h, i) {
|
|
1812
|
+
if (this.disposed) return Promise.reject(c("ChunkLoader has been disposed."));
|
|
1813
|
+
if (e != null && e.aborted) return Promise.reject(c("Chunk load was cancelled."));
|
|
1814
|
+
const f = {
|
|
1815
|
+
type: "load",
|
|
1816
|
+
source: t,
|
|
1817
|
+
format: n,
|
|
1818
|
+
...r ? { lcc: r } : {},
|
|
1819
|
+
...s ? { rad: s } : {},
|
|
1820
|
+
...h ? { sog: h } : {},
|
|
1821
|
+
...l ? { files: l } : {},
|
|
1822
|
+
...i ? { progress: !0 } : {}
|
|
1823
|
+
}, u = this.clientFor(n);
|
|
1824
|
+
return u instanceof Promise ? u.then((b) => {
|
|
1825
|
+
if (this.disposed) throw c("ChunkLoader has been disposed.");
|
|
1826
|
+
return b.request(f, e, i);
|
|
1827
|
+
}) : u.request(f, e, i);
|
|
1828
|
+
}
|
|
1829
|
+
/**
|
|
1830
|
+
* The worker for `format`, constructing the one-shot worker on first need.
|
|
1831
|
+
*
|
|
1832
|
+
* The in-flight promise is cached, not just the resolved client, so two
|
|
1833
|
+
* concurrent `.spz` loads share one worker instead of racing to build two.
|
|
1834
|
+
*/
|
|
1835
|
+
clientFor(t) {
|
|
1836
|
+
return $.has(t) ? this.oneShotClient ? this.oneShotClient : (this.oneShot ?? (this.oneShot = import("./one-shot-worker-G80btnth.js").then(
|
|
1837
|
+
({ default: n }) => {
|
|
1838
|
+
const e = new w(new n());
|
|
1839
|
+
return this.oneShotClient = e, this.disposed && e.dispose(), e;
|
|
1840
|
+
}
|
|
1841
|
+
)), this.oneShot) : this.streaming;
|
|
1842
|
+
}
|
|
1843
|
+
/** Terminates both workers and rejects all in-flight requests. */
|
|
1844
|
+
dispose() {
|
|
1845
|
+
var t;
|
|
1846
|
+
this.disposed || (this.disposed = !0, this.streaming.dispose(), (t = this.oneShotClient) == null || t.dispose());
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
const L = ["ply", "spz", "splat", "ksplat", "sog", "rad"];
|
|
1850
|
+
function p(o, t) {
|
|
1851
|
+
return L.includes(t) ? { ...o, format: t } : o;
|
|
1852
|
+
}
|
|
1853
|
+
function v(o, t, n) {
|
|
1854
|
+
return n === "lcc-bin" || n === "rad-chunk" ? n : t === "directory" ? "sog" : n !== "auto" ? n : m(R(new URL(o)), o);
|
|
1855
|
+
}
|
|
1856
|
+
export {
|
|
1857
|
+
S as C
|
|
1858
|
+
};
|
|
1859
|
+
//# sourceMappingURL=chunk-loader-DlNwggfG.js.map
|