@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/streaming.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var d = (
|
|
4
|
-
import { h as Be, f as W, a as
|
|
1
|
+
var Fe = Object.defineProperty;
|
|
2
|
+
var Me = (l, i, e) => i in l ? Fe(l, i, { enumerable: !0, configurable: !0, writable: !0, value: e }) : l[i] = e;
|
|
3
|
+
var d = (l, i, e) => Me(l, typeof i != "symbol" ? i + "" : i, e);
|
|
4
|
+
import { h as Be, f as W, a as Pe, l as ke } from "./splat-budget-DuVZspPQ.js";
|
|
5
5
|
import * as w from "three/webgpu";
|
|
6
|
-
import { S as
|
|
7
|
-
import { L as We, r as C } from "./lod-scheduler-
|
|
8
|
-
import { S as q, t as ee, r as Ae, i as
|
|
9
|
-
import { y as Le } from "./relighting-
|
|
6
|
+
import { S as Ee, a as ie, y as xe } from "./splat-mesh-CsLOQb08.js";
|
|
7
|
+
import { L as We, r as C } from "./lod-scheduler-ChoZyEeq.js";
|
|
8
|
+
import { S as q, t as ee, r as Ae, i as D, a as _ } from "./loading-wLo8vRbA.js";
|
|
9
|
+
import { y as Le } from "./relighting-Tiwep8yd.js";
|
|
10
10
|
import { C as Ve } from "./chunk-loader-DlNwggfG.js";
|
|
11
|
-
import { s as
|
|
12
|
-
import { w as
|
|
13
|
-
import { r as
|
|
14
|
-
const
|
|
15
|
-
function _e(
|
|
16
|
-
return
|
|
11
|
+
import { s as Te } from "./sh-pack-D5wAe5gg.js";
|
|
12
|
+
import { w as E } from "./logging-BfPdd7NJ.js";
|
|
13
|
+
import { r as Ge, M as Ne, a as ne, i as j } from "./splat-mesh-types-BZIko-_9.js";
|
|
14
|
+
const De = 32e3;
|
|
15
|
+
function _e(l) {
|
|
16
|
+
return l.map((i) => ({
|
|
17
17
|
adds: [i],
|
|
18
18
|
removes: [],
|
|
19
19
|
leafStart: i.leafStart,
|
|
@@ -21,38 +21,38 @@ function _e(o) {
|
|
|
21
21
|
addCount: i.count
|
|
22
22
|
})).sort((i, e) => i.leafStart - e.leafStart);
|
|
23
23
|
}
|
|
24
|
-
function
|
|
25
|
-
const e = [...
|
|
24
|
+
function Oe(l, i) {
|
|
25
|
+
const e = [...l, ...i.map(([, n]) => n.run)];
|
|
26
26
|
if (e.length > 0 && e.every((n) => n.coverageGroup !== void 0)) {
|
|
27
|
-
const n = /* @__PURE__ */ new Map(),
|
|
28
|
-
let c = n.get(
|
|
29
|
-
return c || (c = { adds: [], removes: [] }, n.set(
|
|
27
|
+
const n = /* @__PURE__ */ new Map(), a = (r) => {
|
|
28
|
+
let c = n.get(r);
|
|
29
|
+
return c || (c = { adds: [], removes: [] }, n.set(r, c)), c;
|
|
30
30
|
};
|
|
31
|
-
for (const
|
|
32
|
-
r
|
|
33
|
-
for (const
|
|
34
|
-
r
|
|
35
|
-
const
|
|
36
|
-
for (const
|
|
37
|
-
const c = /* @__PURE__ */ new Map(),
|
|
38
|
-
const v = h
|
|
31
|
+
for (const r of l)
|
|
32
|
+
a(r.coverageGroup).adds.push(r);
|
|
33
|
+
for (const r of i)
|
|
34
|
+
a(r[1].run.coverageGroup).removes.push(r);
|
|
35
|
+
const o = [];
|
|
36
|
+
for (const r of n.values()) {
|
|
37
|
+
const c = /* @__PURE__ */ new Map(), u = (h, g) => `${h}:${g}`, f = (h, g) => {
|
|
38
|
+
const v = u(h, g);
|
|
39
39
|
let m = c.get(v);
|
|
40
|
-
return m || (m = { adds: [], removes: [], leafStart:
|
|
40
|
+
return m || (m = { adds: [], removes: [], leafStart: h, leafEnd: g, addCount: 0 }, c.set(v, m)), m;
|
|
41
41
|
};
|
|
42
|
-
for (const
|
|
43
|
-
const g = f(
|
|
44
|
-
g.adds.push(
|
|
42
|
+
for (const h of r.adds) {
|
|
43
|
+
const g = f(h.leafStart, h.leafEnd);
|
|
44
|
+
g.adds.push(h), g.addCount += h.count;
|
|
45
45
|
}
|
|
46
|
-
for (const
|
|
47
|
-
const g =
|
|
48
|
-
v.removes.push(
|
|
46
|
+
for (const h of r.removes) {
|
|
47
|
+
const g = h[1].run, v = f(g.leafStart, g.leafEnd);
|
|
48
|
+
v.removes.push(h), v.leafStart = Math.min(v.leafStart, g.leafStart), v.leafEnd = Math.max(v.leafEnd, g.leafEnd);
|
|
49
49
|
}
|
|
50
|
-
|
|
50
|
+
o.push(...c.values());
|
|
51
51
|
}
|
|
52
|
-
return
|
|
52
|
+
return o.sort((r, c) => r.leafStart - c.leafStart);
|
|
53
53
|
}
|
|
54
54
|
const t = [
|
|
55
|
-
...
|
|
55
|
+
...l.map((n) => ({
|
|
56
56
|
start: n.leafStart,
|
|
57
57
|
end: n.leafEnd,
|
|
58
58
|
add: n,
|
|
@@ -64,48 +64,48 @@ function ze(o, i) {
|
|
|
64
64
|
add: void 0,
|
|
65
65
|
remove: n
|
|
66
66
|
}))
|
|
67
|
-
].sort((n,
|
|
67
|
+
].sort((n, a) => n.start - a.start || a.end - n.end), s = [];
|
|
68
68
|
for (const n of t) {
|
|
69
|
-
const
|
|
70
|
-
(!
|
|
69
|
+
const a = s[s.length - 1];
|
|
70
|
+
(!a || n.start >= a.leafEnd) && s.push({
|
|
71
71
|
adds: [],
|
|
72
72
|
removes: [],
|
|
73
73
|
leafStart: n.start,
|
|
74
74
|
leafEnd: n.end,
|
|
75
75
|
addCount: 0
|
|
76
76
|
});
|
|
77
|
-
const
|
|
78
|
-
|
|
77
|
+
const o = s[s.length - 1];
|
|
78
|
+
o.leafEnd = Math.max(o.leafEnd, n.end), n.add && (o.adds.push(n.add), o.addCount += n.add.count), n.remove && o.removes.push(n.remove);
|
|
79
79
|
}
|
|
80
80
|
return s;
|
|
81
81
|
}
|
|
82
|
-
function
|
|
83
|
-
if (
|
|
84
|
-
const i = -Math.max(...
|
|
85
|
-
return
|
|
82
|
+
function ae(l) {
|
|
83
|
+
if (l.adds.length === 0) return 1e3;
|
|
84
|
+
const i = -Math.max(...l.adds.map((e) => e.level));
|
|
85
|
+
return l.removes.length === 0 ? -1e3 + i : i;
|
|
86
86
|
}
|
|
87
|
-
function
|
|
88
|
-
return
|
|
87
|
+
function ze(l) {
|
|
88
|
+
return l.length > 0 && l.every(
|
|
89
89
|
(i) => [...i.adds, ...i.removes.map(([, e]) => e.run)].every(
|
|
90
90
|
(e) => e.coverageGroup !== void 0
|
|
91
91
|
)
|
|
92
92
|
);
|
|
93
93
|
}
|
|
94
|
-
function Ue(
|
|
94
|
+
function Ue(l, i) {
|
|
95
95
|
const e = (n) => {
|
|
96
|
-
const
|
|
96
|
+
const a = [...n.adds, ...n.removes.map(([, o]) => o.run)];
|
|
97
97
|
return {
|
|
98
98
|
removeOnly: n.adds.length === 0 ? 1 : 0,
|
|
99
|
-
view:
|
|
100
|
-
finest: n.adds.some((
|
|
101
|
-
screen: Math.min(...
|
|
102
|
-
distance: Math.min(...
|
|
99
|
+
view: a.some((o) => o.inView !== !1) ? 0 : 1,
|
|
100
|
+
finest: n.adds.some((o) => o.level === 0) ? 0 : 1,
|
|
101
|
+
screen: Math.min(...a.map((o) => o.screenImportance ?? Number.POSITIVE_INFINITY)),
|
|
102
|
+
distance: Math.min(...a.map((o) => o.distance ?? Number.POSITIVE_INFINITY))
|
|
103
103
|
};
|
|
104
|
-
}, t = e(
|
|
105
|
-
return t.removeOnly - s.removeOnly || t.view - s.view || t.finest - s.finest || t.screen - s.screen || t.distance - s.distance ||
|
|
104
|
+
}, t = e(l), s = e(i);
|
|
105
|
+
return t.removeOnly - s.removeOnly || t.view - s.view || t.finest - s.finest || t.screen - s.screen || t.distance - s.distance || l.leafStart - i.leafStart;
|
|
106
106
|
}
|
|
107
|
-
function
|
|
108
|
-
switch (
|
|
107
|
+
function re(l) {
|
|
108
|
+
switch (l) {
|
|
109
109
|
case "environment":
|
|
110
110
|
return -1;
|
|
111
111
|
case "finest-target":
|
|
@@ -118,76 +118,76 @@ function ae(o) {
|
|
|
118
118
|
return 3;
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
-
function He(
|
|
122
|
-
return
|
|
121
|
+
function He(l) {
|
|
122
|
+
return l === "background" ? "base" : "priority";
|
|
123
123
|
}
|
|
124
|
-
function
|
|
125
|
-
return
|
|
124
|
+
function N(l, i) {
|
|
125
|
+
return l.coverageGroup < 0 ? `file:${i}` : l.phase === "finest-target" ? `cell:${l.coverageGroup}` : `slice:${l.coverageGroup}:${l.leafStart}:${l.leafEnd}`;
|
|
126
126
|
}
|
|
127
|
-
function $e(
|
|
127
|
+
function $e(l, i = 10, e = !1) {
|
|
128
128
|
const t = te(i), s = /* @__PURE__ */ new Map();
|
|
129
|
-
for (const [n,
|
|
130
|
-
if (
|
|
131
|
-
const
|
|
132
|
-
if (!
|
|
133
|
-
s.set(
|
|
134
|
-
distance:
|
|
129
|
+
for (const [n, a] of l) {
|
|
130
|
+
if (a.phase === "environment") continue;
|
|
131
|
+
const o = N(a, n), r = s.get(o);
|
|
132
|
+
if (!r) {
|
|
133
|
+
s.set(o, {
|
|
134
|
+
distance: a.distance,
|
|
135
135
|
count: 1,
|
|
136
|
-
inView:
|
|
137
|
-
screenImportance:
|
|
138
|
-
finest:
|
|
136
|
+
inView: a.inView,
|
|
137
|
+
screenImportance: a.screenImportance,
|
|
138
|
+
finest: a.phase === "finest-target"
|
|
139
139
|
});
|
|
140
140
|
continue;
|
|
141
141
|
}
|
|
142
|
-
|
|
142
|
+
a.distance < r.distance && (r.distance = a.distance), a.inView && (r.inView = !0), a.screenImportance < r.screenImportance && (r.screenImportance = a.screenImportance), a.phase === "finest-target" && (r.finest = !0), r.count++;
|
|
143
143
|
}
|
|
144
|
-
for (const [n,
|
|
145
|
-
if (
|
|
146
|
-
|
|
144
|
+
for (const [n, a] of l) {
|
|
145
|
+
if (a.phase === "environment") {
|
|
146
|
+
a.kind = "priority", a.groupDistance = 0, a.groupPending = 1, a.groupInView = !0, a.groupScreenImportance = Number.NEGATIVE_INFINITY, a.groupFinest = !0, a.groupId = "environment", a.groupClass = 0;
|
|
147
147
|
continue;
|
|
148
148
|
}
|
|
149
|
-
const
|
|
150
|
-
if (!
|
|
151
|
-
const c =
|
|
152
|
-
|
|
149
|
+
const o = N(a, n), r = s.get(o);
|
|
150
|
+
if (!r) continue;
|
|
151
|
+
const c = r.inView ? 0 : r.distance <= t ? 1 : 2, u = c === 0 || c === 1 && e ? "priority" : "base";
|
|
152
|
+
a.groupDistance = r.distance, a.groupPending = r.count, a.groupInView = r.inView, a.groupScreenImportance = r.screenImportance, a.groupFinest = r.finest, a.groupId = o, a.groupClass = c, a.kind = u;
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
|
-
function te(
|
|
156
|
-
return
|
|
155
|
+
function te(l, i = 2) {
|
|
156
|
+
return l;
|
|
157
157
|
}
|
|
158
|
-
function Ye(
|
|
159
|
-
return
|
|
158
|
+
function Ye(l) {
|
|
159
|
+
return l.adds.some((i) => i.level === 0);
|
|
160
160
|
}
|
|
161
|
-
function qe(
|
|
162
|
-
if (
|
|
163
|
-
const t =
|
|
164
|
-
return
|
|
161
|
+
function qe(l, i, e = 2) {
|
|
162
|
+
if (l.level === 0) return "finest-target";
|
|
163
|
+
const t = l.distance ?? Number.POSITIVE_INFINITY;
|
|
164
|
+
return l.inView === !1 && t > te(i) ? "background" : "target";
|
|
165
165
|
}
|
|
166
|
-
function je(
|
|
167
|
-
const t =
|
|
168
|
-
return
|
|
166
|
+
function je(l, i, e = 2) {
|
|
167
|
+
const t = l.distance ?? Number.POSITIVE_INFINITY;
|
|
168
|
+
return l.inView === !1 && t > te(i) ? "background" : "coverage";
|
|
169
169
|
}
|
|
170
|
-
function oe(
|
|
171
|
-
const s = t.distance ?? Number.POSITIVE_INFINITY, n = t.level,
|
|
172
|
-
if (!
|
|
173
|
-
const v =
|
|
174
|
-
{ phase: e, coverageGroup:
|
|
170
|
+
function oe(l, i, e, t) {
|
|
171
|
+
const s = t.distance ?? Number.POSITIVE_INFINITY, n = t.level, a = t.inView !== !1, o = t.coverageGroup ?? -1, r = t.screenImportance ?? Number.POSITIVE_INFINITY, c = He(e), u = l.get(i);
|
|
172
|
+
if (!u) {
|
|
173
|
+
const v = N(
|
|
174
|
+
{ phase: e, coverageGroup: o, leafStart: t.leafStart, leafEnd: t.leafEnd },
|
|
175
175
|
i
|
|
176
176
|
);
|
|
177
|
-
|
|
177
|
+
l.set(i, {
|
|
178
178
|
kind: c,
|
|
179
179
|
phase: e,
|
|
180
180
|
distance: s,
|
|
181
181
|
level: n,
|
|
182
|
-
inView:
|
|
183
|
-
coverageGroup:
|
|
182
|
+
inView: a,
|
|
183
|
+
coverageGroup: o,
|
|
184
184
|
leafStart: t.leafStart,
|
|
185
185
|
leafEnd: t.leafEnd,
|
|
186
|
-
screenImportance:
|
|
186
|
+
screenImportance: r,
|
|
187
187
|
groupDistance: s,
|
|
188
188
|
groupPending: 1,
|
|
189
|
-
groupInView:
|
|
190
|
-
groupScreenImportance:
|
|
189
|
+
groupInView: a,
|
|
190
|
+
groupScreenImportance: r,
|
|
191
191
|
groupFinest: e === "finest-target",
|
|
192
192
|
groupId: v,
|
|
193
193
|
// Provisional; finalized in stampClassicFetchGroups().
|
|
@@ -195,41 +195,41 @@ function oe(o, i, e, t) {
|
|
|
195
195
|
});
|
|
196
196
|
return;
|
|
197
197
|
}
|
|
198
|
-
const f =
|
|
199
|
-
(f ||
|
|
198
|
+
const f = re(e) < re(u.phase), h = e === u.phase && (s < u.distance || s === u.distance && n < u.level), g = e === u.phase && s === u.distance && n === u.level && a && !u.inView;
|
|
199
|
+
(f || h || g) && l.set(i, {
|
|
200
200
|
kind: c,
|
|
201
201
|
phase: e,
|
|
202
202
|
distance: s,
|
|
203
203
|
level: n,
|
|
204
|
-
inView:
|
|
205
|
-
coverageGroup:
|
|
204
|
+
inView: a || u.inView,
|
|
205
|
+
coverageGroup: o >= 0 ? o : u.coverageGroup,
|
|
206
206
|
leafStart: t.leafStart,
|
|
207
207
|
leafEnd: t.leafEnd,
|
|
208
|
-
screenImportance:
|
|
209
|
-
groupDistance: Math.min(s,
|
|
210
|
-
groupPending:
|
|
211
|
-
groupInView:
|
|
212
|
-
groupScreenImportance: Math.min(
|
|
213
|
-
groupFinest: e === "finest-target" ||
|
|
214
|
-
groupId:
|
|
215
|
-
groupClass:
|
|
208
|
+
screenImportance: r,
|
|
209
|
+
groupDistance: Math.min(s, u.groupDistance),
|
|
210
|
+
groupPending: u.groupPending,
|
|
211
|
+
groupInView: a || u.groupInView,
|
|
212
|
+
groupScreenImportance: Math.min(r, u.groupScreenImportance),
|
|
213
|
+
groupFinest: e === "finest-target" || u.groupFinest,
|
|
214
|
+
groupId: u.groupId,
|
|
215
|
+
groupClass: u.groupClass
|
|
216
216
|
});
|
|
217
217
|
}
|
|
218
|
-
function X(
|
|
219
|
-
const s =
|
|
220
|
-
return
|
|
218
|
+
function X(l, i, e, t) {
|
|
219
|
+
const s = l.groupDistance ?? l.distance, n = i.groupDistance ?? i.distance, a = l.groupPending ?? 1, o = i.groupPending ?? 1, r = l.groupId ?? N(l, e), c = i.groupId ?? N(i, t), u = l.groupClass ?? (l.inView ? 0 : 2), f = i.groupClass ?? (i.inView ? 0 : 2), h = l.groupScreenImportance ?? l.screenImportance, g = i.groupScreenImportance ?? i.screenImportance, v = l.groupFinest ? 0 : 1, m = i.groupFinest ? 0 : 1, b = (y) => y === "coverage" ? 0 : y === "background" ? 2 : 1, I = l.phase === "environment" ? 0 : 1, T = i.phase === "environment" ? 0 : 1;
|
|
220
|
+
return I - T || u - f || v - m || h - g || s - n || o - a || (r < c ? -1 : r > c ? 1 : 0) || b(l.phase) - b(i.phase) || l.level - i.level || e - t;
|
|
221
221
|
}
|
|
222
|
-
function K(
|
|
223
|
-
if (i < 0 || e < 0 || i + e >
|
|
222
|
+
function K(l, i, e) {
|
|
223
|
+
if (i < 0 || e < 0 || i + e > l.count)
|
|
224
224
|
throw new Error(
|
|
225
|
-
`Splat range [${i}, ${i + e}) exceeds its chunk's ${
|
|
225
|
+
`Splat range [${i}, ${i + e}) exceeds its chunk's ${l.count} splats; the manifest and chunk data disagree.`
|
|
226
226
|
);
|
|
227
|
-
const t =
|
|
227
|
+
const t = l.shPacked;
|
|
228
228
|
return {
|
|
229
229
|
count: e,
|
|
230
|
-
positions:
|
|
231
|
-
colors:
|
|
232
|
-
covariances:
|
|
230
|
+
positions: l.positions.subarray(i * 3, (i + e) * 3),
|
|
231
|
+
colors: l.colors.subarray(i * 4, (i + e) * 4),
|
|
232
|
+
covariances: l.covariances.subarray(i * 6, (i + e) * 6),
|
|
233
233
|
// Per-splat SH is splat-major, so it slices like everything else. Palette
|
|
234
234
|
// shN (`chunk.sh`) is deliberately not carried: its labels index a
|
|
235
235
|
// per-file codebook the shared pool has no way to hold.
|
|
@@ -244,30 +244,30 @@ function K(o, i, e) {
|
|
|
244
244
|
} : {},
|
|
245
245
|
// Per-splat frontier `parent_size` (foveated `.rad`) slices splat-major like
|
|
246
246
|
// the rest; uploaded into `covarianceB.w` by the pool.
|
|
247
|
-
...
|
|
247
|
+
...l.frontierParent ? { frontierParent: l.frontierParent.subarray(i, i + e) } : {}
|
|
248
248
|
};
|
|
249
249
|
}
|
|
250
|
-
function le(
|
|
251
|
-
return
|
|
250
|
+
function le(l) {
|
|
251
|
+
return l === 1 ? 3 : l === 2 ? 8 : 15;
|
|
252
252
|
}
|
|
253
|
-
function Xe(
|
|
253
|
+
function Xe(l) {
|
|
254
254
|
var i;
|
|
255
|
-
return
|
|
255
|
+
return l.positions.byteLength + l.colors.byteLength + l.covariances.byteLength + // SH is the largest part of an LCC Quality chunk (64 B/splat against the
|
|
256
256
|
// base 32); omitting it would let the CPU cache run ~3x over its cap.
|
|
257
|
-
(((i =
|
|
257
|
+
(((i = l.shPacked) == null ? void 0 : i.packed.byteLength) ?? 0);
|
|
258
258
|
}
|
|
259
|
-
function Ke(
|
|
260
|
-
const i =
|
|
259
|
+
function Ke(l) {
|
|
260
|
+
const i = l.reason;
|
|
261
261
|
return i instanceof Error ? i : new DOMException("Aborted", "AbortError");
|
|
262
262
|
}
|
|
263
|
-
function Qe(
|
|
264
|
-
const i =
|
|
263
|
+
function Qe(l) {
|
|
264
|
+
const i = l ?? De;
|
|
265
265
|
if (!Number.isInteger(i) || i <= 0)
|
|
266
266
|
throw new RangeError("StreamedSplatMesh maxSplatsPerSwap must be a positive integer.");
|
|
267
267
|
return i;
|
|
268
268
|
}
|
|
269
|
-
function ce(
|
|
270
|
-
const i =
|
|
269
|
+
function ce(l) {
|
|
270
|
+
const i = l ?? 1;
|
|
271
271
|
if (!Number.isFinite(i) || i <= 0)
|
|
272
272
|
throw new RangeError("StreamedSplatMesh lodScale must be a positive finite number.");
|
|
273
273
|
return i;
|
|
@@ -275,88 +275,88 @@ function ce(o) {
|
|
|
275
275
|
function Je() {
|
|
276
276
|
return Be();
|
|
277
277
|
}
|
|
278
|
-
function Ze(
|
|
279
|
-
const e =
|
|
278
|
+
function Ze(l, i) {
|
|
279
|
+
const e = l;
|
|
280
280
|
if (typeof e != "object" || e === null)
|
|
281
281
|
throw new Error("Streamed SOG manifest is not a JSON object.");
|
|
282
282
|
if (e.version !== 1)
|
|
283
283
|
throw new Error(`Unsupported Streamed SOG manifest version: ${e.version} (expected 1).`);
|
|
284
|
-
if (!Array.isArray(e.filenames) || e.filenames.some((
|
|
284
|
+
if (!Array.isArray(e.filenames) || e.filenames.some((r) => typeof r != "string"))
|
|
285
285
|
throw new Error('Streamed SOG manifest "filenames" must be an array of strings.');
|
|
286
|
-
if (!Array.isArray(e.counts) || e.counts.some((
|
|
286
|
+
if (!Array.isArray(e.counts) || e.counts.some((r) => !Number.isSafeInteger(r) || r < 0))
|
|
287
287
|
throw new Error('Streamed SOG manifest "counts" must be an array of non-negative integers.');
|
|
288
288
|
if (!Number.isSafeInteger(e.lodLevels) || e.lodLevels < 1 || e.lodLevels > 64)
|
|
289
289
|
throw new Error(`Streamed SOG manifest declares an invalid lodLevels: ${e.lodLevels}.`);
|
|
290
|
-
const t = e.filenames.map((
|
|
291
|
-
(
|
|
292
|
-
), n = [],
|
|
293
|
-
for (;
|
|
294
|
-
const
|
|
295
|
-
if (typeof
|
|
290
|
+
const t = e.filenames.map((r) => r.replace(/\/?meta\.json$/, "/")), s = t.map(
|
|
291
|
+
(r) => i.resolve(r) ?? `${i.manifestUrl}#${r}`
|
|
292
|
+
), n = [], a = e.lodLevels, o = [e.tree];
|
|
293
|
+
for (; o.length > 0; ) {
|
|
294
|
+
const r = o.pop();
|
|
295
|
+
if (typeof r != "object" || r === null)
|
|
296
296
|
throw new Error("Streamed SOG manifest tree contains a malformed node.");
|
|
297
|
-
if (
|
|
298
|
-
if (!Array.isArray(
|
|
297
|
+
if (r.children) {
|
|
298
|
+
if (!Array.isArray(r.children) || r.children.length !== 2)
|
|
299
299
|
throw new Error("Streamed SOG manifest tree node must have exactly two children.");
|
|
300
|
-
|
|
300
|
+
o.push(r.children[1], r.children[0]);
|
|
301
301
|
continue;
|
|
302
302
|
}
|
|
303
|
-
const c = new Array(
|
|
303
|
+
const c = new Array(a).fill(
|
|
304
304
|
void 0
|
|
305
305
|
);
|
|
306
|
-
for (const [
|
|
307
|
-
const
|
|
308
|
-
|
|
306
|
+
for (const [u, f] of Object.entries(r.lods ?? {})) {
|
|
307
|
+
const h = Number(u);
|
|
308
|
+
h >= 0 && h < a && (et(f, e.filenames.length), c[h] = f);
|
|
309
309
|
}
|
|
310
|
-
n.push({ bounds: he(
|
|
310
|
+
n.push({ bounds: he(r.bound), lods: c });
|
|
311
311
|
}
|
|
312
312
|
return {
|
|
313
313
|
leaves: n,
|
|
314
314
|
chunkUrls: s,
|
|
315
315
|
chunkDirectories: t,
|
|
316
316
|
counts: e.counts,
|
|
317
|
-
lodLevels:
|
|
317
|
+
lodLevels: a,
|
|
318
318
|
bounds: he(e.tree.bound)
|
|
319
319
|
};
|
|
320
320
|
}
|
|
321
|
-
function et(
|
|
322
|
-
if (typeof
|
|
321
|
+
function et(l, i) {
|
|
322
|
+
if (typeof l != "object" || l === null || !Number.isSafeInteger(l.file) || l.file < 0 || l.file >= i || !Number.isSafeInteger(l.offset) || l.offset < 0 || !Number.isSafeInteger(l.count) || l.count < 0)
|
|
323
323
|
throw new Error(
|
|
324
|
-
`Streamed SOG manifest leaf declares an invalid LOD range (file ${
|
|
324
|
+
`Streamed SOG manifest leaf declares an invalid LOD range (file ${l == null ? void 0 : l.file}, offset ${l == null ? void 0 : l.offset}, count ${l == null ? void 0 : l.count}).`
|
|
325
325
|
);
|
|
326
326
|
}
|
|
327
|
-
function he(
|
|
327
|
+
function he(l) {
|
|
328
328
|
return new w.Box3(
|
|
329
|
-
new w.Vector3(
|
|
330
|
-
new w.Vector3(
|
|
329
|
+
new w.Vector3(l.min[0], l.min[1], l.min[2]),
|
|
330
|
+
new w.Vector3(l.max[0], l.max[1], l.max[2])
|
|
331
331
|
);
|
|
332
332
|
}
|
|
333
|
-
function tt(
|
|
334
|
-
const s = Ze(
|
|
333
|
+
function tt(l, i, e, t = 0) {
|
|
334
|
+
const s = Ze(l, i), n = t >= 1 ? t : void 0, a = s.chunkUrls.map((o, r) => {
|
|
335
335
|
var f;
|
|
336
|
-
const c = (f = s.chunkDirectories) == null ? void 0 : f[
|
|
337
|
-
if (!(!
|
|
336
|
+
const c = (f = s.chunkDirectories) == null ? void 0 : f[r], u = c ? i.directoryFiles(c) : null;
|
|
337
|
+
if (!(!u && !n))
|
|
338
338
|
return {
|
|
339
339
|
format: "sog",
|
|
340
|
-
...
|
|
340
|
+
...u ? { files: u } : {},
|
|
341
341
|
...n ? { sog: { packShBands: n } } : {}
|
|
342
342
|
};
|
|
343
343
|
});
|
|
344
344
|
return {
|
|
345
345
|
source: new We(s, e),
|
|
346
346
|
chunkUrls: s.chunkUrls,
|
|
347
|
-
...
|
|
347
|
+
...a.some(Boolean) ? { chunkOptions: a } : {},
|
|
348
348
|
...n ? { shBands: n } : {},
|
|
349
349
|
chunkKind: "directory",
|
|
350
350
|
// Streamed SOG chunks are unbundled directories
|
|
351
351
|
bounds: s.bounds,
|
|
352
|
-
pinnedFiles:
|
|
352
|
+
pinnedFiles: it(s),
|
|
353
353
|
maxResidentSplats: s.counts[0] ?? e.budget,
|
|
354
|
-
minimumCoverageSplats:
|
|
354
|
+
minimumCoverageSplats: st(s)
|
|
355
355
|
};
|
|
356
356
|
}
|
|
357
|
-
function
|
|
357
|
+
function st(l) {
|
|
358
358
|
let i = 0;
|
|
359
|
-
for (const e of
|
|
359
|
+
for (const e of l.leaves)
|
|
360
360
|
for (let t = e.lods.length - 1; t >= 0; t--) {
|
|
361
361
|
const s = e.lods[t];
|
|
362
362
|
if (s) {
|
|
@@ -366,9 +366,9 @@ function it(o) {
|
|
|
366
366
|
}
|
|
367
367
|
return Math.max(1, i);
|
|
368
368
|
}
|
|
369
|
-
function
|
|
369
|
+
function it(l) {
|
|
370
370
|
const i = /* @__PURE__ */ new Set();
|
|
371
|
-
for (const e of
|
|
371
|
+
for (const e of l.leaves)
|
|
372
372
|
for (let t = e.lods.length - 1; t >= 0; t--) {
|
|
373
373
|
const s = e.lods[t];
|
|
374
374
|
if (s) {
|
|
@@ -378,20 +378,20 @@ function st(o) {
|
|
|
378
378
|
}
|
|
379
379
|
return i;
|
|
380
380
|
}
|
|
381
|
-
function nt(
|
|
381
|
+
function nt(l, i) {
|
|
382
382
|
return {
|
|
383
|
-
manifestUrl:
|
|
384
|
-
resolve: (e) => new URL(e,
|
|
385
|
-
size: (e) =>
|
|
383
|
+
manifestUrl: l,
|
|
384
|
+
resolve: (e) => new URL(e, l).href,
|
|
385
|
+
size: (e) => at(new URL(e, l).href, i),
|
|
386
386
|
directoryFiles: () => null,
|
|
387
387
|
dispose: () => {
|
|
388
388
|
}
|
|
389
389
|
};
|
|
390
390
|
}
|
|
391
|
-
async function
|
|
391
|
+
async function at(l, i) {
|
|
392
392
|
var e;
|
|
393
393
|
try {
|
|
394
|
-
const t = await fetch(
|
|
394
|
+
const t = await fetch(l, { ...ee(i), method: "HEAD" });
|
|
395
395
|
if (await ue(t), t.ok) {
|
|
396
396
|
const s = t.headers.get("content-length");
|
|
397
397
|
if (s !== null) return de(Number(s));
|
|
@@ -400,7 +400,7 @@ async function rt(o, i) {
|
|
|
400
400
|
} catch {
|
|
401
401
|
}
|
|
402
402
|
try {
|
|
403
|
-
const t = await fetch(
|
|
403
|
+
const t = await fetch(l, {
|
|
404
404
|
...ee(i),
|
|
405
405
|
headers: { ...(i == null ? void 0 : i.headers) ?? {}, Range: "bytes=0-0" }
|
|
406
406
|
});
|
|
@@ -411,29 +411,29 @@ async function rt(o, i) {
|
|
|
411
411
|
return null;
|
|
412
412
|
}
|
|
413
413
|
}
|
|
414
|
-
async function ue(
|
|
414
|
+
async function ue(l) {
|
|
415
415
|
var i;
|
|
416
416
|
try {
|
|
417
|
-
await ((i =
|
|
417
|
+
await ((i = l.body) == null ? void 0 : i.cancel());
|
|
418
418
|
} catch {
|
|
419
419
|
}
|
|
420
420
|
}
|
|
421
|
-
function de(
|
|
422
|
-
return Number.isSafeInteger(
|
|
421
|
+
function de(l) {
|
|
422
|
+
return Number.isSafeInteger(l) && l >= 0 ? l : null;
|
|
423
423
|
}
|
|
424
|
-
const
|
|
425
|
-
{ test: (
|
|
426
|
-
{ test: (
|
|
424
|
+
const rt = [
|
|
425
|
+
{ test: (l) => l.endsWith(".lcc2"), format: "lcc2" },
|
|
426
|
+
{ test: (l) => l.endsWith(".lcc"), format: "lcc" },
|
|
427
427
|
// The `.rad` header of a `--rad-chunked` set; `.radc` chunk files are not
|
|
428
428
|
// manifests (they end in `.radc`, so `endsWith('.rad')` excludes them).
|
|
429
|
-
{ test: (
|
|
430
|
-
{ test: (
|
|
429
|
+
{ test: (l) => l.endsWith(".rad"), format: "rad" },
|
|
430
|
+
{ test: (l) => l === "lod-meta.json", format: "streamed-sog" }
|
|
431
431
|
];
|
|
432
|
-
function ot(
|
|
432
|
+
function ot(l) {
|
|
433
433
|
const i = [];
|
|
434
|
-
for (const
|
|
435
|
-
const
|
|
436
|
-
c && Re(
|
|
434
|
+
for (const o of l.keys()) {
|
|
435
|
+
const r = $(o).toLowerCase(), c = rt.find((u) => u.test(r));
|
|
436
|
+
c && Re(o) === lt(l, c) && i.push({ path: o, format: c.format });
|
|
437
437
|
}
|
|
438
438
|
if (i.length === 0)
|
|
439
439
|
throw new q(
|
|
@@ -441,54 +441,54 @@ function ot(o) {
|
|
|
441
441
|
{ phase: "manifest", url: "local-folder", retryable: !1 }
|
|
442
442
|
);
|
|
443
443
|
if (i.length > 1) {
|
|
444
|
-
const
|
|
444
|
+
const o = i.map((r) => $(r.path)).join(", ");
|
|
445
445
|
throw new q(
|
|
446
|
-
`That folder holds more than one scene manifest (${
|
|
446
|
+
`That folder holds more than one scene manifest (${o}) - drop one scene at a time.`,
|
|
447
447
|
{ phase: "manifest", url: "local-folder", retryable: !1 }
|
|
448
448
|
);
|
|
449
449
|
}
|
|
450
|
-
const e = i[0], t = e.path.includes("/") ? e.path.slice(0, e.path.lastIndexOf("/") + 1) : "", s = /* @__PURE__ */ new Map(), n = (
|
|
451
|
-
const
|
|
452
|
-
if (
|
|
453
|
-
const c =
|
|
450
|
+
const e = i[0], t = e.path.includes("/") ? e.path.slice(0, e.path.lastIndexOf("/") + 1) : "", s = /* @__PURE__ */ new Map(), n = (o) => {
|
|
451
|
+
const r = s.get(o);
|
|
452
|
+
if (r !== void 0) return r;
|
|
453
|
+
const c = l.get(o);
|
|
454
454
|
if (!c) return null;
|
|
455
|
-
const
|
|
456
|
-
return s.set(
|
|
455
|
+
const u = URL.createObjectURL(c);
|
|
456
|
+
return s.set(o, u), u;
|
|
457
457
|
};
|
|
458
458
|
return { source: {
|
|
459
459
|
manifestUrl: n(e.path),
|
|
460
|
-
resolve: (
|
|
461
|
-
size: (
|
|
462
|
-
var
|
|
463
|
-
return Promise.resolve(((
|
|
460
|
+
resolve: (o) => n(t + Q(o)),
|
|
461
|
+
size: (o) => {
|
|
462
|
+
var r;
|
|
463
|
+
return Promise.resolve(((r = l.get(t + Q(o))) == null ? void 0 : r.size) ?? null);
|
|
464
464
|
},
|
|
465
|
-
directoryFiles: (
|
|
466
|
-
const
|
|
467
|
-
for (const
|
|
468
|
-
if (!
|
|
469
|
-
const f = n(
|
|
470
|
-
f && (c[
|
|
465
|
+
directoryFiles: (o) => {
|
|
466
|
+
const r = t + Q(o).replace(/\/?$/, "/"), c = {};
|
|
467
|
+
for (const u of l.keys()) {
|
|
468
|
+
if (!u.startsWith(r)) continue;
|
|
469
|
+
const f = n(u);
|
|
470
|
+
f && (c[u.slice(r.length)] = f);
|
|
471
471
|
}
|
|
472
472
|
return Object.keys(c).length > 0 ? c : null;
|
|
473
473
|
},
|
|
474
474
|
dispose: () => {
|
|
475
|
-
for (const
|
|
475
|
+
for (const o of s.values()) URL.revokeObjectURL(o);
|
|
476
476
|
s.clear();
|
|
477
477
|
}
|
|
478
478
|
}, format: e.format, name: $(e.path) };
|
|
479
479
|
}
|
|
480
|
-
function Q(
|
|
481
|
-
return
|
|
480
|
+
function Q(l) {
|
|
481
|
+
return l.replace(/^\.?\//, "");
|
|
482
482
|
}
|
|
483
|
-
function $(
|
|
484
|
-
return
|
|
483
|
+
function $(l) {
|
|
484
|
+
return l.slice(l.lastIndexOf("/") + 1);
|
|
485
485
|
}
|
|
486
|
-
function Re(
|
|
487
|
-
return
|
|
486
|
+
function Re(l) {
|
|
487
|
+
return l.split("/").length - 1;
|
|
488
488
|
}
|
|
489
|
-
function lt(
|
|
489
|
+
function lt(l, i) {
|
|
490
490
|
let e = 1 / 0;
|
|
491
|
-
for (const t of
|
|
491
|
+
for (const t of l.keys())
|
|
492
492
|
i.test($(t).toLowerCase()) && (e = Math.min(e, Re(t)));
|
|
493
493
|
return e;
|
|
494
494
|
}
|
|
@@ -497,14 +497,14 @@ const fe = {
|
|
|
497
497
|
coneFov: 120,
|
|
498
498
|
coneFoveate: 0.4,
|
|
499
499
|
behindFoveate: 0.2
|
|
500
|
-
},
|
|
501
|
-
function bt(
|
|
502
|
-
const i = 52 + (
|
|
500
|
+
}, B = 2048, ct = 6e4, ht = 0.25, ut = 8, dt = 600, ft = 250, gt = 4, pt = 500, mt = 3, vt = 4e6, ge = 65536, St = 2 * 1024 * 1024 * 1024;
|
|
501
|
+
function bt(l) {
|
|
502
|
+
const i = 52 + (l.shBands ? 16 * Math.ceil(Te(l.shBands) / 4) : 0), t = (l.chunkSize === void 0 ? void 0 : l.chunkSize * l.chunkUrls.length) ?? l.contentSplatCount ?? l.maxResidentSplats;
|
|
503
503
|
return Math.max(1, t) * i;
|
|
504
504
|
}
|
|
505
|
-
class Y extends
|
|
506
|
-
constructor(e, t, s, n,
|
|
507
|
-
var
|
|
505
|
+
class Y extends Ee {
|
|
506
|
+
constructor(e, t, s, n, a, o = !1) {
|
|
507
|
+
var h, g, v;
|
|
508
508
|
super({ capacity: s }, n);
|
|
509
509
|
d(this, "scene");
|
|
510
510
|
d(this, "loader", new Ve());
|
|
@@ -647,6 +647,15 @@ class Y extends Pe {
|
|
|
647
647
|
/** Last frontier's drawn (non-degenerate) splat count - the true on-screen size
|
|
648
648
|
* in `page-table` mode, where the slab is fully "active" but mostly degenerate. */
|
|
649
649
|
d(this, "pageTableDrawn", 0);
|
|
650
|
+
d(this, "frontierConverged", !0);
|
|
651
|
+
d(this, "pendingFrontierSplats", 0);
|
|
652
|
+
d(this, "staleResidentSplats", 0);
|
|
653
|
+
d(this, "lastPlanAppends", 0);
|
|
654
|
+
d(this, "lastPlanMoves", 0);
|
|
655
|
+
d(this, "lastPlanGeneration", 0);
|
|
656
|
+
d(this, "lastPlanBudget", 0);
|
|
657
|
+
d(this, "lastPlanCamera", null);
|
|
658
|
+
d(this, "firstFrontierCamera", null);
|
|
650
659
|
/** Monotonic reschedule id; a stale plan (superseded by a newer request) is
|
|
651
660
|
* dropped. `pageTableInFlight` coalesces to one outstanding traversal. */
|
|
652
661
|
d(this, "pageTableSeq", 0);
|
|
@@ -658,7 +667,7 @@ class Y extends Pe {
|
|
|
658
667
|
* These outrank the background sweep - they are the detail actually on screen. */
|
|
659
668
|
d(this, "pageTableFetchPriority", []);
|
|
660
669
|
/** Frontier-cut target node size (px) and foveation ramp; see `frontierView`. */
|
|
661
|
-
d(this, "pageTableTargetPx",
|
|
670
|
+
d(this, "pageTableTargetPx", ie);
|
|
662
671
|
d(this, "pageTableFoveation", fe);
|
|
663
672
|
/** Drawing-buffer height, sampled in `update` so `reschedule` can derive the
|
|
664
673
|
* cut limit the same way the material does (`targetPx / focalY`). */
|
|
@@ -713,15 +722,15 @@ class Y extends Pe {
|
|
|
713
722
|
d(this, "coverageScratch");
|
|
714
723
|
d(this, "lastCameraPos", new w.Vector3(1 / 0, 1 / 0, 1 / 0));
|
|
715
724
|
d(this, "lastCameraQuat", new w.Quaternion());
|
|
716
|
-
this.scene = e, this.budgetValue = t, this.maximumBudget = n.maxBudget === void 0 ? t : Math.max(t, W(n.maxBudget)), this.lodScaleValue = ce(n.lodScale), this.stagedSwapsEnabled = n.experimentalStagedSwaps !== !1, this.neverRetireCoverageEarly =
|
|
717
|
-
const
|
|
718
|
-
|
|
725
|
+
this.scene = e, this.budgetValue = t, this.maximumBudget = n.maxBudget === void 0 ? t : Math.max(t, W(n.maxBudget)), this.lodScaleValue = ce(n.lodScale), this.stagedSwapsEnabled = n.experimentalStagedSwaps !== !1, this.neverRetireCoverageEarly = o, this.appendCap = Qe(n.maxSplatsPerSwap);
|
|
726
|
+
const r = n.initialReveal === "hold-coverage" && this.scene.source.coverageRunsFor !== void 0, c = n.initialReveal === "hold-near-l0" && o;
|
|
727
|
+
r || c ? (this.initialRevealHold = r ? "hold-coverage" : "hold-near-l0", this.initialRevealPhase = "capture", this.initialRevealStateValue = {
|
|
719
728
|
status: "pending",
|
|
720
729
|
stagedSplats: 0,
|
|
721
730
|
totalSplats: 0,
|
|
722
731
|
readyGroups: 0,
|
|
723
732
|
totalGroups: 0
|
|
724
|
-
}) : (this.initialRevealHold = "off", this.initialRevealPhase = "off", this.initialRevealStateValue = { status: "disabled" }), this.onPerformanceEvent = n.onPerformanceEvent, this.cpuCacheBytes = n.cpuCacheBytes ?? Je(), this.requestOptions = n.request, this.envFile = (
|
|
733
|
+
}) : (this.initialRevealHold = "off", this.initialRevealPhase = "off", this.initialRevealStateValue = { status: "disabled" }), this.onPerformanceEvent = n.onPerformanceEvent, this.cpuCacheBytes = n.cpuCacheBytes ?? Je(), this.requestOptions = n.request, this.envFile = (h = e.environment) == null ? void 0 : h.file, this.envEnabled = n.environmentEnabled !== !1, this.fetchWeight = n.fetchWeight, this.fetchScheduler = n.fetchScheduler, this.cacheBudget = n.cacheBudget, this.fetchHandle = (g = this.fetchScheduler) == null ? void 0 : g.register({
|
|
725
734
|
// No weight supplied: claim an equal share rather than none, so a partly
|
|
726
735
|
// wired host degrades to round-robin instead of silently starving.
|
|
727
736
|
weight: () => {
|
|
@@ -733,7 +742,7 @@ class Y extends Pe {
|
|
|
733
742
|
},
|
|
734
743
|
shedFetches: (m) => this.abortFetches(m)
|
|
735
744
|
});
|
|
736
|
-
const
|
|
745
|
+
const u = j(n.foveationMode), f = u ? Math.max(
|
|
737
746
|
this.cpuCacheBytes,
|
|
738
747
|
Math.min(St, bt(e))
|
|
739
748
|
) : this.cpuCacheBytes;
|
|
@@ -748,13 +757,13 @@ class Y extends Pe {
|
|
|
748
757
|
},
|
|
749
758
|
ceilingBytes: f,
|
|
750
759
|
onAllowanceChanged: (m) => this.applyCacheAllowance(m)
|
|
751
|
-
}), this.cacheLimitBytes = this.cacheBudget && this.cacheBudgetHandle ? this.cacheBudget.allowanceFor(this.cacheBudgetHandle) : f,
|
|
752
|
-
if (!
|
|
760
|
+
}), this.cacheLimitBytes = this.cacheBudget && this.cacheBudgetHandle ? this.cacheBudget.allowanceFor(this.cacheBudgetHandle) : f, u || (this.cpuCacheBytes = this.cacheLimitBytes), this.fetchCountsValue.cacheLimitBytes = this.cacheLimitBytes, j(n.foveationMode)) {
|
|
761
|
+
if (!a)
|
|
753
762
|
throw new Error("StreamedSplatMesh: page-table foveation requires the frontier worker.");
|
|
754
|
-
this.pageTableDrawTarget = n.foveationDrawBudget ?? vt, this.pageTableDrawTargetExplicit = n.foveationDrawBudget !== void 0, this.pageTableDrawBudget = Math.min(t, this.pageTableDrawTarget), this.pageTableTargetPx = n.foveationTargetPx ??
|
|
763
|
+
this.pageTableDrawTarget = n.foveationDrawBudget ?? vt, this.pageTableDrawTargetExplicit = n.foveationDrawBudget !== void 0, this.pageTableDrawBudget = Math.min(t, this.pageTableDrawTarget), this.pageTableTargetPx = n.foveationTargetPx ?? ie, this.pageTableFoveation = { ...fe, ...n.frontierFoveation }, (n.minSplatScreenRadius !== void 0 || n.maxSplatScreenRadius !== void 0) && (this.frontierBandBase = {
|
|
755
764
|
min: n.minSplatScreenRadius ?? 0,
|
|
756
765
|
max: n.maxSplatScreenRadius ?? 0
|
|
757
|
-
}), this.slabPageSplats = Math.min(ge, s), this.slabCeiling = s, this.syncSlabPages(this.pageTableDrawBudget), this.frontierWorker = new
|
|
766
|
+
}), this.slabPageSplats = Math.min(ge, s), this.slabCeiling = s, this.syncSlabPages(this.pageTableDrawBudget), this.frontierWorker = new a(), this.frontierWorker.onmessage = (b) => this.applyFrontierPlan(b.data), this.pagerSlots = this.slabSlots, this.postToWorker({
|
|
758
767
|
type: "init",
|
|
759
768
|
capacity: this.pagerSlots,
|
|
760
769
|
chunkSize: e.chunkSize ?? 65536,
|
|
@@ -781,10 +790,10 @@ class Y extends Pe {
|
|
|
781
790
|
* failure, or a `DOMException` named `AbortError` when `options.signal` fires.
|
|
782
791
|
*/
|
|
783
792
|
static async load(e, t = {}) {
|
|
784
|
-
const s = Ae(e, t.baseUrl).href, n = s.toLowerCase(),
|
|
793
|
+
const s = Ae(e, t.baseUrl).href, n = s.toLowerCase(), a = t.format !== void 0 && t.format !== "auto" ? t.format : n.endsWith(".lcc2") ? "lcc2" : n.endsWith(".lcc") ? "lcc" : n.endsWith(".rad") ? "rad" : "streamed-sog";
|
|
785
794
|
return Y.fromSource(
|
|
786
795
|
nt(s, t.request),
|
|
787
|
-
|
|
796
|
+
a,
|
|
788
797
|
t
|
|
789
798
|
);
|
|
790
799
|
}
|
|
@@ -823,34 +832,34 @@ class Y extends Pe {
|
|
|
823
832
|
}
|
|
824
833
|
/** Shared load path: fetch the manifest from a source, then build the scene. */
|
|
825
834
|
static async fromSource(e, t, s) {
|
|
826
|
-
const n = s.deviceProfile,
|
|
835
|
+
const n = s.deviceProfile, a = W(s.budget, n, {
|
|
827
836
|
format: t,
|
|
828
837
|
...s.budgetCap === void 0 ? {} : { cap: s.budgetCap }
|
|
829
|
-
}),
|
|
830
|
-
if (
|
|
838
|
+
}), o = s.maxBudget === void 0 ? a : W(s.maxBudget, n);
|
|
839
|
+
if (o < a)
|
|
831
840
|
throw new RangeError(
|
|
832
|
-
`StreamedSplatMesh: maxBudget (${
|
|
841
|
+
`StreamedSplatMesh: maxBudget (${o}) must be >= budget (${a}).`
|
|
833
842
|
);
|
|
834
|
-
const
|
|
835
|
-
budget:
|
|
843
|
+
const r = {
|
|
844
|
+
budget: o,
|
|
836
845
|
lodBaseDistance: s.lodBaseDistance ?? 10,
|
|
837
846
|
lodMultiplier: s.lodMultiplier ?? 2
|
|
838
|
-
}, c = s.shBands ?? (
|
|
839
|
-
|
|
847
|
+
}, c = s.shBands ?? (Ge(s.performanceProfile, n) === "smooth" ? 0 : Ne), u = Pe(n), f = (s.allowFinestLevelLift === !0 || s.budget === void 0 && s.maxBudget === void 0) && s.budgetCap === void 0, h = s.signal;
|
|
848
|
+
h == null || h.throwIfAborted();
|
|
840
849
|
let g;
|
|
841
850
|
if (t === "rad")
|
|
842
851
|
try {
|
|
843
852
|
const { buildRadScene: p } = await import("./formats/rad.js");
|
|
844
|
-
g = await p(e,
|
|
853
|
+
g = await p(e, r, s.request, c, f);
|
|
845
854
|
} catch (p) {
|
|
846
|
-
throw
|
|
855
|
+
throw D(p) ? p : _(p, { phase: "manifest", url: e.manifestUrl });
|
|
847
856
|
}
|
|
848
857
|
else {
|
|
849
858
|
let p;
|
|
850
859
|
try {
|
|
851
|
-
p = await fetch(e.manifestUrl, ee(s.request,
|
|
860
|
+
p = await fetch(e.manifestUrl, ee(s.request, h));
|
|
852
861
|
} catch (S) {
|
|
853
|
-
throw
|
|
862
|
+
throw D(S) ? S : _(S, { phase: "fetch", url: e.manifestUrl });
|
|
854
863
|
}
|
|
855
864
|
if (!p.ok)
|
|
856
865
|
throw _(
|
|
@@ -860,45 +869,44 @@ class Y extends Pe {
|
|
|
860
869
|
try {
|
|
861
870
|
const S = await p.json();
|
|
862
871
|
if (t === "lcc2") {
|
|
863
|
-
const { buildLcc2Scene:
|
|
864
|
-
g =
|
|
872
|
+
const { buildLcc2Scene: F } = await import("./formats/lcc.js");
|
|
873
|
+
g = F(S, e, r, s.shBands ?? 0);
|
|
865
874
|
} else if (t === "lcc") {
|
|
866
|
-
const { buildLccScene:
|
|
867
|
-
g = await
|
|
875
|
+
const { buildLccScene: F } = await import("./formats/lcc.js");
|
|
876
|
+
g = await F(S, e, { ...r, shBands: c });
|
|
868
877
|
} else
|
|
869
|
-
g = tt(S, e,
|
|
878
|
+
g = tt(S, e, r, s.shBands ?? 0);
|
|
870
879
|
} catch (S) {
|
|
871
|
-
throw
|
|
880
|
+
throw D(S) ? S : _(S, { phase: "manifest", url: e.manifestUrl });
|
|
872
881
|
}
|
|
873
882
|
}
|
|
874
|
-
|
|
875
|
-
const v = (t === "lcc" || t === "rad") && f ? ke(
|
|
883
|
+
h == null || h.throwIfAborted();
|
|
884
|
+
const v = (t === "lcc" || t === "rad") && f ? ke(o, g.maxResidentSplats, n) : o, m = s.maxBudget === void 0 ? v : Math.min(a, v);
|
|
876
885
|
g.source.budget = m;
|
|
877
|
-
const b = Math.min(v, g.maxResidentSplats),
|
|
886
|
+
const b = Math.min(v, g.maxResidentSplats), I = s.experimentalStagedSwaps !== !1 ? 1.5 : 1.4, T = Math.max(
|
|
878
887
|
1,
|
|
879
|
-
Math.ceil(b *
|
|
888
|
+
Math.ceil(b * I / B)
|
|
880
889
|
), y = g.foveation ? ne(
|
|
881
890
|
s.foveationMode,
|
|
882
891
|
t === "rad" ? "page-table" : "frontier"
|
|
883
892
|
) : s.foveationMode === void 0 ? void 0 : ne(s.foveationMode);
|
|
884
893
|
let A;
|
|
885
894
|
if (j(y)) {
|
|
886
|
-
A = (await import("./frontier-worker-CAnK_Cmu.js")).default,
|
|
895
|
+
A = (await import("./frontier-worker-CAnK_Cmu.js")).default, h == null || h.throwIfAborted();
|
|
887
896
|
const S = g.source;
|
|
888
897
|
S.needsParentSizes !== void 0 && (S.needsParentSizes = !1);
|
|
889
898
|
}
|
|
890
899
|
const R = new Y(
|
|
891
900
|
g,
|
|
892
901
|
m,
|
|
893
|
-
|
|
902
|
+
T * B,
|
|
894
903
|
{
|
|
895
904
|
...s,
|
|
896
|
-
// Classic
|
|
897
|
-
//
|
|
898
|
-
//
|
|
899
|
-
//
|
|
900
|
-
...t === "lcc" && s.initialReveal === void 0 ? { initialReveal: "hold-
|
|
901
|
-
...t === "lcc2" && s.initialReveal === void 0 ? { initialReveal: "hold-coverage" } : {},
|
|
905
|
+
// Classic `.lcc` and `.lcc2` wait for in-view coverage so first paint
|
|
906
|
+
// has no empty cells (classic nearby cells at L1, farther at coarsest).
|
|
907
|
+
// Keep every other format progressive, and let a caller explicitly
|
|
908
|
+
// request progressive or hold-near-l0.
|
|
909
|
+
...(t === "lcc" || t === "lcc2") && s.initialReveal === void 0 ? { initialReveal: "hold-coverage" } : {},
|
|
902
910
|
// The resolved ceiling, not the caller's raw option: it may have been
|
|
903
911
|
// lifted to a moderate capture's leaf count above.
|
|
904
912
|
maxBudget: v,
|
|
@@ -927,7 +935,7 @@ class Y extends Pe {
|
|
|
927
935
|
// `maxStdDev` still wins, through `...options` above.
|
|
928
936
|
...t === "rad" ? {
|
|
929
937
|
lodAlpha: s.lodAlpha ?? !0,
|
|
930
|
-
...s.maxStdDev === void 0 &&
|
|
938
|
+
...s.maxStdDev === void 0 && u !== void 0 ? { maxStdDev: u } : {}
|
|
931
939
|
} : {},
|
|
932
940
|
// A foveated scene renders whole chunks and picks the LOD cut per splat.
|
|
933
941
|
// `.rad` defaults to Spark's selected-index page table (only the frontier is
|
|
@@ -943,7 +951,7 @@ class Y extends Pe {
|
|
|
943
951
|
A,
|
|
944
952
|
t === "lcc"
|
|
945
953
|
), L = g.formatTransform ?? (R.orientation === "y-up" ? xe(t) : null);
|
|
946
|
-
return L && (R.matrix.copy(L), R.matrix.decompose(R.position, R.quaternion, R.scale), R.matrixWorldNeedsUpdate = !0),
|
|
954
|
+
return L && (R.matrix.copy(L), R.matrix.decompose(R.position, R.quaternion, R.scale), R.matrixWorldNeedsUpdate = !0), h != null && h.aborted && (R.dispose(), h.throwIfAborted()), R;
|
|
947
955
|
}
|
|
948
956
|
/** Slots the currently reserved pages can hold. */
|
|
949
957
|
get slabSlots() {
|
|
@@ -991,10 +999,10 @@ class Y extends Pe {
|
|
|
991
999
|
writeSlabSlots(e, t, s) {
|
|
992
1000
|
let n = 0;
|
|
993
1001
|
for (; n < s; ) {
|
|
994
|
-
const
|
|
995
|
-
if (!
|
|
996
|
-
const
|
|
997
|
-
this.overwriteRangeData(
|
|
1002
|
+
const a = t + n, o = this.slabPages[Math.floor(a / this.slabPageSplats)];
|
|
1003
|
+
if (!o) return;
|
|
1004
|
+
const r = a % this.slabPageSplats, c = Math.min(s - n, this.slabPageSplats - r);
|
|
1005
|
+
this.overwriteRangeData(o, K(e, n, c), r), n += c;
|
|
998
1006
|
}
|
|
999
1007
|
}
|
|
1000
1008
|
/** Zeros slots `[slot, slot + count)`, splitting at page boundaries like
|
|
@@ -1002,10 +1010,10 @@ class Y extends Pe {
|
|
|
1002
1010
|
degenerateSlabSlots(e, t) {
|
|
1003
1011
|
let s = 0;
|
|
1004
1012
|
for (; s < t; ) {
|
|
1005
|
-
const n = e + s,
|
|
1006
|
-
if (!
|
|
1007
|
-
const
|
|
1008
|
-
this.degenerateRange(
|
|
1013
|
+
const n = e + s, a = this.slabPages[Math.floor(n / this.slabPageSplats)];
|
|
1014
|
+
if (!a) return;
|
|
1015
|
+
const o = n % this.slabPageSplats, r = Math.min(t - s, this.slabPageSplats - o);
|
|
1016
|
+
this.degenerateRange(a, o, r), s += r;
|
|
1009
1017
|
}
|
|
1010
1018
|
}
|
|
1011
1019
|
/**
|
|
@@ -1073,19 +1081,19 @@ class Y extends Pe {
|
|
|
1073
1081
|
* {@link dispose} is called while the load is in flight.
|
|
1074
1082
|
*/
|
|
1075
1083
|
async loadCollisionMeshes(e = {}) {
|
|
1076
|
-
var
|
|
1077
|
-
(
|
|
1084
|
+
var a;
|
|
1085
|
+
(a = e.signal) == null || a.throwIfAborted();
|
|
1078
1086
|
const t = this.scene.collision;
|
|
1079
1087
|
if (!t || t.meshes.length === 0) return [];
|
|
1080
1088
|
if (!this.collisionTiles) {
|
|
1081
|
-
const
|
|
1082
|
-
this.collisionAbort =
|
|
1083
|
-
({ loadCollisionMeshTiles:
|
|
1089
|
+
const o = new AbortController();
|
|
1090
|
+
this.collisionAbort = o, this.collisionTiles = import("./formats/lcc.js").then(
|
|
1091
|
+
({ loadCollisionMeshTiles: r }) => r(t, {
|
|
1084
1092
|
...this.requestOptions ? { request: this.requestOptions } : {},
|
|
1085
|
-
signal:
|
|
1093
|
+
signal: o.signal
|
|
1086
1094
|
})
|
|
1087
|
-
).catch((
|
|
1088
|
-
throw this.collisionTiles = void 0,
|
|
1095
|
+
).catch((r) => {
|
|
1096
|
+
throw this.collisionTiles = void 0, r;
|
|
1089
1097
|
});
|
|
1090
1098
|
}
|
|
1091
1099
|
const { signal: s } = e;
|
|
@@ -1094,8 +1102,8 @@ class Y extends Pe {
|
|
|
1094
1102
|
try {
|
|
1095
1103
|
return await Promise.race([
|
|
1096
1104
|
this.collisionTiles,
|
|
1097
|
-
new Promise((
|
|
1098
|
-
n = () =>
|
|
1105
|
+
new Promise((o, r) => {
|
|
1106
|
+
n = () => r(Ke(s)), s.addEventListener("abort", n, { once: !0 });
|
|
1099
1107
|
})
|
|
1100
1108
|
]);
|
|
1101
1109
|
} finally {
|
|
@@ -1168,6 +1176,14 @@ class Y extends Pe {
|
|
|
1168
1176
|
get contentSplatCount() {
|
|
1169
1177
|
return this.scene.contentSplatCount;
|
|
1170
1178
|
}
|
|
1179
|
+
/**
|
|
1180
|
+
* Which `.rad` streaming strategy this mesh selected at load, or `null` when
|
|
1181
|
+
* the scene is not a Spark `.rad` capture.
|
|
1182
|
+
*/
|
|
1183
|
+
get radStrategy() {
|
|
1184
|
+
var e, t;
|
|
1185
|
+
return ((t = (e = this.scene.chunkOptions) == null ? void 0 : e[0]) == null ? void 0 : t.format) !== "rad-chunk" ? null : this.frontierWorker ? "page-table" : "prefix";
|
|
1186
|
+
}
|
|
1171
1187
|
/**
|
|
1172
1188
|
* The drawn-splat target currently driving the `.rad` page-table frontier -
|
|
1173
1189
|
* the governed budget, capped by
|
|
@@ -1181,6 +1197,23 @@ class Y extends Pe {
|
|
|
1181
1197
|
get drawBudget() {
|
|
1182
1198
|
return this.frontierWorker ? this.pageTableDrawBudget : 0;
|
|
1183
1199
|
}
|
|
1200
|
+
/**
|
|
1201
|
+
* Page-table frontier coherence for hosts that gate preload/transitions.
|
|
1202
|
+
* `undefined` fields stay 0 when this mesh is not in page-table mode.
|
|
1203
|
+
*/
|
|
1204
|
+
get frontierState() {
|
|
1205
|
+
return {
|
|
1206
|
+
frontierConverged: this.frontierWorker ? this.frontierConverged : !0,
|
|
1207
|
+
pendingFrontierSplats: this.pendingFrontierSplats,
|
|
1208
|
+
staleResidentSplats: this.staleResidentSplats,
|
|
1209
|
+
lastPlanAppends: this.lastPlanAppends,
|
|
1210
|
+
lastPlanMoves: this.lastPlanMoves,
|
|
1211
|
+
planGeneration: this.lastPlanGeneration,
|
|
1212
|
+
planBudget: this.lastPlanBudget,
|
|
1213
|
+
lastPlanCamera: this.lastPlanCamera,
|
|
1214
|
+
firstFrontierCamera: this.firstFrontierCamera
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1184
1217
|
/**
|
|
1185
1218
|
* Spark's per-mesh `lodScale` (see {@link StreamedSplatMeshOptions.lodScale}).
|
|
1186
1219
|
* Mutable: raise it to sharpen a focused mesh, lower it to coarsen a
|
|
@@ -1211,7 +1244,7 @@ class Y extends Pe {
|
|
|
1211
1244
|
*/
|
|
1212
1245
|
setBudget(e) {
|
|
1213
1246
|
const t = Math.min(W(e), this.maximumBudget);
|
|
1214
|
-
return t === this.budgetValue ? this.budgetValue : (this.budgetValue = t, this.scene.source.budget = t, this.frontierWorker && (this.pageTableDrawBudget = Math.min(t, this.pageTableDrawTarget), this.syncSlabPages(this.pageTableDrawBudget), this.pageTableDrawTargetExplicit && this.pageTableDrawTarget < t && !this.warnedDrawTargetCap && (this.warnedDrawTargetCap = !0,
|
|
1247
|
+
return t === this.budgetValue ? this.budgetValue : (this.budgetValue = t, this.scene.source.budget = t, this.frontierWorker && (this.pageTableDrawBudget = Math.min(t, this.pageTableDrawTarget), this.syncSlabPages(this.pageTableDrawBudget), this.pageTableDrawTargetExplicit && this.pageTableDrawTarget < t && !this.warnedDrawTargetCap && (this.warnedDrawTargetCap = !0, E(
|
|
1215
1248
|
`StreamedSplatMesh: budget raised to ${t} but foveationDrawBudget caps the drawn frontier at ${this.pageTableDrawTarget}; the extra budget cannot buy detail. Raise or drop foveationDrawBudget to let the shared budget through.`
|
|
1216
1249
|
))), this.pendingWork = !0, this.lastScheduleTime = -1 / 0, t);
|
|
1217
1250
|
}
|
|
@@ -1313,12 +1346,12 @@ class Y extends Pe {
|
|
|
1313
1346
|
update(e, t, s = {}) {
|
|
1314
1347
|
const n = performance.now();
|
|
1315
1348
|
e.updateMatrixWorld(), this.updateWorldMatrix(!0, !1);
|
|
1316
|
-
const
|
|
1317
|
-
this.frontierWorker && (
|
|
1318
|
-
const
|
|
1319
|
-
if (super.update(e, t, s),
|
|
1349
|
+
const a = Le(e, t);
|
|
1350
|
+
this.frontierWorker && (a ? this.pageTableViewportY = a.height : (t.getDrawingBufferSize(Se), this.pageTableViewportY = Se.y));
|
|
1351
|
+
const o = (a == null ? void 0 : a.head) ?? e, r = this.shouldReschedule(o, n) ? this.reschedule(o, n) : null;
|
|
1352
|
+
if (super.update(e, t, s), r && this.onPerformanceEvent) {
|
|
1320
1353
|
const c = this.getUpdateTimings();
|
|
1321
|
-
|
|
1354
|
+
r.cpuMs += performance.now() - r.timestamp, r.activeListMs = c.activeListMs, r.uploadMs = c.uploadMs, r.sortSubmitMs = c.sortSubmitMs, r.stagingTextureAllocations = c.stagingTextureAllocations, r.activeListUpdateRanges = c.activeListUpdateRanges, this.onPerformanceEvent(r);
|
|
1322
1355
|
}
|
|
1323
1356
|
}
|
|
1324
1357
|
/** Root bounds of the whole scene, valid before any chunk has loaded. */
|
|
@@ -1412,38 +1445,38 @@ class Y extends Pe {
|
|
|
1412
1445
|
* {@link definePersistentChannel}.
|
|
1413
1446
|
*/
|
|
1414
1447
|
paintPersistent(e, t, s, n) {
|
|
1415
|
-
const
|
|
1416
|
-
if (!
|
|
1448
|
+
const a = this.persistentChannels.get(e);
|
|
1449
|
+
if (!a)
|
|
1417
1450
|
throw new Error(
|
|
1418
1451
|
`StreamedSplatMesh.paintPersistent: channel "${e}" is not a persistent channel. Call definePersistentChannel("${e}") first.`
|
|
1419
1452
|
);
|
|
1420
1453
|
V.copy(t), this.worldToLocal(V);
|
|
1421
|
-
const
|
|
1422
|
-
let
|
|
1454
|
+
const o = s * s;
|
|
1455
|
+
let r = 0;
|
|
1423
1456
|
const c = /* @__PURE__ */ new Set();
|
|
1424
|
-
for (const { run:
|
|
1425
|
-
const f = this.cache.get(
|
|
1457
|
+
for (const { run: u } of this.resident.values()) {
|
|
1458
|
+
const f = this.cache.get(u.file);
|
|
1426
1459
|
if (!f) continue;
|
|
1427
|
-
const
|
|
1460
|
+
const h = f.data.positions, g = a.edits.get(u.file) ?? /* @__PURE__ */ new Map();
|
|
1428
1461
|
let v = !1;
|
|
1429
|
-
for (let m = 0; m <
|
|
1430
|
-
const b =
|
|
1431
|
-
if (!(
|
|
1432
|
-
if (
|
|
1433
|
-
|
|
1434
|
-
`StreamedSplatMesh.paintPersistent: channel "${e}" hit its maxEdits cap (${
|
|
1462
|
+
for (let m = 0; m < u.count; m++) {
|
|
1463
|
+
const b = u.offset + m, I = h[b * 3 + 0] - V.x, T = h[b * 3 + 1] - V.y, y = h[b * 3 + 2] - V.z;
|
|
1464
|
+
if (!(I * I + T * T + y * y > o) && !g.has(b)) {
|
|
1465
|
+
if (a.total >= a.maxEdits) {
|
|
1466
|
+
a.warned || (a.warned = !0, E(
|
|
1467
|
+
`StreamedSplatMesh.paintPersistent: channel "${e}" hit its maxEdits cap (${a.maxEdits}); further new edits are dropped.`
|
|
1435
1468
|
));
|
|
1436
1469
|
continue;
|
|
1437
1470
|
}
|
|
1438
|
-
|
|
1471
|
+
a.total++, g.set(b, n), v = !0, r++;
|
|
1439
1472
|
}
|
|
1440
1473
|
}
|
|
1441
|
-
v && (
|
|
1474
|
+
v && (a.edits.set(u.file, g), c.add(u.file));
|
|
1442
1475
|
}
|
|
1443
1476
|
if (c.size > 0)
|
|
1444
|
-
for (const { run:
|
|
1445
|
-
c.has(
|
|
1446
|
-
return
|
|
1477
|
+
for (const { run: u, handle: f } of this.resident.values())
|
|
1478
|
+
c.has(u.file) && this.applyPersistentRun(e, a, u, f);
|
|
1479
|
+
return r;
|
|
1447
1480
|
}
|
|
1448
1481
|
/**
|
|
1449
1482
|
* Clears every stored edit for a persistent channel and zeroes the value on
|
|
@@ -1460,21 +1493,21 @@ class Y extends Pe {
|
|
|
1460
1493
|
);
|
|
1461
1494
|
t.edits.clear(), t.total = 0;
|
|
1462
1495
|
for (const { run: s, handle: n } of this.resident.values()) {
|
|
1463
|
-
const
|
|
1464
|
-
this.writeChannel(n, e,
|
|
1496
|
+
const a = t.type === "byte" ? new Uint8Array(s.count) : new Float32Array(s.count);
|
|
1497
|
+
this.writeChannel(n, e, a);
|
|
1465
1498
|
}
|
|
1466
1499
|
}
|
|
1467
1500
|
dispose() {
|
|
1468
|
-
var e, t, s, n,
|
|
1501
|
+
var e, t, s, n, a;
|
|
1469
1502
|
if (!this.disposed) {
|
|
1470
1503
|
this.loader.dispose(), this.frontierWorker && (this.frontierWorker.onmessage = null, this.frontierWorker.terminate()), this.pageTableDisposed = !0, (e = this.collisionAbort) == null || e.abort(), (t = this.collisionTiles) == null || t.catch(() => {
|
|
1471
1504
|
}), this.collisionTiles = void 0;
|
|
1472
|
-
for (const { controller:
|
|
1505
|
+
for (const { controller: o } of this.fetching.values()) o.abort();
|
|
1473
1506
|
if (this.fetching.clear(), this.fetchHandle && ((s = this.fetchScheduler) == null || s.unregister(this.fetchHandle)), this.cacheBudgetHandle) {
|
|
1474
|
-
const
|
|
1475
|
-
this.cacheBudgetHandle = void 0, (n = this.cacheBudget) == null || n.unregister(
|
|
1507
|
+
const o = this.cacheBudgetHandle;
|
|
1508
|
+
this.cacheBudgetHandle = void 0, (n = this.cacheBudget) == null || n.unregister(o);
|
|
1476
1509
|
}
|
|
1477
|
-
(
|
|
1510
|
+
(a = this.localSource) == null || a.dispose(), this.localSource = void 0, this.cache.clear(), this.cacheBytesTotal = 0, this.retrying.clear(), this.failedFiles.clear(), this.neededFiles.clear(), this.persistentChannels.clear(), this.resident.clear(), this.staged.clear(), this.pageTableCachedFiles.clear(), this.envHandle = void 0, this.envSplatCount = 0, super.dispose();
|
|
1478
1511
|
}
|
|
1479
1512
|
}
|
|
1480
1513
|
shouldReschedule(e, t) {
|
|
@@ -1492,11 +1525,11 @@ class Y extends Pe {
|
|
|
1492
1525
|
for (const [p, S] of this.resident) n.resident.set(p, S.run.count);
|
|
1493
1526
|
for (const [p, S] of this.staged) n.staged.set(p, S.uploadedCount);
|
|
1494
1527
|
}
|
|
1495
|
-
const
|
|
1496
|
-
if (this.pendingWork = !1, this.lastScheduleTime = t, e.getWorldPosition(this.lastCameraPos), e.getWorldQuaternion(this.lastCameraQuat), x.copy(this.lastCameraPos), this.worldToLocal(x), ve.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse).multiply(this.matrixWorld),
|
|
1497
|
-
e.getWorldDirection(
|
|
1528
|
+
const a = this.compactionCount;
|
|
1529
|
+
if (this.pendingWork = !1, this.lastScheduleTime = t, e.getWorldPosition(this.lastCameraPos), e.getWorldQuaternion(this.lastCameraQuat), x.copy(this.lastCameraPos), this.worldToLocal(x), ve.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse).multiply(this.matrixWorld), O.setFromProjectionMatrix(ve), this.frontierWorker) {
|
|
1530
|
+
e.getWorldDirection(M).add(this.lastCameraPos), this.worldToLocal(M), M.sub(x).normalize();
|
|
1498
1531
|
const p = e.projectionMatrix.elements[5] * this.pageTableViewportY / 2;
|
|
1499
|
-
if (p > 0 && (this.pageTableLimit = this.pageTableTargetPx / p), this.reschedulePageTable(x,
|
|
1532
|
+
if (p > 0 && (this.pageTableLimit = this.pageTableTargetPx / p), this.reschedulePageTable(x, M, O, t), this.onPerformanceEvent === void 0) return null;
|
|
1500
1533
|
const S = performance.now();
|
|
1501
1534
|
return {
|
|
1502
1535
|
timestamp: S,
|
|
@@ -1515,46 +1548,47 @@ class Y extends Pe {
|
|
|
1515
1548
|
compacted: !1
|
|
1516
1549
|
};
|
|
1517
1550
|
}
|
|
1518
|
-
e.getWorldDirection(
|
|
1519
|
-
const
|
|
1551
|
+
e.getWorldDirection(M).add(this.lastCameraPos), this.worldToLocal(M), M.sub(x).normalize();
|
|
1552
|
+
const o = this.scene.source.computeDesiredRuns(
|
|
1520
1553
|
x,
|
|
1521
|
-
|
|
1554
|
+
O,
|
|
1522
1555
|
t,
|
|
1523
|
-
|
|
1524
|
-
),
|
|
1525
|
-
|
|
1556
|
+
M
|
|
1557
|
+
), r = this.captureOrContinueInitialReveal(
|
|
1558
|
+
o,
|
|
1526
1559
|
t,
|
|
1527
1560
|
x,
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1561
|
+
O,
|
|
1562
|
+
M
|
|
1563
|
+
), c = r !== null, u = r ?? o, f = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Set();
|
|
1564
|
+
for (const p of u)
|
|
1565
|
+
f.set(C(p), p), h.add(p.file);
|
|
1532
1566
|
for (const [p, S] of this.staged)
|
|
1533
|
-
f.has(p) || c && ((L = this.frozenCriticalRuns) != null && L.some((
|
|
1567
|
+
f.has(p) || c && ((L = this.frozenCriticalRuns) != null && L.some((F) => C(F) === p)) || (this.removeRange(S.handle), this.staged.delete(p));
|
|
1534
1568
|
for (const [p, { controller: S }] of this.fetching)
|
|
1535
|
-
!
|
|
1569
|
+
!h.has(p) && !this.scene.pinnedFiles.has(p) && S.abort();
|
|
1536
1570
|
for (const p of this.retrying.keys())
|
|
1537
|
-
!
|
|
1571
|
+
!h.has(p) && !this.scene.pinnedFiles.has(p) && this.retrying.delete(p);
|
|
1538
1572
|
this.neededFiles.clear();
|
|
1539
|
-
for (const p of
|
|
1573
|
+
for (const p of u) {
|
|
1540
1574
|
const S = C(p);
|
|
1541
1575
|
if (this.resident.has(S)) continue;
|
|
1542
|
-
const
|
|
1543
|
-
|
|
1576
|
+
const F = this.staged.get(S);
|
|
1577
|
+
F && F.uploadedCount === p.count || this.neededFiles.add(p.file);
|
|
1544
1578
|
}
|
|
1545
1579
|
this.envFile !== void 0 && this.envEnabled && this.envHandle === void 0 && !this.envUnfit && !this.failedFiles.has(this.envFile) && this.neededFiles.add(this.envFile);
|
|
1546
|
-
const g =
|
|
1580
|
+
const g = u.filter((p) => !this.resident.has(C(p))), v = c ? [] : [...this.resident.entries()].filter(([p]) => !f.has(p)), m = c ? (
|
|
1547
1581
|
// Mesh is invisible during the hold, so L0 cell-atomicity (no holes) is
|
|
1548
1582
|
// irrelevant - commit each frozen slice as it lands so a partial home
|
|
1549
1583
|
// cell cannot block reveal behind sibling subchunks still fetching.
|
|
1550
1584
|
_e(g)
|
|
1551
|
-
) :
|
|
1585
|
+
) : Oe(g, v), b = !c && ze(m);
|
|
1552
1586
|
m.sort(
|
|
1553
|
-
(p, S) => b ? Ue(p, S) :
|
|
1587
|
+
(p, S) => b ? Ue(p, S) : ae(p) - ae(S)
|
|
1554
1588
|
);
|
|
1555
|
-
const
|
|
1556
|
-
this.updateEnvironment(t,
|
|
1557
|
-
let
|
|
1589
|
+
const I = /* @__PURE__ */ new Map();
|
|
1590
|
+
this.updateEnvironment(t, I);
|
|
1591
|
+
let T = 0, y = !1, A = !1, R = !1;
|
|
1558
1592
|
for (const p of m) {
|
|
1559
1593
|
if (!b && p.removes.length > 0 && y) {
|
|
1560
1594
|
if (this.neverRetireCoverageEarly || !A && this.retireHeldTicks < dt) {
|
|
@@ -1567,39 +1601,39 @@ class Y extends Pe {
|
|
|
1567
1601
|
this.applyGroup(p, t);
|
|
1568
1602
|
continue;
|
|
1569
1603
|
}
|
|
1570
|
-
const S = p.adds.filter((
|
|
1604
|
+
const S = p.adds.filter((P) => !this.cache.has(P.file)), F = c || Ye(p) && this.initialRevealHold !== "hold-coverage";
|
|
1571
1605
|
if (S.length > 0) {
|
|
1572
|
-
let
|
|
1606
|
+
let P = !1;
|
|
1573
1607
|
for (const k of S)
|
|
1574
1608
|
this.failedFiles.has(k.file) || (oe(
|
|
1575
|
-
|
|
1609
|
+
I,
|
|
1576
1610
|
k.file,
|
|
1577
1611
|
qe(k, this.scene.source.lodBaseDistance),
|
|
1578
1612
|
k
|
|
1579
|
-
),
|
|
1580
|
-
if (c || this.substituteCoverage(p, t,
|
|
1613
|
+
), P = !0);
|
|
1614
|
+
if (c || this.substituteCoverage(p, t, I, F), P && (this.pendingWork = !0, y = !0), !c) continue;
|
|
1581
1615
|
}
|
|
1582
1616
|
if (c && this.environmentPendingForReveal()) {
|
|
1583
1617
|
this.pendingWork = !0, y = !0;
|
|
1584
1618
|
continue;
|
|
1585
1619
|
}
|
|
1586
1620
|
if ((c || this.stagedSwapsEnabled && p.addCount > this.appendCap) && this.canStageGroup(p)) {
|
|
1587
|
-
const
|
|
1588
|
-
if (
|
|
1589
|
-
var
|
|
1590
|
-
return ((
|
|
1621
|
+
const P = this.stageGroup(p, t, Math.max(0, this.appendCap - T));
|
|
1622
|
+
if (T += P, !p.adds.every((k) => {
|
|
1623
|
+
var se;
|
|
1624
|
+
return ((se = this.staged.get(C(k))) == null ? void 0 : se.uploadedCount) === k.count;
|
|
1591
1625
|
})) {
|
|
1592
1626
|
this.pendingWork = !0, y = !0;
|
|
1593
1627
|
continue;
|
|
1594
1628
|
}
|
|
1595
|
-
if (
|
|
1629
|
+
if (P > 0 && !c) {
|
|
1596
1630
|
this.deferNextSortRequest(), this.pendingWork = !0, y = !0;
|
|
1597
1631
|
continue;
|
|
1598
1632
|
}
|
|
1599
1633
|
this.commitStagedGroup(p);
|
|
1600
1634
|
continue;
|
|
1601
1635
|
}
|
|
1602
|
-
if (!c &&
|
|
1636
|
+
if (!c && T > 0 && T + p.addCount > this.appendCap) {
|
|
1603
1637
|
this.pendingWork = !0, y = !0;
|
|
1604
1638
|
continue;
|
|
1605
1639
|
}
|
|
@@ -1611,17 +1645,17 @@ class Y extends Pe {
|
|
|
1611
1645
|
this.pendingWork = !0, A = !0;
|
|
1612
1646
|
continue;
|
|
1613
1647
|
}
|
|
1614
|
-
|
|
1648
|
+
T += p.addCount;
|
|
1615
1649
|
}
|
|
1616
|
-
return this.flushClassicFetches(
|
|
1650
|
+
return this.flushClassicFetches(I, this.scene.source.lodBaseDistance, c), this.retireHeldTicks = R ? this.retireHeldTicks + 1 : 0, c && (this.finishInitialRevealIfComplete(), this.initialRevealPhase === "holding" && (this.pendingWork = !0)), this.fetchCountsValue.cacheBytes = this.cacheBytesTotal, this.fetchCountsValue.cacheLimitBytes = this.cpuCacheBytes, this.cacheBytesTotal > this.cpuCacheBytes && (this.fetchCountsValue.cacheFull = !0), this.evictChunks(t), n === null ? null : this.createPerformanceEvent(
|
|
1617
1651
|
n.resident,
|
|
1618
1652
|
n.staged,
|
|
1619
|
-
|
|
1653
|
+
a,
|
|
1620
1654
|
s
|
|
1621
1655
|
);
|
|
1622
1656
|
}
|
|
1623
1657
|
rowAlignedSplats(e) {
|
|
1624
|
-
return Math.ceil(e /
|
|
1658
|
+
return Math.ceil(e / B) * B;
|
|
1625
1659
|
}
|
|
1626
1660
|
/**
|
|
1627
1661
|
* Startup hold seeds: the coverage group containing (or nearest to) the
|
|
@@ -1631,32 +1665,32 @@ class Y extends Pe {
|
|
|
1631
1665
|
* Coarser home levels come from {@link LodSource.runsAtLevelFor}.
|
|
1632
1666
|
*/
|
|
1633
1667
|
selectHomeSeedRuns(e) {
|
|
1634
|
-
var
|
|
1668
|
+
var a;
|
|
1635
1669
|
const t = this.scene.source.lodBaseDistance, s = e.filter(
|
|
1636
|
-
(
|
|
1670
|
+
(o) => o.coverageGroup !== void 0 && (o.distance ?? Number.POSITIVE_INFINITY) <= t
|
|
1637
1671
|
).sort(
|
|
1638
|
-
(
|
|
1639
|
-
(
|
|
1640
|
-
), n = (
|
|
1641
|
-
return n === void 0 ? [] : s.filter((
|
|
1672
|
+
(o, r) => (o.distance ?? Number.POSITIVE_INFINITY) - (r.distance ?? Number.POSITIVE_INFINITY) || // Same distance: prefer in-view, then finer.
|
|
1673
|
+
(o.inView === !0 ? 0 : 1) - (r.inView === !0 ? 0 : 1) || o.level - r.level || o.leafStart - r.leafStart
|
|
1674
|
+
), n = (a = s[0]) == null ? void 0 : a.coverageGroup;
|
|
1675
|
+
return n === void 0 ? [] : s.filter((o) => o.coverageGroup === n);
|
|
1642
1676
|
}
|
|
1643
1677
|
coarsenHomeRuns(e, t) {
|
|
1644
|
-
var
|
|
1678
|
+
var a;
|
|
1645
1679
|
const s = [], n = this.scene.source;
|
|
1646
|
-
for (const
|
|
1647
|
-
if (
|
|
1648
|
-
s.push(
|
|
1680
|
+
for (const o of e) {
|
|
1681
|
+
if (o.level === t) {
|
|
1682
|
+
s.push(o);
|
|
1649
1683
|
continue;
|
|
1650
1684
|
}
|
|
1651
|
-
const
|
|
1652
|
-
if (
|
|
1653
|
-
for (const c of
|
|
1685
|
+
const r = ((a = n.runsAtLevelFor) == null ? void 0 : a.call(n, o.leafStart, o.leafEnd, t)) ?? [];
|
|
1686
|
+
if (r.length !== 0)
|
|
1687
|
+
for (const c of r)
|
|
1654
1688
|
s.push({
|
|
1655
1689
|
...c,
|
|
1656
|
-
distance:
|
|
1657
|
-
inView:
|
|
1658
|
-
...
|
|
1659
|
-
...
|
|
1690
|
+
distance: o.distance,
|
|
1691
|
+
inView: o.inView,
|
|
1692
|
+
...o.coverageGroup === void 0 ? {} : { coverageGroup: o.coverageGroup },
|
|
1693
|
+
...o.screenImportance === void 0 ? {} : { screenImportance: o.screenImportance }
|
|
1660
1694
|
});
|
|
1661
1695
|
}
|
|
1662
1696
|
return s;
|
|
@@ -1668,34 +1702,34 @@ class Y extends Pe {
|
|
|
1668
1702
|
}
|
|
1669
1703
|
publishInitialRevealProgress(e) {
|
|
1670
1704
|
const t = /* @__PURE__ */ new Map();
|
|
1671
|
-
for (const
|
|
1672
|
-
const c =
|
|
1673
|
-
let
|
|
1674
|
-
|
|
1705
|
+
for (const r of e) {
|
|
1706
|
+
const c = r.coverageGroup !== void 0 ? `g:${r.coverageGroup}` : C(r);
|
|
1707
|
+
let u = t.get(c);
|
|
1708
|
+
u || (u = [], t.set(c, u)), u.push(r);
|
|
1675
1709
|
}
|
|
1676
|
-
let s = 0, n = 0,
|
|
1677
|
-
for (const
|
|
1710
|
+
let s = 0, n = 0, a = 0;
|
|
1711
|
+
for (const r of t.values()) {
|
|
1678
1712
|
let c = !0;
|
|
1679
|
-
for (const
|
|
1680
|
-
n +=
|
|
1681
|
-
const f = C(
|
|
1713
|
+
for (const u of r) {
|
|
1714
|
+
n += u.count;
|
|
1715
|
+
const f = C(u);
|
|
1682
1716
|
if (this.resident.has(f)) {
|
|
1683
|
-
s +=
|
|
1717
|
+
s += u.count;
|
|
1684
1718
|
continue;
|
|
1685
1719
|
}
|
|
1686
|
-
const
|
|
1687
|
-
s += (
|
|
1720
|
+
const h = this.staged.get(f);
|
|
1721
|
+
s += (h == null ? void 0 : h.uploadedCount) ?? 0, (!h || h.uploadedCount !== u.count) && (c = !1);
|
|
1688
1722
|
}
|
|
1689
|
-
c &&
|
|
1723
|
+
c && a++;
|
|
1690
1724
|
}
|
|
1691
|
-
const
|
|
1692
|
-
if (
|
|
1725
|
+
const o = this.initialRevealStateValue;
|
|
1726
|
+
if (o.status === "degraded") {
|
|
1693
1727
|
this.initialRevealStateValue = {
|
|
1694
1728
|
status: "degraded",
|
|
1695
|
-
reason:
|
|
1729
|
+
reason: o.reason,
|
|
1696
1730
|
stagedSplats: s,
|
|
1697
1731
|
totalSplats: n,
|
|
1698
|
-
readyGroups:
|
|
1732
|
+
readyGroups: a,
|
|
1699
1733
|
totalGroups: t.size
|
|
1700
1734
|
};
|
|
1701
1735
|
return;
|
|
@@ -1704,32 +1738,35 @@ class Y extends Pe {
|
|
|
1704
1738
|
status: "pending",
|
|
1705
1739
|
stagedSplats: s,
|
|
1706
1740
|
totalSplats: n,
|
|
1707
|
-
readyGroups:
|
|
1741
|
+
readyGroups: a,
|
|
1708
1742
|
totalGroups: t.size
|
|
1709
1743
|
};
|
|
1710
1744
|
}
|
|
1711
1745
|
releaseInitialReveal(e, t) {
|
|
1712
1746
|
const s = this.frozenCriticalRuns ?? [];
|
|
1713
1747
|
this.publishInitialRevealProgress(s);
|
|
1714
|
-
const n = this.initialRevealStateValue,
|
|
1748
|
+
const n = this.initialRevealStateValue, a = n.status === "pending" || n.status === "degraded" ? n.stagedSplats : 0, o = n.status === "pending" || n.status === "degraded" ? n.totalSplats : 0, r = n.status === "pending" || n.status === "degraded" ? n.readyGroups : 0, c = n.status === "pending" || n.status === "degraded" ? n.totalGroups : 0;
|
|
1715
1749
|
e === "ready" ? this.initialRevealStateValue = { status: "ready" } : this.initialRevealStateValue = {
|
|
1716
1750
|
status: "degraded",
|
|
1717
1751
|
reason: t ?? "fetch-failed",
|
|
1718
|
-
stagedSplats:
|
|
1719
|
-
totalSplats:
|
|
1720
|
-
readyGroups:
|
|
1752
|
+
stagedSplats: a,
|
|
1753
|
+
totalSplats: o,
|
|
1754
|
+
readyGroups: r,
|
|
1721
1755
|
totalGroups: c
|
|
1722
1756
|
}, this.frozenCriticalRuns = null, this.initialRevealPhase = "released", this.pendingWork = !0;
|
|
1723
1757
|
}
|
|
1724
1758
|
/**
|
|
1725
|
-
*
|
|
1759
|
+
* Coverage hold: freeze covering runs for in-view cells (classic `.lcc`
|
|
1760
|
+
* physical cells at L1 near / coarsest far, `.lcc2` octree root-children).
|
|
1726
1761
|
* Missing `coverageRunsFor` (or an empty result after fallback) releases
|
|
1727
1762
|
* immediately so the mesh does not stay hidden with nothing to fetch.
|
|
1763
|
+
* If the mixed set overflows the pool, coarsen only the near (non-coarsest)
|
|
1764
|
+
* groups one more rung before degrading to progressive.
|
|
1728
1765
|
*/
|
|
1729
|
-
captureCoverageHold(e, t, s) {
|
|
1730
|
-
var
|
|
1731
|
-
|
|
1732
|
-
if (
|
|
1766
|
+
captureCoverageHold(e, t, s, n) {
|
|
1767
|
+
var o, r;
|
|
1768
|
+
let a = ((r = (o = this.scene.source).coverageRunsFor) == null ? void 0 : r.call(o, e, t, n)) ?? [];
|
|
1769
|
+
if (a.length === 0) {
|
|
1733
1770
|
if (this.environmentPendingForReveal()) {
|
|
1734
1771
|
this.frozenCriticalRuns = [], this.initialRevealStartedAt = s, this.initialRevealPhase = "holding", this.publishInitialRevealProgress([]);
|
|
1735
1772
|
return;
|
|
@@ -1737,58 +1774,87 @@ class Y extends Pe {
|
|
|
1737
1774
|
this.initialRevealStateValue = { status: "ready" }, this.initialRevealPhase = "released";
|
|
1738
1775
|
return;
|
|
1739
1776
|
}
|
|
1740
|
-
if (!this.criticalRunsFitCapacity(
|
|
1741
|
-
|
|
1742
|
-
|
|
1777
|
+
if (!this.criticalRunsFitCapacity(a)) {
|
|
1778
|
+
const c = this.coarsenCoverageNearRuns(a);
|
|
1779
|
+
if (this.criticalRunsFitCapacity(c))
|
|
1780
|
+
a = c;
|
|
1781
|
+
else {
|
|
1782
|
+
this.frozenCriticalRuns = a, this.releaseInitialReveal("degraded", "capacity");
|
|
1783
|
+
return;
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
this.frozenCriticalRuns = a, this.initialRevealStartedAt = s, this.initialRevealPhase = "holding", this.publishInitialRevealProgress(a);
|
|
1787
|
+
}
|
|
1788
|
+
/**
|
|
1789
|
+
* Bump each coverage run one coarser rung when the source has one. Already-
|
|
1790
|
+
* coarsest (far) runs stay put so a tight pool only drops near L1 → L2.
|
|
1791
|
+
*/
|
|
1792
|
+
coarsenCoverageNearRuns(e) {
|
|
1793
|
+
var n;
|
|
1794
|
+
const t = [], s = this.scene.source;
|
|
1795
|
+
for (const a of e) {
|
|
1796
|
+
const o = ((n = s.runsAtLevelFor) == null ? void 0 : n.call(s, a.leafStart, a.leafEnd, a.level + 1)) ?? [];
|
|
1797
|
+
if (o.length === 0 || o.every((r) => r.level <= a.level)) {
|
|
1798
|
+
t.push(a);
|
|
1799
|
+
continue;
|
|
1800
|
+
}
|
|
1801
|
+
for (const r of o)
|
|
1802
|
+
t.push({
|
|
1803
|
+
...r,
|
|
1804
|
+
distance: a.distance,
|
|
1805
|
+
inView: a.inView,
|
|
1806
|
+
...a.coverageGroup === void 0 ? {} : { coverageGroup: a.coverageGroup },
|
|
1807
|
+
...a.screenImportance === void 0 ? {} : { screenImportance: a.screenImportance }
|
|
1808
|
+
});
|
|
1743
1809
|
}
|
|
1744
|
-
|
|
1810
|
+
return t;
|
|
1745
1811
|
}
|
|
1746
|
-
captureOrContinueInitialReveal(e, t, s, n) {
|
|
1812
|
+
captureOrContinueInitialReveal(e, t, s, n, a) {
|
|
1747
1813
|
if (this.initialRevealPhase === "off" || this.initialRevealPhase === "released") return null;
|
|
1748
1814
|
if (this.initialRevealPhase === "capture")
|
|
1749
1815
|
if (this.initialRevealHold === "hold-coverage")
|
|
1750
|
-
this.captureCoverageHold(s, n, t);
|
|
1816
|
+
this.captureCoverageHold(s, n, t, a);
|
|
1751
1817
|
else {
|
|
1752
|
-
const
|
|
1753
|
-
let
|
|
1754
|
-
if (
|
|
1755
|
-
const
|
|
1756
|
-
(
|
|
1757
|
-
),
|
|
1758
|
-
(
|
|
1818
|
+
const o = this.selectHomeSeedRuns(e);
|
|
1819
|
+
let r = [];
|
|
1820
|
+
if (o.length === 0) {
|
|
1821
|
+
const c = this.scene.source.lodBaseDistance * this.scene.source.lodMultiplier * this.scene.source.lodMultiplier, u = e.filter(
|
|
1822
|
+
(h) => h.level <= 2 && h.coverageGroup !== void 0 && (h.distance ?? Number.POSITIVE_INFINITY) <= c
|
|
1823
|
+
), f = [...u].sort(
|
|
1824
|
+
(h, g) => (h.distance ?? Number.POSITIVE_INFINITY) - (g.distance ?? Number.POSITIVE_INFINITY) || (h.inView === !0 ? 0 : 1) - (g.inView === !0 ? 0 : 1) || (h.screenImportance ?? Number.POSITIVE_INFINITY) - (g.screenImportance ?? Number.POSITIVE_INFINITY) || h.leafStart - g.leafStart
|
|
1759
1825
|
)[0];
|
|
1760
|
-
if (!
|
|
1826
|
+
if (!f)
|
|
1761
1827
|
return this.initialRevealStateValue = { status: "ready" }, this.initialRevealPhase = "released", null;
|
|
1762
|
-
if (
|
|
1763
|
-
(
|
|
1764
|
-
).slice(0, 1) :
|
|
1765
|
-
return this.frozenCriticalRuns =
|
|
1766
|
-
this.frozenCriticalRuns =
|
|
1828
|
+
if (r = f.coverageGroup !== void 0 ? u.filter((h) => h.coverageGroup === f.coverageGroup) : [f], this.criticalRunsFitCapacity(r) || (r = f.coverageGroup !== void 0 ? u.filter(
|
|
1829
|
+
(h) => h.coverageGroup === f.coverageGroup && this.criticalRunsFitCapacity([h])
|
|
1830
|
+
).slice(0, 1) : u.filter((h) => this.criticalRunsFitCapacity([h])).slice(0, 1)), r.length === 0 || !this.criticalRunsFitCapacity(r))
|
|
1831
|
+
return this.frozenCriticalRuns = r.length > 0 ? r : [f], this.releaseInitialReveal("degraded", "capacity"), null;
|
|
1832
|
+
this.frozenCriticalRuns = r, this.initialRevealStartedAt = t, this.initialRevealPhase = "holding", this.publishInitialRevealProgress(r);
|
|
1767
1833
|
} else {
|
|
1768
|
-
for (const
|
|
1769
|
-
const
|
|
1770
|
-
if (
|
|
1771
|
-
if (this.criticalRunsFitCapacity(
|
|
1772
|
-
|
|
1834
|
+
for (const c of [0, 1, 2]) {
|
|
1835
|
+
const u = this.coarsenHomeRuns(o, c);
|
|
1836
|
+
if (u.length !== 0) {
|
|
1837
|
+
if (this.criticalRunsFitCapacity(u)) {
|
|
1838
|
+
r = u;
|
|
1773
1839
|
break;
|
|
1774
1840
|
}
|
|
1775
|
-
|
|
1841
|
+
r = u;
|
|
1776
1842
|
}
|
|
1777
1843
|
}
|
|
1778
|
-
if (
|
|
1844
|
+
if (r.length === 0)
|
|
1779
1845
|
return this.initialRevealStateValue = { status: "ready" }, this.initialRevealPhase = "released", null;
|
|
1780
|
-
if (!this.criticalRunsFitCapacity(
|
|
1781
|
-
return this.frozenCriticalRuns =
|
|
1782
|
-
this.frozenCriticalRuns =
|
|
1846
|
+
if (!this.criticalRunsFitCapacity(r))
|
|
1847
|
+
return this.frozenCriticalRuns = r, this.releaseInitialReveal("degraded", "capacity"), null;
|
|
1848
|
+
this.frozenCriticalRuns = r, this.initialRevealStartedAt = t, this.initialRevealPhase = "holding", this.publishInitialRevealProgress(r);
|
|
1783
1849
|
}
|
|
1784
1850
|
}
|
|
1785
1851
|
if (this.initialRevealPhase !== "holding" || !this.frozenCriticalRuns) return null;
|
|
1786
1852
|
if (this.initialRevealStartedAt !== void 0 && t - this.initialRevealStartedAt >= ct)
|
|
1787
1853
|
return this.releaseInitialReveal("degraded", "timeout"), null;
|
|
1788
|
-
for (const
|
|
1789
|
-
if (this.failedFiles.has(
|
|
1790
|
-
const
|
|
1791
|
-
if (!
|
|
1854
|
+
for (const o of this.frozenCriticalRuns)
|
|
1855
|
+
if (this.failedFiles.has(o.file) && !this.resident.has(C(o))) {
|
|
1856
|
+
const r = this.staged.get(C(o));
|
|
1857
|
+
if (!r || r.uploadedCount !== o.count)
|
|
1792
1858
|
return this.releaseInitialReveal("degraded", "fetch-failed"), null;
|
|
1793
1859
|
}
|
|
1794
1860
|
return this.publishInitialRevealProgress(this.frozenCriticalRuns), this.frozenCriticalRuns;
|
|
@@ -1806,17 +1872,17 @@ class Y extends Pe {
|
|
|
1806
1872
|
}
|
|
1807
1873
|
/** Creates a performance event for a changed streamed-LOD tick, if any. */
|
|
1808
1874
|
createPerformanceEvent(e, t, s, n) {
|
|
1809
|
-
let
|
|
1810
|
-
for (const [
|
|
1811
|
-
|
|
1812
|
-
let
|
|
1813
|
-
for (const [
|
|
1814
|
-
this.resident.has(
|
|
1875
|
+
let a = 0, o = 0;
|
|
1876
|
+
for (const [h, g] of this.resident)
|
|
1877
|
+
o += g.run.count, e.has(h) || (a += g.run.count);
|
|
1878
|
+
let r = 0;
|
|
1879
|
+
for (const [h, g] of e)
|
|
1880
|
+
this.resident.has(h) || (r += g);
|
|
1815
1881
|
let c = 0;
|
|
1816
|
-
for (const [
|
|
1817
|
-
c += Math.max(0, g.uploadedCount - (t.get(
|
|
1818
|
-
const
|
|
1819
|
-
if (
|
|
1882
|
+
for (const [h, g] of this.staged)
|
|
1883
|
+
c += Math.max(0, g.uploadedCount - (t.get(h) ?? 0));
|
|
1884
|
+
const u = this.compactionCount !== s;
|
|
1885
|
+
if (a === 0 && r === 0 && c === 0 && !u) return null;
|
|
1820
1886
|
const f = performance.now();
|
|
1821
1887
|
return {
|
|
1822
1888
|
timestamp: f,
|
|
@@ -1826,13 +1892,13 @@ class Y extends Pe {
|
|
|
1826
1892
|
sortSubmitMs: 0,
|
|
1827
1893
|
stagingTextureAllocations: 0,
|
|
1828
1894
|
activeListUpdateRanges: 0,
|
|
1829
|
-
appendedCount:
|
|
1830
|
-
removedCount:
|
|
1895
|
+
appendedCount: a,
|
|
1896
|
+
removedCount: r,
|
|
1831
1897
|
stagedCount: c,
|
|
1832
|
-
uploadCount:
|
|
1833
|
-
activeCount:
|
|
1834
|
-
forcedSort:
|
|
1835
|
-
compacted:
|
|
1898
|
+
uploadCount: a + c,
|
|
1899
|
+
activeCount: o,
|
|
1900
|
+
forcedSort: o === 0 || a + r >= o * ht,
|
|
1901
|
+
compacted: u
|
|
1836
1902
|
};
|
|
1837
1903
|
}
|
|
1838
1904
|
/** Returns whether all new rows can coexist with the currently visible region. */
|
|
@@ -1846,36 +1912,36 @@ class Y extends Pe {
|
|
|
1846
1912
|
stageGroup(e, t, s) {
|
|
1847
1913
|
if (s <= 0) return 0;
|
|
1848
1914
|
let n = 0;
|
|
1849
|
-
for (const
|
|
1850
|
-
const
|
|
1851
|
-
if (!
|
|
1852
|
-
let c = this.staged.get(
|
|
1915
|
+
for (const a of e.adds) {
|
|
1916
|
+
const o = C(a), r = this.cache.get(a.file);
|
|
1917
|
+
if (!r) continue;
|
|
1918
|
+
let c = this.staged.get(o);
|
|
1853
1919
|
if (!c) {
|
|
1854
1920
|
let f;
|
|
1855
1921
|
try {
|
|
1856
|
-
f = this.reserveInactiveRange(
|
|
1922
|
+
f = this.reserveInactiveRange(a.count);
|
|
1857
1923
|
} catch {
|
|
1858
1924
|
this.compactionCount++, this.compact();
|
|
1859
1925
|
try {
|
|
1860
|
-
f = this.reserveInactiveRange(
|
|
1926
|
+
f = this.reserveInactiveRange(a.count);
|
|
1861
1927
|
} catch {
|
|
1862
1928
|
this.pendingWork = !0;
|
|
1863
1929
|
break;
|
|
1864
1930
|
}
|
|
1865
1931
|
}
|
|
1866
|
-
c = { run:
|
|
1932
|
+
c = { run: a, handle: f, uploadedCount: 0 }, this.staged.set(o, c);
|
|
1867
1933
|
}
|
|
1868
|
-
if (c.uploadedCount ===
|
|
1869
|
-
const
|
|
1870
|
-
if (
|
|
1934
|
+
if (c.uploadedCount === a.count) continue;
|
|
1935
|
+
const u = Math.min(a.count - c.uploadedCount, s - n);
|
|
1936
|
+
if (u <= 0) break;
|
|
1871
1937
|
if (this.writeInactiveRange(
|
|
1872
1938
|
c.handle,
|
|
1873
|
-
K(
|
|
1939
|
+
K(r.data, a.offset + c.uploadedCount, u),
|
|
1874
1940
|
c.uploadedCount
|
|
1875
|
-
), c.uploadedCount +=
|
|
1876
|
-
this.writeLodLevelChannel(c.handle,
|
|
1877
|
-
for (const [f,
|
|
1878
|
-
this.applyPersistentRun(f,
|
|
1941
|
+
), c.uploadedCount += u, r.lastUsed = t, n += u, c.uploadedCount === a.count) {
|
|
1942
|
+
this.writeLodLevelChannel(c.handle, a.level);
|
|
1943
|
+
for (const [f, h] of this.persistentChannels)
|
|
1944
|
+
this.applyPersistentRun(f, h, a, c.handle);
|
|
1879
1945
|
}
|
|
1880
1946
|
if (n >= s) break;
|
|
1881
1947
|
}
|
|
@@ -1902,12 +1968,12 @@ class Y extends Pe {
|
|
|
1902
1968
|
* removals - the caller defers it and the old runs keep rendering.
|
|
1903
1969
|
*/
|
|
1904
1970
|
applyGroup(e, t) {
|
|
1905
|
-
const s = (
|
|
1906
|
-
if (n > this.freeSplatCapacity +
|
|
1907
|
-
for (const [
|
|
1908
|
-
this.resident.has(
|
|
1909
|
-
for (const
|
|
1910
|
-
this.appendRun(
|
|
1971
|
+
const s = (o) => Math.ceil(o / B) * B, n = e.adds.reduce((o, r) => o + s(r.count), 0), a = e.removes.reduce((o, [, r]) => o + s(r.run.count), 0);
|
|
1972
|
+
if (n > this.freeSplatCapacity + a) return !1;
|
|
1973
|
+
for (const [o, r] of e.removes)
|
|
1974
|
+
this.resident.has(o) && (this.removeRange(r.handle), this.resident.delete(o));
|
|
1975
|
+
for (const o of e.adds)
|
|
1976
|
+
this.appendRun(o, t);
|
|
1911
1977
|
return !0;
|
|
1912
1978
|
}
|
|
1913
1979
|
/** Appends one run from the cache, compacting the pool on fragmentation. */
|
|
@@ -1915,37 +1981,37 @@ class Y extends Pe {
|
|
|
1915
1981
|
const s = this.cache.get(e.file);
|
|
1916
1982
|
if (!s) return;
|
|
1917
1983
|
const n = K(s.data, e.offset, e.count);
|
|
1918
|
-
let
|
|
1984
|
+
let a;
|
|
1919
1985
|
try {
|
|
1920
|
-
|
|
1986
|
+
a = this.appendRange(n);
|
|
1921
1987
|
} catch {
|
|
1922
1988
|
this.compactionCount++, this.compact();
|
|
1923
1989
|
try {
|
|
1924
|
-
|
|
1990
|
+
a = this.appendRange(n);
|
|
1925
1991
|
} catch {
|
|
1926
1992
|
this.pendingWork = !0;
|
|
1927
1993
|
return;
|
|
1928
1994
|
}
|
|
1929
1995
|
}
|
|
1930
|
-
this.resident.set(C(e), { run: e, handle:
|
|
1931
|
-
for (const [
|
|
1932
|
-
this.applyPersistentRun(
|
|
1996
|
+
this.resident.set(C(e), { run: e, handle: a }), s.lastUsed = t, this.writeLodLevelChannel(a, e.level);
|
|
1997
|
+
for (const [o, r] of this.persistentChannels)
|
|
1998
|
+
this.applyPersistentRun(o, r, e, a);
|
|
1933
1999
|
}
|
|
1934
2000
|
/**
|
|
1935
2001
|
* Writes the stored edits for one run's `[offset, offset + count)` splats
|
|
1936
2002
|
* into its freshly appended pool range. No-op when the file has no edits.
|
|
1937
2003
|
*/
|
|
1938
2004
|
applyPersistentRun(e, t, s, n) {
|
|
1939
|
-
const
|
|
1940
|
-
if (!
|
|
1941
|
-
const
|
|
1942
|
-
t.fill &&
|
|
1943
|
-
let
|
|
2005
|
+
const a = t.edits.get(s.file);
|
|
2006
|
+
if (!a || a.size === 0) return;
|
|
2007
|
+
const o = t.type === "byte" ? new Uint8Array(s.count) : new Float32Array(s.count);
|
|
2008
|
+
t.fill && o.fill(t.fill);
|
|
2009
|
+
let r = !1;
|
|
1944
2010
|
for (let c = 0; c < s.count; c++) {
|
|
1945
|
-
const
|
|
1946
|
-
|
|
2011
|
+
const u = a.get(s.offset + c);
|
|
2012
|
+
u !== void 0 && (o[c] = u, r = !0);
|
|
1947
2013
|
}
|
|
1948
|
-
|
|
2014
|
+
r && this.writeChannel(n, e, o);
|
|
1949
2015
|
}
|
|
1950
2016
|
/**
|
|
1951
2017
|
* Covers a deferred group's leaves that no resident run covers with each
|
|
@@ -1959,20 +2025,20 @@ class Y extends Pe {
|
|
|
1959
2025
|
* for that cell. Far gaps keep the shell.
|
|
1960
2026
|
*/
|
|
1961
2027
|
substituteCoverage(e, t, s, n) {
|
|
1962
|
-
const
|
|
1963
|
-
(this.coverageScratch === void 0 || this.coverageScratch.length <
|
|
1964
|
-
const
|
|
1965
|
-
|
|
1966
|
-
for (const { run:
|
|
1967
|
-
const f = Math.max(
|
|
1968
|
-
|
|
2028
|
+
const a = e.leafEnd - e.leafStart;
|
|
2029
|
+
(this.coverageScratch === void 0 || this.coverageScratch.length < a) && (this.coverageScratch = new Uint8Array(a));
|
|
2030
|
+
const o = this.coverageScratch;
|
|
2031
|
+
o.fill(0, 0, a);
|
|
2032
|
+
for (const { run: u } of this.resident.values()) {
|
|
2033
|
+
const f = Math.max(u.leafStart, e.leafStart), h = Math.min(u.leafEnd, e.leafEnd);
|
|
2034
|
+
h > f && o.fill(1, f - e.leafStart, h - e.leafStart);
|
|
1969
2035
|
}
|
|
1970
|
-
const
|
|
2036
|
+
const r = o.subarray(0, a);
|
|
1971
2037
|
let c = 0;
|
|
1972
|
-
for (; c <
|
|
1973
|
-
const
|
|
1974
|
-
if (
|
|
1975
|
-
const f =
|
|
2038
|
+
for (; c < a; ) {
|
|
2039
|
+
const u = r.indexOf(0, c);
|
|
2040
|
+
if (u < 0) break;
|
|
2041
|
+
const f = r.indexOf(1, u), h = f < 0 ? a : f, g = e.leafStart + u, v = e.leafStart + h;
|
|
1976
2042
|
for (const m of this.scene.source.coarsestRunsFor(g, v))
|
|
1977
2043
|
if (!this.resident.has(C(m))) {
|
|
1978
2044
|
if (n) {
|
|
@@ -1988,11 +2054,11 @@ class Y extends Pe {
|
|
|
1988
2054
|
), this.fetchCountsValue.uncovered += Math.min(m.leafEnd, v) - Math.max(m.leafStart, g);
|
|
1989
2055
|
continue;
|
|
1990
2056
|
}
|
|
1991
|
-
for (const [b,
|
|
1992
|
-
|
|
2057
|
+
for (const [b, I] of this.resident)
|
|
2058
|
+
I.run.leafStart < m.leafEnd && I.run.leafEnd > m.leafStart && (this.removeRange(I.handle), this.resident.delete(b));
|
|
1993
2059
|
this.appendRun(m, t);
|
|
1994
2060
|
}
|
|
1995
|
-
c =
|
|
2061
|
+
c = h;
|
|
1996
2062
|
}
|
|
1997
2063
|
}
|
|
1998
2064
|
/** Issues pending classic-path chunk wants in group-priority order. */
|
|
@@ -2000,10 +2066,10 @@ class Y extends Pe {
|
|
|
2000
2066
|
if (e.size === 0) return;
|
|
2001
2067
|
$e(e, t, s);
|
|
2002
2068
|
const n = [...e.entries()].sort(
|
|
2003
|
-
(
|
|
2069
|
+
(a, o) => X(a[1], o[1], a[0], o[0])
|
|
2004
2070
|
);
|
|
2005
2071
|
this.preemptClassicFetches(n);
|
|
2006
|
-
for (const [
|
|
2072
|
+
for (const [a, o] of n) this.requestChunk(a, o.kind, o);
|
|
2007
2073
|
}
|
|
2008
2074
|
/**
|
|
2009
2075
|
* A camera turn must not wait for all eight old visible requests to finish.
|
|
@@ -2014,10 +2080,10 @@ class Y extends Pe {
|
|
|
2014
2080
|
var t;
|
|
2015
2081
|
for (const [s, n] of e) {
|
|
2016
2082
|
if (this.cache.has(s) || this.fetching.has(s)) continue;
|
|
2017
|
-
let
|
|
2018
|
-
for (const [
|
|
2019
|
-
c.classicWant && (!
|
|
2020
|
-
if (
|
|
2083
|
+
let a, o;
|
|
2084
|
+
for (const [r, c] of this.fetching)
|
|
2085
|
+
c.classicWant && (!o || X(c.classicWant, o, r, a) > 0) && (a = r, o = c.classicWant);
|
|
2086
|
+
if (o && a !== void 0 && X(n, o, s, a) < 0 && ((t = this.fetching.get(a)) == null || t.controller.abort()), this.fetching.size >= this.maxInflight) return;
|
|
2021
2087
|
}
|
|
2022
2088
|
}
|
|
2023
2089
|
/**
|
|
@@ -2037,30 +2103,30 @@ class Y extends Pe {
|
|
|
2037
2103
|
this.failedFiles.has(s) || (t ? this.enqueueEnvironmentFetch(t, s) : this.requestChunk(s, "priority"), this.pendingWork = !0);
|
|
2038
2104
|
return;
|
|
2039
2105
|
}
|
|
2040
|
-
const
|
|
2041
|
-
if (
|
|
2042
|
-
this.envUnfit = !0,
|
|
2106
|
+
const a = Math.ceil(n.data.count / B) * B;
|
|
2107
|
+
if (a > this.capacity) {
|
|
2108
|
+
this.envUnfit = !0, E(
|
|
2043
2109
|
`the environment tile (${n.data.count} splats) exceeds the pool capacity (${this.capacity}); it will not be shown. Raise the splat budget to fit it.`
|
|
2044
2110
|
);
|
|
2045
2111
|
return;
|
|
2046
2112
|
}
|
|
2047
|
-
if (
|
|
2113
|
+
if (a > this.freeSplatCapacity) {
|
|
2048
2114
|
this.pendingWork = !0;
|
|
2049
2115
|
return;
|
|
2050
2116
|
}
|
|
2051
|
-
let
|
|
2117
|
+
let o;
|
|
2052
2118
|
try {
|
|
2053
|
-
|
|
2119
|
+
o = this.appendRange(n.data);
|
|
2054
2120
|
} catch {
|
|
2055
2121
|
this.compactionCount++, this.compact();
|
|
2056
2122
|
try {
|
|
2057
|
-
|
|
2123
|
+
o = this.appendRange(n.data);
|
|
2058
2124
|
} catch {
|
|
2059
2125
|
this.pendingWork = !0;
|
|
2060
2126
|
return;
|
|
2061
2127
|
}
|
|
2062
2128
|
}
|
|
2063
|
-
this.envHandle =
|
|
2129
|
+
this.envHandle = o, this.envSplatCount = n.data.count, n.lastUsed = e;
|
|
2064
2130
|
}
|
|
2065
2131
|
/** Ranks the env tile ahead of every LOD want in {@link flushClassicFetches}. */
|
|
2066
2132
|
enqueueEnvironmentFetch(e, t) {
|
|
@@ -2090,15 +2156,15 @@ class Y extends Pe {
|
|
|
2090
2156
|
* never blocks. Also drives chunk fetching, in priority order.
|
|
2091
2157
|
*/
|
|
2092
2158
|
reschedulePageTable(e, t, s, n) {
|
|
2093
|
-
for (const
|
|
2094
|
-
const
|
|
2095
|
-
for (const
|
|
2096
|
-
|
|
2097
|
-
for (const [
|
|
2098
|
-
|
|
2159
|
+
for (const o of this.pageTableFetchPriority) this.requestChunk(o, "priority");
|
|
2160
|
+
const a = new Set(this.pageTableFetchPriority);
|
|
2161
|
+
for (const o of this.scene.source.computeDesiredRuns(e, s, n))
|
|
2162
|
+
a.add(o.file), this.requestChunk(o.file, "base");
|
|
2163
|
+
for (const [o, r] of this.fetching)
|
|
2164
|
+
r.kind !== "sweep" && !a.has(o) && !this.scene.pinnedFiles.has(o) && r.controller.abort();
|
|
2099
2165
|
if (!this.pageTableCacheAtLimit && this.sweepAllowed()) {
|
|
2100
|
-
const
|
|
2101
|
-
for (let c = 0; c <
|
|
2166
|
+
const o = Math.max(1, this.maxInflight - mt), r = this.scene.chunkUrls.length;
|
|
2167
|
+
for (let c = 0; c < r && this.fetching.size < o; c++)
|
|
2102
2168
|
this.pageTableCachedFiles.has(c) || this.requestChunk(c, "sweep");
|
|
2103
2169
|
}
|
|
2104
2170
|
this.pageTableInFlight || (this.pageTableInFlight = !0, this.postToWorker({
|
|
@@ -2124,40 +2190,40 @@ class Y extends Pe {
|
|
|
2124
2190
|
const t = this.pagerSlots;
|
|
2125
2191
|
e.capacity !== t && (this.pendingWork = !0, this.lastScheduleTime = -1 / 0);
|
|
2126
2192
|
const s = performance.now(), n = e.moveSlots;
|
|
2127
|
-
for (let
|
|
2193
|
+
for (let h = 0; h < n.length; ) {
|
|
2128
2194
|
let g = 1;
|
|
2129
|
-
for (;
|
|
2195
|
+
for (; h + g < n.length && n[h + g] === n[h] + g; )
|
|
2130
2196
|
g++;
|
|
2131
|
-
const v = n[
|
|
2132
|
-
m > 0 && this.writeSlabSlots(yt(e.moves,
|
|
2197
|
+
const v = n[h], m = Math.min(g, t - v);
|
|
2198
|
+
m > 0 && this.writeSlabSlots(yt(e.moves, h, m), v, m), h += g;
|
|
2133
2199
|
}
|
|
2134
2200
|
if (e.appends.count > 0) {
|
|
2135
|
-
const
|
|
2136
|
-
|
|
2201
|
+
const h = Math.min(e.appends.count, t - e.appendStart);
|
|
2202
|
+
h > 0 && this.writeSlabSlots(e.appends, e.appendStart, h);
|
|
2137
2203
|
}
|
|
2138
|
-
const
|
|
2139
|
-
this.setSlabResident(
|
|
2140
|
-
const
|
|
2141
|
-
c > 0 && this.degenerateSlabSlots(
|
|
2142
|
-
const
|
|
2143
|
-
this.pageTableDrawn =
|
|
2204
|
+
const a = performance.now(), o = Math.min(e.residentCount, t);
|
|
2205
|
+
this.setSlabResident(o);
|
|
2206
|
+
const r = Math.min(e.degenerateStart, t), c = Math.min(e.degenerateCount, t - r);
|
|
2207
|
+
c > 0 && this.degenerateSlabSlots(r, c);
|
|
2208
|
+
const u = performance.now();
|
|
2209
|
+
this.pageTableDrawn = o, this.frontierConverged = e.converged, this.pendingFrontierSplats = e.pendingFrontierSplats ?? 0, this.staleResidentSplats = e.staleResidentSplats ?? 0, this.lastPlanAppends = e.lastPlanAppends ?? e.appends.count, this.lastPlanMoves = e.lastPlanMoves ?? e.moveSlots.length, this.lastPlanGeneration = e.planGeneration ?? this.lastPlanGeneration + 1, this.lastPlanBudget = e.planBudget ?? this.pageTableDrawBudget, e.cameraLocal && (this.lastPlanCamera = e.cameraLocal, this.firstFrontierCamera ?? (this.firstFrontierCamera = e.cameraLocal)), e.gatherMissing > 0 && E(
|
|
2144
2210
|
`StreamedSplatMesh: page-table plan gathered ${e.gatherMissing} splats from evicted chunks; they render as holes.`
|
|
2145
2211
|
);
|
|
2146
2212
|
const f = this.planTimingsValue;
|
|
2147
|
-
if (f.applyMs =
|
|
2148
|
-
const
|
|
2213
|
+
if (f.applyMs = u - s, f.writeMs = a - s, f.residentMs = u - a, f.moves = e.moveSlots.length, f.appends = e.appends.count, f.applyMs > f.worstApplyMs && (f.worstApplyMs = f.applyMs, f.worstSplats = f.moves + f.appends), this.frontierBandBase !== null && e.solvedLimit > 0 && this.pageTableLimit > 0) {
|
|
2214
|
+
const h = Math.min(1, e.solvedLimit / this.pageTableLimit);
|
|
2149
2215
|
this.setScreenRadiusBand(
|
|
2150
|
-
this.frontierBandBase.min *
|
|
2151
|
-
this.frontierBandBase.max *
|
|
2216
|
+
this.frontierBandBase.min * h,
|
|
2217
|
+
this.frontierBandBase.max * h
|
|
2152
2218
|
);
|
|
2153
2219
|
}
|
|
2154
|
-
this.invalidateSort(), e.dropped > 0 &&
|
|
2220
|
+
this.invalidateSort(), e.dropped > 0 && E(
|
|
2155
2221
|
`StreamedSplatMesh: page-table slab full, dropped ${e.dropped} frontier splats (draw budget ${this.pageTableDrawBudget} exceeds the pool).`
|
|
2156
2222
|
);
|
|
2157
|
-
for (let
|
|
2158
|
-
this.pageTableCachedFiles.delete(e.evicted[
|
|
2223
|
+
for (let h = 0; h < e.evicted.length; h++)
|
|
2224
|
+
this.pageTableCachedFiles.delete(e.evicted[h]);
|
|
2159
2225
|
this.fetchCountsValue.cacheBytes = e.cacheBytes, this.fetchCountsValue.cacheLimitBytes = e.cacheLimitBytes, this.pageTableCacheAtLimit = e.cacheBytes >= e.cacheLimitBytes, e.evicted.length > 0 && (this.fetchCountsValue.cacheFull = !0, this.fetchCountsValue.evicted += e.evicted.length), this.pageTableFetchPriority = Array.from(e.touched);
|
|
2160
|
-
for (const
|
|
2226
|
+
for (const h of this.pageTableFetchPriority) this.requestChunk(h, "priority");
|
|
2161
2227
|
(this.fetching.size > 0 || !e.converged) && (this.pendingWork = !0, e.converged || (this.lastScheduleTime = -1 / 0));
|
|
2162
2228
|
}
|
|
2163
2229
|
/** Forwards a decoded chunk's arrays to the worker (buffers transferred) so the
|
|
@@ -2227,41 +2293,41 @@ class Y extends Pe {
|
|
|
2227
2293
|
t.kind === e && t.controller.abort();
|
|
2228
2294
|
}
|
|
2229
2295
|
requestChunk(e, t, s) {
|
|
2230
|
-
var
|
|
2296
|
+
var r, c;
|
|
2231
2297
|
if (this.cache.has(e) || this.pageTableCachedFiles.has(e) || this.fetching.has(e) || this.fetching.size >= this.maxInflight || this.failedFiles.has(e)) return;
|
|
2232
2298
|
const n = this.retrying.get(e);
|
|
2233
2299
|
if (n && performance.now() < n.readyAt) return;
|
|
2234
2300
|
this.fetchCountsValue[t]++;
|
|
2235
|
-
const
|
|
2236
|
-
if (
|
|
2237
|
-
|
|
2301
|
+
const a = this.scene.chunkUrls[e];
|
|
2302
|
+
if (a === void 0) {
|
|
2303
|
+
E(`StreamedSplatMesh: manifest references unknown chunk file #${e}.`), this.failedFiles.add(e);
|
|
2238
2304
|
return;
|
|
2239
2305
|
}
|
|
2240
|
-
if (this.fetchHandle && !((
|
|
2241
|
-
const
|
|
2242
|
-
this.fetching.set(e, { controller:
|
|
2306
|
+
if (this.fetchHandle && !((r = this.fetchScheduler) != null && r.tryAcquire(this.fetchHandle, t))) return;
|
|
2307
|
+
const o = new AbortController();
|
|
2308
|
+
this.fetching.set(e, { controller: o, kind: t, classicWant: s }), this.loader.load(a, {
|
|
2243
2309
|
kind: this.scene.chunkKind,
|
|
2244
|
-
signal:
|
|
2310
|
+
signal: o.signal,
|
|
2245
2311
|
...(c = this.scene.chunkOptions) == null ? void 0 : c[e]
|
|
2246
|
-
}).then((
|
|
2247
|
-
var f,
|
|
2248
|
-
this.disposed || (this.retrying.delete(e), (
|
|
2249
|
-
}).catch((
|
|
2250
|
-
var
|
|
2251
|
-
if (
|
|
2252
|
-
const f = (((
|
|
2312
|
+
}).then((u) => {
|
|
2313
|
+
var f, h;
|
|
2314
|
+
this.disposed || (this.retrying.delete(e), (h = (f = this.scene.source).onChunkDecoded) == null || h.call(f, e, u), this.frontierWorker ? (this.forwardChunkToWorker(e, u), this.pendingWork = !0) : this.cacheChunk(e, u));
|
|
2315
|
+
}).catch((u) => {
|
|
2316
|
+
var h;
|
|
2317
|
+
if (D(u)) return;
|
|
2318
|
+
const f = (((h = this.retrying.get(e)) == null ? void 0 : h.attempts) ?? 0) + 1;
|
|
2253
2319
|
if (f >= gt)
|
|
2254
|
-
this.retrying.delete(e), this.failedFiles.add(e),
|
|
2255
|
-
`StreamedSplatMesh: gave up on chunk #${e} (${
|
|
2256
|
-
|
|
2320
|
+
this.retrying.delete(e), this.failedFiles.add(e), E(
|
|
2321
|
+
`StreamedSplatMesh: gave up on chunk #${e} (${a}) after ${f} attempts.`,
|
|
2322
|
+
u
|
|
2257
2323
|
);
|
|
2258
2324
|
else {
|
|
2259
2325
|
const g = pt * 2 ** (f - 1);
|
|
2260
2326
|
this.retrying.set(e, { attempts: f, readyAt: performance.now() + g });
|
|
2261
2327
|
}
|
|
2262
2328
|
}).finally(() => {
|
|
2263
|
-
var
|
|
2264
|
-
this.fetching.delete(e), this.fetchHandle && ((
|
|
2329
|
+
var u;
|
|
2330
|
+
this.fetching.delete(e), this.fetchHandle && ((u = this.fetchScheduler) == null || u.release(this.fetchHandle)), this.pendingWork = !0;
|
|
2265
2331
|
});
|
|
2266
2332
|
}
|
|
2267
2333
|
/**
|
|
@@ -2279,25 +2345,25 @@ class Y extends Pe {
|
|
|
2279
2345
|
let t = this.cacheBytesTotal;
|
|
2280
2346
|
if (t <= this.cpuCacheBytes) return;
|
|
2281
2347
|
const s = [...this.cache.entries()].filter(
|
|
2282
|
-
([n,
|
|
2283
|
-
).sort((n,
|
|
2284
|
-
for (const [n,
|
|
2348
|
+
([n, a]) => a.lastUsed !== e && !this.scene.pinnedFiles.has(n) && !this.neededFiles.has(n)
|
|
2349
|
+
).sort((n, a) => n[1].lastUsed - a[1].lastUsed);
|
|
2350
|
+
for (const [n, a] of s) {
|
|
2285
2351
|
if (t <= this.cpuCacheBytes) break;
|
|
2286
|
-
this.cache.delete(n), this.cacheBytesTotal -=
|
|
2352
|
+
this.cache.delete(n), this.cacheBytesTotal -= a.bytes, t -= a.bytes, this.fetchCountsValue.evicted++;
|
|
2287
2353
|
}
|
|
2288
2354
|
}
|
|
2289
2355
|
}
|
|
2290
|
-
const V = new w.Vector3(), pe = new w.Vector3(), me = new w.Quaternion(), x = new w.Vector3(), ve = new w.Matrix4(),
|
|
2291
|
-
function be(
|
|
2292
|
-
return Math.ceil(3 *
|
|
2356
|
+
const V = new w.Vector3(), pe = new w.Vector3(), me = new w.Quaternion(), x = new w.Vector3(), ve = new w.Matrix4(), O = new w.Frustum(), wt = new w.Sphere(), M = new w.Vector3(), Se = new w.Vector2();
|
|
2357
|
+
function be(l) {
|
|
2358
|
+
return Math.ceil(3 * Te(l) / 4);
|
|
2293
2359
|
}
|
|
2294
|
-
function yt(
|
|
2295
|
-
const t =
|
|
2360
|
+
function yt(l, i, e) {
|
|
2361
|
+
const t = l.shPacked;
|
|
2296
2362
|
return {
|
|
2297
2363
|
count: e,
|
|
2298
|
-
positions:
|
|
2299
|
-
colors:
|
|
2300
|
-
covariances:
|
|
2364
|
+
positions: l.positions.subarray(i * 3, (i + e) * 3),
|
|
2365
|
+
colors: l.colors.subarray(i * 4, (i + e) * 4),
|
|
2366
|
+
covariances: l.covariances.subarray(i * 6, (i + e) * 6),
|
|
2301
2367
|
...t ? {
|
|
2302
2368
|
shPacked: {
|
|
2303
2369
|
...t,
|
|
@@ -2310,7 +2376,7 @@ function yt(o, i, e) {
|
|
|
2310
2376
|
};
|
|
2311
2377
|
}
|
|
2312
2378
|
const Ct = 1;
|
|
2313
|
-
class
|
|
2379
|
+
class It {
|
|
2314
2380
|
constructor(i = {}) {
|
|
2315
2381
|
d(this, "entries", /* @__PURE__ */ new Map());
|
|
2316
2382
|
d(this, "total");
|
|
@@ -2411,14 +2477,14 @@ class Tt {
|
|
|
2411
2477
|
t.weight === 0 ? this.applyTarget(t, Ct) : i.push(t);
|
|
2412
2478
|
let e = this.total;
|
|
2413
2479
|
for (; i.length > 0; ) {
|
|
2414
|
-
const t = i.reduce((
|
|
2480
|
+
const t = i.reduce((a, o) => a + o.weight, 0), s = [];
|
|
2415
2481
|
let n = 0;
|
|
2416
|
-
for (const
|
|
2417
|
-
const
|
|
2418
|
-
this.applyTarget(
|
|
2482
|
+
for (const a of i) {
|
|
2483
|
+
const o = Math.max(1, Math.floor(e * a.weight / t));
|
|
2484
|
+
this.applyTarget(a, o) && (s.push(a), n += a.applied);
|
|
2419
2485
|
}
|
|
2420
2486
|
if (s.length === 0) break;
|
|
2421
|
-
e = Math.max(0, e - n), i = i.filter((
|
|
2487
|
+
e = Math.max(0, e - n), i = i.filter((a) => !s.includes(a));
|
|
2422
2488
|
}
|
|
2423
2489
|
}
|
|
2424
2490
|
/**
|
|
@@ -2449,15 +2515,15 @@ class Tt {
|
|
|
2449
2515
|
return i.applied = i.member.setBudget(e), i.applied < e;
|
|
2450
2516
|
}
|
|
2451
2517
|
}
|
|
2452
|
-
function J(
|
|
2453
|
-
if (!Number.isFinite(
|
|
2518
|
+
function J(l) {
|
|
2519
|
+
if (!Number.isFinite(l) || l < 0)
|
|
2454
2520
|
throw new RangeError(
|
|
2455
2521
|
"BudgetGovernor member weight must be a non-negative finite number (0 suspends the member)."
|
|
2456
2522
|
);
|
|
2457
|
-
return
|
|
2523
|
+
return l;
|
|
2458
2524
|
}
|
|
2459
|
-
const we = new w.Vector3(), ye = new w.Matrix4(), Ce = new w.Frustum(), Z = new w.Box3(),
|
|
2460
|
-
class
|
|
2525
|
+
const we = new w.Vector3(), ye = new w.Matrix4(), Ce = new w.Frustum(), Z = new w.Box3(), z = new w.Sphere();
|
|
2526
|
+
class zt {
|
|
2461
2527
|
constructor(i = {}) {
|
|
2462
2528
|
d(this, "entries", /* @__PURE__ */ new Map());
|
|
2463
2529
|
d(this, "budgetGovernor");
|
|
@@ -2470,7 +2536,7 @@ class Ot {
|
|
|
2470
2536
|
d(this, "lastUpdateAt", -1 / 0);
|
|
2471
2537
|
/** Set by membership/priority changes: the next update ignores both damps. */
|
|
2472
2538
|
d(this, "forceNext", !0);
|
|
2473
|
-
if (this.budgetGovernor = i.governor ?? new
|
|
2539
|
+
if (this.budgetGovernor = i.governor ?? new It(i), this.minIntervalMs = G(i.minIntervalMs ?? 250, "minIntervalMs"), this.weightDeadband = G(i.weightDeadband ?? 0.15, "weightDeadband"), this.falloff = U(i.falloff ?? 1, "falloff"), this.offScreenWeight = U(i.offScreenWeight ?? 0.25, "offScreenWeight"), this.minWeight = U(i.minWeight ?? 0.05, "minWeight"), this.maxWeight = U(i.maxWeight ?? 8, "maxWeight"), this.maxWeight < this.minWeight)
|
|
2474
2540
|
throw new RangeError("CameraBudgetGovernor maxWeight must be >= minWeight.");
|
|
2475
2541
|
}
|
|
2476
2542
|
/** The governor this drives; use it for fixed-weight members and diagnostics. */
|
|
@@ -2499,7 +2565,7 @@ class Ot {
|
|
|
2499
2565
|
register(i, e = {}) {
|
|
2500
2566
|
if (this.entries.has(i))
|
|
2501
2567
|
throw new Error("CameraBudgetGovernor: member is already registered.");
|
|
2502
|
-
const t =
|
|
2568
|
+
const t = G(e.priority ?? 1, "priority"), s = e.fixedWeight === void 0 ? void 0 : G(e.fixedWeight, "fixedWeight"), n = s ?? t;
|
|
2503
2569
|
this.budgetGovernor.register(i, { weight: n }), this.entries.set(i, { member: i, priority: t, fixedWeight: s, applied: n }), this.forceNext = !0;
|
|
2504
2570
|
}
|
|
2505
2571
|
/**
|
|
@@ -2521,7 +2587,7 @@ class Ot {
|
|
|
2521
2587
|
const t = this.entries.get(i);
|
|
2522
2588
|
if (t === void 0)
|
|
2523
2589
|
throw new Error("CameraBudgetGovernor: member is not registered.");
|
|
2524
|
-
const s =
|
|
2590
|
+
const s = G(e, "priority");
|
|
2525
2591
|
s !== t.priority && (t.priority = s, this.forceNext = !0);
|
|
2526
2592
|
}
|
|
2527
2593
|
/**
|
|
@@ -2546,15 +2612,15 @@ class Ot {
|
|
|
2546
2612
|
i.updateMatrixWorld(), i.getWorldPosition(we), ye.multiplyMatrices(i.projectionMatrix, i.matrixWorldInverse), Ce.setFromProjectionMatrix(ye);
|
|
2547
2613
|
const s = [];
|
|
2548
2614
|
let n = !1;
|
|
2549
|
-
for (const
|
|
2550
|
-
const
|
|
2551
|
-
s.push([
|
|
2615
|
+
for (const a of this.entries.values()) {
|
|
2616
|
+
const o = this.weightFor(a);
|
|
2617
|
+
s.push([a.member, o]), !n && this.isSignificant(a.applied, o) && (n = !0);
|
|
2552
2618
|
}
|
|
2553
2619
|
if (!t && !n) return !1;
|
|
2554
2620
|
this.budgetGovernor.setWeights(s);
|
|
2555
|
-
for (const [
|
|
2556
|
-
const
|
|
2557
|
-
|
|
2621
|
+
for (const [a, o] of s) {
|
|
2622
|
+
const r = this.entries.get(a);
|
|
2623
|
+
r !== void 0 && (r.applied = o);
|
|
2558
2624
|
}
|
|
2559
2625
|
return this.lastUpdateAt = e, this.forceNext = !1, !0;
|
|
2560
2626
|
}
|
|
@@ -2592,33 +2658,33 @@ class Ot {
|
|
|
2592
2658
|
const { member: e, priority: t } = i;
|
|
2593
2659
|
if (t === 0 || !(e.effectiveVisibility ?? e.visible)) return 0;
|
|
2594
2660
|
if (e.updateWorldMatrix(!0, !1), Z.copy(e.computeSplatBounds()), Z.isEmpty()) return t * this.minWeight;
|
|
2595
|
-
Z.applyMatrix4(e.matrixWorld).getBoundingSphere(
|
|
2596
|
-
const s =
|
|
2661
|
+
Z.applyMatrix4(e.matrixWorld).getBoundingSphere(z);
|
|
2662
|
+
const s = z.radius;
|
|
2597
2663
|
if (!(s > 0)) return t * this.minWeight;
|
|
2598
|
-
const n =
|
|
2599
|
-
if (!Number.isFinite(
|
|
2600
|
-
const
|
|
2601
|
-
return t *
|
|
2664
|
+
const n = z.center.distanceTo(we) - s, a = Math.max(n, s * 1e-3, 1e-6), o = Tt((s / a) ** this.falloff, this.minWeight, this.maxWeight);
|
|
2665
|
+
if (!Number.isFinite(o)) return t * this.minWeight;
|
|
2666
|
+
const r = Ce.intersectsSphere(z) ? 1 : this.offScreenWeight;
|
|
2667
|
+
return t * o * r;
|
|
2602
2668
|
}
|
|
2603
2669
|
/** Whether a weight moved enough to be worth a reallocation. */
|
|
2604
2670
|
isSignificant(i, e) {
|
|
2605
2671
|
return i === 0 || e === 0 ? i !== e : Math.abs(e - i) > this.weightDeadband * i;
|
|
2606
2672
|
}
|
|
2607
2673
|
}
|
|
2608
|
-
function
|
|
2609
|
-
return Math.min(e, Math.max(i,
|
|
2674
|
+
function Tt(l, i, e) {
|
|
2675
|
+
return Math.min(e, Math.max(i, l));
|
|
2610
2676
|
}
|
|
2611
|
-
function
|
|
2612
|
-
if (!Number.isFinite(
|
|
2677
|
+
function G(l, i) {
|
|
2678
|
+
if (!Number.isFinite(l) || l < 0)
|
|
2613
2679
|
throw new RangeError(`CameraBudgetGovernor ${i} must be a non-negative finite number.`);
|
|
2614
|
-
return
|
|
2680
|
+
return l;
|
|
2615
2681
|
}
|
|
2616
|
-
function U(
|
|
2617
|
-
if (!Number.isFinite(
|
|
2682
|
+
function U(l, i) {
|
|
2683
|
+
if (!Number.isFinite(l) || l <= 0)
|
|
2618
2684
|
throw new RangeError(`CameraBudgetGovernor ${i} must be a positive finite number.`);
|
|
2619
|
-
return
|
|
2685
|
+
return l;
|
|
2620
2686
|
}
|
|
2621
|
-
const Rt = 16,
|
|
2687
|
+
const Rt = 16, Ft = 1;
|
|
2622
2688
|
class Ut {
|
|
2623
2689
|
constructor(i = {}) {
|
|
2624
2690
|
d(this, "entries", /* @__PURE__ */ new Set());
|
|
@@ -2629,7 +2695,7 @@ class Ut {
|
|
|
2629
2695
|
this.maxGlobalInflight = Math.max(
|
|
2630
2696
|
1,
|
|
2631
2697
|
Math.floor(i.maxGlobalInflight ?? Rt)
|
|
2632
|
-
), this.perMeshFloor = Math.max(0, Math.floor(i.perMeshFloor ??
|
|
2698
|
+
), this.perMeshFloor = Math.max(0, Math.floor(i.perMeshFloor ?? Ft));
|
|
2633
2699
|
}
|
|
2634
2700
|
/** Total slots granted and not yet released. */
|
|
2635
2701
|
get inflight() {
|
|
@@ -2718,13 +2784,13 @@ class Ut {
|
|
|
2718
2784
|
*/
|
|
2719
2785
|
shareFor(i, e) {
|
|
2720
2786
|
let t = 0, s = 0;
|
|
2721
|
-
for (const
|
|
2722
|
-
const c =
|
|
2723
|
-
|
|
2787
|
+
for (const r of this.entries) {
|
|
2788
|
+
const c = r === i ? e : H(r.client.weight());
|
|
2789
|
+
r !== i && c <= 0 && r.held === 0 && !r.demanding || (t++, s += c);
|
|
2724
2790
|
}
|
|
2725
2791
|
if (t <= 1) return this.maxGlobalInflight;
|
|
2726
|
-
const n = s > 0 ? this.maxGlobalInflight * e / s : this.maxGlobalInflight / t,
|
|
2727
|
-
return Math.max(1, Math.min(
|
|
2792
|
+
const n = s > 0 ? this.maxGlobalInflight * e / s : this.maxGlobalInflight / t, a = Math.max(1, this.perMeshFloor, Math.round(n)), o = Math.max(1, this.perMeshFloor) * (t - 1);
|
|
2793
|
+
return Math.max(1, Math.min(a, this.maxGlobalInflight - o));
|
|
2728
2794
|
}
|
|
2729
2795
|
/** Pokes the heaviest mesh that was denied since its last grant. */
|
|
2730
2796
|
wake() {
|
|
@@ -2738,10 +2804,10 @@ class Ut {
|
|
|
2738
2804
|
i && (i.demanding = !1, i.client.onSlotAvailable());
|
|
2739
2805
|
}
|
|
2740
2806
|
}
|
|
2741
|
-
function H(
|
|
2742
|
-
return Number.isFinite(
|
|
2807
|
+
function H(l) {
|
|
2808
|
+
return Number.isFinite(l) && l > 0 ? l : 0;
|
|
2743
2809
|
}
|
|
2744
|
-
const
|
|
2810
|
+
const Mt = 32 * 1024 * 1024, Bt = 250, Pt = 0.15;
|
|
2745
2811
|
class Ht {
|
|
2746
2812
|
constructor(i) {
|
|
2747
2813
|
d(this, "entries", /* @__PURE__ */ new Set());
|
|
@@ -2755,8 +2821,8 @@ class Ht {
|
|
|
2755
2821
|
throw new RangeError("Chunk cache totalBytes must be a positive finite number.");
|
|
2756
2822
|
this.totalBytesValue = Math.floor(i.totalBytes), this.perMeshFloorBytes = Math.max(
|
|
2757
2823
|
0,
|
|
2758
|
-
Math.floor(i.perMeshFloorBytes ??
|
|
2759
|
-
), this.minIntervalMs = Math.max(0, i.minIntervalMs ?? Bt), this.deadband = Math.max(0, i.deadband ??
|
|
2824
|
+
Math.floor(i.perMeshFloorBytes ?? Mt)
|
|
2825
|
+
), this.minIntervalMs = Math.max(0, i.minIntervalMs ?? Bt), this.deadband = Math.max(0, i.deadband ?? Pt);
|
|
2760
2826
|
}
|
|
2761
2827
|
/** Bytes shared across every registered mesh. */
|
|
2762
2828
|
get totalBytes() {
|
|
@@ -2830,25 +2896,25 @@ class Ht {
|
|
|
2830
2896
|
if (this.disposed) return;
|
|
2831
2897
|
const e = [...this.entries];
|
|
2832
2898
|
if (e.length === 0) return;
|
|
2833
|
-
const t = this.totalBytesValue, s = Math.min(this.perMeshFloorBytes, Math.floor(t / e.length)), n = /* @__PURE__ */ new Map(),
|
|
2834
|
-
let
|
|
2835
|
-
for (let
|
|
2836
|
-
const c = Math.max(0,
|
|
2837
|
-
let
|
|
2838
|
-
for (const
|
|
2899
|
+
const t = this.totalBytesValue, s = Math.min(this.perMeshFloorBytes, Math.floor(t / e.length)), n = /* @__PURE__ */ new Map(), a = new Set(e);
|
|
2900
|
+
let o = t;
|
|
2901
|
+
for (let r = 0; r <= e.length && a.size > 0; r++) {
|
|
2902
|
+
const c = Math.max(0, o - s * a.size);
|
|
2903
|
+
let u = 0;
|
|
2904
|
+
for (const h of a) u += Ie(h.client.weight());
|
|
2839
2905
|
const f = [];
|
|
2840
|
-
for (const
|
|
2841
|
-
const g =
|
|
2842
|
-
b >= m ? (n.set(
|
|
2906
|
+
for (const h of a) {
|
|
2907
|
+
const g = Ie(h.client.weight()), v = u > 0 ? c * g / u : c / a.size, m = kt(h.client.ceilingBytes), b = Math.floor(s + v);
|
|
2908
|
+
b >= m ? (n.set(h, m), f.push(h)) : n.set(h, b);
|
|
2843
2909
|
}
|
|
2844
2910
|
if (f.length === 0) break;
|
|
2845
|
-
for (const
|
|
2846
|
-
|
|
2847
|
-
|
|
2911
|
+
for (const h of f)
|
|
2912
|
+
a.delete(h), o -= n.get(h) ?? 0;
|
|
2913
|
+
o = Math.max(0, o);
|
|
2848
2914
|
}
|
|
2849
|
-
for (const
|
|
2850
|
-
const c = n.get(
|
|
2851
|
-
|
|
2915
|
+
for (const r of e) {
|
|
2916
|
+
const c = n.get(r) ?? 0, u = r.allowance;
|
|
2917
|
+
r.allowance = c, r !== i.silentFor && (!i.force && !this.movedEnough(u, c) || u !== c && r.client.onAllowanceChanged(c));
|
|
2852
2918
|
}
|
|
2853
2919
|
}
|
|
2854
2920
|
/** Suppresses reposts for changes too small to alter any mesh's behaviour. */
|
|
@@ -2856,22 +2922,22 @@ class Ht {
|
|
|
2856
2922
|
return i === e ? !1 : i === 0 || e === 0 ? !0 : Math.abs(e - i) / i >= this.deadband;
|
|
2857
2923
|
}
|
|
2858
2924
|
}
|
|
2859
|
-
function
|
|
2860
|
-
return Number.isFinite(
|
|
2925
|
+
function Ie(l) {
|
|
2926
|
+
return Number.isFinite(l) && l > 0 ? l : 0;
|
|
2861
2927
|
}
|
|
2862
|
-
function kt(
|
|
2863
|
-
return Number.isFinite(
|
|
2928
|
+
function kt(l) {
|
|
2929
|
+
return Number.isFinite(l) && l > 0 ? Math.floor(l) : Number.MAX_SAFE_INTEGER;
|
|
2864
2930
|
}
|
|
2865
2931
|
export {
|
|
2866
|
-
|
|
2867
|
-
|
|
2932
|
+
It as BudgetGovernor,
|
|
2933
|
+
zt as CameraBudgetGovernor,
|
|
2868
2934
|
Ht as ChunkCacheBudget,
|
|
2869
2935
|
Ut as ChunkFetchScheduler,
|
|
2870
2936
|
q as SplatLoadError,
|
|
2871
2937
|
Y as StreamedSplatMesh,
|
|
2872
2938
|
ot as createLocalDataset,
|
|
2873
2939
|
nt as httpDatasetSource,
|
|
2874
|
-
|
|
2940
|
+
D as isAbortError,
|
|
2875
2941
|
Be as resolveCpuCacheBytes
|
|
2876
2942
|
};
|
|
2877
2943
|
//# sourceMappingURL=streaming.js.map
|