@voluma/vlam 0.3.0 → 0.3.4
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 +2 -4
- package/dist/chunk-loader-DlNwggfG.js.map +1 -1
- package/dist/{index.d.ts → core/index.d.ts} +2 -2
- package/dist/{splat-budget.d.ts → core/splat-budget.d.ts} +1 -1
- package/dist/{splat-data.d.ts → core/splat-data.d.ts} +1 -1
- package/dist/{splat-mesh-types.d.ts → core/splat-mesh-types.d.ts} +5 -2
- package/dist/{effects.d.ts → effects/index.d.ts} +3 -3
- package/dist/effects.js.map +1 -1
- package/dist/formats/ksplat/parse-ksplat.d.ts +1 -1
- package/dist/formats/ksplat.js.map +1 -1
- package/dist/formats/lcc/collision-mesh.d.ts +2 -2
- package/dist/formats/lcc/collision-partition.d.ts +1 -1
- package/dist/formats/lcc/lcc.d.ts +3 -3
- package/dist/formats/lcc/lcc2.d.ts +2 -2
- package/dist/formats/lcc/parse-lcc.d.ts +1 -1
- package/dist/formats/lcc.js +276 -277
- package/dist/formats/lcc.js.map +1 -1
- package/dist/formats/ply/parse-compressed-ply.d.ts +2 -2
- package/dist/formats/ply/parse-splat-ply.d.ts +2 -2
- package/dist/formats/ply.js.map +1 -1
- package/dist/formats/rad/frontier-worker-protocol.d.ts +8 -1
- package/dist/formats/rad/index.d.ts +2 -2
- package/dist/formats/rad/parse-rad.d.ts +2 -2
- package/dist/formats/rad/rad-foveated-source.d.ts +3 -3
- package/dist/formats/rad/rad.d.ts +5 -5
- package/dist/formats/rad.js.map +1 -1
- package/dist/formats/sog/parse-sog.d.ts +2 -2
- package/dist/formats/sog.js.map +1 -1
- package/dist/formats/splat/parse-splat.d.ts +1 -1
- package/dist/formats/splat.js.map +1 -1
- package/dist/formats/spz/parse-spz.d.ts +1 -1
- package/dist/formats/spz.js.map +1 -1
- package/dist/half-float-Cs4FDq8Q.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/{chunk-loader.d.ts → loaders/chunk-loader.d.ts} +2 -2
- package/dist/{load-splat-data.d.ts → loaders/load-splat-data.d.ts} +1 -1
- package/dist/{load-worker-protocol.d.ts → loaders/load-worker-protocol.d.ts} +2 -2
- package/dist/loaders.js.map +1 -1
- package/dist/loading-wLo8vRbA.js.map +1 -1
- package/dist/lod-scheduler-ChoZyEeq.js +466 -0
- package/dist/lod-scheduler-ChoZyEeq.js.map +1 -0
- package/dist/logging-BfPdd7NJ.js.map +1 -1
- package/dist/ply-header-B9WllbPg.js.map +1 -1
- package/dist/{radix-sorter-R0FCSqKu.js → radix-sorter-BrbUg_CV.js} +2 -2
- package/dist/radix-sorter-BrbUg_CV.js.map +1 -0
- package/dist/{relighting-CSQF3UcL.js → relighting-Tiwep8yd.js} +302 -294
- package/dist/relighting-Tiwep8yd.js.map +1 -0
- package/dist/{selection-volume.d.ts → selection/selection-volume.d.ts} +1 -1
- package/dist/{splat-partition.d.ts → selection/splat-partition.d.ts} +1 -1
- package/dist/selection.js.map +1 -1
- package/dist/sh-pack-D5wAe5gg.js.map +1 -1
- package/dist/splat-budget-DuVZspPQ.js.map +1 -1
- package/dist/splat-data-BZM5dhhx.js.map +1 -1
- package/dist/{splat-mesh-aQdcWA6v.js → splat-mesh-CsLOQb08.js} +3 -3
- package/dist/splat-mesh-CsLOQb08.js.map +1 -0
- package/dist/splat-mesh-types-BZIko-_9.js.map +1 -1
- package/dist/{static-lod-splat-mesh.d.ts → static-lod/static-lod-splat-mesh.d.ts} +2 -2
- package/dist/{static-lod-worker-protocol.d.ts → static-lod/static-lod-worker-protocol.d.ts} +1 -1
- package/dist/{static-lod.d.ts → static-lod/static-lod.d.ts} +1 -1
- package/dist/static-lod.js +1 -1
- package/dist/static-lod.js.map +1 -1
- package/dist/{dataset-source.d.ts → streaming/dataset-source.d.ts} +1 -1
- package/dist/{streaming.d.ts → streaming/index.d.ts} +3 -3
- package/dist/{lod-scheduler.d.ts → streaming/lod-scheduler.d.ts} +32 -0
- package/dist/{lod-source.d.ts → streaming/lod-source.d.ts} +19 -13
- package/dist/{streamed-splat-mesh-utils.d.ts → streaming/streamed-splat-mesh-utils.d.ts} +2 -2
- package/dist/{streamed-splat-mesh.d.ts → streaming/streamed-splat-mesh.d.ts} +83 -27
- package/dist/streaming.js +711 -645
- package/dist/streaming.js.map +1 -1
- package/dist/{unified-splat-mesh.d.ts → unified/unified-splat-mesh.d.ts} +13 -6
- package/dist/{work-buffer-gather.d.ts → unified/work-buffer-gather.d.ts} +5 -5
- package/dist/{work-buffer-material.d.ts → unified/work-buffer-material.d.ts} +1 -1
- package/dist/unified.js +280 -272
- package/dist/unified.js.map +1 -1
- package/dist/webgpu-limits-Y3CI_6_6.js.map +1 -1
- package/package.json +9 -9
- package/dist/lod-scheduler-B0a_uBlv.js +0 -383
- package/dist/lod-scheduler-B0a_uBlv.js.map +0 -1
- package/dist/radix-sorter-R0FCSqKu.js.map +0 -1
- package/dist/relighting-CSQF3UcL.js.map +0 -1
- package/dist/splat-mesh-aQdcWA6v.js.map +0 -1
- /package/dist/{compute-sorter.d.ts → core/compute-sorter.d.ts} +0 -0
- /package/dist/{create-splat-renderer.d.ts → core/create-splat-renderer.d.ts} +0 -0
- /package/dist/{depth-of-field.d.ts → core/depth-of-field.d.ts} +0 -0
- /package/dist/{half-float.d.ts → core/half-float.d.ts} +0 -0
- /package/dist/{logging.d.ts → core/logging.d.ts} +0 -0
- /package/dist/{merged-splat-mesh.d.ts → core/merged-splat-mesh.d.ts} +0 -0
- /package/dist/{orientation.d.ts → core/orientation.d.ts} +0 -0
- /package/dist/{radix-sort.d.ts → core/radix-sort.d.ts} +0 -0
- /package/dist/{radix-sorter.d.ts → core/radix-sorter.d.ts} +0 -0
- /package/dist/{relighting-pass.d.ts → core/relighting-pass.d.ts} +0 -0
- /package/dist/{relighting.d.ts → core/relighting.d.ts} +0 -0
- /package/dist/{sh-pack.d.ts → core/sh-pack.d.ts} +0 -0
- /package/dist/{sort-scheduler.d.ts → core/sort-scheduler.d.ts} +0 -0
- /package/dist/{sort-worker-protocol.d.ts → core/sort-worker-protocol.d.ts} +0 -0
- /package/dist/{sorter.d.ts → core/sorter.d.ts} +0 -0
- /package/dist/{source-transform.d.ts → core/source-transform.d.ts} +0 -0
- /package/dist/{splat-depth-pack.d.ts → core/splat-depth-pack.d.ts} +0 -0
- /package/dist/{splat-mesh-material.d.ts → core/splat-mesh-material.d.ts} +0 -0
- /package/dist/{splat-mesh-picking.d.ts → core/splat-mesh-picking.d.ts} +0 -0
- /package/dist/{splat-mesh-pool.d.ts → core/splat-mesh-pool.d.ts} +0 -0
- /package/dist/{splat-mesh.d.ts → core/splat-mesh.d.ts} +0 -0
- /package/dist/{splat-modifier-stack.d.ts → core/splat-modifier-stack.d.ts} +0 -0
- /package/dist/{splat-modifier.d.ts → core/splat-modifier.d.ts} +0 -0
- /package/dist/{splat-query.d.ts → core/splat-query.d.ts} +0 -0
- /package/dist/{splat-sort-bounds.d.ts → core/splat-sort-bounds.d.ts} +0 -0
- /package/dist/{storage-attribute-mirror.d.ts → core/storage-attribute-mirror.d.ts} +0 -0
- /package/dist/{webgpu-limits.d.ts → core/webgpu-limits.d.ts} +0 -0
- /package/dist/{worker-sorter.d.ts → core/worker-sorter.d.ts} +0 -0
- /package/dist/{xr-view.d.ts → core/xr-view.d.ts} +0 -0
- /package/dist/{loaders.d.ts → loaders/index.d.ts} +0 -0
- /package/dist/{loading.d.ts → loaders/loading.d.ts} +0 -0
- /package/dist/{ply-header.d.ts → loaders/ply-header.d.ts} +0 -0
- /package/dist/{selection.d.ts → selection/index.d.ts} +0 -0
- /package/dist/{static-lod-entry.d.ts → static-lod/index.d.ts} +0 -0
- /package/dist/{budget-governor.d.ts → streaming/budget-governor.d.ts} +0 -0
- /package/dist/{camera-budget-governor.d.ts → streaming/camera-budget-governor.d.ts} +0 -0
- /package/dist/{chunk-cache-budget.d.ts → streaming/chunk-cache-budget.d.ts} +0 -0
- /package/dist/{chunk-fetch-scheduler.d.ts → streaming/chunk-fetch-scheduler.d.ts} +0 -0
- /package/dist/{lod-manifest.d.ts → streaming/lod-manifest.d.ts} +0 -0
- /package/dist/{unified.d.ts → unified/index.d.ts} +0 -0
- /package/dist/{unified-work-buffer.d.ts → unified/unified-work-buffer.d.ts} +0 -0
package/dist/formats/lcc.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var A = (e, t, n) =>
|
|
4
|
-
import { w as
|
|
5
|
-
import { a as
|
|
6
|
-
import * as
|
|
7
|
-
import { L as
|
|
8
|
-
import { t as
|
|
9
|
-
import { M as
|
|
1
|
+
var gt = Object.defineProperty;
|
|
2
|
+
var wt = (e, t, n) => t in e ? gt(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
|
|
3
|
+
var A = (e, t, n) => wt(e, typeof t != "symbol" ? t + "" : t, n);
|
|
4
|
+
import { w as mt } from "../splat-data-BZM5dhhx.js";
|
|
5
|
+
import { a as pt, r as Ct } from "../sh-pack-D5wAe5gg.js";
|
|
6
|
+
import * as S from "three/webgpu";
|
|
7
|
+
import { L as yt } from "../lod-scheduler-ChoZyEeq.js";
|
|
8
|
+
import { t as at, a as W } from "../loading-wLo8vRbA.js";
|
|
9
|
+
import { M as vt } from "../splat-mesh-types-BZIko-_9.js";
|
|
10
10
|
import { w as z } from "../logging-BfPdd7NJ.js";
|
|
11
|
-
import { c as xt, a as
|
|
12
|
-
const
|
|
13
|
-
function
|
|
11
|
+
import { c as xt, a as bt, b as Lt, p as Y, d as j } from "../ply-header-B9WllbPg.js";
|
|
12
|
+
const T = 32, O = 64, K = 1 << 24;
|
|
13
|
+
function Et(e) {
|
|
14
14
|
return e === 1 ? 3 : e === 2 ? 8 : 15;
|
|
15
15
|
}
|
|
16
|
-
function
|
|
16
|
+
function St(e) {
|
|
17
17
|
const t = e, n = String(t.version ?? "");
|
|
18
18
|
if (!/^[2345]\./.test(n))
|
|
19
19
|
throw new Error(
|
|
@@ -33,38 +33,38 @@ function Et(e) {
|
|
|
33
33
|
const a = t.splats;
|
|
34
34
|
if (!Array.isArray(a) || a.length !== i)
|
|
35
35
|
throw new Error(`LCC manifest "splats" must list one count per level (${i}).`);
|
|
36
|
-
for (const
|
|
37
|
-
if (!Number.isSafeInteger(
|
|
38
|
-
throw new Error(`LCC manifest "splats" contains an invalid count: ${String(
|
|
36
|
+
for (const p of a)
|
|
37
|
+
if (!Number.isSafeInteger(p) || p < 0)
|
|
38
|
+
throw new Error(`LCC manifest "splats" contains an invalid count: ${String(p)}.`);
|
|
39
39
|
const r = t.totalSplats;
|
|
40
40
|
if (!Number.isSafeInteger(r) || r < 0)
|
|
41
41
|
throw new Error(`LCC manifest declares an invalid totalSplats: ${String(r)}.`);
|
|
42
42
|
const u = J(t, "cellLengthX"), f = J(t, "cellLengthY");
|
|
43
43
|
if (u <= 0 || f <= 0)
|
|
44
44
|
throw new Error("LCC manifest cell lengths must be positive.");
|
|
45
|
-
const h =
|
|
46
|
-
if (Array.isArray(d) && d.some((
|
|
45
|
+
const h = $t(t), d = t.shift;
|
|
46
|
+
if (Array.isArray(d) && d.some((p) => p !== 0))
|
|
47
47
|
throw new Error(
|
|
48
48
|
`LCC manifest "shift" is non-zero (${JSON.stringify(d)}), which is not supported.`
|
|
49
49
|
);
|
|
50
|
-
const
|
|
51
|
-
if (Array.isArray(
|
|
50
|
+
const w = t.scale;
|
|
51
|
+
if (Array.isArray(w) && w.some((p) => p !== 1))
|
|
52
52
|
throw new Error(
|
|
53
|
-
`LCC manifest "scale" is non-identity (${JSON.stringify(
|
|
53
|
+
`LCC manifest "scale" is non-identity (${JSON.stringify(w)}), which is not supported.`
|
|
54
54
|
);
|
|
55
|
-
const
|
|
56
|
-
if (!Array.isArray(
|
|
57
|
-
const
|
|
58
|
-
for (const
|
|
59
|
-
typeof (
|
|
60
|
-
min: P(
|
|
61
|
-
max: P(
|
|
55
|
+
const m = t.boundingBox, $ = P(m == null ? void 0 : m.min, "boundingBox.min"), x = P(m == null ? void 0 : m.max, "boundingBox.max"), g = t.attributes;
|
|
56
|
+
if (!Array.isArray(g)) throw new Error('LCC manifest is missing "attributes".');
|
|
57
|
+
const y = /* @__PURE__ */ new Map();
|
|
58
|
+
for (const p of g)
|
|
59
|
+
typeof (p == null ? void 0 : p.name) == "string" && (!Array.isArray(p.min) || p.min.length < 3 || y.set(p.name, {
|
|
60
|
+
min: P(p.min, `attributes.${p.name}.min`),
|
|
61
|
+
max: P(p.max, `attributes.${p.name}.max`)
|
|
62
62
|
}));
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
if (!
|
|
66
|
-
return
|
|
67
|
-
},
|
|
63
|
+
const b = (p) => {
|
|
64
|
+
const v = y.get(p);
|
|
65
|
+
if (!v) throw new Error(`LCC manifest is missing the "${p}" attribute range.`);
|
|
66
|
+
return v;
|
|
67
|
+
}, C = y.get("shcoef") ?? V, L = At(t.fileType, C);
|
|
68
68
|
return {
|
|
69
69
|
totalSplats: r,
|
|
70
70
|
totalLevel: i,
|
|
@@ -72,18 +72,18 @@ function Et(e) {
|
|
|
72
72
|
cellLengthY: f,
|
|
73
73
|
indexDataSize: c,
|
|
74
74
|
splats: a,
|
|
75
|
-
bounds: { min: $, max:
|
|
75
|
+
bounds: { min: $, max: x },
|
|
76
76
|
fileType: L,
|
|
77
|
-
scale:
|
|
77
|
+
scale: b("scale"),
|
|
78
78
|
// A Portable capture has no SH at all; keep a benign range so the type
|
|
79
79
|
// stays total rather than sprinkling optionality through the loader.
|
|
80
|
-
shcoef:
|
|
81
|
-
envScale:
|
|
82
|
-
envShcoef:
|
|
80
|
+
shcoef: C,
|
|
81
|
+
envScale: y.get("envscale") ?? V,
|
|
82
|
+
envShcoef: y.get("envshcoef") ?? V,
|
|
83
83
|
georeference: h
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
|
-
function
|
|
86
|
+
function $t(e) {
|
|
87
87
|
const t = e.offset;
|
|
88
88
|
if (!Array.isArray(t) || !t.some((o) => o !== 0)) return;
|
|
89
89
|
const n = e.epsg;
|
|
@@ -92,18 +92,18 @@ function St(e) {
|
|
|
92
92
|
epsg: Number.isSafeInteger(n) && n > 0 ? n : void 0
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
|
-
function
|
|
95
|
+
function At(e, t) {
|
|
96
96
|
if (e === "Portable" || e === "Quality") return e;
|
|
97
|
-
if (e === void 0) return
|
|
97
|
+
if (e === void 0) return Mt(t) ? "Portable" : "Quality";
|
|
98
98
|
throw new Error(
|
|
99
99
|
`Unsupported LCC fileType: "${String(e)}" (expected Portable or Quality).`
|
|
100
100
|
);
|
|
101
101
|
}
|
|
102
|
-
function
|
|
102
|
+
function Mt(e) {
|
|
103
103
|
return e.min.every((t) => t === 0) && e.max.every((t) => t === 0 || t === 1);
|
|
104
104
|
}
|
|
105
|
-
const
|
|
106
|
-
function
|
|
105
|
+
const V = { min: [0, 0, 0], max: [0, 0, 0] };
|
|
106
|
+
function Ft(e, t) {
|
|
107
107
|
const { indexDataSize: n, totalLevel: o } = t;
|
|
108
108
|
if (e.byteLength === 0 || e.byteLength % n !== 0)
|
|
109
109
|
throw new Error(
|
|
@@ -119,9 +119,9 @@ function Mt(e, t) {
|
|
|
119
119
|
`LCC index.bin has a byte offset beyond Number.MAX_SAFE_INTEGER: ${f}.`
|
|
120
120
|
);
|
|
121
121
|
const h = s.getUint32(r + 12, !0);
|
|
122
|
-
if (h !== u *
|
|
122
|
+
if (h !== u * T)
|
|
123
123
|
throw new Error(
|
|
124
|
-
`LCC index.bin level ${a} declares ${u} splats but ${h} bytes (expected ${u *
|
|
124
|
+
`LCC index.bin level ${a} declares ${u} splats but ${h} bytes (expected ${u * T}).`
|
|
125
125
|
);
|
|
126
126
|
c.push({ count: u, byteOffset: Number(f), byteSize: h });
|
|
127
127
|
}
|
|
@@ -133,24 +133,24 @@ function Mt(e, t) {
|
|
|
133
133
|
}
|
|
134
134
|
return i;
|
|
135
135
|
}
|
|
136
|
-
function
|
|
136
|
+
function Tt(e) {
|
|
137
137
|
const t = e >>> 30 & 3, n = [0, 0, 0, 0];
|
|
138
138
|
let o = 0;
|
|
139
139
|
for (let i = 0; i < 4; i++) {
|
|
140
140
|
if (i === t) continue;
|
|
141
141
|
const l = e >>> 10 * o & 1023;
|
|
142
|
-
n[i] = (l - 511) *
|
|
142
|
+
n[i] = (l - 511) * Ut, o++;
|
|
143
143
|
}
|
|
144
144
|
const s = n[0] ** 2 + n[1] ** 2 + n[2] ** 2 + n[3] ** 2;
|
|
145
145
|
return n[t] = Math.sqrt(Math.max(0, 1 - s)), [n[3], n[0], n[1], n[2]];
|
|
146
146
|
}
|
|
147
|
-
const
|
|
148
|
-
async function
|
|
149
|
-
var
|
|
147
|
+
const Ut = 1 / (511 * Math.SQRT2);
|
|
148
|
+
async function ce(e, t, n, o) {
|
|
149
|
+
var b;
|
|
150
150
|
const s = t.stride;
|
|
151
|
-
if (s !==
|
|
151
|
+
if (s !== T && s !== T + O)
|
|
152
152
|
throw new Error(`LCC chunk declares an unsupported ${s}-byte record.`);
|
|
153
|
-
if (((
|
|
153
|
+
if (((b = t.sh) == null ? void 0 : b.source) === "inline" && s === T)
|
|
154
154
|
throw new Error("LCC chunk asks for inline SH but its records have no room for it.");
|
|
155
155
|
if (e.byteLength % s !== 0)
|
|
156
156
|
throw new Error(
|
|
@@ -161,40 +161,40 @@ async function le(e, t, n, o) {
|
|
|
161
161
|
throw new Error(
|
|
162
162
|
`LCC chunk holds ${i} splats, above the supported maximum of ${K}.`
|
|
163
163
|
);
|
|
164
|
-
const l = new DataView(e), c = new Float32Array(i * 3), a = new Uint8Array(i * 4), r = new Float32Array(i * 6), u = new Uint8Array(e), { min: f, max: h } = t.scale, d = f[0],
|
|
165
|
-
for (let
|
|
166
|
-
o && (
|
|
167
|
-
const L =
|
|
168
|
-
c[
|
|
169
|
-
const [
|
|
170
|
-
|
|
164
|
+
const l = new DataView(e), c = new Float32Array(i * 3), a = new Uint8Array(i * 4), r = new Float32Array(i * 6), u = new Uint8Array(e), { min: f, max: h } = t.scale, d = f[0], w = f[1], m = f[2], $ = h[0] - f[0], x = h[1] - f[1], g = h[2] - f[2];
|
|
165
|
+
for (let C = 0; C < i; C++) {
|
|
166
|
+
o && (C & 65535) === 0 && C > 0 && (await new Promise((F) => setTimeout(F, 0)), o.throwIfAborted());
|
|
167
|
+
const L = C * s;
|
|
168
|
+
c[C * 3 + 0] = l.getFloat32(L, !0), c[C * 3 + 1] = l.getFloat32(L + 4, !0), c[C * 3 + 2] = l.getFloat32(L + 8, !0), a[C * 4 + 0] = u[L + 12], a[C * 4 + 1] = u[L + 13], a[C * 4 + 2] = u[L + 14], a[C * 4 + 3] = u[L + 15];
|
|
169
|
+
const [p, v, E, U] = Tt(l.getUint32(L + 22, !0));
|
|
170
|
+
mt(
|
|
171
171
|
r,
|
|
172
|
-
|
|
172
|
+
C,
|
|
173
173
|
d + $ * (l.getUint16(L + 16, !0) / 65535),
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
174
|
+
w + x * (l.getUint16(L + 18, !0) / 65535),
|
|
175
|
+
m + g * (l.getUint16(L + 20, !0) / 65535),
|
|
176
|
+
p,
|
|
177
|
+
v,
|
|
178
|
+
E,
|
|
179
|
+
U
|
|
180
180
|
);
|
|
181
181
|
}
|
|
182
182
|
o == null || o.throwIfAborted();
|
|
183
|
-
const
|
|
183
|
+
const y = t.sh ? Bt(e, n, t.sh, i, s) : void 0;
|
|
184
184
|
return {
|
|
185
185
|
count: i,
|
|
186
186
|
positions: c,
|
|
187
187
|
colors: a,
|
|
188
188
|
covariances: r,
|
|
189
|
-
...
|
|
189
|
+
...y ? { shPacked: y } : {}
|
|
190
190
|
};
|
|
191
191
|
}
|
|
192
|
-
function
|
|
193
|
-
const i =
|
|
192
|
+
function Bt(e, t, n, o, s) {
|
|
193
|
+
const i = Et(n.bands), l = new Uint32Array(o * i);
|
|
194
194
|
if (n.source === "inline") {
|
|
195
195
|
const r = new DataView(e);
|
|
196
196
|
for (let u = 0; u < o; u++) {
|
|
197
|
-
const f = u * s +
|
|
197
|
+
const f = u * s + T;
|
|
198
198
|
for (let h = 0; h < i; h++)
|
|
199
199
|
l[u * i + h] = r.getUint32(f + h * 4, !0);
|
|
200
200
|
}
|
|
@@ -216,10 +216,10 @@ function Ut(e, t, n, o, s) {
|
|
|
216
216
|
}
|
|
217
217
|
function Z(e, t) {
|
|
218
218
|
const n = t.requantizeTo;
|
|
219
|
-
if (!n ||
|
|
219
|
+
if (!n || pt(t.range, n))
|
|
220
220
|
return { bands: t.bands, packed: e, range: t.range };
|
|
221
221
|
for (let o = 0; o < e.length; o++)
|
|
222
|
-
e[o] =
|
|
222
|
+
e[o] = Ct(e[o], t.range, n);
|
|
223
223
|
return { bands: t.bands, packed: e, range: n };
|
|
224
224
|
}
|
|
225
225
|
function J(e, t) {
|
|
@@ -238,53 +238,53 @@ function P(e, t) {
|
|
|
238
238
|
});
|
|
239
239
|
}
|
|
240
240
|
function H() {
|
|
241
|
-
return new
|
|
241
|
+
return new S.Matrix4().set(-1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1);
|
|
242
242
|
}
|
|
243
|
-
function
|
|
243
|
+
function ae(e) {
|
|
244
244
|
e.matrix.copy(H()), e.matrix.decompose(e.position, e.quaternion, e.scale), e.matrixWorldNeedsUpdate = !0;
|
|
245
245
|
}
|
|
246
|
-
const
|
|
247
|
-
async function
|
|
248
|
-
const o =
|
|
249
|
-
const
|
|
250
|
-
if (
|
|
251
|
-
return
|
|
252
|
-
}, i = s("data.bin"), l = t.resolve("environment.bin"), c =
|
|
253
|
-
await
|
|
246
|
+
const It = 128e3;
|
|
247
|
+
async function ue(e, t, n) {
|
|
248
|
+
const o = St(e), s = (v) => {
|
|
249
|
+
const E = t.resolve(v);
|
|
250
|
+
if (E === null) throw new Error(`LCC dataset is missing "${v}".`);
|
|
251
|
+
return E;
|
|
252
|
+
}, i = s("data.bin"), l = t.resolve("environment.bin"), c = Ft(
|
|
253
|
+
await Dt(s("index.bin"), n, "manifest"),
|
|
254
254
|
o
|
|
255
255
|
);
|
|
256
|
-
|
|
257
|
-
const a = o.fileType === "Quality" ?
|
|
258
|
-
let
|
|
259
|
-
const
|
|
260
|
-
for (let
|
|
261
|
-
const
|
|
256
|
+
Rt(c, o);
|
|
257
|
+
const a = o.fileType === "Quality" ? vt : 0, r = n.shBands ?? a, u = Math.min(r, a), f = u === 0 ? void 0 : u, h = f === void 0 ? null : s("shcoef.bin"), d = [], w = [], m = (v, E) => (d.push(v), w.push(E), d.length - 1), $ = [], x = /* @__PURE__ */ new Set();
|
|
258
|
+
let g = 0;
|
|
259
|
+
const y = o.totalLevel;
|
|
260
|
+
for (let v = 0; v < c.length; v++) {
|
|
261
|
+
const E = c[v];
|
|
262
262
|
let U = 0;
|
|
263
|
-
for (let
|
|
264
|
-
const
|
|
265
|
-
if (
|
|
266
|
-
U =
|
|
263
|
+
for (let M = 0; M < y; M++) {
|
|
264
|
+
const B = E.levels[M].count;
|
|
265
|
+
if (B > 0) {
|
|
266
|
+
U = B;
|
|
267
267
|
break;
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
|
-
const
|
|
271
|
-
for (let
|
|
272
|
-
const
|
|
270
|
+
const F = Math.max(1, Math.ceil(U / It));
|
|
271
|
+
for (let M = 0; M < F; M++) {
|
|
272
|
+
const B = new Array(y).fill(
|
|
273
273
|
void 0
|
|
274
274
|
);
|
|
275
|
-
let
|
|
276
|
-
for (let I = 0; I <
|
|
277
|
-
const R =
|
|
275
|
+
let k = -1, G = 0;
|
|
276
|
+
for (let I = 0; I < y; I++) {
|
|
277
|
+
const R = E.levels[I];
|
|
278
278
|
if (R.count === 0) continue;
|
|
279
|
-
const N = Math.floor(
|
|
279
|
+
const N = Math.floor(M * R.count / F), _ = Math.floor((M + 1) * R.count / F);
|
|
280
280
|
if (_ === N) continue;
|
|
281
|
-
const
|
|
281
|
+
const dt = `${i}#c${E.cellX}_${E.cellY}-l${I}${F > 1 ? `.${M}` : ""}`, Q = m(dt, {
|
|
282
282
|
format: "lcc-bin",
|
|
283
283
|
lcc: {
|
|
284
284
|
kind: "splats",
|
|
285
|
-
start: R.byteOffset + N *
|
|
286
|
-
length: (_ - N) *
|
|
287
|
-
stride:
|
|
285
|
+
start: R.byteOffset + N * T,
|
|
286
|
+
length: (_ - N) * T,
|
|
287
|
+
stride: T,
|
|
288
288
|
scale: o.scale,
|
|
289
289
|
...f === void 0 ? {} : {
|
|
290
290
|
sh: {
|
|
@@ -299,22 +299,23 @@ async function ae(e, t, n) {
|
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
301
|
});
|
|
302
|
-
|
|
302
|
+
B[I] = { file: Q, offset: 0, count: _ - N }, k = Q, G = _ - N;
|
|
303
303
|
}
|
|
304
|
-
|
|
304
|
+
k >= 0 && (x.add(k), g += G), $.push({ bounds: Pt(E, o), lods: B, budgetGroup: v });
|
|
305
305
|
}
|
|
306
306
|
}
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
307
|
+
const b = await _t(t, o);
|
|
308
|
+
let C;
|
|
309
|
+
if (b > 0 && l !== null) {
|
|
310
|
+
const v = ut(o), E = m(`${l}#env`, {
|
|
310
311
|
format: "lcc-bin",
|
|
311
312
|
lcc: {
|
|
312
313
|
kind: "environment",
|
|
313
314
|
start: 0,
|
|
314
|
-
length:
|
|
315
|
+
length: b * v,
|
|
315
316
|
// From `fileType`, never from whether SH is enabled: a Quality
|
|
316
317
|
// environment record is 96 bytes even when its SH is being skipped.
|
|
317
|
-
stride:
|
|
318
|
+
stride: v,
|
|
318
319
|
scale: o.envScale,
|
|
319
320
|
...f === void 0 ? {} : {
|
|
320
321
|
sh: {
|
|
@@ -329,25 +330,22 @@ async function ae(e, t, n) {
|
|
|
329
330
|
}
|
|
330
331
|
}
|
|
331
332
|
});
|
|
332
|
-
|
|
333
|
-
bounds: V(o),
|
|
334
|
-
lods: [{ file: x, offset: 0, count: v }]
|
|
335
|
-
});
|
|
333
|
+
x.add(E), g += b, C = { file: E };
|
|
336
334
|
}
|
|
337
|
-
const
|
|
335
|
+
const L = {
|
|
338
336
|
leaves: $,
|
|
339
337
|
chunkUrls: d,
|
|
340
338
|
// Per-level splat totals; index 0 is the finest. Informational here (the
|
|
341
339
|
// pool and coverage floor are sized explicitly below), but kept accurate.
|
|
342
|
-
counts: o.splats.slice(0,
|
|
343
|
-
lodLevels:
|
|
344
|
-
bounds:
|
|
345
|
-
},
|
|
340
|
+
counts: o.splats.slice(0, y),
|
|
341
|
+
lodLevels: y,
|
|
342
|
+
bounds: tt(o)
|
|
343
|
+
}, p = await Nt(t);
|
|
346
344
|
return {
|
|
347
345
|
// Classic LCC cells are broad XY tiles. Keep their priority independent of
|
|
348
346
|
// frustum crossings so an orbit does not demote a sharp tile as it leaves
|
|
349
347
|
// one edge, then rebuild it when the same tile re-enters the other edge.
|
|
350
|
-
source: new
|
|
348
|
+
source: new yt(L, {
|
|
351
349
|
...n,
|
|
352
350
|
// Classic LCC cells are broad XY tiles. Keep their priority independent of
|
|
353
351
|
// frustum crossings so an orbit does not demote a sharp tile as it leaves
|
|
@@ -368,25 +366,26 @@ async function ae(e, t, n) {
|
|
|
368
366
|
forceFinestWhenFits: !1
|
|
369
367
|
}),
|
|
370
368
|
chunkUrls: d,
|
|
371
|
-
chunkOptions:
|
|
369
|
+
chunkOptions: w,
|
|
372
370
|
shBands: f ?? 0,
|
|
373
371
|
chunkKind: "file",
|
|
374
|
-
bounds:
|
|
375
|
-
pinnedFiles:
|
|
372
|
+
bounds: tt(o),
|
|
373
|
+
pinnedFiles: x,
|
|
376
374
|
// Worst case is every cell resident at its finest level, plus the sky.
|
|
377
|
-
maxResidentSplats: (o.splats[0] ?? n.budget) +
|
|
375
|
+
maxResidentSplats: (o.splats[0] ?? n.budget) + b,
|
|
378
376
|
// Full coarse coverage is each cell's coarsest level plus the sky - the
|
|
379
377
|
// budget floor below which even the substitute levels cannot all fit.
|
|
380
|
-
minimumCoverageSplats: Math.max(1,
|
|
378
|
+
minimumCoverageSplats: Math.max(1, g),
|
|
381
379
|
// Same Z-up frame as .lcc2; bounds stay source-local and matrixWorld
|
|
382
380
|
// handles the conversion.
|
|
383
381
|
formatTransform: H(),
|
|
384
382
|
// Optional classic-LCC collision mesh file. One descriptor for the whole
|
|
385
383
|
// `.lci`; `loadCollisionMeshes` expands it into per-cell triangle tiles.
|
|
386
|
-
...
|
|
384
|
+
...p !== null ? { collision: { meshes: [{ url: p }] } } : {},
|
|
385
|
+
...C !== void 0 ? { environment: C } : {}
|
|
387
386
|
};
|
|
388
387
|
}
|
|
389
|
-
async function
|
|
388
|
+
async function Nt(e) {
|
|
390
389
|
for (const t of ["collision.lci", "Collision.lci"]) {
|
|
391
390
|
const n = await e.size(t);
|
|
392
391
|
if (n !== null && Number.isSafeInteger(n) && n > 0)
|
|
@@ -394,28 +393,28 @@ async function It(e) {
|
|
|
394
393
|
}
|
|
395
394
|
return null;
|
|
396
395
|
}
|
|
397
|
-
function
|
|
398
|
-
return e.fileType === "Quality" ?
|
|
396
|
+
function ut(e) {
|
|
397
|
+
return e.fileType === "Quality" ? T + O : T;
|
|
399
398
|
}
|
|
400
|
-
function
|
|
399
|
+
function Pt(e, t) {
|
|
401
400
|
const { min: n, max: o } = t.bounds, s = n[0] + e.cellX * t.cellLengthX, i = n[1] + e.cellY * t.cellLengthY;
|
|
402
|
-
return new
|
|
403
|
-
new
|
|
404
|
-
new
|
|
401
|
+
return new S.Box3(
|
|
402
|
+
new S.Vector3(Math.min(s, o[0]), Math.min(i, o[1]), n[2]),
|
|
403
|
+
new S.Vector3(
|
|
405
404
|
Math.min(s + t.cellLengthX, o[0]),
|
|
406
405
|
Math.min(i + t.cellLengthY, o[1]),
|
|
407
406
|
o[2]
|
|
408
407
|
)
|
|
409
408
|
);
|
|
410
409
|
}
|
|
411
|
-
function
|
|
410
|
+
function tt(e) {
|
|
412
411
|
const { min: t, max: n } = e.bounds;
|
|
413
|
-
return new
|
|
414
|
-
new
|
|
415
|
-
new
|
|
412
|
+
return new S.Box3(
|
|
413
|
+
new S.Vector3(t[0], t[1], t[2]),
|
|
414
|
+
new S.Vector3(n[0], n[1], n[2])
|
|
416
415
|
);
|
|
417
416
|
}
|
|
418
|
-
function
|
|
417
|
+
function Rt(e, t) {
|
|
419
418
|
for (let n = 0; n < t.totalLevel; n++) {
|
|
420
419
|
let o = 0;
|
|
421
420
|
for (const c of e) o += c.levels[n].count;
|
|
@@ -426,20 +425,20 @@ function Pt(e, t) {
|
|
|
426
425
|
);
|
|
427
426
|
}
|
|
428
427
|
}
|
|
429
|
-
async function
|
|
428
|
+
async function _t(e, t) {
|
|
430
429
|
const n = await e.size("environment.bin");
|
|
431
430
|
if (n === null || !Number.isSafeInteger(n) || n <= 0) return 0;
|
|
432
|
-
const o =
|
|
431
|
+
const o = ut(t);
|
|
433
432
|
if (n % o !== 0)
|
|
434
433
|
throw new Error(
|
|
435
434
|
`LCC environment.bin is ${n} bytes, not a multiple of the ${o}-byte ${t.fileType} record.`
|
|
436
435
|
);
|
|
437
436
|
return n / o;
|
|
438
437
|
}
|
|
439
|
-
async function
|
|
438
|
+
async function Dt(e, t, n) {
|
|
440
439
|
let o;
|
|
441
440
|
try {
|
|
442
|
-
o = await fetch(e,
|
|
441
|
+
o = await fetch(e, at(t.request, t.signal));
|
|
443
442
|
} catch (s) {
|
|
444
443
|
throw W(s, { phase: n, url: e });
|
|
445
444
|
}
|
|
@@ -451,40 +450,40 @@ async function _t(e, t, n) {
|
|
|
451
450
|
});
|
|
452
451
|
return o.arrayBuffer();
|
|
453
452
|
}
|
|
454
|
-
const
|
|
455
|
-
function
|
|
456
|
-
var $,
|
|
457
|
-
const s = e, i = s.root.splatFiles.map((
|
|
458
|
-
const
|
|
459
|
-
if (
|
|
460
|
-
return
|
|
453
|
+
const zt = 3, Ot = 0.1, et = 0.1, kt = 500;
|
|
454
|
+
function he(e, t, n, o = 0) {
|
|
455
|
+
var $, x;
|
|
456
|
+
const s = e, i = s.root.splatFiles.map((g) => {
|
|
457
|
+
const y = t.resolve(g);
|
|
458
|
+
if (y === null) throw new Error(`LCC2 dataset is missing the tile "${g}".`);
|
|
459
|
+
return y;
|
|
461
460
|
}), l = [], c = [];
|
|
462
461
|
let a = 0;
|
|
463
|
-
const r = (
|
|
464
|
-
var
|
|
465
|
-
const
|
|
466
|
-
if (!
|
|
467
|
-
const
|
|
462
|
+
const r = (g, y) => {
|
|
463
|
+
var U;
|
|
464
|
+
const b = (U = g.data) == null ? void 0 : U["3dgs"];
|
|
465
|
+
if (!b) throw new Error("LCC2 node is missing 3dgs data.");
|
|
466
|
+
const C = l.length;
|
|
468
467
|
l.push(null);
|
|
469
|
-
const L = a,
|
|
470
|
-
if (
|
|
471
|
-
c[a] =
|
|
468
|
+
const L = a, p = [], v = g.child ? Object.values(g.child) : [];
|
|
469
|
+
if (v.length === 0)
|
|
470
|
+
c[a] = C, a++;
|
|
472
471
|
else
|
|
473
|
-
for (const
|
|
474
|
-
const
|
|
475
|
-
return l[
|
|
476
|
-
file:
|
|
477
|
-
offset:
|
|
478
|
-
count:
|
|
479
|
-
bounds: q(
|
|
480
|
-
level: s.totalLevels -
|
|
481
|
-
children:
|
|
472
|
+
for (const F of v) p.push(r(F, y + 1));
|
|
473
|
+
const E = v.length === 0 ? L + 1 : a;
|
|
474
|
+
return l[C] = {
|
|
475
|
+
file: b.name,
|
|
476
|
+
offset: b.start,
|
|
477
|
+
count: b.count,
|
|
478
|
+
bounds: q(g.boundingBox),
|
|
479
|
+
level: s.totalLevels - y,
|
|
480
|
+
children: p,
|
|
482
481
|
leafStart: L,
|
|
483
|
-
leafEnd:
|
|
484
|
-
},
|
|
485
|
-
}, u = Object.values(s.root.child ?? {}).map((
|
|
486
|
-
d !== void 0 &&
|
|
487
|
-
const
|
|
482
|
+
leafEnd: E
|
|
483
|
+
}, C;
|
|
484
|
+
}, u = Object.values(s.root.child ?? {}).map((g) => r(g, 1)), f = new Vt(l, u, c, s.totalLevels - 1, n), h = new Set(u.map((g) => l[g].file)), d = (x = ($ = s.root.data) == null ? void 0 : $.env) == null ? void 0 : x.name, w = d !== void 0 && i[d] !== void 0 ? { file: d } : void 0;
|
|
485
|
+
d !== void 0 && w === void 0 && z(`LCC2 root references env tile #${d}, which the manifest does not list.`), w && h.add(w.file);
|
|
486
|
+
const m = o >= 1 ? o : void 0;
|
|
488
487
|
return {
|
|
489
488
|
source: f,
|
|
490
489
|
chunkUrls: i,
|
|
@@ -494,24 +493,24 @@ function ue(e, t, n, o = 0) {
|
|
|
494
493
|
// `.sog` extension, so the chunk loader cannot sniff the parser from the URL.
|
|
495
494
|
chunkOptions: i.map(() => ({
|
|
496
495
|
format: "sog",
|
|
497
|
-
...
|
|
496
|
+
...m ? { sog: { packShBands: m } } : {}
|
|
498
497
|
})),
|
|
499
498
|
bounds: q(s.root.boundingBox),
|
|
500
499
|
pinnedFiles: h,
|
|
501
500
|
maxResidentSplats: s.lodSplats[0] ?? n.budget,
|
|
502
501
|
minimumCoverageSplats: Math.max(
|
|
503
502
|
1,
|
|
504
|
-
u.reduce((
|
|
503
|
+
u.reduce((g, y) => g + l[y].count, 0)
|
|
505
504
|
),
|
|
506
|
-
...
|
|
507
|
-
...
|
|
508
|
-
...
|
|
505
|
+
...Yt(s, t),
|
|
506
|
+
...w ? { environment: w } : {},
|
|
507
|
+
...m ? { shBands: m } : {},
|
|
509
508
|
// Match the established XGRIDS LCC and Spark viewer coordinate frame.
|
|
510
509
|
// Bounds remain source-local and matrixWorld handles the conversion.
|
|
511
510
|
formatTransform: H()
|
|
512
511
|
};
|
|
513
512
|
}
|
|
514
|
-
function
|
|
513
|
+
function Yt(e, t) {
|
|
515
514
|
const n = e.root.meshFiles;
|
|
516
515
|
if (!n || n.length === 0) return {};
|
|
517
516
|
const o = /* @__PURE__ */ new Map(), s = (c) => {
|
|
@@ -537,7 +536,7 @@ function kt(e, t) {
|
|
|
537
536
|
}
|
|
538
537
|
return l.length > 0 ? { collision: { meshes: l } } : {};
|
|
539
538
|
}
|
|
540
|
-
class
|
|
539
|
+
class Vt {
|
|
541
540
|
constructor(t, n, o, s, i) {
|
|
542
541
|
A(this, "budget");
|
|
543
542
|
A(this, "lodBaseDistance");
|
|
@@ -554,8 +553,8 @@ class Yt {
|
|
|
554
553
|
A(this, "changedAt");
|
|
555
554
|
/** Index into {@link rootChildren} of the subtree containing each cell. */
|
|
556
555
|
A(this, "cellRootChild");
|
|
557
|
-
A(this, "scratchBox", new
|
|
558
|
-
A(this, "scratchSize", new
|
|
556
|
+
A(this, "scratchBox", new S.Box3());
|
|
557
|
+
A(this, "scratchSize", new S.Vector3());
|
|
559
558
|
this.nodes = t, this.rootChildren = n, this.cellNodes = o, this.coarsest = s, this.budget = i.budget, this.lodBaseDistance = i.lodBaseDistance, this.lodMultiplier = i.lodMultiplier;
|
|
560
559
|
const l = o.length;
|
|
561
560
|
this.cellFinestLevel = new Int32Array(l), this.cellLevel = new Int32Array(l).fill(s), this.changedAt = new Float64Array(l);
|
|
@@ -571,8 +570,8 @@ class Yt {
|
|
|
571
570
|
let c = l.reduce((h, d) => h + d, 0);
|
|
572
571
|
const a = (h, d) => {
|
|
573
572
|
i[h] = i[h] + d;
|
|
574
|
-
const
|
|
575
|
-
c +=
|
|
573
|
+
const w = this.cellRootChild[h], m = this.subtreeCutTotal(this.rootChildren[w], i);
|
|
574
|
+
c += m - l[w], l[w] = m;
|
|
576
575
|
}, r = [...this.cellNodes.keys()].sort(
|
|
577
576
|
(h, d) => s[d] - s[h]
|
|
578
577
|
);
|
|
@@ -625,7 +624,7 @@ class Yt {
|
|
|
625
624
|
/** Finest-cell AABB expanded by {@link FRUSTUM_MARGIN}, written into scratch. */
|
|
626
625
|
expandCellBox(t) {
|
|
627
626
|
const n = this.nodes[this.cellNodes[t]];
|
|
628
|
-
return this.scratchBox.copy(n.bounds), n.bounds.getSize(this.scratchSize), this.scratchBox.expandByScalar(this.scratchSize.length() *
|
|
627
|
+
return this.scratchBox.copy(n.bounds), n.bounds.getSize(this.scratchSize), this.scratchBox.expandByScalar(this.scratchSize.length() * Ot), this.scratchBox;
|
|
629
628
|
}
|
|
630
629
|
cellIntersectsFrustum(t, n) {
|
|
631
630
|
return t.intersectsBox(this.expandCellBox(n));
|
|
@@ -633,7 +632,7 @@ class Yt {
|
|
|
633
632
|
/** Distance (frustum-penalized) to each finest cell's node bounds. */
|
|
634
633
|
cellDistanceOf(t, n, o) {
|
|
635
634
|
const i = this.nodes[this.cellNodes[o]].bounds.distanceToPoint(t);
|
|
636
|
-
return this.cellIntersectsFrustum(n, o) ? i : i *
|
|
635
|
+
return this.cellIntersectsFrustum(n, o) ? i : i * zt;
|
|
637
636
|
}
|
|
638
637
|
/** Advances each cell's dwelled level toward the distance target. */
|
|
639
638
|
updateCellLevels(t, n, o) {
|
|
@@ -643,9 +642,9 @@ class Yt {
|
|
|
643
642
|
l[c] = a;
|
|
644
643
|
const r = this.cellFinestLevel[c];
|
|
645
644
|
let u = Math.min(this.coarsest, Math.max(r, this.cellLevel[c]));
|
|
646
|
-
for (; u < this.coarsest && a > s * i ** u * (1 +
|
|
647
|
-
for (; u > r && a <= s * i ** (u - 1) * (1 -
|
|
648
|
-
u !== this.cellLevel[c] && o - this.changedAt[c] >=
|
|
645
|
+
for (; u < this.coarsest && a > s * i ** u * (1 + et); ) u++;
|
|
646
|
+
for (; u > r && a <= s * i ** (u - 1) * (1 - et); ) u--;
|
|
647
|
+
u !== this.cellLevel[c] && o - this.changedAt[c] >= kt && (this.cellLevel[c] = u, this.changedAt[c] = o);
|
|
649
648
|
}
|
|
650
649
|
return l;
|
|
651
650
|
}
|
|
@@ -693,19 +692,19 @@ function X(e) {
|
|
|
693
692
|
};
|
|
694
693
|
}
|
|
695
694
|
function q(e) {
|
|
696
|
-
return new
|
|
697
|
-
new
|
|
698
|
-
new
|
|
695
|
+
return new S.Box3(
|
|
696
|
+
new S.Vector3(e.min[0], e.min[1], e.min[2]),
|
|
697
|
+
new S.Vector3(e.max[0], e.max[1], e.max[2])
|
|
699
698
|
);
|
|
700
699
|
}
|
|
701
|
-
const
|
|
702
|
-
function
|
|
700
|
+
const nt = ["vertex_indices", "vertex_index"];
|
|
701
|
+
function Xt(e) {
|
|
703
702
|
const t = xt(e), n = t.element("vertex");
|
|
704
703
|
if (!n) throw new Error('Not a mesh PLY: no "vertex" element.');
|
|
705
|
-
|
|
706
|
-
const o =
|
|
704
|
+
bt(n, ["x", "y", "z"], ["float", "float32"], "Mesh PLY vertex"), Lt(n, e.byteLength);
|
|
705
|
+
const o = qt(e, n), s = t.element("face");
|
|
707
706
|
if (!s) throw new Error('Not a mesh PLY: no "face" element.');
|
|
708
|
-
const i =
|
|
707
|
+
const i = Ht(e, s, n.count);
|
|
709
708
|
return {
|
|
710
709
|
vertexCount: n.count,
|
|
711
710
|
triangleCount: i.length / 3,
|
|
@@ -713,15 +712,15 @@ function Vt(e) {
|
|
|
713
712
|
indices: i
|
|
714
713
|
};
|
|
715
714
|
}
|
|
716
|
-
function
|
|
717
|
-
const n = new DataView(e, t.offset), o =
|
|
715
|
+
function qt(e, t) {
|
|
716
|
+
const n = new DataView(e, t.offset), o = Y(t, "x"), s = Y(t, "y"), i = Y(t, "z"), l = new Float32Array(t.count * 3);
|
|
718
717
|
for (let c = 0; c < t.count; c++) {
|
|
719
718
|
const a = c * t.stride;
|
|
720
719
|
l[c * 3] = n.getFloat32(a + o, !0), l[c * 3 + 1] = n.getFloat32(a + s, !0), l[c * 3 + 2] = n.getFloat32(a + i, !0);
|
|
721
720
|
}
|
|
722
721
|
return l;
|
|
723
722
|
}
|
|
724
|
-
function
|
|
723
|
+
function Ht(e, t, n) {
|
|
725
724
|
if (t.count === 0) return new Uint32Array(0);
|
|
726
725
|
if (t.offset < 0)
|
|
727
726
|
throw new Error(
|
|
@@ -731,41 +730,41 @@ function qt(e, t, n) {
|
|
|
731
730
|
throw new Error(
|
|
732
731
|
'Unsupported mesh PLY: the "face" element mixes scalar properties with its index list.'
|
|
733
732
|
);
|
|
734
|
-
const o =
|
|
733
|
+
const o = nt.find((h) => t.listProperties.has(h)), s = o ? t.listProperties.get(o) : void 0;
|
|
735
734
|
if (!s)
|
|
736
735
|
throw new Error(
|
|
737
|
-
`Mesh PLY "face" element is missing an index list (${
|
|
736
|
+
`Mesh PLY "face" element is missing an index list (${nt.join(" or ")}).`
|
|
738
737
|
);
|
|
739
738
|
const i = j(s.countType), l = j(s.itemType), c = new DataView(e), a = e.byteLength;
|
|
740
739
|
let r = new Uint32Array(t.count * 3), u = 0, f = t.offset;
|
|
741
740
|
for (let h = 0; h < t.count; h++) {
|
|
742
|
-
if (f + i > a) throw new Error(
|
|
743
|
-
const d =
|
|
741
|
+
if (f + i > a) throw new Error(ot(h));
|
|
742
|
+
const d = st(c, f, s.countType, i);
|
|
744
743
|
if (d < 0)
|
|
745
744
|
throw new Error(`Mesh PLY face ${h} declares a negative vertex count (${d}).`);
|
|
746
|
-
if (f += i, f + d * l > a) throw new Error(
|
|
747
|
-
const
|
|
748
|
-
if (u +
|
|
749
|
-
const
|
|
750
|
-
|
|
745
|
+
if (f += i, f + d * l > a) throw new Error(ot(h));
|
|
746
|
+
const w = Math.max(0, d - 2);
|
|
747
|
+
if (u + w * 3 > r.length) {
|
|
748
|
+
const x = new Uint32Array(Math.max(r.length * 2, u + w * 3));
|
|
749
|
+
x.set(r.subarray(0, u)), r = x;
|
|
751
750
|
}
|
|
752
|
-
let
|
|
753
|
-
for (let
|
|
754
|
-
const
|
|
755
|
-
if (
|
|
751
|
+
let m = 0, $ = 0;
|
|
752
|
+
for (let x = 0; x < d; x++) {
|
|
753
|
+
const g = st(c, f + x * l, s.itemType, l);
|
|
754
|
+
if (g < 0 || g >= n)
|
|
756
755
|
throw new Error(
|
|
757
|
-
`Mesh PLY face ${h} references vertex ${
|
|
756
|
+
`Mesh PLY face ${h} references vertex ${g}, but the file has ${n}.`
|
|
758
757
|
);
|
|
759
|
-
|
|
758
|
+
x === 0 ? m = g : x >= 2 && (r[u++] = m, r[u++] = $, r[u++] = g), $ = g;
|
|
760
759
|
}
|
|
761
760
|
f += d * l;
|
|
762
761
|
}
|
|
763
762
|
return u === r.length ? r : r.slice(0, u);
|
|
764
763
|
}
|
|
765
|
-
function
|
|
764
|
+
function ot(e) {
|
|
766
765
|
return `Truncated PLY file: the "face" element ends inside face ${e}.`;
|
|
767
766
|
}
|
|
768
|
-
function
|
|
767
|
+
function st(e, t, n, o) {
|
|
769
768
|
switch (n) {
|
|
770
769
|
case "char":
|
|
771
770
|
case "int8":
|
|
@@ -789,31 +788,31 @@ function ot(e, t, n, o) {
|
|
|
789
788
|
throw new Error(`Unsupported PLY index type: "${n}" (${o} bytes).`);
|
|
790
789
|
}
|
|
791
790
|
}
|
|
792
|
-
const
|
|
793
|
-
function
|
|
791
|
+
const Gt = 1819045731, it = 2, D = 48, rt = 40, ht = 3, ft = 3, lt = ht * 4, Qt = ft * 4;
|
|
792
|
+
function Wt(e) {
|
|
794
793
|
if (e.byteLength < D)
|
|
795
794
|
throw new Error(
|
|
796
795
|
`collision.lci is truncated: ${e.byteLength} bytes, need at least ${D}.`
|
|
797
796
|
);
|
|
798
797
|
const t = new DataView(e), n = t.getUint32(0, !0);
|
|
799
|
-
if (n !==
|
|
798
|
+
if (n !== Gt)
|
|
800
799
|
throw new Error(
|
|
801
800
|
`Not a collision.lci: expected magic "coll", got 0x${n.toString(16).padStart(8, "0")}.`
|
|
802
801
|
);
|
|
803
802
|
const o = t.getUint32(4, !0);
|
|
804
|
-
if (o !==
|
|
803
|
+
if (o !== it)
|
|
805
804
|
throw new Error(
|
|
806
|
-
`Unsupported collision.lci version ${o} (expected ${
|
|
805
|
+
`Unsupported collision.lci version ${o} (expected ${it}).`
|
|
807
806
|
);
|
|
808
|
-
const s = t.getUint32(8, !0), i = new
|
|
807
|
+
const s = t.getUint32(8, !0), i = new S.Vector3(
|
|
809
808
|
t.getFloat32(12, !0),
|
|
810
809
|
t.getFloat32(16, !0),
|
|
811
810
|
t.getFloat32(20, !0)
|
|
812
|
-
), l = new
|
|
811
|
+
), l = new S.Vector3(
|
|
813
812
|
t.getFloat32(24, !0),
|
|
814
813
|
t.getFloat32(28, !0),
|
|
815
814
|
t.getFloat32(32, !0)
|
|
816
|
-
), c = t.getFloat32(36, !0), a = t.getFloat32(40, !0), r = t.getUint32(44, !0), u = D + r *
|
|
815
|
+
), c = t.getFloat32(36, !0), a = t.getFloat32(40, !0), r = t.getUint32(44, !0), u = D + r * rt;
|
|
817
816
|
if (s !== u)
|
|
818
817
|
throw new Error(
|
|
819
818
|
`collision.lci headerLen ${s} does not match ${r} mesh headers (expected ${u}).`
|
|
@@ -826,46 +825,46 @@ function Qt(e) {
|
|
|
826
825
|
throw new Error(
|
|
827
826
|
`collision.lci cell lengths must be positive (got ${c} × ${a}).`
|
|
828
827
|
);
|
|
829
|
-
const f = new
|
|
828
|
+
const f = new S.Box3(i.clone(), l.clone()), h = [];
|
|
830
829
|
let d = s;
|
|
831
|
-
for (let
|
|
832
|
-
const
|
|
833
|
-
if (!Number.isSafeInteger(
|
|
834
|
-
throw new Error(`collision.lci mesh ${
|
|
835
|
-
if (
|
|
830
|
+
for (let w = 0; w < r; w++) {
|
|
831
|
+
const m = D + w * rt, $ = t.getUint32(m, !0), x = t.getUint32(m + 4, !0), g = Number(t.getBigUint64(m + 8, !0)), y = Number(t.getBigUint64(m + 16, !0)), b = t.getUint32(m + 24, !0), C = t.getUint32(m + 28, !0), L = t.getUint32(m + 32, !0);
|
|
832
|
+
if (!Number.isSafeInteger(g) || !Number.isSafeInteger(y))
|
|
833
|
+
throw new Error(`collision.lci mesh ${w} has an unsafe data offset/size.`);
|
|
834
|
+
if (g !== d)
|
|
836
835
|
throw new Error(
|
|
837
|
-
`collision.lci mesh ${
|
|
836
|
+
`collision.lci mesh ${w} data offset ${g} is not contiguous (expected ${d}).`
|
|
838
837
|
);
|
|
839
|
-
if (
|
|
838
|
+
if (b * lt + C * Qt + L !== y)
|
|
840
839
|
throw new Error(
|
|
841
|
-
`collision.lci mesh ${
|
|
840
|
+
`collision.lci mesh ${w} size ${y} != ${b}*12 + ${C}*12 + BVH ${L}.`
|
|
842
841
|
);
|
|
843
|
-
const
|
|
844
|
-
if (
|
|
842
|
+
const v = g + y;
|
|
843
|
+
if (v > e.byteLength)
|
|
845
844
|
throw new Error(
|
|
846
|
-
`collision.lci mesh ${
|
|
845
|
+
`collision.lci mesh ${w} extends to byte ${v}, past file length ${e.byteLength}.`
|
|
847
846
|
);
|
|
848
|
-
const
|
|
849
|
-
for (let
|
|
850
|
-
const B =
|
|
851
|
-
if (B >=
|
|
847
|
+
const E = new Float32Array(e, g, b * ht), U = g + b * lt, F = new Uint32Array(e, U, C * ft);
|
|
848
|
+
for (let M = 0; M < F.length; M++) {
|
|
849
|
+
const B = F[M];
|
|
850
|
+
if (B >= b)
|
|
852
851
|
throw new Error(
|
|
853
|
-
`collision.lci mesh ${
|
|
852
|
+
`collision.lci mesh ${w} face index ${B} is out of range (vertexCount ${b}).`
|
|
854
853
|
);
|
|
855
854
|
}
|
|
856
855
|
h.push({
|
|
857
856
|
cellX: $,
|
|
858
|
-
cellY:
|
|
857
|
+
cellY: x,
|
|
859
858
|
data: {
|
|
860
|
-
vertexCount:
|
|
861
|
-
triangleCount:
|
|
859
|
+
vertexCount: b,
|
|
860
|
+
triangleCount: C,
|
|
862
861
|
// Copy so the returned arrays outlive a transferred/detached buffer
|
|
863
862
|
// and are not views into the BVH-adjacent region.
|
|
864
|
-
positions:
|
|
865
|
-
indices:
|
|
863
|
+
positions: E.slice(),
|
|
864
|
+
indices: F.slice()
|
|
866
865
|
},
|
|
867
|
-
bounds:
|
|
868
|
-
}), d =
|
|
866
|
+
bounds: jt($, x, c, a, f)
|
|
867
|
+
}), d = v;
|
|
869
868
|
}
|
|
870
869
|
if (d !== e.byteLength)
|
|
871
870
|
throw new Error(
|
|
@@ -879,21 +878,21 @@ function Qt(e) {
|
|
|
879
878
|
tiles: h
|
|
880
879
|
};
|
|
881
880
|
}
|
|
882
|
-
function
|
|
881
|
+
function jt(e, t, n, o, s) {
|
|
883
882
|
const i = s.min.x + e * n, l = s.min.y + t * o;
|
|
884
|
-
return new
|
|
885
|
-
new
|
|
886
|
-
new
|
|
883
|
+
return new S.Box3(
|
|
884
|
+
new S.Vector3(Math.min(i, s.max.x), Math.min(l, s.max.y), s.min.z),
|
|
885
|
+
new S.Vector3(
|
|
887
886
|
Math.min(i + n, s.max.x),
|
|
888
887
|
Math.min(l + o, s.max.y),
|
|
889
888
|
s.max.z
|
|
890
889
|
)
|
|
891
890
|
);
|
|
892
891
|
}
|
|
893
|
-
async function
|
|
892
|
+
async function fe(e, t = {}) {
|
|
894
893
|
var s;
|
|
895
894
|
const n = await Promise.allSettled(
|
|
896
|
-
e.meshes.map((i) =>
|
|
895
|
+
e.meshes.map((i) => Kt(i, t))
|
|
897
896
|
);
|
|
898
897
|
(s = t.signal) == null || s.throwIfAborted();
|
|
899
898
|
const o = [];
|
|
@@ -901,18 +900,18 @@ async function he(e, t = {}) {
|
|
|
901
900
|
i.status === "fulfilled" ? o.push(...i.value) : z("Skipping a collision mesh that failed to load:", i.reason);
|
|
902
901
|
return o;
|
|
903
902
|
}
|
|
904
|
-
async function
|
|
905
|
-
const n = await fetch(e.url,
|
|
903
|
+
async function Kt(e, t) {
|
|
904
|
+
const n = await fetch(e.url, at(t.request, t.signal));
|
|
906
905
|
if (!n.ok)
|
|
907
906
|
throw new Error(`HTTP ${n.status} for collision mesh ${e.url}`);
|
|
908
907
|
const o = await n.arrayBuffer();
|
|
909
|
-
if (
|
|
910
|
-
return
|
|
908
|
+
if (Zt(e.url))
|
|
909
|
+
return Wt(o).tiles.map((l) => ({
|
|
911
910
|
url: `${e.url}#c${l.cellX}_${l.cellY}`,
|
|
912
911
|
data: l.data,
|
|
913
912
|
bounds: l.bounds
|
|
914
913
|
}));
|
|
915
|
-
const s =
|
|
914
|
+
const s = Xt(o);
|
|
916
915
|
return [
|
|
917
916
|
{
|
|
918
917
|
url: e.url,
|
|
@@ -921,15 +920,15 @@ async function jt(e, t) {
|
|
|
921
920
|
}
|
|
922
921
|
];
|
|
923
922
|
}
|
|
924
|
-
function
|
|
923
|
+
function Zt(e) {
|
|
925
924
|
try {
|
|
926
925
|
return new URL(e, "https://example.invalid/").pathname.toLowerCase().endsWith(".lci");
|
|
927
926
|
} catch {
|
|
928
927
|
return e.toLowerCase().includes(".lci");
|
|
929
928
|
}
|
|
930
929
|
}
|
|
931
|
-
function
|
|
932
|
-
|
|
930
|
+
function de(e, t) {
|
|
931
|
+
Jt(e);
|
|
933
932
|
const { positions: n, indices: o, vertexCount: s, triangleCount: i } = e, l = new Uint8Array(s);
|
|
934
933
|
for (let r = 0; r < s; r++)
|
|
935
934
|
l[r] = t.containsPoint(
|
|
@@ -944,11 +943,11 @@ function fe(e, t) {
|
|
|
944
943
|
(l[u] === 1 || l[f] === 1 || l[h] === 1) && (c[r] = 1, a++);
|
|
945
944
|
}
|
|
946
945
|
return {
|
|
947
|
-
inside:
|
|
948
|
-
outside:
|
|
946
|
+
inside: ct(e, c, 1, a),
|
|
947
|
+
outside: ct(e, c, 0, i - a)
|
|
949
948
|
};
|
|
950
949
|
}
|
|
951
|
-
function
|
|
950
|
+
function Jt(e) {
|
|
952
951
|
if (e.positions.length < e.vertexCount * 3)
|
|
953
952
|
throw new Error(
|
|
954
953
|
`partitionTriangleMesh: positions hold ${e.positions.length} floats, too few for ${e.vertexCount} vertices.`
|
|
@@ -965,7 +964,7 @@ function Zt(e) {
|
|
|
965
964
|
);
|
|
966
965
|
}
|
|
967
966
|
}
|
|
968
|
-
function
|
|
967
|
+
function ct(e, t, n, o) {
|
|
969
968
|
const s = new Int32Array(e.vertexCount).fill(-1), i = new Uint32Array(o * 3);
|
|
970
969
|
let l = 0, c = 0;
|
|
971
970
|
for (let r = 0; r < e.triangleCount; r++)
|
|
@@ -983,16 +982,16 @@ function lt(e, t, n, o) {
|
|
|
983
982
|
return { vertexCount: l, triangleCount: o, positions: a, indices: i };
|
|
984
983
|
}
|
|
985
984
|
export {
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
985
|
+
ae as applyLcc2ToThreeTransform,
|
|
986
|
+
he as buildLcc2Scene,
|
|
987
|
+
ue as buildLccScene,
|
|
989
988
|
H as createLcc2ToThreeMatrix,
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
989
|
+
fe as loadCollisionMeshTiles,
|
|
990
|
+
Wt as parseCollisionLci,
|
|
991
|
+
ce as parseLccChunk,
|
|
992
|
+
Ft as parseLccIndex,
|
|
993
|
+
St as parseLccManifest,
|
|
994
|
+
Xt as parseMeshPly,
|
|
995
|
+
de as partitionTriangleMesh
|
|
997
996
|
};
|
|
998
997
|
//# sourceMappingURL=lcc.js.map
|