@voluma/vlam 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +0 -2
  2. package/dist/chunk-loader-DlNwggfG.js.map +1 -1
  3. package/dist/{index.d.ts → core/index.d.ts} +1 -1
  4. package/dist/{splat-budget.d.ts → core/splat-budget.d.ts} +1 -1
  5. package/dist/{splat-data.d.ts → core/splat-data.d.ts} +1 -1
  6. package/dist/{splat-mesh-types.d.ts → core/splat-mesh-types.d.ts} +5 -2
  7. package/dist/{effects.d.ts → effects/index.d.ts} +3 -3
  8. package/dist/effects.js.map +1 -1
  9. package/dist/formats/ksplat/parse-ksplat.d.ts +1 -1
  10. package/dist/formats/ksplat.js.map +1 -1
  11. package/dist/formats/lcc/collision-mesh.d.ts +2 -2
  12. package/dist/formats/lcc/collision-partition.d.ts +1 -1
  13. package/dist/formats/lcc/lcc.d.ts +3 -3
  14. package/dist/formats/lcc/lcc2.d.ts +2 -2
  15. package/dist/formats/lcc/parse-lcc.d.ts +1 -1
  16. package/dist/formats/lcc.js.map +1 -1
  17. package/dist/formats/ply/parse-compressed-ply.d.ts +2 -2
  18. package/dist/formats/ply/parse-splat-ply.d.ts +2 -2
  19. package/dist/formats/ply.js.map +1 -1
  20. package/dist/formats/rad/frontier-worker-protocol.d.ts +8 -1
  21. package/dist/formats/rad/index.d.ts +1 -1
  22. package/dist/formats/rad/parse-rad.d.ts +1 -1
  23. package/dist/formats/rad/rad-foveated-source.d.ts +3 -3
  24. package/dist/formats/rad/rad.d.ts +5 -5
  25. package/dist/formats/rad.js.map +1 -1
  26. package/dist/formats/sog/parse-sog.d.ts +2 -2
  27. package/dist/formats/sog.js.map +1 -1
  28. package/dist/formats/splat/parse-splat.d.ts +1 -1
  29. package/dist/formats/splat.js.map +1 -1
  30. package/dist/formats/spz/parse-spz.d.ts +1 -1
  31. package/dist/formats/spz.js.map +1 -1
  32. package/dist/half-float-Cs4FDq8Q.js.map +1 -1
  33. package/dist/index.js +3 -3
  34. package/dist/index.js.map +1 -1
  35. package/dist/{chunk-loader.d.ts → loaders/chunk-loader.d.ts} +2 -2
  36. package/dist/{load-splat-data.d.ts → loaders/load-splat-data.d.ts} +1 -1
  37. package/dist/{load-worker-protocol.d.ts → loaders/load-worker-protocol.d.ts} +2 -2
  38. package/dist/loaders.js.map +1 -1
  39. package/dist/loading-wLo8vRbA.js.map +1 -1
  40. package/dist/lod-scheduler-B0a_uBlv.js.map +1 -1
  41. package/dist/logging-BfPdd7NJ.js.map +1 -1
  42. package/dist/ply-header-B9WllbPg.js.map +1 -1
  43. package/dist/{radix-sorter-R0FCSqKu.js → radix-sorter-BrbUg_CV.js} +2 -2
  44. package/dist/radix-sorter-BrbUg_CV.js.map +1 -0
  45. package/dist/{relighting-CSQF3UcL.js → relighting-Tiwep8yd.js} +302 -294
  46. package/dist/relighting-Tiwep8yd.js.map +1 -0
  47. package/dist/{selection-volume.d.ts → selection/selection-volume.d.ts} +1 -1
  48. package/dist/{splat-partition.d.ts → selection/splat-partition.d.ts} +1 -1
  49. package/dist/selection.js.map +1 -1
  50. package/dist/sh-pack-D5wAe5gg.js.map +1 -1
  51. package/dist/splat-budget-DuVZspPQ.js.map +1 -1
  52. package/dist/splat-data-BZM5dhhx.js.map +1 -1
  53. package/dist/{splat-mesh-aQdcWA6v.js → splat-mesh-CsLOQb08.js} +3 -3
  54. package/dist/splat-mesh-CsLOQb08.js.map +1 -0
  55. package/dist/splat-mesh-types-BZIko-_9.js.map +1 -1
  56. package/dist/{static-lod-splat-mesh.d.ts → static-lod/static-lod-splat-mesh.d.ts} +2 -2
  57. package/dist/{static-lod-worker-protocol.d.ts → static-lod/static-lod-worker-protocol.d.ts} +1 -1
  58. package/dist/{static-lod.d.ts → static-lod/static-lod.d.ts} +1 -1
  59. package/dist/static-lod.js +1 -1
  60. package/dist/static-lod.js.map +1 -1
  61. package/dist/{dataset-source.d.ts → streaming/dataset-source.d.ts} +1 -1
  62. package/dist/{streaming.d.ts → streaming/index.d.ts} +3 -3
  63. package/dist/{lod-source.d.ts → streaming/lod-source.d.ts} +4 -4
  64. package/dist/{streamed-splat-mesh-utils.d.ts → streaming/streamed-splat-mesh-utils.d.ts} +2 -2
  65. package/dist/{streamed-splat-mesh.d.ts → streaming/streamed-splat-mesh.d.ts} +45 -5
  66. package/dist/streaming.js +844 -810
  67. package/dist/streaming.js.map +1 -1
  68. package/dist/{unified-splat-mesh.d.ts → unified/unified-splat-mesh.d.ts} +13 -6
  69. package/dist/{work-buffer-gather.d.ts → unified/work-buffer-gather.d.ts} +5 -5
  70. package/dist/{work-buffer-material.d.ts → unified/work-buffer-material.d.ts} +1 -1
  71. package/dist/unified.js +280 -272
  72. package/dist/unified.js.map +1 -1
  73. package/dist/webgpu-limits-Y3CI_6_6.js.map +1 -1
  74. package/package.json +9 -9
  75. package/dist/radix-sorter-R0FCSqKu.js.map +0 -1
  76. package/dist/relighting-CSQF3UcL.js.map +0 -1
  77. package/dist/splat-mesh-aQdcWA6v.js.map +0 -1
  78. /package/dist/{compute-sorter.d.ts → core/compute-sorter.d.ts} +0 -0
  79. /package/dist/{create-splat-renderer.d.ts → core/create-splat-renderer.d.ts} +0 -0
  80. /package/dist/{depth-of-field.d.ts → core/depth-of-field.d.ts} +0 -0
  81. /package/dist/{half-float.d.ts → core/half-float.d.ts} +0 -0
  82. /package/dist/{logging.d.ts → core/logging.d.ts} +0 -0
  83. /package/dist/{merged-splat-mesh.d.ts → core/merged-splat-mesh.d.ts} +0 -0
  84. /package/dist/{orientation.d.ts → core/orientation.d.ts} +0 -0
  85. /package/dist/{radix-sort.d.ts → core/radix-sort.d.ts} +0 -0
  86. /package/dist/{radix-sorter.d.ts → core/radix-sorter.d.ts} +0 -0
  87. /package/dist/{relighting-pass.d.ts → core/relighting-pass.d.ts} +0 -0
  88. /package/dist/{relighting.d.ts → core/relighting.d.ts} +0 -0
  89. /package/dist/{sh-pack.d.ts → core/sh-pack.d.ts} +0 -0
  90. /package/dist/{sort-scheduler.d.ts → core/sort-scheduler.d.ts} +0 -0
  91. /package/dist/{sort-worker-protocol.d.ts → core/sort-worker-protocol.d.ts} +0 -0
  92. /package/dist/{sorter.d.ts → core/sorter.d.ts} +0 -0
  93. /package/dist/{source-transform.d.ts → core/source-transform.d.ts} +0 -0
  94. /package/dist/{splat-depth-pack.d.ts → core/splat-depth-pack.d.ts} +0 -0
  95. /package/dist/{splat-mesh-material.d.ts → core/splat-mesh-material.d.ts} +0 -0
  96. /package/dist/{splat-mesh-picking.d.ts → core/splat-mesh-picking.d.ts} +0 -0
  97. /package/dist/{splat-mesh-pool.d.ts → core/splat-mesh-pool.d.ts} +0 -0
  98. /package/dist/{splat-mesh.d.ts → core/splat-mesh.d.ts} +0 -0
  99. /package/dist/{splat-modifier-stack.d.ts → core/splat-modifier-stack.d.ts} +0 -0
  100. /package/dist/{splat-modifier.d.ts → core/splat-modifier.d.ts} +0 -0
  101. /package/dist/{splat-query.d.ts → core/splat-query.d.ts} +0 -0
  102. /package/dist/{splat-sort-bounds.d.ts → core/splat-sort-bounds.d.ts} +0 -0
  103. /package/dist/{storage-attribute-mirror.d.ts → core/storage-attribute-mirror.d.ts} +0 -0
  104. /package/dist/{webgpu-limits.d.ts → core/webgpu-limits.d.ts} +0 -0
  105. /package/dist/{worker-sorter.d.ts → core/worker-sorter.d.ts} +0 -0
  106. /package/dist/{xr-view.d.ts → core/xr-view.d.ts} +0 -0
  107. /package/dist/{loaders.d.ts → loaders/index.d.ts} +0 -0
  108. /package/dist/{loading.d.ts → loaders/loading.d.ts} +0 -0
  109. /package/dist/{ply-header.d.ts → loaders/ply-header.d.ts} +0 -0
  110. /package/dist/{selection.d.ts → selection/index.d.ts} +0 -0
  111. /package/dist/{static-lod-entry.d.ts → static-lod/index.d.ts} +0 -0
  112. /package/dist/{budget-governor.d.ts → streaming/budget-governor.d.ts} +0 -0
  113. /package/dist/{camera-budget-governor.d.ts → streaming/camera-budget-governor.d.ts} +0 -0
  114. /package/dist/{chunk-cache-budget.d.ts → streaming/chunk-cache-budget.d.ts} +0 -0
  115. /package/dist/{chunk-fetch-scheduler.d.ts → streaming/chunk-fetch-scheduler.d.ts} +0 -0
  116. /package/dist/{lod-manifest.d.ts → streaming/lod-manifest.d.ts} +0 -0
  117. /package/dist/{lod-scheduler.d.ts → streaming/lod-scheduler.d.ts} +0 -0
  118. /package/dist/{unified.d.ts → unified/index.d.ts} +0 -0
  119. /package/dist/{unified-work-buffer.d.ts → unified/unified-work-buffer.d.ts} +0 -0
package/dist/streaming.js CHANGED
@@ -1,55 +1,55 @@
1
1
  var Me = Object.defineProperty;
2
- var Fe = (o, i, e) => i in o ? Me(o, i, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[i] = e;
3
- var d = (o, i, e) => Fe(o, typeof i != "symbol" ? i + "" : i, e);
4
- import { h as Be, f as W, a as Ee, l as ke } from "./splat-budget-DuVZspPQ.js";
2
+ var Fe = (o, s, e) => s in o ? Me(o, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[s] = e;
3
+ var u = (o, s, e) => Fe(o, typeof s != "symbol" ? s + "" : s, 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 Pe, a as se, y as xe } from "./splat-mesh-aQdcWA6v.js";
6
+ import { S as Ee, a as ie, y as xe } from "./splat-mesh-CsLOQb08.js";
7
7
  import { L as We, r as C } from "./lod-scheduler-B0a_uBlv.js";
8
- import { S as q, t as ee, r as Ae, i as G, a as _ } from "./loading-wLo8vRbA.js";
9
- import { y as Le } from "./relighting-CSQF3UcL.js";
8
+ import { S as q, t as ee, r as Ae, i as N, 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
11
  import { s as Ie } from "./sh-pack-D5wAe5gg.js";
12
- import { w as P } from "./logging-BfPdd7NJ.js";
13
- import { r as Ne, M as De, a as ne, i as j } from "./splat-mesh-types-BZIko-_9.js";
14
- const Ge = 32e3;
12
+ import { w as E } from "./logging-BfPdd7NJ.js";
13
+ import { r as De, M as Ge, a as ne, i as j } from "./splat-mesh-types-BZIko-_9.js";
14
+ const Ne = 32e3;
15
15
  function _e(o) {
16
- return o.map((i) => ({
17
- adds: [i],
16
+ return o.map((s) => ({
17
+ adds: [s],
18
18
  removes: [],
19
- leafStart: i.leafStart,
20
- leafEnd: i.leafEnd,
21
- addCount: i.count
22
- })).sort((i, e) => i.leafStart - e.leafStart);
19
+ leafStart: s.leafStart,
20
+ leafEnd: s.leafEnd,
21
+ addCount: s.count
22
+ })).sort((s, e) => s.leafStart - e.leafStart);
23
23
  }
24
- function ze(o, i) {
25
- const e = [...o, ...i.map(([, n]) => n.run)];
24
+ function Oe(o, s) {
25
+ const e = [...o, ...s.map(([, n]) => n.run)];
26
26
  if (e.length > 0 && e.every((n) => n.coverageGroup !== void 0)) {
27
- const n = /* @__PURE__ */ new Map(), r = (l) => {
27
+ const n = /* @__PURE__ */ new Map(), a = (l) => {
28
28
  let c = n.get(l);
29
29
  return c || (c = { adds: [], removes: [] }, n.set(l, c)), c;
30
30
  };
31
31
  for (const l of o)
32
- r(l.coverageGroup).adds.push(l);
33
- for (const l of i)
34
- r(l[1].run.coverageGroup).removes.push(l);
35
- const a = [];
32
+ a(l.coverageGroup).adds.push(l);
33
+ for (const l of s)
34
+ a(l[1].run.coverageGroup).removes.push(l);
35
+ const r = [];
36
36
  for (const l of n.values()) {
37
- const c = /* @__PURE__ */ new Map(), h = (u, g) => `${u}:${g}`, f = (u, g) => {
38
- const v = h(u, g);
37
+ const c = /* @__PURE__ */ new Map(), h = (d, g) => `${d}:${g}`, f = (d, g) => {
38
+ const v = h(d, g);
39
39
  let m = c.get(v);
40
- return m || (m = { adds: [], removes: [], leafStart: u, leafEnd: g, addCount: 0 }, c.set(v, m)), m;
40
+ return m || (m = { adds: [], removes: [], leafStart: d, leafEnd: g, addCount: 0 }, c.set(v, m)), m;
41
41
  };
42
- for (const u of l.adds) {
43
- const g = f(u.leafStart, u.leafEnd);
44
- g.adds.push(u), g.addCount += u.count;
42
+ for (const d of l.adds) {
43
+ const g = f(d.leafStart, d.leafEnd);
44
+ g.adds.push(d), g.addCount += d.count;
45
45
  }
46
- for (const u of l.removes) {
47
- const g = u[1].run, v = f(g.leafStart, g.leafEnd);
48
- v.removes.push(u), v.leafStart = Math.min(v.leafStart, g.leafStart), v.leafEnd = Math.max(v.leafEnd, g.leafEnd);
46
+ for (const d of l.removes) {
47
+ const g = d[1].run, v = f(g.leafStart, g.leafEnd);
48
+ v.removes.push(d), v.leafStart = Math.min(v.leafStart, g.leafStart), v.leafEnd = Math.max(v.leafEnd, g.leafEnd);
49
49
  }
50
- a.push(...c.values());
50
+ r.push(...c.values());
51
51
  }
52
- return a.sort((l, c) => l.leafStart - c.leafStart);
52
+ return r.sort((l, c) => l.leafStart - c.leafStart);
53
53
  }
54
54
  const t = [
55
55
  ...o.map((n) => ({
@@ -58,53 +58,53 @@ function ze(o, i) {
58
58
  add: n,
59
59
  remove: void 0
60
60
  })),
61
- ...i.map((n) => ({
61
+ ...s.map((n) => ({
62
62
  start: n[1].run.leafStart,
63
63
  end: n[1].run.leafEnd,
64
64
  add: void 0,
65
65
  remove: n
66
66
  }))
67
- ].sort((n, r) => n.start - r.start || r.end - n.end), s = [];
67
+ ].sort((n, a) => n.start - a.start || a.end - n.end), i = [];
68
68
  for (const n of t) {
69
- const r = s[s.length - 1];
70
- (!r || n.start >= r.leafEnd) && s.push({
69
+ const a = i[i.length - 1];
70
+ (!a || n.start >= a.leafEnd) && i.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 a = s[s.length - 1];
78
- a.leafEnd = Math.max(a.leafEnd, n.end), n.add && (a.adds.push(n.add), a.addCount += n.add.count), n.remove && a.removes.push(n.remove);
77
+ const r = i[i.length - 1];
78
+ r.leafEnd = Math.max(r.leafEnd, n.end), n.add && (r.adds.push(n.add), r.addCount += n.add.count), n.remove && r.removes.push(n.remove);
79
79
  }
80
- return s;
80
+ return i;
81
81
  }
82
- function re(o) {
82
+ function ae(o) {
83
83
  if (o.adds.length === 0) return 1e3;
84
- const i = -Math.max(...o.adds.map((e) => e.level));
85
- return o.removes.length === 0 ? -1e3 + i : i;
84
+ const s = -Math.max(...o.adds.map((e) => e.level));
85
+ return o.removes.length === 0 ? -1e3 + s : s;
86
86
  }
87
- function Oe(o) {
87
+ function ze(o) {
88
88
  return o.length > 0 && o.every(
89
- (i) => [...i.adds, ...i.removes.map(([, e]) => e.run)].every(
89
+ (s) => [...s.adds, ...s.removes.map(([, e]) => e.run)].every(
90
90
  (e) => e.coverageGroup !== void 0
91
91
  )
92
92
  );
93
93
  }
94
- function Ue(o, i) {
94
+ function Ue(o, s) {
95
95
  const e = (n) => {
96
- const r = [...n.adds, ...n.removes.map(([, a]) => a.run)];
96
+ const a = [...n.adds, ...n.removes.map(([, r]) => r.run)];
97
97
  return {
98
98
  removeOnly: n.adds.length === 0 ? 1 : 0,
99
- view: r.some((a) => a.inView !== !1) ? 0 : 1,
100
- finest: n.adds.some((a) => a.level === 0) ? 0 : 1,
101
- screen: Math.min(...r.map((a) => a.screenImportance ?? Number.POSITIVE_INFINITY)),
102
- distance: Math.min(...r.map((a) => a.distance ?? Number.POSITIVE_INFINITY))
99
+ view: a.some((r) => r.inView !== !1) ? 0 : 1,
100
+ finest: n.adds.some((r) => r.level === 0) ? 0 : 1,
101
+ screen: Math.min(...a.map((r) => r.screenImportance ?? Number.POSITIVE_INFINITY)),
102
+ distance: Math.min(...a.map((r) => r.distance ?? Number.POSITIVE_INFINITY))
103
103
  };
104
- }, t = e(o), 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 || o.leafStart - i.leafStart;
104
+ }, t = e(o), i = e(s);
105
+ return t.removeOnly - i.removeOnly || t.view - i.view || t.finest - i.finest || t.screen - i.screen || t.distance - i.distance || o.leafStart - s.leafStart;
106
106
  }
107
- function ae(o) {
107
+ function re(o) {
108
108
  switch (o) {
109
109
  case "environment":
110
110
  return -1;
@@ -121,72 +121,72 @@ function ae(o) {
121
121
  function He(o) {
122
122
  return o === "background" ? "base" : "priority";
123
123
  }
124
- function D(o, i) {
125
- return o.coverageGroup < 0 ? `file:${i}` : o.phase === "finest-target" ? `cell:${o.coverageGroup}` : `slice:${o.coverageGroup}:${o.leafStart}:${o.leafEnd}`;
124
+ function G(o, s) {
125
+ return o.coverageGroup < 0 ? `file:${s}` : o.phase === "finest-target" ? `cell:${o.coverageGroup}` : `slice:${o.coverageGroup}:${o.leafStart}:${o.leafEnd}`;
126
126
  }
127
- function $e(o, i = 10, e = !1) {
128
- const t = te(i), s = /* @__PURE__ */ new Map();
129
- for (const [n, r] of o) {
130
- if (r.phase === "environment") continue;
131
- const a = D(r, n), l = s.get(a);
127
+ function $e(o, s = 10, e = !1) {
128
+ const t = te(s), i = /* @__PURE__ */ new Map();
129
+ for (const [n, a] of o) {
130
+ if (a.phase === "environment") continue;
131
+ const r = G(a, n), l = i.get(r);
132
132
  if (!l) {
133
- s.set(a, {
134
- distance: r.distance,
133
+ i.set(r, {
134
+ distance: a.distance,
135
135
  count: 1,
136
- inView: r.inView,
137
- screenImportance: r.screenImportance,
138
- finest: r.phase === "finest-target"
136
+ inView: a.inView,
137
+ screenImportance: a.screenImportance,
138
+ finest: a.phase === "finest-target"
139
139
  });
140
140
  continue;
141
141
  }
142
- r.distance < l.distance && (l.distance = r.distance), r.inView && (l.inView = !0), r.screenImportance < l.screenImportance && (l.screenImportance = r.screenImportance), r.phase === "finest-target" && (l.finest = !0), l.count++;
142
+ a.distance < l.distance && (l.distance = a.distance), a.inView && (l.inView = !0), a.screenImportance < l.screenImportance && (l.screenImportance = a.screenImportance), a.phase === "finest-target" && (l.finest = !0), l.count++;
143
143
  }
144
- for (const [n, r] of o) {
145
- if (r.phase === "environment") {
146
- r.kind = "priority", r.groupDistance = 0, r.groupPending = 1, r.groupInView = !0, r.groupScreenImportance = Number.NEGATIVE_INFINITY, r.groupFinest = !0, r.groupId = "environment", r.groupClass = 0;
144
+ for (const [n, a] of o) {
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 a = D(r, n), l = s.get(a);
149
+ const r = G(a, n), l = i.get(r);
150
150
  if (!l) continue;
151
151
  const c = l.inView ? 0 : l.distance <= t ? 1 : 2, h = c === 0 || c === 1 && e ? "priority" : "base";
152
- r.groupDistance = l.distance, r.groupPending = l.count, r.groupInView = l.inView, r.groupScreenImportance = l.screenImportance, r.groupFinest = l.finest, r.groupId = a, r.groupClass = c, r.kind = h;
152
+ a.groupDistance = l.distance, a.groupPending = l.count, a.groupInView = l.inView, a.groupScreenImportance = l.screenImportance, a.groupFinest = l.finest, a.groupId = r, a.groupClass = c, a.kind = h;
153
153
  }
154
154
  }
155
- function te(o, i = 2) {
155
+ function te(o, s = 2) {
156
156
  return o;
157
157
  }
158
158
  function Ye(o) {
159
- return o.adds.some((i) => i.level === 0);
159
+ return o.adds.some((s) => s.level === 0);
160
160
  }
161
- function qe(o, i, e = 2) {
161
+ function qe(o, s, e = 2) {
162
162
  if (o.level === 0) return "finest-target";
163
163
  const t = o.distance ?? Number.POSITIVE_INFINITY;
164
- return o.inView === !1 && t > te(i) ? "background" : "target";
164
+ return o.inView === !1 && t > te(s) ? "background" : "target";
165
165
  }
166
- function je(o, i, e = 2) {
166
+ function je(o, s, e = 2) {
167
167
  const t = o.distance ?? Number.POSITIVE_INFINITY;
168
- return o.inView === !1 && t > te(i) ? "background" : "coverage";
168
+ return o.inView === !1 && t > te(s) ? "background" : "coverage";
169
169
  }
170
- function oe(o, i, e, t) {
171
- const s = t.distance ?? Number.POSITIVE_INFINITY, n = t.level, r = t.inView !== !1, a = t.coverageGroup ?? -1, l = t.screenImportance ?? Number.POSITIVE_INFINITY, c = He(e), h = o.get(i);
170
+ function oe(o, s, e, t) {
171
+ const i = t.distance ?? Number.POSITIVE_INFINITY, n = t.level, a = t.inView !== !1, r = t.coverageGroup ?? -1, l = t.screenImportance ?? Number.POSITIVE_INFINITY, c = He(e), h = o.get(s);
172
172
  if (!h) {
173
- const v = D(
174
- { phase: e, coverageGroup: a, leafStart: t.leafStart, leafEnd: t.leafEnd },
175
- i
173
+ const v = G(
174
+ { phase: e, coverageGroup: r, leafStart: t.leafStart, leafEnd: t.leafEnd },
175
+ s
176
176
  );
177
- o.set(i, {
177
+ o.set(s, {
178
178
  kind: c,
179
179
  phase: e,
180
- distance: s,
180
+ distance: i,
181
181
  level: n,
182
- inView: r,
183
- coverageGroup: a,
182
+ inView: a,
183
+ coverageGroup: r,
184
184
  leafStart: t.leafStart,
185
185
  leafEnd: t.leafEnd,
186
186
  screenImportance: l,
187
- groupDistance: s,
187
+ groupDistance: i,
188
188
  groupPending: 1,
189
- groupInView: r,
189
+ groupInView: a,
190
190
  groupScreenImportance: l,
191
191
  groupFinest: e === "finest-target",
192
192
  groupId: v,
@@ -195,41 +195,41 @@ function oe(o, i, e, t) {
195
195
  });
196
196
  return;
197
197
  }
198
- const f = ae(e) < ae(h.phase), u = e === h.phase && (s < h.distance || s === h.distance && n < h.level), g = e === h.phase && s === h.distance && n === h.level && r && !h.inView;
199
- (f || u || g) && o.set(i, {
198
+ const f = re(e) < re(h.phase), d = e === h.phase && (i < h.distance || i === h.distance && n < h.level), g = e === h.phase && i === h.distance && n === h.level && a && !h.inView;
199
+ (f || d || g) && o.set(s, {
200
200
  kind: c,
201
201
  phase: e,
202
- distance: s,
202
+ distance: i,
203
203
  level: n,
204
- inView: r || h.inView,
205
- coverageGroup: a >= 0 ? a : h.coverageGroup,
204
+ inView: a || h.inView,
205
+ coverageGroup: r >= 0 ? r : h.coverageGroup,
206
206
  leafStart: t.leafStart,
207
207
  leafEnd: t.leafEnd,
208
208
  screenImportance: l,
209
- groupDistance: Math.min(s, h.groupDistance),
209
+ groupDistance: Math.min(i, h.groupDistance),
210
210
  groupPending: h.groupPending,
211
- groupInView: r || h.groupInView,
211
+ groupInView: a || h.groupInView,
212
212
  groupScreenImportance: Math.min(l, h.groupScreenImportance),
213
213
  groupFinest: e === "finest-target" || h.groupFinest,
214
214
  groupId: h.groupId,
215
215
  groupClass: h.groupClass
216
216
  });
217
217
  }
218
- function X(o, i, e, t) {
219
- const s = o.groupDistance ?? o.distance, n = i.groupDistance ?? i.distance, r = o.groupPending ?? 1, a = i.groupPending ?? 1, l = o.groupId ?? D(o, e), c = i.groupId ?? D(i, t), h = o.groupClass ?? (o.inView ? 0 : 2), f = i.groupClass ?? (i.inView ? 0 : 2), u = o.groupScreenImportance ?? o.screenImportance, g = i.groupScreenImportance ?? i.screenImportance, v = o.groupFinest ? 0 : 1, m = i.groupFinest ? 0 : 1, b = (y) => y === "coverage" ? 0 : y === "background" ? 2 : 1, T = o.phase === "environment" ? 0 : 1, I = i.phase === "environment" ? 0 : 1;
220
- return T - I || h - f || v - m || u - g || s - n || a - r || (l < c ? -1 : l > c ? 1 : 0) || b(o.phase) - b(i.phase) || o.level - i.level || e - t;
218
+ function X(o, s, e, t) {
219
+ const i = o.groupDistance ?? o.distance, n = s.groupDistance ?? s.distance, a = o.groupPending ?? 1, r = s.groupPending ?? 1, l = o.groupId ?? G(o, e), c = s.groupId ?? G(s, t), h = o.groupClass ?? (o.inView ? 0 : 2), f = s.groupClass ?? (s.inView ? 0 : 2), d = o.groupScreenImportance ?? o.screenImportance, g = s.groupScreenImportance ?? s.screenImportance, v = o.groupFinest ? 0 : 1, m = s.groupFinest ? 0 : 1, b = (y) => y === "coverage" ? 0 : y === "background" ? 2 : 1, T = o.phase === "environment" ? 0 : 1, I = s.phase === "environment" ? 0 : 1;
220
+ return T - I || h - f || v - m || d - g || i - n || r - a || (l < c ? -1 : l > c ? 1 : 0) || b(o.phase) - b(s.phase) || o.level - s.level || e - t;
221
221
  }
222
- function K(o, i, e) {
223
- if (i < 0 || e < 0 || i + e > o.count)
222
+ function K(o, s, e) {
223
+ if (s < 0 || e < 0 || s + e > o.count)
224
224
  throw new Error(
225
- `Splat range [${i}, ${i + e}) exceeds its chunk's ${o.count} splats; the manifest and chunk data disagree.`
225
+ `Splat range [${s}, ${s + e}) exceeds its chunk's ${o.count} splats; the manifest and chunk data disagree.`
226
226
  );
227
227
  const t = o.shPacked;
228
228
  return {
229
229
  count: e,
230
- positions: o.positions.subarray(i * 3, (i + e) * 3),
231
- colors: o.colors.subarray(i * 4, (i + e) * 4),
232
- covariances: o.covariances.subarray(i * 6, (i + e) * 6),
230
+ positions: o.positions.subarray(s * 3, (s + e) * 3),
231
+ colors: o.colors.subarray(s * 4, (s + e) * 4),
232
+ covariances: o.covariances.subarray(s * 6, (s + 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.
@@ -237,45 +237,45 @@ function K(o, i, e) {
237
237
  shPacked: {
238
238
  ...t,
239
239
  packed: t.packed.subarray(
240
- i * le(t.bands),
241
- (i + e) * le(t.bands)
240
+ s * le(t.bands),
241
+ (s + e) * le(t.bands)
242
242
  )
243
243
  }
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
- ...o.frontierParent ? { frontierParent: o.frontierParent.subarray(i, i + e) } : {}
247
+ ...o.frontierParent ? { frontierParent: o.frontierParent.subarray(s, s + e) } : {}
248
248
  };
249
249
  }
250
250
  function le(o) {
251
251
  return o === 1 ? 3 : o === 2 ? 8 : 15;
252
252
  }
253
253
  function Xe(o) {
254
- var i;
254
+ var s;
255
255
  return o.positions.byteLength + o.colors.byteLength + o.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 = o.shPacked) == null ? void 0 : i.packed.byteLength) ?? 0);
257
+ (((s = o.shPacked) == null ? void 0 : s.packed.byteLength) ?? 0);
258
258
  }
259
259
  function Ke(o) {
260
- const i = o.reason;
261
- return i instanceof Error ? i : new DOMException("Aborted", "AbortError");
260
+ const s = o.reason;
261
+ return s instanceof Error ? s : new DOMException("Aborted", "AbortError");
262
262
  }
263
263
  function Qe(o) {
264
- const i = o ?? Ge;
265
- if (!Number.isInteger(i) || i <= 0)
264
+ const s = o ?? Ne;
265
+ if (!Number.isInteger(s) || s <= 0)
266
266
  throw new RangeError("StreamedSplatMesh maxSplatsPerSwap must be a positive integer.");
267
- return i;
267
+ return s;
268
268
  }
269
269
  function ce(o) {
270
- const i = o ?? 1;
271
- if (!Number.isFinite(i) || i <= 0)
270
+ const s = o ?? 1;
271
+ if (!Number.isFinite(s) || s <= 0)
272
272
  throw new RangeError("StreamedSplatMesh lodScale must be a positive finite number.");
273
- return i;
273
+ return s;
274
274
  }
275
275
  function Je() {
276
276
  return Be();
277
277
  }
278
- function Ze(o, i) {
278
+ function Ze(o, s) {
279
279
  const e = o;
280
280
  if (typeof e != "object" || e === null)
281
281
  throw new Error("Streamed SOG manifest is not a JSON object.");
@@ -287,39 +287,39 @@ function Ze(o, i) {
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((l) => l.replace(/\/?meta\.json$/, "/")), s = t.map(
291
- (l) => i.resolve(l) ?? `${i.manifestUrl}#${l}`
292
- ), n = [], r = e.lodLevels, a = [e.tree];
293
- for (; a.length > 0; ) {
294
- const l = a.pop();
290
+ const t = e.filenames.map((l) => l.replace(/\/?meta\.json$/, "/")), i = t.map(
291
+ (l) => s.resolve(l) ?? `${s.manifestUrl}#${l}`
292
+ ), n = [], a = e.lodLevels, r = [e.tree];
293
+ for (; r.length > 0; ) {
294
+ const l = r.pop();
295
295
  if (typeof l != "object" || l === null)
296
296
  throw new Error("Streamed SOG manifest tree contains a malformed node.");
297
297
  if (l.children) {
298
298
  if (!Array.isArray(l.children) || l.children.length !== 2)
299
299
  throw new Error("Streamed SOG manifest tree node must have exactly two children.");
300
- a.push(l.children[1], l.children[0]);
300
+ r.push(l.children[1], l.children[0]);
301
301
  continue;
302
302
  }
303
- const c = new Array(r).fill(
303
+ const c = new Array(a).fill(
304
304
  void 0
305
305
  );
306
306
  for (const [h, f] of Object.entries(l.lods ?? {})) {
307
- const u = Number(h);
308
- u >= 0 && u < r && (et(f, e.filenames.length), c[u] = f);
307
+ const d = Number(h);
308
+ d >= 0 && d < a && (et(f, e.filenames.length), c[d] = f);
309
309
  }
310
310
  n.push({ bounds: he(l.bound), lods: c });
311
311
  }
312
312
  return {
313
313
  leaves: n,
314
- chunkUrls: s,
314
+ chunkUrls: i,
315
315
  chunkDirectories: t,
316
316
  counts: e.counts,
317
- lodLevels: r,
317
+ lodLevels: a,
318
318
  bounds: he(e.tree.bound)
319
319
  };
320
320
  }
321
- function et(o, i) {
322
- if (typeof o != "object" || o === null || !Number.isSafeInteger(o.file) || o.file < 0 || o.file >= i || !Number.isSafeInteger(o.offset) || o.offset < 0 || !Number.isSafeInteger(o.count) || o.count < 0)
321
+ function et(o, s) {
322
+ if (typeof o != "object" || o === null || !Number.isSafeInteger(o.file) || o.file < 0 || o.file >= s || !Number.isSafeInteger(o.offset) || o.offset < 0 || !Number.isSafeInteger(o.count) || o.count < 0)
323
323
  throw new Error(
324
324
  `Streamed SOG manifest leaf declares an invalid LOD range (file ${o == null ? void 0 : o.file}, offset ${o == null ? void 0 : o.offset}, count ${o == null ? void 0 : o.count}).`
325
325
  );
@@ -330,10 +330,10 @@ function he(o) {
330
330
  new w.Vector3(o.max[0], o.max[1], o.max[2])
331
331
  );
332
332
  }
333
- function tt(o, i, e, t = 0) {
334
- const s = Ze(o, i), n = t >= 1 ? t : void 0, r = s.chunkUrls.map((a, l) => {
333
+ function tt(o, s, e, t = 0) {
334
+ const i = Ze(o, s), n = t >= 1 ? t : void 0, a = i.chunkUrls.map((r, l) => {
335
335
  var f;
336
- const c = (f = s.chunkDirectories) == null ? void 0 : f[l], h = c ? i.directoryFiles(c) : null;
336
+ const c = (f = i.chunkDirectories) == null ? void 0 : f[l], h = c ? s.directoryFiles(c) : null;
337
337
  if (!(!h && !n))
338
338
  return {
339
339
  format: "sog",
@@ -342,86 +342,86 @@ function tt(o, i, e, t = 0) {
342
342
  };
343
343
  });
344
344
  return {
345
- source: new We(s, e),
346
- chunkUrls: s.chunkUrls,
347
- ...r.some(Boolean) ? { chunkOptions: r } : {},
345
+ source: new We(i, e),
346
+ chunkUrls: i.chunkUrls,
347
+ ...a.some(Boolean) ? { chunkOptions: a } : {},
348
348
  ...n ? { shBands: n } : {},
349
349
  chunkKind: "directory",
350
350
  // Streamed SOG chunks are unbundled directories
351
- bounds: s.bounds,
352
- pinnedFiles: st(s),
353
- maxResidentSplats: s.counts[0] ?? e.budget,
354
- minimumCoverageSplats: it(s)
351
+ bounds: i.bounds,
352
+ pinnedFiles: it(i),
353
+ maxResidentSplats: i.counts[0] ?? e.budget,
354
+ minimumCoverageSplats: st(i)
355
355
  };
356
356
  }
357
- function it(o) {
358
- let i = 0;
357
+ function st(o) {
358
+ let s = 0;
359
359
  for (const e of o.leaves)
360
360
  for (let t = e.lods.length - 1; t >= 0; t--) {
361
- const s = e.lods[t];
362
- if (s) {
363
- i += s.count;
361
+ const i = e.lods[t];
362
+ if (i) {
363
+ s += i.count;
364
364
  break;
365
365
  }
366
366
  }
367
- return Math.max(1, i);
367
+ return Math.max(1, s);
368
368
  }
369
- function st(o) {
370
- const i = /* @__PURE__ */ new Set();
369
+ function it(o) {
370
+ const s = /* @__PURE__ */ new Set();
371
371
  for (const e of o.leaves)
372
372
  for (let t = e.lods.length - 1; t >= 0; t--) {
373
- const s = e.lods[t];
374
- if (s) {
375
- i.add(s.file);
373
+ const i = e.lods[t];
374
+ if (i) {
375
+ s.add(i.file);
376
376
  break;
377
377
  }
378
378
  }
379
- return i;
379
+ return s;
380
380
  }
381
- function nt(o, i) {
381
+ function nt(o, s) {
382
382
  return {
383
383
  manifestUrl: o,
384
384
  resolve: (e) => new URL(e, o).href,
385
- size: (e) => rt(new URL(e, o).href, i),
385
+ size: (e) => at(new URL(e, o).href, s),
386
386
  directoryFiles: () => null,
387
387
  dispose: () => {
388
388
  }
389
389
  };
390
390
  }
391
- async function rt(o, i) {
391
+ async function at(o, s) {
392
392
  var e;
393
393
  try {
394
- const t = await fetch(o, { ...ee(i), method: "HEAD" });
395
- if (await ue(t), t.ok) {
396
- const s = t.headers.get("content-length");
397
- if (s !== null) return de(Number(s));
394
+ const t = await fetch(o, { ...ee(s), method: "HEAD" });
395
+ if (await de(t), t.ok) {
396
+ const i = t.headers.get("content-length");
397
+ if (i !== null) return ue(Number(i));
398
398
  } else if (t.status === 404)
399
399
  return null;
400
400
  } catch {
401
401
  }
402
402
  try {
403
403
  const t = await fetch(o, {
404
- ...ee(i),
405
- headers: { ...(i == null ? void 0 : i.headers) ?? {}, Range: "bytes=0-0" }
404
+ ...ee(s),
405
+ headers: { ...(s == null ? void 0 : s.headers) ?? {}, Range: "bytes=0-0" }
406
406
  });
407
- if (await ue(t), t.status !== 206) return null;
408
- const s = (e = t.headers.get("content-range")) == null ? void 0 : e.split("/")[1];
409
- return s === void 0 || s === "*" ? null : de(Number(s));
407
+ if (await de(t), t.status !== 206) return null;
408
+ const i = (e = t.headers.get("content-range")) == null ? void 0 : e.split("/")[1];
409
+ return i === void 0 || i === "*" ? null : ue(Number(i));
410
410
  } catch {
411
411
  return null;
412
412
  }
413
413
  }
414
- async function ue(o) {
415
- var i;
414
+ async function de(o) {
415
+ var s;
416
416
  try {
417
- await ((i = o.body) == null ? void 0 : i.cancel());
417
+ await ((s = o.body) == null ? void 0 : s.cancel());
418
418
  } catch {
419
419
  }
420
420
  }
421
- function de(o) {
421
+ function ue(o) {
422
422
  return Number.isSafeInteger(o) && o >= 0 ? o : null;
423
423
  }
424
- const at = [
424
+ const rt = [
425
425
  { test: (o) => o.endsWith(".lcc2"), format: "lcc2" },
426
426
  { test: (o) => o.endsWith(".lcc"), format: "lcc" },
427
427
  // The `.rad` header of a `--rad-chunked` set; `.radc` chunk files are not
@@ -430,40 +430,40 @@ const at = [
430
430
  { test: (o) => o === "lod-meta.json", format: "streamed-sog" }
431
431
  ];
432
432
  function ot(o) {
433
- const i = [];
434
- for (const a of o.keys()) {
435
- const l = $(a).toLowerCase(), c = at.find((h) => h.test(l));
436
- c && Re(a) === lt(o, c) && i.push({ path: a, format: c.format });
433
+ const s = [];
434
+ for (const r of o.keys()) {
435
+ const l = $(r).toLowerCase(), c = rt.find((h) => h.test(l));
436
+ c && Re(r) === lt(o, c) && s.push({ path: r, format: c.format });
437
437
  }
438
- if (i.length === 0)
438
+ if (s.length === 0)
439
439
  throw new q(
440
440
  "That folder has no streamed-scene manifest in it (expected a .lcc, .lcc2 or lod-meta.json file).",
441
441
  { phase: "manifest", url: "local-folder", retryable: !1 }
442
442
  );
443
- if (i.length > 1) {
444
- const a = i.map((l) => $(l.path)).join(", ");
443
+ if (s.length > 1) {
444
+ const r = s.map((l) => $(l.path)).join(", ");
445
445
  throw new q(
446
- `That folder holds more than one scene manifest (${a}) - drop one scene at a time.`,
446
+ `That folder holds more than one scene manifest (${r}) - 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 = (a) => {
451
- const l = s.get(a);
450
+ const e = s[0], t = e.path.includes("/") ? e.path.slice(0, e.path.lastIndexOf("/") + 1) : "", i = /* @__PURE__ */ new Map(), n = (r) => {
451
+ const l = i.get(r);
452
452
  if (l !== void 0) return l;
453
- const c = o.get(a);
453
+ const c = o.get(r);
454
454
  if (!c) return null;
455
455
  const h = URL.createObjectURL(c);
456
- return s.set(a, h), h;
456
+ return i.set(r, h), h;
457
457
  };
458
458
  return { source: {
459
459
  manifestUrl: n(e.path),
460
- resolve: (a) => n(t + Q(a)),
461
- size: (a) => {
460
+ resolve: (r) => n(t + Q(r)),
461
+ size: (r) => {
462
462
  var l;
463
- return Promise.resolve(((l = o.get(t + Q(a))) == null ? void 0 : l.size) ?? null);
463
+ return Promise.resolve(((l = o.get(t + Q(r))) == null ? void 0 : l.size) ?? null);
464
464
  },
465
- directoryFiles: (a) => {
466
- const l = t + Q(a).replace(/\/?$/, "/"), c = {};
465
+ directoryFiles: (r) => {
466
+ const l = t + Q(r).replace(/\/?$/, "/"), c = {};
467
467
  for (const h of o.keys()) {
468
468
  if (!h.startsWith(l)) continue;
469
469
  const f = n(h);
@@ -472,8 +472,8 @@ function ot(o) {
472
472
  return Object.keys(c).length > 0 ? c : null;
473
473
  },
474
474
  dispose: () => {
475
- for (const a of s.values()) URL.revokeObjectURL(a);
476
- s.clear();
475
+ for (const r of i.values()) URL.revokeObjectURL(r);
476
+ i.clear();
477
477
  }
478
478
  }, format: e.format, name: $(e.path) };
479
479
  }
@@ -486,10 +486,10 @@ function $(o) {
486
486
  function Re(o) {
487
487
  return o.split("/").length - 1;
488
488
  }
489
- function lt(o, i) {
489
+ function lt(o, s) {
490
490
  let e = 1 / 0;
491
491
  for (const t of o.keys())
492
- i.test($(t).toLowerCase()) && (e = Math.min(e, Re(t)));
492
+ s.test($(t).toLowerCase()) && (e = Math.min(e, Re(t)));
493
493
  return e;
494
494
  }
495
495
  const fe = {
@@ -497,17 +497,17 @@ const fe = {
497
497
  coneFov: 120,
498
498
  coneFoveate: 0.4,
499
499
  behindFoveate: 0.2
500
- }, F = 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;
500
+ }, F = 2048, ct = 6e4, ht = 0.25, dt = 8, ut = 600, ft = 250, gt = 4, pt = 500, mt = 3, vt = 4e6, ge = 65536, St = 2 * 1024 * 1024 * 1024;
501
501
  function bt(o) {
502
- const i = 52 + (o.shBands ? 16 * Math.ceil(Ie(o.shBands) / 4) : 0), t = (o.chunkSize === void 0 ? void 0 : o.chunkSize * o.chunkUrls.length) ?? o.contentSplatCount ?? o.maxResidentSplats;
503
- return Math.max(1, t) * i;
502
+ const s = 52 + (o.shBands ? 16 * Math.ceil(Ie(o.shBands) / 4) : 0), t = (o.chunkSize === void 0 ? void 0 : o.chunkSize * o.chunkUrls.length) ?? o.contentSplatCount ?? o.maxResidentSplats;
503
+ return Math.max(1, t) * s;
504
504
  }
505
- class Y extends Pe {
506
- constructor(e, t, s, n, r, a = !1) {
507
- var u, g, v;
508
- super({ capacity: s }, n);
509
- d(this, "scene");
510
- d(this, "loader", new Ve());
505
+ class Y extends Ee {
506
+ constructor(e, t, i, n, a, r = !1) {
507
+ var d, g, v;
508
+ super({ capacity: i }, n);
509
+ u(this, "scene");
510
+ u(this, "loader", new Ve());
511
511
  /**
512
512
  * Cap the *classic* (non-page-table) chunk cache evicts against.
513
513
  *
@@ -515,67 +515,67 @@ class Y extends Pe {
515
515
  * moves; without a budget it stays at the value `options.cpuCacheBytes` or the
516
516
  * device default set at construction.
517
517
  */
518
- d(this, "cpuCacheBytes");
519
- d(this, "budgetValue");
520
- d(this, "maximumBudget");
518
+ u(this, "cpuCacheBytes");
519
+ u(this, "budgetValue");
520
+ u(this, "maximumBudget");
521
521
  /** Spark's per-mesh `lodScale`; divides the page-table cut limit. */
522
- d(this, "lodScaleValue");
522
+ u(this, "lodScaleValue");
523
523
  /** Set once the governed budget has been reported as exceeding an explicit
524
524
  * `foveationDrawBudget`, so the warning is issued at most once. */
525
- d(this, "warnedDrawTargetCap", !1);
526
- d(this, "stagedSwapsEnabled");
525
+ u(this, "warnedDrawTargetCap", !1);
526
+ u(this, "stagedSwapsEnabled");
527
527
  /** Classic LCC must keep old cell coverage while a replacement is pending. */
528
- d(this, "neverRetireCoverageEarly");
529
- d(this, "appendCap");
530
- d(this, "onPerformanceEvent");
531
- d(this, "compactionCount", 0);
532
- d(this, "cache", /* @__PURE__ */ new Map());
528
+ u(this, "neverRetireCoverageEarly");
529
+ u(this, "appendCap");
530
+ u(this, "onPerformanceEvent");
531
+ u(this, "compactionCount", 0);
532
+ u(this, "cache", /* @__PURE__ */ new Map());
533
533
  /** Running byte total of {@link cache}; maintained by {@link cacheChunk}, eviction and dispose. */
534
- d(this, "cacheBytesTotal", 0);
534
+ u(this, "cacheBytesTotal", 0);
535
535
  /** In-flight chunk fetches. The kind is kept so a weight change can shed the
536
536
  * speculative ones without touching the detail that is actually on screen. */
537
- d(this, "fetching", /* @__PURE__ */ new Map());
537
+ u(this, "fetching", /* @__PURE__ */ new Map());
538
538
  /** This mesh's camera-projected share of the scene's fetch bandwidth. */
539
- d(this, "fetchWeight");
539
+ u(this, "fetchWeight");
540
540
  /** Scene-wide fetch arbitration, when the host shares one; see `requestChunk`. */
541
- d(this, "fetchScheduler");
542
- d(this, "fetchHandle");
541
+ u(this, "fetchScheduler");
542
+ u(this, "fetchHandle");
543
543
  /**
544
544
  * Blob-URL dataset from {@link loadLocal}, owned by this mesh so its object
545
545
  * URLs are revoked on {@link dispose} rather than leaking for the document's
546
546
  * lifetime. Undefined for every network-loaded mesh.
547
547
  */
548
- d(this, "localSource");
548
+ u(this, "localSource");
549
549
  /** Scene-wide chunk-cache ceiling, when the host shares one. */
550
- d(this, "cacheBudget");
551
- d(this, "cacheBudgetHandle");
550
+ u(this, "cacheBudget");
551
+ u(this, "cacheBudgetHandle");
552
552
  /**
553
553
  * The cap this mesh's frontier worker is currently evicting against.
554
554
  *
555
555
  * Mirrored on the main thread so `applyCacheAllowance` can skip no-op posts
556
556
  * and so `fetchCounts.cacheLimitBytes` stays truthful between plans.
557
557
  */
558
- d(this, "cacheLimitBytes", 0);
559
- d(this, "resident", /* @__PURE__ */ new Map());
558
+ u(this, "cacheLimitBytes", 0);
559
+ u(this, "resident", /* @__PURE__ */ new Map());
560
560
  /** Replacement runs hidden while their pool data is uploaded in bounded segments. */
561
- d(this, "staged", /* @__PURE__ */ new Map());
561
+ u(this, "staged", /* @__PURE__ */ new Map());
562
562
  /** Files awaiting a backoff retry after a transient fetch/decode error. */
563
- d(this, "retrying", /* @__PURE__ */ new Map());
563
+ u(this, "retrying", /* @__PURE__ */ new Map());
564
564
  /** Files given up on after {@link MAX_CHUNK_ATTEMPTS} failures. */
565
- d(this, "failedFiles", /* @__PURE__ */ new Set());
565
+ u(this, "failedFiles", /* @__PURE__ */ new Set());
566
566
  /**
567
567
  * When true, each resident run writes its LOD `level` into the `lodLevel`
568
568
  * float channel for false-color debug modifiers.
569
569
  */
570
- d(this, "lodLevelDebug", !1);
571
- d(this, "lodLevelChannelReady", !1);
572
- d(this, "lodLevelScratch");
570
+ u(this, "lodLevelDebug", !1);
571
+ u(this, "lodLevelChannelReady", !1);
572
+ u(this, "lodLevelScratch");
573
573
  /** Desired-but-not-resident files this tick; protected from cache eviction. */
574
- d(this, "neededFiles", /* @__PURE__ */ new Set());
574
+ u(this, "neededFiles", /* @__PURE__ */ new Set());
575
575
  /** Non-null in `foveationMode: 'page-table'`: the worker that owns the chunk
576
576
  * cache + traversal + pager off the main thread, and the always-active slab it
577
577
  * pages the returned frontier into. */
578
- d(this, "frontierWorker");
578
+ u(this, "frontierWorker");
579
579
  /**
580
580
  * The frontier's slots, as a list of equally sized pages rather than one
581
581
  * contiguous run.
@@ -588,15 +588,15 @@ class Y extends Pe {
588
588
  * (Spark's pager does the same thing one level down, binding fixed pages to
589
589
  * `(source, chunk)` pairs.)
590
590
  */
591
- d(this, "slabPages", []);
591
+ u(this, "slabPages", []);
592
592
  /** Most slots the slab may ever hold - the construction capacity. */
593
- d(this, "slabCeiling", 0);
593
+ u(this, "slabCeiling", 0);
594
594
  /** Slot count the worker's pager was last told about. */
595
- d(this, "pagerSlots", 0);
595
+ u(this, "pagerSlots", 0);
596
596
  /** Consecutive ticks the wave gate has held retirements back. */
597
- d(this, "retireHeldTicks", 0);
597
+ u(this, "retireHeldTicks", 0);
598
598
  /** Backing store for {@link planTimings}. */
599
- d(this, "planTimingsValue", {
599
+ u(this, "planTimingsValue", {
600
600
  applyMs: 0,
601
601
  worstApplyMs: 0,
602
602
  writeMs: 0,
@@ -610,7 +610,7 @@ class Y extends Pe {
610
610
  * they answer is about a *steady state* - "this keeps streaming after the view
611
611
  * settled" - which a per-frame or windowed number cannot express.
612
612
  */
613
- d(this, "fetchCountsValue", {
613
+ u(this, "fetchCountsValue", {
614
614
  priority: 0,
615
615
  base: 0,
616
616
  sweep: 0,
@@ -626,46 +626,55 @@ class Y extends Pe {
626
626
  * with the solved frontier cut and always relative to the original - scaling
627
627
  * the live values repeatedly would drift. Null when the scene has no band.
628
628
  */
629
- d(this, "frontierBandBase", null);
629
+ u(this, "frontierBandBase", null);
630
630
  /**
631
631
  * Splats per slab page for this mesh: {@link SLAB_PAGE_SPLATS}, or the whole
632
632
  * capacity when that is smaller. Spark can use one fixed page size because
633
633
  * its pool is a single large arena; here a mesh may be smaller than a page,
634
634
  * and rounding it up to one would waste most of the reservation.
635
635
  */
636
- d(this, "slabPageSplats", ge);
636
+ u(this, "slabPageSplats", ge);
637
637
  /** Target drawn-splat count for the page-table frontier; see the constructor. */
638
- d(this, "pageTableDrawBudget", 0);
638
+ u(this, "pageTableDrawBudget", 0);
639
639
  /** The unclamped draw target (`foveationDrawBudget` or the default), kept so
640
640
  * `setBudget` can re-derive the effective draw budget when the pool budget
641
641
  * moves (e.g. under a `BudgetGovernor`). */
642
- d(this, "pageTableDrawTarget", 0);
642
+ u(this, "pageTableDrawTarget", 0);
643
643
  /** Whether {@link pageTableDrawTarget} came from an explicit
644
644
  * `foveationDrawBudget` - a caller-chosen hard cap worth warning about when a
645
645
  * governed budget outgrows it, rather than the library's own default. */
646
- d(this, "pageTableDrawTargetExplicit", !1);
646
+ u(this, "pageTableDrawTargetExplicit", !1);
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
- d(this, "pageTableDrawn", 0);
649
+ u(this, "pageTableDrawn", 0);
650
+ u(this, "frontierConverged", !0);
651
+ u(this, "pendingFrontierSplats", 0);
652
+ u(this, "staleResidentSplats", 0);
653
+ u(this, "lastPlanAppends", 0);
654
+ u(this, "lastPlanMoves", 0);
655
+ u(this, "lastPlanGeneration", 0);
656
+ u(this, "lastPlanBudget", 0);
657
+ u(this, "lastPlanCamera", null);
658
+ u(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
- d(this, "pageTableSeq", 0);
653
- d(this, "pageTableInFlight", !1);
654
- d(this, "pageTableDisposed", !1);
661
+ u(this, "pageTableSeq", 0);
662
+ u(this, "pageTableInFlight", !1);
663
+ u(this, "pageTableDisposed", !1);
655
664
  /** Files whose data has been forwarded to the worker (so we don't refetch). */
656
- d(this, "pageTableCachedFiles", /* @__PURE__ */ new Set());
665
+ u(this, "pageTableCachedFiles", /* @__PURE__ */ new Set());
657
666
  /** Chunks the last frontier wanted but did not have, biggest-on-screen first.
658
667
  * These outrank the background sweep - they are the detail actually on screen. */
659
- d(this, "pageTableFetchPriority", []);
668
+ u(this, "pageTableFetchPriority", []);
660
669
  /** Frontier-cut target node size (px) and foveation ramp; see `frontierView`. */
661
- d(this, "pageTableTargetPx", se);
662
- d(this, "pageTableFoveation", fe);
670
+ u(this, "pageTableTargetPx", ie);
671
+ u(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`). */
665
- d(this, "pageTableViewportY", 0);
674
+ u(this, "pageTableViewportY", 0);
666
675
  /** Frontier cut on foveated `size / distance`. Re-derived each reschedule once
667
676
  * the drawing buffer is known; the initial value only covers the first frame. */
668
- d(this, "pageTableLimit", 0.02);
677
+ u(this, "pageTableLimit", 0.02);
669
678
  /**
670
679
  * Whether the worker's cache is sitting at its cap: sweeping past that point
671
680
  * only evicts what the frontier is using.
@@ -677,51 +686,51 @@ class Y extends Pe {
677
686
  * and is trimmed - and latching would kill its sweep for the session, so a
678
687
  * mesh that went cold could never re-warm when the camera returned.
679
688
  */
680
- d(this, "pageTableCacheAtLimit", !1);
689
+ u(this, "pageTableCacheAtLimit", !1);
681
690
  /** Per-splat channels whose edits survive chunk eviction/reload (M7.6). */
682
- d(this, "persistentChannels", /* @__PURE__ */ new Map());
691
+ u(this, "persistentChannels", /* @__PURE__ */ new Map());
683
692
  /** Chunk-file index of the always-resident environment tile, if the scene ships one. */
684
- d(this, "envFile");
693
+ u(this, "envFile");
685
694
  /** Whether the environment tile should be visible; toggled live. */
686
- d(this, "envEnabled");
695
+ u(this, "envEnabled");
687
696
  /** Pool handle of the environment tile once it has loaded (kept for toggling). */
688
- d(this, "envHandle");
697
+ u(this, "envHandle");
689
698
  /** Env splat count, measured when the tile decodes; 0 until then. */
690
- d(this, "envSplatCount", 0);
699
+ u(this, "envSplatCount", 0);
691
700
  /** Set when the env tile is larger than the whole pool - terminal, warned once. */
692
- d(this, "envUnfit", !1);
701
+ u(this, "envUnfit", !1);
693
702
  /**
694
703
  * Startup hold. `'capture'` waits for the first schedule after the host
695
704
  * applies the final camera; `'holding'` freezes that coverage set.
696
705
  */
697
- d(this, "initialRevealPhase", "off");
706
+ u(this, "initialRevealPhase", "off");
698
707
  /** Which hold, if any, was armed at construction. Survives release for recapture. */
699
- d(this, "initialRevealHold", "off");
708
+ u(this, "initialRevealHold", "off");
700
709
  /** Frozen nearby-detail / in-view coverage runs for {@link initialRevealPhase} `'holding'`. */
701
- d(this, "frozenCriticalRuns", null);
710
+ u(this, "frozenCriticalRuns", null);
702
711
  /** Timestamp of the final-camera capture that began the current hold. */
703
- d(this, "initialRevealStartedAt");
704
- d(this, "initialRevealStateValue", { status: "disabled" });
712
+ u(this, "initialRevealStartedAt");
713
+ u(this, "initialRevealStateValue", { status: "disabled" });
705
714
  /** Fetch settings this mesh was loaded with, reused for collision meshes. */
706
- d(this, "requestOptions");
715
+ u(this, "requestOptions");
707
716
  /** In-flight or settled collision load; see {@link loadCollisionMeshes}. */
708
- d(this, "collisionTiles");
709
- d(this, "collisionAbort");
710
- d(this, "pendingWork", !0);
711
- d(this, "lastScheduleTime", -1 / 0);
717
+ u(this, "collisionTiles");
718
+ u(this, "collisionAbort");
719
+ u(this, "pendingWork", !0);
720
+ u(this, "lastScheduleTime", -1 / 0);
712
721
  /** Reused leaf-coverage bitmap for {@link substituteCoverage}; grows only. */
713
- d(this, "coverageScratch");
714
- d(this, "lastCameraPos", new w.Vector3(1 / 0, 1 / 0, 1 / 0));
715
- 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 = a, this.appendCap = Qe(n.maxSplatsPerSwap);
717
- const l = n.initialReveal === "hold-coverage" && this.scene.source.coverageRunsFor !== void 0, c = n.initialReveal === "hold-near-l0" && a;
722
+ u(this, "coverageScratch");
723
+ u(this, "lastCameraPos", new w.Vector3(1 / 0, 1 / 0, 1 / 0));
724
+ u(this, "lastCameraQuat", new w.Quaternion());
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 = r, this.appendCap = Qe(n.maxSplatsPerSwap);
726
+ const l = n.initialReveal === "hold-coverage" && this.scene.source.coverageRunsFor !== void 0, c = n.initialReveal === "hold-near-l0" && r;
718
727
  l || c ? (this.initialRevealHold = l ? "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 = (u = e.environment) == null ? void 0 : u.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({
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 = (d = e.environment) == null ? void 0 : d.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: () => {
@@ -749,12 +758,12 @@ class Y extends Pe {
749
758
  ceilingBytes: f,
750
759
  onAllowanceChanged: (m) => this.applyCacheAllowance(m)
751
760
  }), this.cacheLimitBytes = this.cacheBudget && this.cacheBudgetHandle ? this.cacheBudget.allowanceFor(this.cacheBudgetHandle) : f, h || (this.cpuCacheBytes = this.cacheLimitBytes), this.fetchCountsValue.cacheLimitBytes = this.cacheLimitBytes, j(n.foveationMode)) {
752
- if (!r)
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 ?? se, this.pageTableFoveation = { ...fe, ...n.frontierFoveation }, (n.minSplatScreenRadius !== void 0 || n.maxSplatScreenRadius !== void 0) && (this.frontierBandBase = {
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 r(), this.frontierWorker.onmessage = (b) => this.applyFrontierPlan(b.data), this.pagerSlots = this.slabSlots, this.postToWorker({
766
+ }), this.slabPageSplats = Math.min(ge, i), this.slabCeiling = i, 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(), r = t.format !== void 0 && t.format !== "auto" ? t.format : n.endsWith(".lcc2") ? "lcc2" : n.endsWith(".lcc") ? "lcc" : n.endsWith(".rad") ? "rad" : "streamed-sog";
793
+ const i = Ae(e, t.baseUrl).href, n = i.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
- nt(s, t.request),
787
- r,
795
+ nt(i, t.request),
796
+ a,
788
797
  t
789
798
  );
790
799
  }
@@ -803,9 +812,9 @@ class Y extends Pe {
803
812
  * `DOMException` named `AbortError` when `options.signal` fires.
804
813
  */
805
814
  static async loadLocal(e, t = {}) {
806
- let s;
815
+ let i;
807
816
  try {
808
- s = ot(e);
817
+ i = ot(e);
809
818
  } catch (n) {
810
819
  throw n instanceof q ? n : new q(n instanceof Error ? n.message : String(n), {
811
820
  phase: "manifest",
@@ -815,42 +824,42 @@ class Y extends Pe {
815
824
  });
816
825
  }
817
826
  try {
818
- const n = await Y.fromSource(s.source, s.format, t);
819
- return n.localSource = s.source, n;
827
+ const n = await Y.fromSource(i.source, i.format, t);
828
+ return n.localSource = i.source, n;
820
829
  } catch (n) {
821
- throw s.source.dispose(), n;
830
+ throw i.source.dispose(), n;
822
831
  }
823
832
  }
824
833
  /** Shared load path: fetch the manifest from a source, then build the scene. */
825
- static async fromSource(e, t, s) {
826
- const n = s.deviceProfile, r = W(s.budget, n, {
834
+ static async fromSource(e, t, i) {
835
+ const n = i.deviceProfile, a = W(i.budget, n, {
827
836
  format: t,
828
- ...s.budgetCap === void 0 ? {} : { cap: s.budgetCap }
829
- }), a = s.maxBudget === void 0 ? r : W(s.maxBudget, n);
830
- if (a < r)
837
+ ...i.budgetCap === void 0 ? {} : { cap: i.budgetCap }
838
+ }), r = i.maxBudget === void 0 ? a : W(i.maxBudget, n);
839
+ if (r < a)
831
840
  throw new RangeError(
832
- `StreamedSplatMesh: maxBudget (${a}) must be >= budget (${r}).`
841
+ `StreamedSplatMesh: maxBudget (${r}) must be >= budget (${a}).`
833
842
  );
834
843
  const l = {
835
- budget: a,
836
- lodBaseDistance: s.lodBaseDistance ?? 10,
837
- lodMultiplier: s.lodMultiplier ?? 2
838
- }, c = s.shBands ?? (Ne(s.performanceProfile, n) === "smooth" ? 0 : De), h = Ee(n), f = s.budget === void 0 && s.maxBudget === void 0 && s.budgetCap === void 0, u = s.signal;
839
- u == null || u.throwIfAborted();
844
+ budget: r,
845
+ lodBaseDistance: i.lodBaseDistance ?? 10,
846
+ lodMultiplier: i.lodMultiplier ?? 2
847
+ }, c = i.shBands ?? (De(i.performanceProfile, n) === "smooth" ? 0 : Ge), h = Pe(n), f = (i.allowFinestLevelLift === !0 || i.budget === void 0 && i.maxBudget === void 0) && i.budgetCap === void 0, d = i.signal;
848
+ d == null || d.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, l, s.request, c, f);
853
+ g = await p(e, l, i.request, c, f);
845
854
  } catch (p) {
846
- throw G(p) ? p : _(p, { phase: "manifest", url: e.manifestUrl });
855
+ throw N(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, u));
860
+ p = await fetch(e.manifestUrl, ee(i.request, d));
852
861
  } catch (S) {
853
- throw G(S) ? S : _(S, { phase: "fetch", url: e.manifestUrl });
862
+ throw N(S) ? S : _(S, { phase: "fetch", url: e.manifestUrl });
854
863
  }
855
864
  if (!p.ok)
856
865
  throw _(
@@ -861,29 +870,29 @@ class Y extends Pe {
861
870
  const S = await p.json();
862
871
  if (t === "lcc2") {
863
872
  const { buildLcc2Scene: M } = await import("./formats/lcc.js");
864
- g = M(S, e, l, s.shBands ?? 0);
873
+ g = M(S, e, l, i.shBands ?? 0);
865
874
  } else if (t === "lcc") {
866
875
  const { buildLccScene: M } = await import("./formats/lcc.js");
867
876
  g = await M(S, e, { ...l, shBands: c });
868
877
  } else
869
- g = tt(S, e, l, s.shBands ?? 0);
878
+ g = tt(S, e, l, i.shBands ?? 0);
870
879
  } catch (S) {
871
- throw G(S) ? S : _(S, { phase: "manifest", url: e.manifestUrl });
880
+ throw N(S) ? S : _(S, { phase: "manifest", url: e.manifestUrl });
872
881
  }
873
882
  }
874
- u == null || u.throwIfAborted();
875
- const v = (t === "lcc" || t === "rad") && f ? ke(a, g.maxResidentSplats, n) : a, m = s.maxBudget === void 0 ? v : Math.min(r, v);
883
+ d == null || d.throwIfAborted();
884
+ const v = (t === "lcc" || t === "rad") && f ? ke(r, g.maxResidentSplats, n) : r, m = i.maxBudget === void 0 ? v : Math.min(a, v);
876
885
  g.source.budget = m;
877
- const b = Math.min(v, g.maxResidentSplats), T = s.experimentalStagedSwaps !== !1 ? 1.5 : 1.4, I = Math.max(
886
+ const b = Math.min(v, g.maxResidentSplats), T = i.experimentalStagedSwaps !== !1 ? 1.5 : 1.4, I = Math.max(
878
887
  1,
879
888
  Math.ceil(b * T / F)
880
889
  ), y = g.foveation ? ne(
881
- s.foveationMode,
890
+ i.foveationMode,
882
891
  t === "rad" ? "page-table" : "frontier"
883
- ) : s.foveationMode === void 0 ? void 0 : ne(s.foveationMode);
892
+ ) : i.foveationMode === void 0 ? void 0 : ne(i.foveationMode);
884
893
  let A;
885
894
  if (j(y)) {
886
- A = (await import("./frontier-worker-CAnK_Cmu.js")).default, u == null || u.throwIfAborted();
895
+ A = (await import("./frontier-worker-CAnK_Cmu.js")).default, d == null || d.throwIfAborted();
887
896
  const S = g.source;
888
897
  S.needsParentSizes !== void 0 && (S.needsParentSizes = !1);
889
898
  }
@@ -892,13 +901,13 @@ class Y extends Pe {
892
901
  m,
893
902
  I * F,
894
903
  {
895
- ...s,
904
+ ...i,
896
905
  // Classic LCC's useful first frame is the bounded nearby-detail set,
897
906
  // not its coarse shell. `.lcc2` waits for in-view coarsest coverage
898
907
  // so empty octree squares do not flash. Keep every other format
899
908
  // progressive, and let a caller explicitly request progressive for A/B.
900
- ...t === "lcc" && s.initialReveal === void 0 ? { initialReveal: "hold-near-l0" } : {},
901
- ...t === "lcc2" && s.initialReveal === void 0 ? { initialReveal: "hold-coverage" } : {},
909
+ ...t === "lcc" && i.initialReveal === void 0 ? { initialReveal: "hold-near-l0" } : {},
910
+ ...t === "lcc2" && i.initialReveal === void 0 ? { initialReveal: "hold-coverage" } : {},
902
911
  // The resolved ceiling, not the caller's raw option: it may have been
903
912
  // lifted to a moderate capture's leaf count above.
904
913
  maxBudget: v,
@@ -914,7 +923,7 @@ class Y extends Pe {
914
923
  // compensation `α·√(detRaw/detBlur)`). Match that default for `.rad`: the
915
924
  // 0.3 low-pass without the compensation makes splats too opaque (uniform
916
925
  // blur) and leaves anisotropic splats bright (needle spikes).
917
- antialias: s.antialias ?? (t === "rad" ? !0 : void 0),
926
+ antialias: i.antialias ?? (t === "rad" ? !0 : void 0),
918
927
  // Older XGRIDS LCC uses a smaller, compensated projected low-pass.
919
928
  ...t === "lcc" ? { projectedFilterProfile: "lcc" } : {},
920
929
  // Match Spark's `.rad` render exactly: the LOD alpha encoding + merged-node
@@ -926,8 +935,8 @@ class Y extends Pe {
926
935
  // same 4 ceiling `.rad` was the only format escaping. An explicit
927
936
  // `maxStdDev` still wins, through `...options` above.
928
937
  ...t === "rad" ? {
929
- lodAlpha: s.lodAlpha ?? !0,
930
- ...s.maxStdDev === void 0 && h !== void 0 ? { maxStdDev: h } : {}
938
+ lodAlpha: i.lodAlpha ?? !0,
939
+ ...i.maxStdDev === void 0 && h !== void 0 ? { maxStdDev: h } : {}
931
940
  } : {},
932
941
  // A foveated scene renders whole chunks and picks the LOD cut per splat.
933
942
  // `.rad` defaults to Spark's selected-index page table (only the frontier is
@@ -943,7 +952,7 @@ class Y extends Pe {
943
952
  A,
944
953
  t === "lcc"
945
954
  ), 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), u != null && u.aborted && (R.dispose(), u.throwIfAborted()), R;
955
+ return L && (R.matrix.copy(L), R.matrix.decompose(R.position, R.quaternion, R.scale), R.matrixWorldNeedsUpdate = !0), d != null && d.aborted && (R.dispose(), d.throwIfAborted()), R;
947
956
  }
948
957
  /** Slots the currently reserved pages can hold. */
949
958
  get slabSlots() {
@@ -965,47 +974,47 @@ class Y extends Pe {
965
974
  syncSlabPages(e) {
966
975
  if (this.slabCeiling === 0) return;
967
976
  const t = Math.max(this.slabPageSplats, Math.min(this.slabCeiling, e));
968
- let s = this.slabSlots;
969
- for (; s < t; ) {
970
- const n = Math.min(this.slabPageSplats, this.slabCeiling - s);
977
+ let i = this.slabSlots;
978
+ for (; i < t; ) {
979
+ const n = Math.min(this.slabPageSplats, this.slabCeiling - i);
971
980
  if (n <= 0) break;
972
981
  try {
973
982
  this.slabPages.push(this.reserveInactiveRange(n));
974
983
  } catch {
975
984
  break;
976
985
  }
977
- s += n;
986
+ i += n;
978
987
  }
979
988
  for (; this.slabPages.length > 1; ) {
980
989
  const n = this.slabPages[this.slabPages.length - 1];
981
- if (s - n.count < t) break;
982
- this.slabPages.pop(), s -= n.count, this.removeRange(n);
990
+ if (i - n.count < t) break;
991
+ this.slabPages.pop(), i -= n.count, this.removeRange(n);
983
992
  }
984
- s !== this.pagerSlots && (this.pagerSlots = s, this.postToWorker({ type: "resize", capacity: s }), this.pageTableDrawn > s && this.setSlabResident(s), this.pendingWork = !0, this.lastScheduleTime = -1 / 0);
993
+ i !== this.pagerSlots && (this.pagerSlots = i, this.postToWorker({ type: "resize", capacity: i }), this.pageTableDrawn > i && this.setSlabResident(i), this.pendingWork = !0, this.lastScheduleTime = -1 / 0);
985
994
  }
986
995
  /**
987
996
  * Writes `data` at slot `slot`, splitting the write where it crosses a page
988
997
  * boundary. The pager's runs are contiguous in *slot* space, which page
989
998
  * storage no longer guarantees is contiguous in the pool.
990
999
  */
991
- writeSlabSlots(e, t, s) {
1000
+ writeSlabSlots(e, t, i) {
992
1001
  let n = 0;
993
- for (; n < s; ) {
994
- const r = t + n, a = this.slabPages[Math.floor(r / this.slabPageSplats)];
995
- if (!a) return;
996
- const l = r % this.slabPageSplats, c = Math.min(s - n, this.slabPageSplats - l);
997
- this.overwriteRangeData(a, K(e, n, c), l), n += c;
1002
+ for (; n < i; ) {
1003
+ const a = t + n, r = this.slabPages[Math.floor(a / this.slabPageSplats)];
1004
+ if (!r) return;
1005
+ const l = a % this.slabPageSplats, c = Math.min(i - n, this.slabPageSplats - l);
1006
+ this.overwriteRangeData(r, K(e, n, c), l), n += c;
998
1007
  }
999
1008
  }
1000
1009
  /** Zeros slots `[slot, slot + count)`, splitting at page boundaries like
1001
1010
  * {@link writeSlabSlots}, so freed slots hold nothing drawable. */
1002
1011
  degenerateSlabSlots(e, t) {
1003
- let s = 0;
1004
- for (; s < t; ) {
1005
- const n = e + s, r = this.slabPages[Math.floor(n / this.slabPageSplats)];
1006
- if (!r) return;
1007
- const a = n % this.slabPageSplats, l = Math.min(t - s, this.slabPageSplats - a);
1008
- this.degenerateRange(r, a, l), s += l;
1012
+ let i = 0;
1013
+ for (; i < t; ) {
1014
+ const n = e + i, a = this.slabPages[Math.floor(n / this.slabPageSplats)];
1015
+ if (!a) return;
1016
+ const r = n % this.slabPageSplats, l = Math.min(t - i, this.slabPageSplats - r);
1017
+ this.degenerateRange(a, r, l), i += l;
1009
1018
  }
1010
1019
  }
1011
1020
  /**
@@ -1017,17 +1026,17 @@ class Y extends Pe {
1017
1026
  */
1018
1027
  setSlabResident(e) {
1019
1028
  for (let t = 0; t < this.slabPages.length; t++) {
1020
- const s = Math.min(
1029
+ const i = Math.min(
1021
1030
  this.slabPageSplats,
1022
1031
  Math.max(0, e - t * this.slabPageSplats)
1023
1032
  );
1024
- this.setRangeActivePrefix(this.slabPages[t], s);
1033
+ this.setRangeActivePrefix(this.slabPages[t], i);
1025
1034
  }
1026
1035
  }
1027
1036
  /** Typed post to the frontier worker. */
1028
1037
  postToWorker(e, t = []) {
1029
- var s;
1030
- (s = this.frontierWorker) == null || s.postMessage(e, t);
1038
+ var i;
1039
+ (i = this.frontierWorker) == null || i.postMessage(e, t);
1031
1040
  }
1032
1041
  /**
1033
1042
  * Applies a new decoded-chunk allowance from the scene's shared
@@ -1073,33 +1082,33 @@ class Y extends Pe {
1073
1082
  * {@link dispose} is called while the load is in flight.
1074
1083
  */
1075
1084
  async loadCollisionMeshes(e = {}) {
1076
- var r;
1077
- (r = e.signal) == null || r.throwIfAborted();
1085
+ var a;
1086
+ (a = e.signal) == null || a.throwIfAborted();
1078
1087
  const t = this.scene.collision;
1079
1088
  if (!t || t.meshes.length === 0) return [];
1080
1089
  if (!this.collisionTiles) {
1081
- const a = new AbortController();
1082
- this.collisionAbort = a, this.collisionTiles = import("./formats/lcc.js").then(
1090
+ const r = new AbortController();
1091
+ this.collisionAbort = r, this.collisionTiles = import("./formats/lcc.js").then(
1083
1092
  ({ loadCollisionMeshTiles: l }) => l(t, {
1084
1093
  ...this.requestOptions ? { request: this.requestOptions } : {},
1085
- signal: a.signal
1094
+ signal: r.signal
1086
1095
  })
1087
1096
  ).catch((l) => {
1088
1097
  throw this.collisionTiles = void 0, l;
1089
1098
  });
1090
1099
  }
1091
- const { signal: s } = e;
1092
- if (!s) return this.collisionTiles;
1100
+ const { signal: i } = e;
1101
+ if (!i) return this.collisionTiles;
1093
1102
  let n;
1094
1103
  try {
1095
1104
  return await Promise.race([
1096
1105
  this.collisionTiles,
1097
- new Promise((a, l) => {
1098
- n = () => l(Ke(s)), s.addEventListener("abort", n, { once: !0 });
1106
+ new Promise((r, l) => {
1107
+ n = () => l(Ke(i)), i.addEventListener("abort", n, { once: !0 });
1099
1108
  })
1100
1109
  ]);
1101
1110
  } finally {
1102
- n && s.removeEventListener("abort", n);
1111
+ n && i.removeEventListener("abort", n);
1103
1112
  }
1104
1113
  }
1105
1114
  /**
@@ -1168,6 +1177,14 @@ class Y extends Pe {
1168
1177
  get contentSplatCount() {
1169
1178
  return this.scene.contentSplatCount;
1170
1179
  }
1180
+ /**
1181
+ * Which `.rad` streaming strategy this mesh selected at load, or `null` when
1182
+ * the scene is not a Spark `.rad` capture.
1183
+ */
1184
+ get radStrategy() {
1185
+ var e, t;
1186
+ return ((t = (e = this.scene.chunkOptions) == null ? void 0 : e[0]) == null ? void 0 : t.format) !== "rad-chunk" ? null : this.frontierWorker ? "page-table" : "prefix";
1187
+ }
1171
1188
  /**
1172
1189
  * The drawn-splat target currently driving the `.rad` page-table frontier -
1173
1190
  * the governed budget, capped by
@@ -1181,6 +1198,23 @@ class Y extends Pe {
1181
1198
  get drawBudget() {
1182
1199
  return this.frontierWorker ? this.pageTableDrawBudget : 0;
1183
1200
  }
1201
+ /**
1202
+ * Page-table frontier coherence for hosts that gate preload/transitions.
1203
+ * `undefined` fields stay 0 when this mesh is not in page-table mode.
1204
+ */
1205
+ get frontierState() {
1206
+ return {
1207
+ frontierConverged: this.frontierWorker ? this.frontierConverged : !0,
1208
+ pendingFrontierSplats: this.pendingFrontierSplats,
1209
+ staleResidentSplats: this.staleResidentSplats,
1210
+ lastPlanAppends: this.lastPlanAppends,
1211
+ lastPlanMoves: this.lastPlanMoves,
1212
+ planGeneration: this.lastPlanGeneration,
1213
+ planBudget: this.lastPlanBudget,
1214
+ lastPlanCamera: this.lastPlanCamera,
1215
+ firstFrontierCamera: this.firstFrontierCamera
1216
+ };
1217
+ }
1184
1218
  /**
1185
1219
  * Spark's per-mesh `lodScale` (see {@link StreamedSplatMeshOptions.lodScale}).
1186
1220
  * Mutable: raise it to sharpen a focused mesh, lower it to coarsen a
@@ -1211,7 +1245,7 @@ class Y extends Pe {
1211
1245
  */
1212
1246
  setBudget(e) {
1213
1247
  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, P(
1248
+ 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
1249
  `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
1250
  ))), this.pendingWork = !0, this.lastScheduleTime = -1 / 0, t);
1217
1251
  }
@@ -1310,13 +1344,13 @@ class Y extends Pe {
1310
1344
  set lodBaseDistance(e) {
1311
1345
  this.scene.source.lodBaseDistance = e, this.pendingWork = !0;
1312
1346
  }
1313
- update(e, t, s = {}) {
1347
+ update(e, t, i = {}) {
1314
1348
  const n = performance.now();
1315
1349
  e.updateMatrixWorld(), this.updateWorldMatrix(!0, !1);
1316
- const r = Le(e, t);
1317
- this.frontierWorker && (r ? this.pageTableViewportY = r.height : (t.getDrawingBufferSize(Se), this.pageTableViewportY = Se.y));
1318
- const a = (r == null ? void 0 : r.head) ?? e, l = this.shouldReschedule(a, n) ? this.reschedule(a, n) : null;
1319
- if (super.update(e, t, s), l && this.onPerformanceEvent) {
1350
+ const a = Le(e, t);
1351
+ this.frontierWorker && (a ? this.pageTableViewportY = a.height : (t.getDrawingBufferSize(Se), this.pageTableViewportY = Se.y));
1352
+ const r = (a == null ? void 0 : a.head) ?? e, l = this.shouldReschedule(r, n) ? this.reschedule(r, n) : null;
1353
+ if (super.update(e, t, i), l && this.onPerformanceEvent) {
1320
1354
  const c = this.getUpdateTimings();
1321
1355
  l.cpuMs += performance.now() - l.timestamp, l.activeListMs = c.activeListMs, l.uploadMs = c.uploadMs, l.sortSubmitMs = c.sortSubmitMs, l.stagingTextureAllocations = c.stagingTextureAllocations, l.activeListUpdateRanges = c.activeListUpdateRanges, this.onPerformanceEvent(l);
1322
1356
  }
@@ -1334,10 +1368,10 @@ class Y extends Pe {
1334
1368
  setLodLevelDebug(e) {
1335
1369
  if (e) {
1336
1370
  this.lodLevelChannelReady || (this.defineChannel("lodLevel", { type: "float", fill: -1 }), this.lodLevelChannelReady = !0), this.lodLevelDebug = !0;
1337
- for (const { run: t, handle: s } of this.resident.values())
1338
- this.writeLodLevelChannel(s, t.level);
1339
- for (const { run: t, handle: s, uploadedCount: n } of this.staged.values())
1340
- n === t.count && this.writeLodLevelChannel(s, t.level);
1371
+ for (const { run: t, handle: i } of this.resident.values())
1372
+ this.writeLodLevelChannel(i, t.level);
1373
+ for (const { run: t, handle: i, uploadedCount: n } of this.staged.values())
1374
+ n === t.count && this.writeLodLevelChannel(i, t.level);
1341
1375
  return;
1342
1376
  }
1343
1377
  this.lodLevelDebug = !1;
@@ -1411,38 +1445,38 @@ class Y extends Pe {
1411
1445
  * @throws {Error} if the channel was not declared with
1412
1446
  * {@link definePersistentChannel}.
1413
1447
  */
1414
- paintPersistent(e, t, s, n) {
1415
- const r = this.persistentChannels.get(e);
1416
- if (!r)
1448
+ paintPersistent(e, t, i, n) {
1449
+ const a = this.persistentChannels.get(e);
1450
+ if (!a)
1417
1451
  throw new Error(
1418
1452
  `StreamedSplatMesh.paintPersistent: channel "${e}" is not a persistent channel. Call definePersistentChannel("${e}") first.`
1419
1453
  );
1420
1454
  V.copy(t), this.worldToLocal(V);
1421
- const a = s * s;
1455
+ const r = i * i;
1422
1456
  let l = 0;
1423
1457
  const c = /* @__PURE__ */ new Set();
1424
1458
  for (const { run: h } of this.resident.values()) {
1425
1459
  const f = this.cache.get(h.file);
1426
1460
  if (!f) continue;
1427
- const u = f.data.positions, g = r.edits.get(h.file) ?? /* @__PURE__ */ new Map();
1461
+ const d = f.data.positions, g = a.edits.get(h.file) ?? /* @__PURE__ */ new Map();
1428
1462
  let v = !1;
1429
1463
  for (let m = 0; m < h.count; m++) {
1430
- const b = h.offset + m, T = u[b * 3 + 0] - V.x, I = u[b * 3 + 1] - V.y, y = u[b * 3 + 2] - V.z;
1431
- if (!(T * T + I * I + y * y > a) && !g.has(b)) {
1432
- if (r.total >= r.maxEdits) {
1433
- r.warned || (r.warned = !0, P(
1434
- `StreamedSplatMesh.paintPersistent: channel "${e}" hit its maxEdits cap (${r.maxEdits}); further new edits are dropped.`
1464
+ const b = h.offset + m, T = d[b * 3 + 0] - V.x, I = d[b * 3 + 1] - V.y, y = d[b * 3 + 2] - V.z;
1465
+ if (!(T * T + I * I + y * y > r) && !g.has(b)) {
1466
+ if (a.total >= a.maxEdits) {
1467
+ a.warned || (a.warned = !0, E(
1468
+ `StreamedSplatMesh.paintPersistent: channel "${e}" hit its maxEdits cap (${a.maxEdits}); further new edits are dropped.`
1435
1469
  ));
1436
1470
  continue;
1437
1471
  }
1438
- r.total++, g.set(b, n), v = !0, l++;
1472
+ a.total++, g.set(b, n), v = !0, l++;
1439
1473
  }
1440
1474
  }
1441
- v && (r.edits.set(h.file, g), c.add(h.file));
1475
+ v && (a.edits.set(h.file, g), c.add(h.file));
1442
1476
  }
1443
1477
  if (c.size > 0)
1444
1478
  for (const { run: h, handle: f } of this.resident.values())
1445
- c.has(h.file) && this.applyPersistentRun(e, r, h, f);
1479
+ c.has(h.file) && this.applyPersistentRun(e, a, h, f);
1446
1480
  return l;
1447
1481
  }
1448
1482
  /**
@@ -1459,48 +1493,48 @@ class Y extends Pe {
1459
1493
  `StreamedSplatMesh.clearPersistentChannel: channel "${e}" is not a persistent channel.`
1460
1494
  );
1461
1495
  t.edits.clear(), t.total = 0;
1462
- for (const { run: s, handle: n } of this.resident.values()) {
1463
- const r = t.type === "byte" ? new Uint8Array(s.count) : new Float32Array(s.count);
1464
- this.writeChannel(n, e, r);
1496
+ for (const { run: i, handle: n } of this.resident.values()) {
1497
+ const a = t.type === "byte" ? new Uint8Array(i.count) : new Float32Array(i.count);
1498
+ this.writeChannel(n, e, a);
1465
1499
  }
1466
1500
  }
1467
1501
  dispose() {
1468
- var e, t, s, n, r;
1502
+ var e, t, i, n, a;
1469
1503
  if (!this.disposed) {
1470
1504
  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
1505
  }), this.collisionTiles = void 0;
1472
- for (const { controller: a } of this.fetching.values()) a.abort();
1473
- if (this.fetching.clear(), this.fetchHandle && ((s = this.fetchScheduler) == null || s.unregister(this.fetchHandle)), this.cacheBudgetHandle) {
1474
- const a = this.cacheBudgetHandle;
1475
- this.cacheBudgetHandle = void 0, (n = this.cacheBudget) == null || n.unregister(a);
1506
+ for (const { controller: r } of this.fetching.values()) r.abort();
1507
+ if (this.fetching.clear(), this.fetchHandle && ((i = this.fetchScheduler) == null || i.unregister(this.fetchHandle)), this.cacheBudgetHandle) {
1508
+ const r = this.cacheBudgetHandle;
1509
+ this.cacheBudgetHandle = void 0, (n = this.cacheBudget) == null || n.unregister(r);
1476
1510
  }
1477
- (r = this.localSource) == null || r.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();
1511
+ (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
1512
  }
1479
1513
  }
1480
1514
  shouldReschedule(e, t) {
1481
1515
  if (this.pendingWork || t - this.lastScheduleTime > ft) return !0;
1482
1516
  e.getWorldPosition(pe);
1483
- const s = this.scene.bounds.getBoundingSphere(wt).radius || 1;
1484
- return pe.distanceTo(this.lastCameraPos) > s * 25e-4 ? !0 : (e.getWorldQuaternion(me), me.angleTo(this.lastCameraQuat) > 87e-4);
1517
+ const i = this.scene.bounds.getBoundingSphere(wt).radius || 1;
1518
+ return pe.distanceTo(this.lastCameraPos) > i * 25e-4 ? !0 : (e.getWorldQuaternion(me), me.angleTo(this.lastCameraQuat) > 87e-4);
1485
1519
  }
1486
1520
  reschedule(e, t) {
1487
1521
  var L;
1488
- const s = performance.now();
1522
+ const i = performance.now();
1489
1523
  let n = null;
1490
1524
  if (this.onPerformanceEvent !== void 0) {
1491
1525
  n = { resident: /* @__PURE__ */ new Map(), staged: /* @__PURE__ */ new Map() };
1492
1526
  for (const [p, S] of this.resident) n.resident.set(p, S.run.count);
1493
1527
  for (const [p, S] of this.staged) n.staged.set(p, S.uploadedCount);
1494
1528
  }
1495
- const r = this.compactionCount;
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), z.setFromProjectionMatrix(ve), this.frontierWorker) {
1529
+ const a = this.compactionCount;
1530
+ 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) {
1497
1531
  e.getWorldDirection(B).add(this.lastCameraPos), this.worldToLocal(B), B.sub(x).normalize();
1498
1532
  const p = e.projectionMatrix.elements[5] * this.pageTableViewportY / 2;
1499
- if (p > 0 && (this.pageTableLimit = this.pageTableTargetPx / p), this.reschedulePageTable(x, B, z, t), this.onPerformanceEvent === void 0) return null;
1533
+ if (p > 0 && (this.pageTableLimit = this.pageTableTargetPx / p), this.reschedulePageTable(x, B, O, t), this.onPerformanceEvent === void 0) return null;
1500
1534
  const S = performance.now();
1501
1535
  return {
1502
1536
  timestamp: S,
1503
- cpuMs: S - s,
1537
+ cpuMs: S - i,
1504
1538
  activeListMs: 0,
1505
1539
  uploadMs: 0,
1506
1540
  sortSubmitMs: 0,
@@ -1516,25 +1550,25 @@ class Y extends Pe {
1516
1550
  };
1517
1551
  }
1518
1552
  e.getWorldDirection(B).add(this.lastCameraPos), this.worldToLocal(B), B.sub(x).normalize();
1519
- const a = this.scene.source.computeDesiredRuns(
1553
+ const r = this.scene.source.computeDesiredRuns(
1520
1554
  x,
1521
- z,
1555
+ O,
1522
1556
  t,
1523
1557
  B
1524
1558
  ), l = this.captureOrContinueInitialReveal(
1525
- a,
1559
+ r,
1526
1560
  t,
1527
1561
  x,
1528
- z
1529
- ), c = l !== null, h = l ?? a, f = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Set();
1562
+ O
1563
+ ), c = l !== null, h = l ?? r, f = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Set();
1530
1564
  for (const p of h)
1531
- f.set(C(p), p), u.add(p.file);
1565
+ f.set(C(p), p), d.add(p.file);
1532
1566
  for (const [p, S] of this.staged)
1533
1567
  f.has(p) || c && ((L = this.frozenCriticalRuns) != null && L.some((M) => C(M) === p)) || (this.removeRange(S.handle), this.staged.delete(p));
1534
1568
  for (const [p, { controller: S }] of this.fetching)
1535
- !u.has(p) && !this.scene.pinnedFiles.has(p) && S.abort();
1569
+ !d.has(p) && !this.scene.pinnedFiles.has(p) && S.abort();
1536
1570
  for (const p of this.retrying.keys())
1537
- !u.has(p) && !this.scene.pinnedFiles.has(p) && this.retrying.delete(p);
1571
+ !d.has(p) && !this.scene.pinnedFiles.has(p) && this.retrying.delete(p);
1538
1572
  this.neededFiles.clear();
1539
1573
  for (const p of h) {
1540
1574
  const S = C(p);
@@ -1548,16 +1582,16 @@ class Y extends Pe {
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
- ) : ze(g, v), b = !c && Oe(m);
1585
+ ) : Oe(g, v), b = !c && ze(m);
1552
1586
  m.sort(
1553
- (p, S) => b ? Ue(p, S) : re(p) - re(S)
1587
+ (p, S) => b ? Ue(p, S) : ae(p) - ae(S)
1554
1588
  );
1555
1589
  const T = /* @__PURE__ */ new Map();
1556
1590
  this.updateEnvironment(t, T);
1557
1591
  let I = 0, y = !1, A = !1, R = !1;
1558
1592
  for (const p of m) {
1559
1593
  if (!b && p.removes.length > 0 && y) {
1560
- if (this.neverRetireCoverageEarly || !A && this.retireHeldTicks < dt) {
1594
+ if (this.neverRetireCoverageEarly || !A && this.retireHeldTicks < ut) {
1561
1595
  this.pendingWork = !0, R = !0;
1562
1596
  continue;
1563
1597
  }
@@ -1567,32 +1601,32 @@ class Y extends Pe {
1567
1601
  this.applyGroup(p, t);
1568
1602
  continue;
1569
1603
  }
1570
- const S = p.adds.filter((E) => !this.cache.has(E.file)), M = c || Ye(p) && this.initialRevealHold !== "hold-coverage";
1604
+ const S = p.adds.filter((P) => !this.cache.has(P.file)), M = c || Ye(p) && this.initialRevealHold !== "hold-coverage";
1571
1605
  if (S.length > 0) {
1572
- let E = !1;
1606
+ let P = !1;
1573
1607
  for (const k of S)
1574
1608
  this.failedFiles.has(k.file) || (oe(
1575
1609
  T,
1576
1610
  k.file,
1577
1611
  qe(k, this.scene.source.lodBaseDistance),
1578
1612
  k
1579
- ), E = !0);
1580
- if (c || this.substituteCoverage(p, t, T, M), E && (this.pendingWork = !0, y = !0), !c) continue;
1613
+ ), P = !0);
1614
+ if (c || this.substituteCoverage(p, t, T, M), 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 E = this.stageGroup(p, t, Math.max(0, this.appendCap - I));
1588
- if (I += E, !p.adds.every((k) => {
1589
- var ie;
1590
- return ((ie = this.staged.get(C(k))) == null ? void 0 : ie.uploadedCount) === k.count;
1621
+ const P = this.stageGroup(p, t, Math.max(0, this.appendCap - I));
1622
+ if (I += 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 (E > 0 && !c) {
1629
+ if (P > 0 && !c) {
1596
1630
  this.deferNextSortRequest(), this.pendingWork = !0, y = !0;
1597
1631
  continue;
1598
1632
  }
@@ -1616,8 +1650,8 @@ class Y extends Pe {
1616
1650
  return this.flushClassicFetches(T, 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
- r,
1620
- s
1653
+ a,
1654
+ i
1621
1655
  );
1622
1656
  }
1623
1657
  rowAlignedSplats(e) {
@@ -1631,39 +1665,39 @@ class Y extends Pe {
1631
1665
  * Coarser home levels come from {@link LodSource.runsAtLevelFor}.
1632
1666
  */
1633
1667
  selectHomeSeedRuns(e) {
1634
- var r;
1635
- const t = this.scene.source.lodBaseDistance, s = e.filter(
1636
- (a) => a.coverageGroup !== void 0 && (a.distance ?? Number.POSITIVE_INFINITY) <= t
1668
+ var a;
1669
+ const t = this.scene.source.lodBaseDistance, i = e.filter(
1670
+ (r) => r.coverageGroup !== void 0 && (r.distance ?? Number.POSITIVE_INFINITY) <= t
1637
1671
  ).sort(
1638
- (a, l) => (a.distance ?? Number.POSITIVE_INFINITY) - (l.distance ?? Number.POSITIVE_INFINITY) || // Same distance: prefer in-view, then finer.
1639
- (a.inView === !0 ? 0 : 1) - (l.inView === !0 ? 0 : 1) || a.level - l.level || a.leafStart - l.leafStart
1640
- ), n = (r = s[0]) == null ? void 0 : r.coverageGroup;
1641
- return n === void 0 ? [] : s.filter((a) => a.coverageGroup === n);
1672
+ (r, l) => (r.distance ?? Number.POSITIVE_INFINITY) - (l.distance ?? Number.POSITIVE_INFINITY) || // Same distance: prefer in-view, then finer.
1673
+ (r.inView === !0 ? 0 : 1) - (l.inView === !0 ? 0 : 1) || r.level - l.level || r.leafStart - l.leafStart
1674
+ ), n = (a = i[0]) == null ? void 0 : a.coverageGroup;
1675
+ return n === void 0 ? [] : i.filter((r) => r.coverageGroup === n);
1642
1676
  }
1643
1677
  coarsenHomeRuns(e, t) {
1644
- var r;
1645
- const s = [], n = this.scene.source;
1646
- for (const a of e) {
1647
- if (a.level === t) {
1648
- s.push(a);
1678
+ var a;
1679
+ const i = [], n = this.scene.source;
1680
+ for (const r of e) {
1681
+ if (r.level === t) {
1682
+ i.push(r);
1649
1683
  continue;
1650
1684
  }
1651
- const l = ((r = n.runsAtLevelFor) == null ? void 0 : r.call(n, a.leafStart, a.leafEnd, t)) ?? [];
1685
+ const l = ((a = n.runsAtLevelFor) == null ? void 0 : a.call(n, r.leafStart, r.leafEnd, t)) ?? [];
1652
1686
  if (l.length !== 0)
1653
1687
  for (const c of l)
1654
- s.push({
1688
+ i.push({
1655
1689
  ...c,
1656
- distance: a.distance,
1657
- inView: a.inView,
1658
- ...a.coverageGroup === void 0 ? {} : { coverageGroup: a.coverageGroup },
1659
- ...a.screenImportance === void 0 ? {} : { screenImportance: a.screenImportance }
1690
+ distance: r.distance,
1691
+ inView: r.inView,
1692
+ ...r.coverageGroup === void 0 ? {} : { coverageGroup: r.coverageGroup },
1693
+ ...r.screenImportance === void 0 ? {} : { screenImportance: r.screenImportance }
1660
1694
  });
1661
1695
  }
1662
- return s;
1696
+ return i;
1663
1697
  }
1664
1698
  criticalRunsFitCapacity(e) {
1665
1699
  let t = 0;
1666
- for (const s of e) t += this.rowAlignedSplats(s.count);
1700
+ for (const i of e) t += this.rowAlignedSplats(i.count);
1667
1701
  return t <= this.freeSplatCapacity;
1668
1702
  }
1669
1703
  publishInitialRevealProgress(e) {
@@ -1673,50 +1707,50 @@ class Y extends Pe {
1673
1707
  let h = t.get(c);
1674
1708
  h || (h = [], t.set(c, h)), h.push(l);
1675
1709
  }
1676
- let s = 0, n = 0, r = 0;
1710
+ let i = 0, n = 0, a = 0;
1677
1711
  for (const l of t.values()) {
1678
1712
  let c = !0;
1679
1713
  for (const h of l) {
1680
1714
  n += h.count;
1681
1715
  const f = C(h);
1682
1716
  if (this.resident.has(f)) {
1683
- s += h.count;
1717
+ i += h.count;
1684
1718
  continue;
1685
1719
  }
1686
- const u = this.staged.get(f);
1687
- s += (u == null ? void 0 : u.uploadedCount) ?? 0, (!u || u.uploadedCount !== h.count) && (c = !1);
1720
+ const d = this.staged.get(f);
1721
+ i += (d == null ? void 0 : d.uploadedCount) ?? 0, (!d || d.uploadedCount !== h.count) && (c = !1);
1688
1722
  }
1689
- c && r++;
1723
+ c && a++;
1690
1724
  }
1691
- const a = this.initialRevealStateValue;
1692
- if (a.status === "degraded") {
1725
+ const r = this.initialRevealStateValue;
1726
+ if (r.status === "degraded") {
1693
1727
  this.initialRevealStateValue = {
1694
1728
  status: "degraded",
1695
- reason: a.reason,
1696
- stagedSplats: s,
1729
+ reason: r.reason,
1730
+ stagedSplats: i,
1697
1731
  totalSplats: n,
1698
- readyGroups: r,
1732
+ readyGroups: a,
1699
1733
  totalGroups: t.size
1700
1734
  };
1701
1735
  return;
1702
1736
  }
1703
1737
  this.initialRevealStateValue = {
1704
1738
  status: "pending",
1705
- stagedSplats: s,
1739
+ stagedSplats: i,
1706
1740
  totalSplats: n,
1707
- readyGroups: r,
1741
+ readyGroups: a,
1708
1742
  totalGroups: t.size
1709
1743
  };
1710
1744
  }
1711
1745
  releaseInitialReveal(e, t) {
1712
- const s = this.frozenCriticalRuns ?? [];
1713
- this.publishInitialRevealProgress(s);
1714
- const n = this.initialRevealStateValue, r = n.status === "pending" || n.status === "degraded" ? n.stagedSplats : 0, a = n.status === "pending" || n.status === "degraded" ? n.totalSplats : 0, l = n.status === "pending" || n.status === "degraded" ? n.readyGroups : 0, c = n.status === "pending" || n.status === "degraded" ? n.totalGroups : 0;
1746
+ const i = this.frozenCriticalRuns ?? [];
1747
+ this.publishInitialRevealProgress(i);
1748
+ const n = this.initialRevealStateValue, a = n.status === "pending" || n.status === "degraded" ? n.stagedSplats : 0, r = n.status === "pending" || n.status === "degraded" ? n.totalSplats : 0, l = 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: r,
1719
- totalSplats: a,
1752
+ stagedSplats: a,
1753
+ totalSplats: r,
1720
1754
  readyGroups: l,
1721
1755
  totalGroups: c
1722
1756
  }, this.frozenCriticalRuns = null, this.initialRevealPhase = "released", this.pendingWork = !0;
@@ -1726,12 +1760,12 @@ class Y extends Pe {
1726
1760
  * Missing `coverageRunsFor` (or an empty result after fallback) releases
1727
1761
  * immediately so the mesh does not stay hidden with nothing to fetch.
1728
1762
  */
1729
- captureCoverageHold(e, t, s) {
1730
- var r, a;
1731
- const n = ((a = (r = this.scene.source).coverageRunsFor) == null ? void 0 : a.call(r, e, t)) ?? [];
1763
+ captureCoverageHold(e, t, i) {
1764
+ var a, r;
1765
+ const n = ((r = (a = this.scene.source).coverageRunsFor) == null ? void 0 : r.call(a, e, t)) ?? [];
1732
1766
  if (n.length === 0) {
1733
1767
  if (this.environmentPendingForReveal()) {
1734
- this.frozenCriticalRuns = [], this.initialRevealStartedAt = s, this.initialRevealPhase = "holding", this.publishInitialRevealProgress([]);
1768
+ this.frozenCriticalRuns = [], this.initialRevealStartedAt = i, this.initialRevealPhase = "holding", this.publishInitialRevealProgress([]);
1735
1769
  return;
1736
1770
  }
1737
1771
  this.initialRevealStateValue = { status: "ready" }, this.initialRevealPhase = "released";
@@ -1741,54 +1775,54 @@ class Y extends Pe {
1741
1775
  this.frozenCriticalRuns = n, this.releaseInitialReveal("degraded", "capacity");
1742
1776
  return;
1743
1777
  }
1744
- this.frozenCriticalRuns = n, this.initialRevealStartedAt = s, this.initialRevealPhase = "holding", this.publishInitialRevealProgress(n);
1778
+ this.frozenCriticalRuns = n, this.initialRevealStartedAt = i, this.initialRevealPhase = "holding", this.publishInitialRevealProgress(n);
1745
1779
  }
1746
- captureOrContinueInitialReveal(e, t, s, n) {
1780
+ captureOrContinueInitialReveal(e, t, i, n) {
1747
1781
  if (this.initialRevealPhase === "off" || this.initialRevealPhase === "released") return null;
1748
1782
  if (this.initialRevealPhase === "capture")
1749
1783
  if (this.initialRevealHold === "hold-coverage")
1750
- this.captureCoverageHold(s, n, t);
1784
+ this.captureCoverageHold(i, n, t);
1751
1785
  else {
1752
- const r = this.selectHomeSeedRuns(e);
1753
- let a = [];
1754
- if (r.length === 0) {
1786
+ const a = this.selectHomeSeedRuns(e);
1787
+ let r = [];
1788
+ if (a.length === 0) {
1755
1789
  const l = this.scene.source.lodBaseDistance * this.scene.source.lodMultiplier * this.scene.source.lodMultiplier, c = e.filter(
1756
1790
  (f) => f.level <= 2 && f.coverageGroup !== void 0 && (f.distance ?? Number.POSITIVE_INFINITY) <= l
1757
1791
  ), h = [...c].sort(
1758
- (f, u) => (f.distance ?? Number.POSITIVE_INFINITY) - (u.distance ?? Number.POSITIVE_INFINITY) || (f.inView === !0 ? 0 : 1) - (u.inView === !0 ? 0 : 1) || (f.screenImportance ?? Number.POSITIVE_INFINITY) - (u.screenImportance ?? Number.POSITIVE_INFINITY) || f.leafStart - u.leafStart
1792
+ (f, d) => (f.distance ?? Number.POSITIVE_INFINITY) - (d.distance ?? Number.POSITIVE_INFINITY) || (f.inView === !0 ? 0 : 1) - (d.inView === !0 ? 0 : 1) || (f.screenImportance ?? Number.POSITIVE_INFINITY) - (d.screenImportance ?? Number.POSITIVE_INFINITY) || f.leafStart - d.leafStart
1759
1793
  )[0];
1760
1794
  if (!h)
1761
1795
  return this.initialRevealStateValue = { status: "ready" }, this.initialRevealPhase = "released", null;
1762
- if (a = h.coverageGroup !== void 0 ? c.filter((f) => f.coverageGroup === h.coverageGroup) : [h], this.criticalRunsFitCapacity(a) || (a = h.coverageGroup !== void 0 ? c.filter(
1796
+ if (r = h.coverageGroup !== void 0 ? c.filter((f) => f.coverageGroup === h.coverageGroup) : [h], this.criticalRunsFitCapacity(r) || (r = h.coverageGroup !== void 0 ? c.filter(
1763
1797
  (f) => f.coverageGroup === h.coverageGroup && this.criticalRunsFitCapacity([f])
1764
- ).slice(0, 1) : c.filter((f) => this.criticalRunsFitCapacity([f])).slice(0, 1)), a.length === 0 || !this.criticalRunsFitCapacity(a))
1765
- return this.frozenCriticalRuns = a.length > 0 ? a : [h], this.releaseInitialReveal("degraded", "capacity"), null;
1766
- this.frozenCriticalRuns = a, this.initialRevealStartedAt = t, this.initialRevealPhase = "holding", this.publishInitialRevealProgress(a);
1798
+ ).slice(0, 1) : c.filter((f) => this.criticalRunsFitCapacity([f])).slice(0, 1)), r.length === 0 || !this.criticalRunsFitCapacity(r))
1799
+ return this.frozenCriticalRuns = r.length > 0 ? r : [h], this.releaseInitialReveal("degraded", "capacity"), null;
1800
+ this.frozenCriticalRuns = r, this.initialRevealStartedAt = t, this.initialRevealPhase = "holding", this.publishInitialRevealProgress(r);
1767
1801
  } else {
1768
1802
  for (const l of [0, 1, 2]) {
1769
- const c = this.coarsenHomeRuns(r, l);
1803
+ const c = this.coarsenHomeRuns(a, l);
1770
1804
  if (c.length !== 0) {
1771
1805
  if (this.criticalRunsFitCapacity(c)) {
1772
- a = c;
1806
+ r = c;
1773
1807
  break;
1774
1808
  }
1775
- a = c;
1809
+ r = c;
1776
1810
  }
1777
1811
  }
1778
- if (a.length === 0)
1812
+ if (r.length === 0)
1779
1813
  return this.initialRevealStateValue = { status: "ready" }, this.initialRevealPhase = "released", null;
1780
- if (!this.criticalRunsFitCapacity(a))
1781
- return this.frozenCriticalRuns = a, this.releaseInitialReveal("degraded", "capacity"), null;
1782
- this.frozenCriticalRuns = a, this.initialRevealStartedAt = t, this.initialRevealPhase = "holding", this.publishInitialRevealProgress(a);
1814
+ if (!this.criticalRunsFitCapacity(r))
1815
+ return this.frozenCriticalRuns = r, this.releaseInitialReveal("degraded", "capacity"), null;
1816
+ this.frozenCriticalRuns = r, this.initialRevealStartedAt = t, this.initialRevealPhase = "holding", this.publishInitialRevealProgress(r);
1783
1817
  }
1784
1818
  }
1785
1819
  if (this.initialRevealPhase !== "holding" || !this.frozenCriticalRuns) return null;
1786
1820
  if (this.initialRevealStartedAt !== void 0 && t - this.initialRevealStartedAt >= ct)
1787
1821
  return this.releaseInitialReveal("degraded", "timeout"), null;
1788
- for (const r of this.frozenCriticalRuns)
1789
- if (this.failedFiles.has(r.file) && !this.resident.has(C(r))) {
1790
- const a = this.staged.get(C(r));
1791
- if (!a || a.uploadedCount !== r.count)
1822
+ for (const a of this.frozenCriticalRuns)
1823
+ if (this.failedFiles.has(a.file) && !this.resident.has(C(a))) {
1824
+ const r = this.staged.get(C(a));
1825
+ if (!r || r.uploadedCount !== a.count)
1792
1826
  return this.releaseInitialReveal("degraded", "fetch-failed"), null;
1793
1827
  }
1794
1828
  return this.publishInitialRevealProgress(this.frozenCriticalRuns), this.frozenCriticalRuns;
@@ -1805,18 +1839,18 @@ class Y extends Pe {
1805
1839
  return this.envFile !== void 0 && this.envEnabled && !this.envUnfit && this.envHandle === void 0 && !this.failedFiles.has(this.envFile);
1806
1840
  }
1807
1841
  /** Creates a performance event for a changed streamed-LOD tick, if any. */
1808
- createPerformanceEvent(e, t, s, n) {
1809
- let r = 0, a = 0;
1810
- for (const [u, g] of this.resident)
1811
- a += g.run.count, e.has(u) || (r += g.run.count);
1842
+ createPerformanceEvent(e, t, i, n) {
1843
+ let a = 0, r = 0;
1844
+ for (const [d, g] of this.resident)
1845
+ r += g.run.count, e.has(d) || (a += g.run.count);
1812
1846
  let l = 0;
1813
- for (const [u, g] of e)
1814
- this.resident.has(u) || (l += g);
1847
+ for (const [d, g] of e)
1848
+ this.resident.has(d) || (l += g);
1815
1849
  let c = 0;
1816
- for (const [u, g] of this.staged)
1817
- c += Math.max(0, g.uploadedCount - (t.get(u) ?? 0));
1818
- const h = this.compactionCount !== s;
1819
- if (r === 0 && l === 0 && c === 0 && !h) return null;
1850
+ for (const [d, g] of this.staged)
1851
+ c += Math.max(0, g.uploadedCount - (t.get(d) ?? 0));
1852
+ const h = this.compactionCount !== i;
1853
+ if (a === 0 && l === 0 && c === 0 && !h) return null;
1820
1854
  const f = performance.now();
1821
1855
  return {
1822
1856
  timestamp: f,
@@ -1826,73 +1860,73 @@ class Y extends Pe {
1826
1860
  sortSubmitMs: 0,
1827
1861
  stagingTextureAllocations: 0,
1828
1862
  activeListUpdateRanges: 0,
1829
- appendedCount: r,
1863
+ appendedCount: a,
1830
1864
  removedCount: l,
1831
1865
  stagedCount: c,
1832
- uploadCount: r + c,
1833
- activeCount: a,
1834
- forcedSort: a === 0 || r + l >= a * ht,
1866
+ uploadCount: a + c,
1867
+ activeCount: r,
1868
+ forcedSort: r === 0 || a + l >= r * ht,
1835
1869
  compacted: h
1836
1870
  };
1837
1871
  }
1838
1872
  /** Returns whether all new rows can coexist with the currently visible region. */
1839
1873
  canStageGroup(e) {
1840
- return e.adds.filter((s) => !this.staged.has(C(s))).reduce((s, n) => s + this.rowAlignedSplats(n.count), 0) <= this.freeSplatCapacity;
1874
+ return e.adds.filter((i) => !this.staged.has(C(i))).reduce((i, n) => i + this.rowAlignedSplats(n.count), 0) <= this.freeSplatCapacity;
1841
1875
  }
1842
1876
  /**
1843
1877
  * Uploads a bounded part of a replacement without rendering it.
1844
1878
  * Skips runs whose chunks are not yet cached so siblings can stage out of order.
1845
1879
  */
1846
- stageGroup(e, t, s) {
1847
- if (s <= 0) return 0;
1880
+ stageGroup(e, t, i) {
1881
+ if (i <= 0) return 0;
1848
1882
  let n = 0;
1849
- for (const r of e.adds) {
1850
- const a = C(r), l = this.cache.get(r.file);
1883
+ for (const a of e.adds) {
1884
+ const r = C(a), l = this.cache.get(a.file);
1851
1885
  if (!l) continue;
1852
- let c = this.staged.get(a);
1886
+ let c = this.staged.get(r);
1853
1887
  if (!c) {
1854
1888
  let f;
1855
1889
  try {
1856
- f = this.reserveInactiveRange(r.count);
1890
+ f = this.reserveInactiveRange(a.count);
1857
1891
  } catch {
1858
1892
  this.compactionCount++, this.compact();
1859
1893
  try {
1860
- f = this.reserveInactiveRange(r.count);
1894
+ f = this.reserveInactiveRange(a.count);
1861
1895
  } catch {
1862
1896
  this.pendingWork = !0;
1863
1897
  break;
1864
1898
  }
1865
1899
  }
1866
- c = { run: r, handle: f, uploadedCount: 0 }, this.staged.set(a, c);
1900
+ c = { run: a, handle: f, uploadedCount: 0 }, this.staged.set(r, c);
1867
1901
  }
1868
- if (c.uploadedCount === r.count) continue;
1869
- const h = Math.min(r.count - c.uploadedCount, s - n);
1902
+ if (c.uploadedCount === a.count) continue;
1903
+ const h = Math.min(a.count - c.uploadedCount, i - n);
1870
1904
  if (h <= 0) break;
1871
1905
  if (this.writeInactiveRange(
1872
1906
  c.handle,
1873
- K(l.data, r.offset + c.uploadedCount, h),
1907
+ K(l.data, a.offset + c.uploadedCount, h),
1874
1908
  c.uploadedCount
1875
- ), c.uploadedCount += h, l.lastUsed = t, n += h, c.uploadedCount === r.count) {
1876
- this.writeLodLevelChannel(c.handle, r.level);
1877
- for (const [f, u] of this.persistentChannels)
1878
- this.applyPersistentRun(f, u, r, c.handle);
1909
+ ), c.uploadedCount += h, l.lastUsed = t, n += h, c.uploadedCount === a.count) {
1910
+ this.writeLodLevelChannel(c.handle, a.level);
1911
+ for (const [f, d] of this.persistentChannels)
1912
+ this.applyPersistentRun(f, d, a, c.handle);
1879
1913
  }
1880
- if (n >= s) break;
1914
+ if (n >= i) break;
1881
1915
  }
1882
1916
  return n;
1883
1917
  }
1884
1918
  /** Switches a fully staged region from old to new visibility in one tick. */
1885
1919
  commitStagedGroup(e) {
1886
1920
  for (const t of e.adds) {
1887
- const s = this.staged.get(C(t));
1888
- if (!s || s.uploadedCount !== t.count)
1921
+ const i = this.staged.get(C(t));
1922
+ if (!i || i.uploadedCount !== t.count)
1889
1923
  throw new Error("StreamedSplatMesh: incomplete staged group commit.");
1890
1924
  }
1891
- for (const [t, s] of e.removes)
1892
- this.resident.has(t) && (this.removeRange(s.handle), this.resident.delete(t));
1925
+ for (const [t, i] of e.removes)
1926
+ this.resident.has(t) && (this.removeRange(i.handle), this.resident.delete(t));
1893
1927
  for (const t of e.adds) {
1894
- const s = C(t), n = this.staged.get(s);
1895
- this.setRangeActive(n.handle, !0), this.resident.set(s, n), this.staged.delete(s);
1928
+ const i = C(t), n = this.staged.get(i);
1929
+ this.setRangeActive(n.handle, !0), this.resident.set(i, n), this.staged.delete(i);
1896
1930
  }
1897
1931
  }
1898
1932
  /**
@@ -1902,50 +1936,50 @@ class Y extends Pe {
1902
1936
  * removals - the caller defers it and the old runs keep rendering.
1903
1937
  */
1904
1938
  applyGroup(e, t) {
1905
- const s = (a) => Math.ceil(a / F) * F, n = e.adds.reduce((a, l) => a + s(l.count), 0), r = e.removes.reduce((a, [, l]) => a + s(l.run.count), 0);
1906
- if (n > this.freeSplatCapacity + r) return !1;
1907
- for (const [a, l] of e.removes)
1908
- this.resident.has(a) && (this.removeRange(l.handle), this.resident.delete(a));
1909
- for (const a of e.adds)
1910
- this.appendRun(a, t);
1939
+ const i = (r) => Math.ceil(r / F) * F, n = e.adds.reduce((r, l) => r + i(l.count), 0), a = e.removes.reduce((r, [, l]) => r + i(l.run.count), 0);
1940
+ if (n > this.freeSplatCapacity + a) return !1;
1941
+ for (const [r, l] of e.removes)
1942
+ this.resident.has(r) && (this.removeRange(l.handle), this.resident.delete(r));
1943
+ for (const r of e.adds)
1944
+ this.appendRun(r, t);
1911
1945
  return !0;
1912
1946
  }
1913
1947
  /** Appends one run from the cache, compacting the pool on fragmentation. */
1914
1948
  appendRun(e, t) {
1915
- const s = this.cache.get(e.file);
1916
- if (!s) return;
1917
- const n = K(s.data, e.offset, e.count);
1918
- let r;
1949
+ const i = this.cache.get(e.file);
1950
+ if (!i) return;
1951
+ const n = K(i.data, e.offset, e.count);
1952
+ let a;
1919
1953
  try {
1920
- r = this.appendRange(n);
1954
+ a = this.appendRange(n);
1921
1955
  } catch {
1922
1956
  this.compactionCount++, this.compact();
1923
1957
  try {
1924
- r = this.appendRange(n);
1958
+ a = this.appendRange(n);
1925
1959
  } catch {
1926
1960
  this.pendingWork = !0;
1927
1961
  return;
1928
1962
  }
1929
1963
  }
1930
- this.resident.set(C(e), { run: e, handle: r }), s.lastUsed = t, this.writeLodLevelChannel(r, e.level);
1931
- for (const [a, l] of this.persistentChannels)
1932
- this.applyPersistentRun(a, l, e, r);
1964
+ this.resident.set(C(e), { run: e, handle: a }), i.lastUsed = t, this.writeLodLevelChannel(a, e.level);
1965
+ for (const [r, l] of this.persistentChannels)
1966
+ this.applyPersistentRun(r, l, e, a);
1933
1967
  }
1934
1968
  /**
1935
1969
  * Writes the stored edits for one run's `[offset, offset + count)` splats
1936
1970
  * into its freshly appended pool range. No-op when the file has no edits.
1937
1971
  */
1938
- applyPersistentRun(e, t, s, n) {
1939
- const r = t.edits.get(s.file);
1940
- if (!r || r.size === 0) return;
1941
- const a = t.type === "byte" ? new Uint8Array(s.count) : new Float32Array(s.count);
1942
- t.fill && a.fill(t.fill);
1972
+ applyPersistentRun(e, t, i, n) {
1973
+ const a = t.edits.get(i.file);
1974
+ if (!a || a.size === 0) return;
1975
+ const r = t.type === "byte" ? new Uint8Array(i.count) : new Float32Array(i.count);
1976
+ t.fill && r.fill(t.fill);
1943
1977
  let l = !1;
1944
- for (let c = 0; c < s.count; c++) {
1945
- const h = r.get(s.offset + c);
1946
- h !== void 0 && (a[c] = h, l = !0);
1978
+ for (let c = 0; c < i.count; c++) {
1979
+ const h = a.get(i.offset + c);
1980
+ h !== void 0 && (r[c] = h, l = !0);
1947
1981
  }
1948
- l && this.writeChannel(n, e, a);
1982
+ l && this.writeChannel(n, e, r);
1949
1983
  }
1950
1984
  /**
1951
1985
  * Covers a deferred group's leaves that no resident run covers with each
@@ -1958,21 +1992,21 @@ class Y extends Pe {
1958
1992
  * paint and its pin fetch entirely - cold load requests only the target cut
1959
1993
  * for that cell. Far gaps keep the shell.
1960
1994
  */
1961
- substituteCoverage(e, t, s, n) {
1962
- const r = e.leafEnd - e.leafStart;
1963
- (this.coverageScratch === void 0 || this.coverageScratch.length < r) && (this.coverageScratch = new Uint8Array(r));
1964
- const a = this.coverageScratch;
1965
- a.fill(0, 0, r);
1995
+ substituteCoverage(e, t, i, n) {
1996
+ const a = e.leafEnd - e.leafStart;
1997
+ (this.coverageScratch === void 0 || this.coverageScratch.length < a) && (this.coverageScratch = new Uint8Array(a));
1998
+ const r = this.coverageScratch;
1999
+ r.fill(0, 0, a);
1966
2000
  for (const { run: h } of this.resident.values()) {
1967
- const f = Math.max(h.leafStart, e.leafStart), u = Math.min(h.leafEnd, e.leafEnd);
1968
- u > f && a.fill(1, f - e.leafStart, u - e.leafStart);
2001
+ const f = Math.max(h.leafStart, e.leafStart), d = Math.min(h.leafEnd, e.leafEnd);
2002
+ d > f && r.fill(1, f - e.leafStart, d - e.leafStart);
1969
2003
  }
1970
- const l = a.subarray(0, r);
2004
+ const l = r.subarray(0, a);
1971
2005
  let c = 0;
1972
- for (; c < r; ) {
2006
+ for (; c < a; ) {
1973
2007
  const h = l.indexOf(0, c);
1974
2008
  if (h < 0) break;
1975
- const f = l.indexOf(1, h), u = f < 0 ? r : f, g = e.leafStart + h, v = e.leafStart + u;
2009
+ const f = l.indexOf(1, h), d = f < 0 ? a : f, g = e.leafStart + h, v = e.leafStart + d;
1976
2010
  for (const m of this.scene.source.coarsestRunsFor(g, v))
1977
2011
  if (!this.resident.has(C(m))) {
1978
2012
  if (n) {
@@ -1981,7 +2015,7 @@ class Y extends Pe {
1981
2015
  }
1982
2016
  if (!this.cache.has(m.file)) {
1983
2017
  oe(
1984
- s,
2018
+ i,
1985
2019
  m.file,
1986
2020
  je(m, this.scene.source.lodBaseDistance),
1987
2021
  m
@@ -1992,18 +2026,18 @@ class Y extends Pe {
1992
2026
  T.run.leafStart < m.leafEnd && T.run.leafEnd > m.leafStart && (this.removeRange(T.handle), this.resident.delete(b));
1993
2027
  this.appendRun(m, t);
1994
2028
  }
1995
- c = u;
2029
+ c = d;
1996
2030
  }
1997
2031
  }
1998
2032
  /** Issues pending classic-path chunk wants in group-priority order. */
1999
- flushClassicFetches(e, t, s = !1) {
2033
+ flushClassicFetches(e, t, i = !1) {
2000
2034
  if (e.size === 0) return;
2001
- $e(e, t, s);
2035
+ $e(e, t, i);
2002
2036
  const n = [...e.entries()].sort(
2003
- (r, a) => X(r[1], a[1], r[0], a[0])
2037
+ (a, r) => X(a[1], r[1], a[0], r[0])
2004
2038
  );
2005
2039
  this.preemptClassicFetches(n);
2006
- for (const [r, a] of n) this.requestChunk(r, a.kind, a);
2040
+ for (const [a, r] of n) this.requestChunk(a, r.kind, r);
2007
2041
  }
2008
2042
  /**
2009
2043
  * A camera turn must not wait for all eight old visible requests to finish.
@@ -2012,12 +2046,12 @@ class Y extends Pe {
2012
2046
  */
2013
2047
  preemptClassicFetches(e) {
2014
2048
  var t;
2015
- for (const [s, n] of e) {
2016
- if (this.cache.has(s) || this.fetching.has(s)) continue;
2017
- let r, a;
2049
+ for (const [i, n] of e) {
2050
+ if (this.cache.has(i) || this.fetching.has(i)) continue;
2051
+ let a, r;
2018
2052
  for (const [l, c] of this.fetching)
2019
- c.classicWant && (!a || X(c.classicWant, a, l, r) > 0) && (r = l, a = c.classicWant);
2020
- if (a && r !== void 0 && X(n, a, s, r) < 0 && ((t = this.fetching.get(r)) == null || t.controller.abort()), this.fetching.size >= this.maxInflight) return;
2053
+ c.classicWant && (!r || X(c.classicWant, r, l, a) > 0) && (a = l, r = c.classicWant);
2054
+ if (r && a !== void 0 && X(n, r, i, a) < 0 && ((t = this.fetching.get(a)) == null || t.controller.abort()), this.fetching.size >= this.maxInflight) return;
2021
2055
  }
2022
2056
  }
2023
2057
  /**
@@ -2029,38 +2063,38 @@ class Y extends Pe {
2029
2063
  * it issues ahead of LOD coverage.
2030
2064
  */
2031
2065
  updateEnvironment(e, t) {
2032
- const s = this.envFile;
2033
- if (s === void 0 || this.envHandle !== void 0 || !this.envEnabled || this.envUnfit)
2066
+ const i = this.envFile;
2067
+ if (i === void 0 || this.envHandle !== void 0 || !this.envEnabled || this.envUnfit)
2034
2068
  return;
2035
- const n = this.cache.get(s);
2069
+ const n = this.cache.get(i);
2036
2070
  if (!n) {
2037
- this.failedFiles.has(s) || (t ? this.enqueueEnvironmentFetch(t, s) : this.requestChunk(s, "priority"), this.pendingWork = !0);
2071
+ this.failedFiles.has(i) || (t ? this.enqueueEnvironmentFetch(t, i) : this.requestChunk(i, "priority"), this.pendingWork = !0);
2038
2072
  return;
2039
2073
  }
2040
- const r = Math.ceil(n.data.count / F) * F;
2041
- if (r > this.capacity) {
2042
- this.envUnfit = !0, P(
2074
+ const a = Math.ceil(n.data.count / F) * F;
2075
+ if (a > this.capacity) {
2076
+ this.envUnfit = !0, E(
2043
2077
  `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
2078
  );
2045
2079
  return;
2046
2080
  }
2047
- if (r > this.freeSplatCapacity) {
2081
+ if (a > this.freeSplatCapacity) {
2048
2082
  this.pendingWork = !0;
2049
2083
  return;
2050
2084
  }
2051
- let a;
2085
+ let r;
2052
2086
  try {
2053
- a = this.appendRange(n.data);
2087
+ r = this.appendRange(n.data);
2054
2088
  } catch {
2055
2089
  this.compactionCount++, this.compact();
2056
2090
  try {
2057
- a = this.appendRange(n.data);
2091
+ r = this.appendRange(n.data);
2058
2092
  } catch {
2059
2093
  this.pendingWork = !0;
2060
2094
  return;
2061
2095
  }
2062
2096
  }
2063
- this.envHandle = a, this.envSplatCount = n.data.count, n.lastUsed = e;
2097
+ this.envHandle = r, this.envSplatCount = n.data.count, n.lastUsed = e;
2064
2098
  }
2065
2099
  /** Ranks the env tile ahead of every LOD want in {@link flushClassicFetches}. */
2066
2100
  enqueueEnvironmentFetch(e, t) {
@@ -2089,16 +2123,16 @@ class Y extends Pe {
2089
2123
  * with a paging plan. Coalesced to one outstanding request so the main thread
2090
2124
  * never blocks. Also drives chunk fetching, in priority order.
2091
2125
  */
2092
- reschedulePageTable(e, t, s, n) {
2093
- for (const a of this.pageTableFetchPriority) this.requestChunk(a, "priority");
2094
- const r = new Set(this.pageTableFetchPriority);
2095
- for (const a of this.scene.source.computeDesiredRuns(e, s, n))
2096
- r.add(a.file), this.requestChunk(a.file, "base");
2097
- for (const [a, l] of this.fetching)
2098
- l.kind !== "sweep" && !r.has(a) && !this.scene.pinnedFiles.has(a) && l.controller.abort();
2126
+ reschedulePageTable(e, t, i, n) {
2127
+ for (const r of this.pageTableFetchPriority) this.requestChunk(r, "priority");
2128
+ const a = new Set(this.pageTableFetchPriority);
2129
+ for (const r of this.scene.source.computeDesiredRuns(e, i, n))
2130
+ a.add(r.file), this.requestChunk(r.file, "base");
2131
+ for (const [r, l] of this.fetching)
2132
+ l.kind !== "sweep" && !a.has(r) && !this.scene.pinnedFiles.has(r) && l.controller.abort();
2099
2133
  if (!this.pageTableCacheAtLimit && this.sweepAllowed()) {
2100
- const a = Math.max(1, this.maxInflight - mt), l = this.scene.chunkUrls.length;
2101
- for (let c = 0; c < l && this.fetching.size < a; c++)
2134
+ const r = Math.max(1, this.maxInflight - mt), l = this.scene.chunkUrls.length;
2135
+ for (let c = 0; c < l && this.fetching.size < r; c++)
2102
2136
  this.pageTableCachedFiles.has(c) || this.requestChunk(c, "sweep");
2103
2137
  }
2104
2138
  this.pageTableInFlight || (this.pageTableInFlight = !0, this.postToWorker({
@@ -2123,48 +2157,48 @@ class Y extends Pe {
2123
2157
  if (this.pageTableInFlight = !1, this.pageTableDisposed || this.slabPages.length === 0) return;
2124
2158
  const t = this.pagerSlots;
2125
2159
  e.capacity !== t && (this.pendingWork = !0, this.lastScheduleTime = -1 / 0);
2126
- const s = performance.now(), n = e.moveSlots;
2127
- for (let u = 0; u < n.length; ) {
2160
+ const i = performance.now(), n = e.moveSlots;
2161
+ for (let d = 0; d < n.length; ) {
2128
2162
  let g = 1;
2129
- for (; u + g < n.length && n[u + g] === n[u] + g; )
2163
+ for (; d + g < n.length && n[d + g] === n[d] + g; )
2130
2164
  g++;
2131
- const v = n[u], m = Math.min(g, t - v);
2132
- m > 0 && this.writeSlabSlots(yt(e.moves, u, m), v, m), u += g;
2165
+ const v = n[d], m = Math.min(g, t - v);
2166
+ m > 0 && this.writeSlabSlots(yt(e.moves, d, m), v, m), d += g;
2133
2167
  }
2134
2168
  if (e.appends.count > 0) {
2135
- const u = Math.min(e.appends.count, t - e.appendStart);
2136
- u > 0 && this.writeSlabSlots(e.appends, e.appendStart, u);
2169
+ const d = Math.min(e.appends.count, t - e.appendStart);
2170
+ d > 0 && this.writeSlabSlots(e.appends, e.appendStart, d);
2137
2171
  }
2138
- const r = performance.now(), a = Math.min(e.residentCount, t);
2139
- this.setSlabResident(a);
2172
+ const a = performance.now(), r = Math.min(e.residentCount, t);
2173
+ this.setSlabResident(r);
2140
2174
  const l = Math.min(e.degenerateStart, t), c = Math.min(e.degenerateCount, t - l);
2141
2175
  c > 0 && this.degenerateSlabSlots(l, c);
2142
2176
  const h = performance.now();
2143
- this.pageTableDrawn = a, e.gatherMissing > 0 && P(
2177
+ this.pageTableDrawn = r, 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
2178
  `StreamedSplatMesh: page-table plan gathered ${e.gatherMissing} splats from evicted chunks; they render as holes.`
2145
2179
  );
2146
2180
  const f = this.planTimingsValue;
2147
- if (f.applyMs = h - s, f.writeMs = r - s, f.residentMs = h - r, 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) {
2148
- const u = Math.min(1, e.solvedLimit / this.pageTableLimit);
2181
+ if (f.applyMs = h - i, f.writeMs = a - i, f.residentMs = h - 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) {
2182
+ const d = Math.min(1, e.solvedLimit / this.pageTableLimit);
2149
2183
  this.setScreenRadiusBand(
2150
- this.frontierBandBase.min * u,
2151
- this.frontierBandBase.max * u
2184
+ this.frontierBandBase.min * d,
2185
+ this.frontierBandBase.max * d
2152
2186
  );
2153
2187
  }
2154
- this.invalidateSort(), e.dropped > 0 && P(
2188
+ this.invalidateSort(), e.dropped > 0 && E(
2155
2189
  `StreamedSplatMesh: page-table slab full, dropped ${e.dropped} frontier splats (draw budget ${this.pageTableDrawBudget} exceeds the pool).`
2156
2190
  );
2157
- for (let u = 0; u < e.evicted.length; u++)
2158
- this.pageTableCachedFiles.delete(e.evicted[u]);
2191
+ for (let d = 0; d < e.evicted.length; d++)
2192
+ this.pageTableCachedFiles.delete(e.evicted[d]);
2159
2193
  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 u of this.pageTableFetchPriority) this.requestChunk(u, "priority");
2194
+ for (const d of this.pageTableFetchPriority) this.requestChunk(d, "priority");
2161
2195
  (this.fetching.size > 0 || !e.converged) && (this.pendingWork = !0, e.converged || (this.lastScheduleTime = -1 / 0));
2162
2196
  }
2163
2197
  /** Forwards a decoded chunk's arrays to the worker (buffers transferred) so the
2164
2198
  * worker's cache/traversal/gather can use it. */
2165
2199
  forwardChunkToWorker(e, t) {
2166
- const s = t.radTree;
2167
- if (!s) return;
2200
+ const i = t.radTree;
2201
+ if (!i) return;
2168
2202
  this.pageTableCachedFiles.add(e);
2169
2203
  const n = this.shBands > 0 ? t.shPacked : void 0;
2170
2204
  this.postToWorker(
@@ -2175,9 +2209,9 @@ class Y extends Pe {
2175
2209
  positions: t.positions,
2176
2210
  colors: t.colors,
2177
2211
  covariances: t.covariances,
2178
- childCount: s.childCount,
2179
- childStart: s.childStart,
2180
- size: s.size,
2212
+ childCount: i.childCount,
2213
+ childStart: i.childStart,
2214
+ size: i.size,
2181
2215
  shBands: (n == null ? void 0 : n.bands) ?? 0,
2182
2216
  ...n ? { shPacked: n.packed, shRange: n.range } : {}
2183
2217
  },
@@ -2185,9 +2219,9 @@ class Y extends Pe {
2185
2219
  t.positions.buffer,
2186
2220
  t.colors.buffer,
2187
2221
  t.covariances.buffer,
2188
- s.childCount.buffer,
2189
- s.childStart.buffer,
2190
- s.size.buffer,
2222
+ i.childCount.buffer,
2223
+ i.childStart.buffer,
2224
+ i.size.buffer,
2191
2225
  ...n ? [n.packed.buffer] : []
2192
2226
  ]
2193
2227
  );
@@ -2196,7 +2230,7 @@ class Y extends Pe {
2196
2230
  * per-host cap simply queues. Same cap for classic and page-table so near
2197
2231
  * detail is not structurally starved on the non-page-table path. */
2198
2232
  get maxInflight() {
2199
- return ut;
2233
+ return dt;
2200
2234
  }
2201
2235
  /**
2202
2236
  * Whether this mesh may run its speculative background sweep. A mesh with no
@@ -2226,33 +2260,33 @@ class Y extends Pe {
2226
2260
  for (const t of this.fetching.values())
2227
2261
  t.kind === e && t.controller.abort();
2228
2262
  }
2229
- requestChunk(e, t, s) {
2263
+ requestChunk(e, t, i) {
2230
2264
  var l, c;
2231
2265
  if (this.cache.has(e) || this.pageTableCachedFiles.has(e) || this.fetching.has(e) || this.fetching.size >= this.maxInflight || this.failedFiles.has(e)) return;
2232
2266
  const n = this.retrying.get(e);
2233
2267
  if (n && performance.now() < n.readyAt) return;
2234
2268
  this.fetchCountsValue[t]++;
2235
- const r = this.scene.chunkUrls[e];
2236
- if (r === void 0) {
2237
- P(`StreamedSplatMesh: manifest references unknown chunk file #${e}.`), this.failedFiles.add(e);
2269
+ const a = this.scene.chunkUrls[e];
2270
+ if (a === void 0) {
2271
+ E(`StreamedSplatMesh: manifest references unknown chunk file #${e}.`), this.failedFiles.add(e);
2238
2272
  return;
2239
2273
  }
2240
2274
  if (this.fetchHandle && !((l = this.fetchScheduler) != null && l.tryAcquire(this.fetchHandle, t))) return;
2241
- const a = new AbortController();
2242
- this.fetching.set(e, { controller: a, kind: t, classicWant: s }), this.loader.load(r, {
2275
+ const r = new AbortController();
2276
+ this.fetching.set(e, { controller: r, kind: t, classicWant: i }), this.loader.load(a, {
2243
2277
  kind: this.scene.chunkKind,
2244
- signal: a.signal,
2278
+ signal: r.signal,
2245
2279
  ...(c = this.scene.chunkOptions) == null ? void 0 : c[e]
2246
2280
  }).then((h) => {
2247
- var f, u;
2248
- this.disposed || (this.retrying.delete(e), (u = (f = this.scene.source).onChunkDecoded) == null || u.call(f, e, h), this.frontierWorker ? (this.forwardChunkToWorker(e, h), this.pendingWork = !0) : this.cacheChunk(e, h));
2281
+ var f, d;
2282
+ this.disposed || (this.retrying.delete(e), (d = (f = this.scene.source).onChunkDecoded) == null || d.call(f, e, h), this.frontierWorker ? (this.forwardChunkToWorker(e, h), this.pendingWork = !0) : this.cacheChunk(e, h));
2249
2283
  }).catch((h) => {
2250
- var u;
2251
- if (G(h)) return;
2252
- const f = (((u = this.retrying.get(e)) == null ? void 0 : u.attempts) ?? 0) + 1;
2284
+ var d;
2285
+ if (N(h)) return;
2286
+ const f = (((d = this.retrying.get(e)) == null ? void 0 : d.attempts) ?? 0) + 1;
2253
2287
  if (f >= gt)
2254
- this.retrying.delete(e), this.failedFiles.add(e), P(
2255
- `StreamedSplatMesh: gave up on chunk #${e} (${r}) after ${f} attempts.`,
2288
+ this.retrying.delete(e), this.failedFiles.add(e), E(
2289
+ `StreamedSplatMesh: gave up on chunk #${e} (${a}) after ${f} attempts.`,
2256
2290
  h
2257
2291
  );
2258
2292
  else {
@@ -2270,40 +2304,40 @@ class Y extends Pe {
2270
2304
  * of {@link cache} (this method, eviction, dispose's clear) maintains it.
2271
2305
  */
2272
2306
  cacheChunk(e, t) {
2273
- const s = this.cache.get(e);
2274
- s !== void 0 && (this.cacheBytesTotal -= s.bytes);
2307
+ const i = this.cache.get(e);
2308
+ i !== void 0 && (this.cacheBytesTotal -= i.bytes);
2275
2309
  const n = Xe(t);
2276
2310
  this.cache.set(e, { data: t, bytes: n, lastUsed: performance.now() }), this.cacheBytesTotal += n;
2277
2311
  }
2278
2312
  evictChunks(e) {
2279
2313
  let t = this.cacheBytesTotal;
2280
2314
  if (t <= this.cpuCacheBytes) return;
2281
- const s = [...this.cache.entries()].filter(
2282
- ([n, r]) => r.lastUsed !== e && !this.scene.pinnedFiles.has(n) && !this.neededFiles.has(n)
2283
- ).sort((n, r) => n[1].lastUsed - r[1].lastUsed);
2284
- for (const [n, r] of s) {
2315
+ const i = [...this.cache.entries()].filter(
2316
+ ([n, a]) => a.lastUsed !== e && !this.scene.pinnedFiles.has(n) && !this.neededFiles.has(n)
2317
+ ).sort((n, a) => n[1].lastUsed - a[1].lastUsed);
2318
+ for (const [n, a] of i) {
2285
2319
  if (t <= this.cpuCacheBytes) break;
2286
- this.cache.delete(n), this.cacheBytesTotal -= r.bytes, t -= r.bytes, this.fetchCountsValue.evicted++;
2320
+ this.cache.delete(n), this.cacheBytesTotal -= a.bytes, t -= a.bytes, this.fetchCountsValue.evicted++;
2287
2321
  }
2288
2322
  }
2289
2323
  }
2290
- const V = new w.Vector3(), pe = new w.Vector3(), me = new w.Quaternion(), x = new w.Vector3(), ve = new w.Matrix4(), z = new w.Frustum(), wt = new w.Sphere(), B = new w.Vector3(), Se = new w.Vector2();
2324
+ 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(), B = new w.Vector3(), Se = new w.Vector2();
2291
2325
  function be(o) {
2292
2326
  return Math.ceil(3 * Ie(o) / 4);
2293
2327
  }
2294
- function yt(o, i, e) {
2328
+ function yt(o, s, e) {
2295
2329
  const t = o.shPacked;
2296
2330
  return {
2297
2331
  count: e,
2298
- positions: o.positions.subarray(i * 3, (i + e) * 3),
2299
- colors: o.colors.subarray(i * 4, (i + e) * 4),
2300
- covariances: o.covariances.subarray(i * 6, (i + e) * 6),
2332
+ positions: o.positions.subarray(s * 3, (s + e) * 3),
2333
+ colors: o.colors.subarray(s * 4, (s + e) * 4),
2334
+ covariances: o.covariances.subarray(s * 6, (s + e) * 6),
2301
2335
  ...t ? {
2302
2336
  shPacked: {
2303
2337
  ...t,
2304
2338
  packed: t.packed.subarray(
2305
- i * be(t.bands),
2306
- (i + e) * be(t.bands)
2339
+ s * be(t.bands),
2340
+ (s + e) * be(t.bands)
2307
2341
  )
2308
2342
  }
2309
2343
  } : {}
@@ -2311,12 +2345,12 @@ function yt(o, i, e) {
2311
2345
  }
2312
2346
  const Ct = 1;
2313
2347
  class Tt {
2314
- constructor(i = {}) {
2315
- d(this, "entries", /* @__PURE__ */ new Map());
2316
- d(this, "total");
2317
- d(this, "hysteresis");
2318
- this.total = W(i.totalBudget);
2319
- const e = i.hysteresis ?? 0.1;
2348
+ constructor(s = {}) {
2349
+ u(this, "entries", /* @__PURE__ */ new Map());
2350
+ u(this, "total");
2351
+ u(this, "hysteresis");
2352
+ this.total = W(s.totalBudget);
2353
+ const e = s.hysteresis ?? 0.1;
2320
2354
  if (!Number.isFinite(e) || e < 0)
2321
2355
  throw new RangeError("BudgetGovernor hysteresis must be a non-negative finite number.");
2322
2356
  this.hysteresis = e;
@@ -2326,8 +2360,8 @@ class Tt {
2326
2360
  return this.total;
2327
2361
  }
2328
2362
  /** Replaces the shared total and reallocates. */
2329
- setTotalBudget(i) {
2330
- const e = W(i);
2363
+ setTotalBudget(s) {
2364
+ const e = W(s);
2331
2365
  e !== this.total && (this.total = e, this.reallocate());
2332
2366
  }
2333
2367
  /** Number of registered members. */
@@ -2343,15 +2377,15 @@ class Tt {
2343
2377
  * proportional to its weight - e.g. main mesh `7`, additional mesh `3` reproduces
2344
2378
  * the old 0.7 host split. `0` registers the member suspended.
2345
2379
  */
2346
- register(i, e = {}) {
2347
- if (this.entries.has(i))
2380
+ register(s, e = {}) {
2381
+ if (this.entries.has(s))
2348
2382
  throw new Error("BudgetGovernor: member is already registered.");
2349
2383
  const t = J(e.weight ?? 1);
2350
- this.entries.set(i, {
2351
- member: i,
2384
+ this.entries.set(s, {
2385
+ member: s,
2352
2386
  weight: t,
2353
- applied: i.budget,
2354
- restoreBudget: i.budget
2387
+ applied: s.budget,
2388
+ restoreBudget: s.budget
2355
2389
  }), this.reallocate();
2356
2390
  }
2357
2391
  /**
@@ -2359,17 +2393,17 @@ class Tt {
2359
2393
  * reallocates the total across the remaining members. No-op for a member
2360
2394
  * that is not registered (so disposing hosts need not track membership).
2361
2395
  */
2362
- unregister(i) {
2363
- const e = this.entries.get(i);
2364
- e !== void 0 && (this.entries.delete(i), e.member.setBudget(e.restoreBudget), this.reallocate());
2396
+ unregister(s) {
2397
+ const e = this.entries.get(s);
2398
+ e !== void 0 && (this.entries.delete(s), e.member.setBudget(e.restoreBudget), this.reallocate());
2365
2399
  }
2366
2400
  /**
2367
2401
  * Changes a member's priority weight and reallocates. `0` suspends the
2368
2402
  * member (see the class doc); any positive weight resumes it.
2369
2403
  */
2370
- setWeight(i, e) {
2371
- const t = this.entryOf(i), s = J(e);
2372
- s !== t.weight && (t.weight = s, this.reallocate());
2404
+ setWeight(s, e) {
2405
+ const t = this.entryOf(s), i = J(e);
2406
+ i !== t.weight && (t.weight = i, this.reallocate());
2373
2407
  }
2374
2408
  /**
2375
2409
  * Writes several weights, then reallocates **once**.
@@ -2386,19 +2420,19 @@ class Tt {
2386
2420
  * is written, so a bad pair leaves every weight untouched.
2387
2421
  * @throws {RangeError} if any weight is not a non-negative finite number.
2388
2422
  */
2389
- setWeights(i) {
2390
- const e = [...i].map(
2391
- ([s, n]) => [this.entryOf(s), J(n)]
2423
+ setWeights(s) {
2424
+ const e = [...s].map(
2425
+ ([i, n]) => [this.entryOf(i), J(n)]
2392
2426
  );
2393
2427
  let t = !1;
2394
- for (const [s, n] of e)
2395
- s.weight !== n && (s.weight = n, t = !0);
2428
+ for (const [i, n] of e)
2429
+ i.weight !== n && (i.weight = n, t = !0);
2396
2430
  t && this.reallocate();
2397
2431
  }
2398
2432
  /** The budget the governor last applied to a member, if registered. */
2399
- budgetOf(i) {
2433
+ budgetOf(s) {
2400
2434
  var e;
2401
- return (e = this.entries.get(i)) == null ? void 0 : e.applied;
2435
+ return (e = this.entries.get(s)) == null ? void 0 : e.applied;
2402
2436
  }
2403
2437
  /**
2404
2438
  * Recomputes and applies every member's share. Called automatically by all
@@ -2406,19 +2440,19 @@ class Tt {
2406
2440
  * outside the governor's view.
2407
2441
  */
2408
2442
  reallocate() {
2409
- let i = [];
2443
+ let s = [];
2410
2444
  for (const t of this.entries.values())
2411
- t.weight === 0 ? this.applyTarget(t, Ct) : i.push(t);
2445
+ t.weight === 0 ? this.applyTarget(t, Ct) : s.push(t);
2412
2446
  let e = this.total;
2413
- for (; i.length > 0; ) {
2414
- const t = i.reduce((r, a) => r + a.weight, 0), s = [];
2447
+ for (; s.length > 0; ) {
2448
+ const t = s.reduce((a, r) => a + r.weight, 0), i = [];
2415
2449
  let n = 0;
2416
- for (const r of i) {
2417
- const a = Math.max(1, Math.floor(e * r.weight / t));
2418
- this.applyTarget(r, a) && (s.push(r), n += r.applied);
2450
+ for (const a of s) {
2451
+ const r = Math.max(1, Math.floor(e * a.weight / t));
2452
+ this.applyTarget(a, r) && (i.push(a), n += a.applied);
2419
2453
  }
2420
- if (s.length === 0) break;
2421
- e = Math.max(0, e - n), i = i.filter((r) => !s.includes(r));
2454
+ if (i.length === 0) break;
2455
+ e = Math.max(0, e - n), s = s.filter((a) => !i.includes(a));
2422
2456
  }
2423
2457
  }
2424
2458
  /**
@@ -2426,13 +2460,13 @@ class Tt {
2426
2460
  * The governor itself stays usable (dispose is just "unregister everyone").
2427
2461
  */
2428
2462
  dispose() {
2429
- for (const i of this.entries.values())
2430
- i.member.setBudget(i.restoreBudget);
2463
+ for (const s of this.entries.values())
2464
+ s.member.setBudget(s.restoreBudget);
2431
2465
  this.entries.clear();
2432
2466
  }
2433
2467
  /** The entry for a registered member, or a thrown error naming the problem. */
2434
- entryOf(i) {
2435
- const e = this.entries.get(i);
2468
+ entryOf(s) {
2469
+ const e = this.entries.get(s);
2436
2470
  if (e === void 0)
2437
2471
  throw new Error("BudgetGovernor: member is not registered.");
2438
2472
  return e;
@@ -2441,12 +2475,12 @@ class Tt {
2441
2475
  * Pushes `target` to a member, with the grow dead-band. Returns true when
2442
2476
  * the member clamped below its target (it is capped and cannot absorb more).
2443
2477
  */
2444
- applyTarget(i, e) {
2445
- if (e > i.applied) {
2446
- if (e - i.applied <= this.hysteresis * i.applied) return !1;
2447
- } else if (e === i.applied)
2478
+ applyTarget(s, e) {
2479
+ if (e > s.applied) {
2480
+ if (e - s.applied <= this.hysteresis * s.applied) return !1;
2481
+ } else if (e === s.applied)
2448
2482
  return !1;
2449
- return i.applied = i.member.setBudget(e), i.applied < e;
2483
+ return s.applied = s.member.setBudget(e), s.applied < e;
2450
2484
  }
2451
2485
  }
2452
2486
  function J(o) {
@@ -2456,21 +2490,21 @@ function J(o) {
2456
2490
  );
2457
2491
  return o;
2458
2492
  }
2459
- const we = new w.Vector3(), ye = new w.Matrix4(), Ce = new w.Frustum(), Z = new w.Box3(), O = new w.Sphere();
2460
- class Ot {
2461
- constructor(i = {}) {
2462
- d(this, "entries", /* @__PURE__ */ new Map());
2463
- d(this, "budgetGovernor");
2464
- d(this, "minIntervalMs");
2465
- d(this, "weightDeadband");
2466
- d(this, "falloff");
2467
- d(this, "offScreenWeight");
2468
- d(this, "minWeight");
2469
- d(this, "maxWeight");
2470
- d(this, "lastUpdateAt", -1 / 0);
2493
+ const we = new w.Vector3(), ye = new w.Matrix4(), Ce = new w.Frustum(), Z = new w.Box3(), z = new w.Sphere();
2494
+ class zt {
2495
+ constructor(s = {}) {
2496
+ u(this, "entries", /* @__PURE__ */ new Map());
2497
+ u(this, "budgetGovernor");
2498
+ u(this, "minIntervalMs");
2499
+ u(this, "weightDeadband");
2500
+ u(this, "falloff");
2501
+ u(this, "offScreenWeight");
2502
+ u(this, "minWeight");
2503
+ u(this, "maxWeight");
2504
+ u(this, "lastUpdateAt", -1 / 0);
2471
2505
  /** Set by membership/priority changes: the next update ignores both damps. */
2472
- d(this, "forceNext", !0);
2473
- if (this.budgetGovernor = i.governor ?? new Tt(i), this.minIntervalMs = N(i.minIntervalMs ?? 250, "minIntervalMs"), this.weightDeadband = N(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)
2506
+ u(this, "forceNext", !0);
2507
+ if (this.budgetGovernor = s.governor ?? new Tt(s), this.minIntervalMs = D(s.minIntervalMs ?? 250, "minIntervalMs"), this.weightDeadband = D(s.weightDeadband ?? 0.15, "weightDeadband"), this.falloff = U(s.falloff ?? 1, "falloff"), this.offScreenWeight = U(s.offScreenWeight ?? 0.25, "offScreenWeight"), this.minWeight = U(s.minWeight ?? 0.05, "minWeight"), this.maxWeight = U(s.maxWeight ?? 8, "maxWeight"), this.maxWeight < this.minWeight)
2474
2508
  throw new RangeError("CameraBudgetGovernor maxWeight must be >= minWeight.");
2475
2509
  }
2476
2510
  /** The governor this drives; use it for fixed-weight members and diagnostics. */
@@ -2482,8 +2516,8 @@ class Ot {
2482
2516
  return this.budgetGovernor.totalBudget;
2483
2517
  }
2484
2518
  /** Replaces the shared total (e.g. the presenting budget on `sessionstart`). */
2485
- setTotalBudget(i) {
2486
- this.budgetGovernor.setTotalBudget(i);
2519
+ setTotalBudget(s) {
2520
+ this.budgetGovernor.setTotalBudget(s);
2487
2521
  }
2488
2522
  /** Number of camera-weighted members. */
2489
2523
  get size() {
@@ -2496,18 +2530,18 @@ class Ot {
2496
2530
  * @throws {Error} if the member is already registered here.
2497
2531
  * @throws {RangeError} if `priority` or `fixedWeight` is invalid.
2498
2532
  */
2499
- register(i, e = {}) {
2500
- if (this.entries.has(i))
2533
+ register(s, e = {}) {
2534
+ if (this.entries.has(s))
2501
2535
  throw new Error("CameraBudgetGovernor: member is already registered.");
2502
- const t = N(e.priority ?? 1, "priority"), s = e.fixedWeight === void 0 ? void 0 : N(e.fixedWeight, "fixedWeight"), n = s ?? t;
2503
- this.budgetGovernor.register(i, { weight: n }), this.entries.set(i, { member: i, priority: t, fixedWeight: s, applied: n }), this.forceNext = !0;
2536
+ const t = D(e.priority ?? 1, "priority"), i = e.fixedWeight === void 0 ? void 0 : D(e.fixedWeight, "fixedWeight"), n = i ?? t;
2537
+ this.budgetGovernor.register(s, { weight: n }), this.entries.set(s, { member: s, priority: t, fixedWeight: i, applied: n }), this.forceNext = !0;
2504
2538
  }
2505
2539
  /**
2506
2540
  * Removes a member from this helper and the underlying governor, restoring
2507
2541
  * the budget it had when it joined. No-op for an unknown member.
2508
2542
  */
2509
- unregister(i) {
2510
- this.entries.delete(i) && (this.budgetGovernor.unregister(i), this.forceNext = !0);
2543
+ unregister(s) {
2544
+ this.entries.delete(s) && (this.budgetGovernor.unregister(s), this.forceNext = !0);
2511
2545
  }
2512
2546
  /**
2513
2547
  * Changes a member's priority tier. Takes effect on the next {@link update},
@@ -2517,12 +2551,12 @@ class Ot {
2517
2551
  * @throws {Error} if the member is not registered here.
2518
2552
  * @throws {RangeError} if `priority` is negative or not finite.
2519
2553
  */
2520
- setPriority(i, e) {
2521
- const t = this.entries.get(i);
2554
+ setPriority(s, e) {
2555
+ const t = this.entries.get(s);
2522
2556
  if (t === void 0)
2523
2557
  throw new Error("CameraBudgetGovernor: member is not registered.");
2524
- const s = N(e, "priority");
2525
- s !== t.priority && (t.priority = s, this.forceNext = !0);
2558
+ const i = D(e, "priority");
2559
+ i !== t.priority && (t.priority = i, this.forceNext = !0);
2526
2560
  }
2527
2561
  /**
2528
2562
  * Recomputes every member's weight from the camera and applies them in one
@@ -2539,33 +2573,33 @@ class Ot {
2539
2573
  * @param now - Timestamp in ms on the `performance.now` clock; defaults to it.
2540
2574
  * @returns whether weights were reapplied.
2541
2575
  */
2542
- update(i, e = performance.now()) {
2576
+ update(s, e = performance.now()) {
2543
2577
  if (this.entries.size === 0) return !1;
2544
2578
  const t = this.forceNext;
2545
2579
  if (!t && e - this.lastUpdateAt < this.minIntervalMs) return !1;
2546
- i.updateMatrixWorld(), i.getWorldPosition(we), ye.multiplyMatrices(i.projectionMatrix, i.matrixWorldInverse), Ce.setFromProjectionMatrix(ye);
2547
- const s = [];
2580
+ s.updateMatrixWorld(), s.getWorldPosition(we), ye.multiplyMatrices(s.projectionMatrix, s.matrixWorldInverse), Ce.setFromProjectionMatrix(ye);
2581
+ const i = [];
2548
2582
  let n = !1;
2549
- for (const r of this.entries.values()) {
2550
- const a = this.weightFor(r);
2551
- s.push([r.member, a]), !n && this.isSignificant(r.applied, a) && (n = !0);
2583
+ for (const a of this.entries.values()) {
2584
+ const r = this.weightFor(a);
2585
+ i.push([a.member, r]), !n && this.isSignificant(a.applied, r) && (n = !0);
2552
2586
  }
2553
2587
  if (!t && !n) return !1;
2554
- this.budgetGovernor.setWeights(s);
2555
- for (const [r, a] of s) {
2556
- const l = this.entries.get(r);
2557
- l !== void 0 && (l.applied = a);
2588
+ this.budgetGovernor.setWeights(i);
2589
+ for (const [a, r] of i) {
2590
+ const l = this.entries.get(a);
2591
+ l !== void 0 && (l.applied = r);
2558
2592
  }
2559
2593
  return this.lastUpdateAt = e, this.forceNext = !1, !0;
2560
2594
  }
2561
2595
  /** The weight currently written for a member, if registered here. */
2562
- weightOf(i) {
2596
+ weightOf(s) {
2563
2597
  var e;
2564
- return (e = this.entries.get(i)) == null ? void 0 : e.applied;
2598
+ return (e = this.entries.get(s)) == null ? void 0 : e.applied;
2565
2599
  }
2566
2600
  /** The budget the underlying governor last applied to a member. */
2567
- budgetOf(i) {
2568
- return this.budgetGovernor.budgetOf(i);
2601
+ budgetOf(s) {
2602
+ return this.budgetGovernor.budgetOf(s);
2569
2603
  }
2570
2604
  /**
2571
2605
  * Unregisters every member, restoring the budget each had when it joined.
@@ -2573,7 +2607,7 @@ class Ot {
2573
2607
  * any members the host registered on it directly.
2574
2608
  */
2575
2609
  dispose() {
2576
- for (const i of [...this.entries.keys()]) this.budgetGovernor.unregister(i);
2610
+ for (const s of [...this.entries.keys()]) this.budgetGovernor.unregister(s);
2577
2611
  this.entries.clear(), this.lastUpdateAt = -1 / 0, this.forceNext = !0;
2578
2612
  }
2579
2613
  /**
@@ -2587,49 +2621,49 @@ class Ot {
2587
2621
  * distant center, and is floored so a camera inside the bounds saturates at
2588
2622
  * `maxWeight` rather than dividing by zero.
2589
2623
  */
2590
- weightFor(i) {
2591
- if (i.fixedWeight !== void 0) return i.fixedWeight;
2592
- const { member: e, priority: t } = i;
2624
+ weightFor(s) {
2625
+ if (s.fixedWeight !== void 0) return s.fixedWeight;
2626
+ const { member: e, priority: t } = s;
2593
2627
  if (t === 0 || !(e.effectiveVisibility ?? e.visible)) return 0;
2594
2628
  if (e.updateWorldMatrix(!0, !1), Z.copy(e.computeSplatBounds()), Z.isEmpty()) return t * this.minWeight;
2595
- Z.applyMatrix4(e.matrixWorld).getBoundingSphere(O);
2596
- const s = O.radius;
2597
- if (!(s > 0)) return t * this.minWeight;
2598
- const n = O.center.distanceTo(we) - s, r = Math.max(n, s * 1e-3, 1e-6), a = It((s / r) ** this.falloff, this.minWeight, this.maxWeight);
2599
- if (!Number.isFinite(a)) return t * this.minWeight;
2600
- const l = Ce.intersectsSphere(O) ? 1 : this.offScreenWeight;
2601
- return t * a * l;
2629
+ Z.applyMatrix4(e.matrixWorld).getBoundingSphere(z);
2630
+ const i = z.radius;
2631
+ if (!(i > 0)) return t * this.minWeight;
2632
+ const n = z.center.distanceTo(we) - i, a = Math.max(n, i * 1e-3, 1e-6), r = It((i / a) ** this.falloff, this.minWeight, this.maxWeight);
2633
+ if (!Number.isFinite(r)) return t * this.minWeight;
2634
+ const l = Ce.intersectsSphere(z) ? 1 : this.offScreenWeight;
2635
+ return t * r * l;
2602
2636
  }
2603
2637
  /** Whether a weight moved enough to be worth a reallocation. */
2604
- isSignificant(i, e) {
2605
- return i === 0 || e === 0 ? i !== e : Math.abs(e - i) > this.weightDeadband * i;
2638
+ isSignificant(s, e) {
2639
+ return s === 0 || e === 0 ? s !== e : Math.abs(e - s) > this.weightDeadband * s;
2606
2640
  }
2607
2641
  }
2608
- function It(o, i, e) {
2609
- return Math.min(e, Math.max(i, o));
2642
+ function It(o, s, e) {
2643
+ return Math.min(e, Math.max(s, o));
2610
2644
  }
2611
- function N(o, i) {
2645
+ function D(o, s) {
2612
2646
  if (!Number.isFinite(o) || o < 0)
2613
- throw new RangeError(`CameraBudgetGovernor ${i} must be a non-negative finite number.`);
2647
+ throw new RangeError(`CameraBudgetGovernor ${s} must be a non-negative finite number.`);
2614
2648
  return o;
2615
2649
  }
2616
- function U(o, i) {
2650
+ function U(o, s) {
2617
2651
  if (!Number.isFinite(o) || o <= 0)
2618
- throw new RangeError(`CameraBudgetGovernor ${i} must be a positive finite number.`);
2652
+ throw new RangeError(`CameraBudgetGovernor ${s} must be a positive finite number.`);
2619
2653
  return o;
2620
2654
  }
2621
2655
  const Rt = 16, Mt = 1;
2622
2656
  class Ut {
2623
- constructor(i = {}) {
2624
- d(this, "entries", /* @__PURE__ */ new Set());
2625
- d(this, "maxGlobalInflight");
2626
- d(this, "perMeshFloor");
2627
- d(this, "inflightCount", 0);
2628
- d(this, "disposed", !1);
2657
+ constructor(s = {}) {
2658
+ u(this, "entries", /* @__PURE__ */ new Set());
2659
+ u(this, "maxGlobalInflight");
2660
+ u(this, "perMeshFloor");
2661
+ u(this, "inflightCount", 0);
2662
+ u(this, "disposed", !1);
2629
2663
  this.maxGlobalInflight = Math.max(
2630
2664
  1,
2631
- Math.floor(i.maxGlobalInflight ?? Rt)
2632
- ), this.perMeshFloor = Math.max(0, Math.floor(i.perMeshFloor ?? Mt));
2665
+ Math.floor(s.maxGlobalInflight ?? Rt)
2666
+ ), this.perMeshFloor = Math.max(0, Math.floor(s.perMeshFloor ?? Mt));
2633
2667
  }
2634
2668
  /** Total slots granted and not yet released. */
2635
2669
  get inflight() {
@@ -2639,16 +2673,16 @@ class Ut {
2639
2673
  get clientCount() {
2640
2674
  return this.entries.size;
2641
2675
  }
2642
- register(i) {
2643
- const e = { client: i, held: 0, demanding: !1, live: !0 };
2676
+ register(s) {
2677
+ const e = { client: s, held: 0, demanding: !1, live: !0 };
2644
2678
  return this.entries.add(e), e;
2645
2679
  }
2646
2680
  /**
2647
2681
  * Drops a mesh. Slots it still holds are released here: a disposing mesh
2648
2682
  * aborts its fetches, and those aborts land after the handle is gone.
2649
2683
  */
2650
- unregister(i) {
2651
- const e = i;
2684
+ unregister(s) {
2685
+ const e = s;
2652
2686
  this.entries.delete(e) && (e.live = !1, e.held > 0 && (this.inflightCount -= e.held, e.held = 0, this.wake()));
2653
2687
  }
2654
2688
  /**
@@ -2658,19 +2692,19 @@ class Ut {
2658
2692
  * mesh simply did not fetch this tick, and will be woken (or reschedule on
2659
2693
  * its own within the idle interval) to ask again.
2660
2694
  */
2661
- tryAcquire(i, e) {
2662
- const t = i;
2695
+ tryAcquire(s, e) {
2696
+ const t = s;
2663
2697
  if (this.disposed || !t.live) return !1;
2664
- const s = H(t.client.weight());
2665
- return e === "sweep" && s <= 0 ? (t.demanding = !1, !1) : this.inflightCount >= this.maxGlobalInflight || t.held >= this.shareFor(t, s) ? (t.demanding = !0, !1) : (t.held++, t.demanding = !1, this.inflightCount++, !0);
2698
+ const i = H(t.client.weight());
2699
+ return e === "sweep" && i <= 0 ? (t.demanding = !1, !1) : this.inflightCount >= this.maxGlobalInflight || t.held >= this.shareFor(t, i) ? (t.demanding = !0, !1) : (t.held++, t.demanding = !1, this.inflightCount++, !0);
2666
2700
  }
2667
2701
  /**
2668
2702
  * Returns a slot. Must be called exactly once for every granted acquire -
2669
2703
  * on success, on failure **and** on abort - or the pipe leaks capacity until
2670
2704
  * the scene is torn down.
2671
2705
  */
2672
- release(i) {
2673
- const e = i;
2706
+ release(s) {
2707
+ const e = s;
2674
2708
  e.held <= 0 || (e.held--, this.inflightCount--, this.wake());
2675
2709
  }
2676
2710
  /**
@@ -2683,8 +2717,8 @@ class Ut {
2683
2717
  */
2684
2718
  weightsChanged() {
2685
2719
  if (!this.disposed) {
2686
- for (const i of this.entries)
2687
- i.held > 0 && H(i.client.weight()) <= 0 && i.client.shedFetches("sweep");
2720
+ for (const s of this.entries)
2721
+ s.held > 0 && H(s.client.weight()) <= 0 && s.client.shedFetches("sweep");
2688
2722
  this.wake();
2689
2723
  }
2690
2724
  }
@@ -2695,8 +2729,8 @@ class Ut {
2695
2729
  */
2696
2730
  dispose() {
2697
2731
  this.disposed = !0;
2698
- for (const i of this.entries)
2699
- i.live = !1, i.held = 0, i.demanding = !1;
2732
+ for (const s of this.entries)
2733
+ s.live = !1, s.held = 0, s.demanding = !1;
2700
2734
  this.entries.clear(), this.inflightCount = 0;
2701
2735
  }
2702
2736
  /**
@@ -2716,47 +2750,47 @@ class Ut {
2716
2750
  * The denominator counts every mesh that plausibly wants the pipe - all
2717
2751
  * registered meshes except those both weightless and idle, plus the caller.
2718
2752
  */
2719
- shareFor(i, e) {
2720
- let t = 0, s = 0;
2753
+ shareFor(s, e) {
2754
+ let t = 0, i = 0;
2721
2755
  for (const l of this.entries) {
2722
- const c = l === i ? e : H(l.client.weight());
2723
- l !== i && c <= 0 && l.held === 0 && !l.demanding || (t++, s += c);
2756
+ const c = l === s ? e : H(l.client.weight());
2757
+ l !== s && c <= 0 && l.held === 0 && !l.demanding || (t++, i += c);
2724
2758
  }
2725
2759
  if (t <= 1) return this.maxGlobalInflight;
2726
- const n = s > 0 ? this.maxGlobalInflight * e / s : this.maxGlobalInflight / t, r = Math.max(1, this.perMeshFloor, Math.round(n)), a = Math.max(1, this.perMeshFloor) * (t - 1);
2727
- return Math.max(1, Math.min(r, this.maxGlobalInflight - a));
2760
+ const n = i > 0 ? this.maxGlobalInflight * e / i : this.maxGlobalInflight / t, a = Math.max(1, this.perMeshFloor, Math.round(n)), r = Math.max(1, this.perMeshFloor) * (t - 1);
2761
+ return Math.max(1, Math.min(a, this.maxGlobalInflight - r));
2728
2762
  }
2729
2763
  /** Pokes the heaviest mesh that was denied since its last grant. */
2730
2764
  wake() {
2731
2765
  if (this.disposed || this.inflightCount >= this.maxGlobalInflight) return;
2732
- let i = null, e = -1 / 0;
2766
+ let s = null, e = -1 / 0;
2733
2767
  for (const t of this.entries) {
2734
2768
  if (!t.demanding) continue;
2735
- const s = H(t.client.weight());
2736
- s > e && (i = t, e = s);
2769
+ const i = H(t.client.weight());
2770
+ i > e && (s = t, e = i);
2737
2771
  }
2738
- i && (i.demanding = !1, i.client.onSlotAvailable());
2772
+ s && (s.demanding = !1, s.client.onSlotAvailable());
2739
2773
  }
2740
2774
  }
2741
2775
  function H(o) {
2742
2776
  return Number.isFinite(o) && o > 0 ? o : 0;
2743
2777
  }
2744
- const Ft = 32 * 1024 * 1024, Bt = 250, Et = 0.15;
2778
+ const Ft = 32 * 1024 * 1024, Bt = 250, Pt = 0.15;
2745
2779
  class Ht {
2746
- constructor(i) {
2747
- d(this, "entries", /* @__PURE__ */ new Set());
2748
- d(this, "perMeshFloorBytes");
2749
- d(this, "minIntervalMs");
2750
- d(this, "deadband");
2751
- d(this, "totalBytesValue");
2752
- d(this, "lastAllocationMs", Number.NEGATIVE_INFINITY);
2753
- d(this, "disposed", !1);
2754
- if (!Number.isFinite(i.totalBytes) || i.totalBytes <= 0)
2780
+ constructor(s) {
2781
+ u(this, "entries", /* @__PURE__ */ new Set());
2782
+ u(this, "perMeshFloorBytes");
2783
+ u(this, "minIntervalMs");
2784
+ u(this, "deadband");
2785
+ u(this, "totalBytesValue");
2786
+ u(this, "lastAllocationMs", Number.NEGATIVE_INFINITY);
2787
+ u(this, "disposed", !1);
2788
+ if (!Number.isFinite(s.totalBytes) || s.totalBytes <= 0)
2755
2789
  throw new RangeError("Chunk cache totalBytes must be a positive finite number.");
2756
- this.totalBytesValue = Math.floor(i.totalBytes), this.perMeshFloorBytes = Math.max(
2790
+ this.totalBytesValue = Math.floor(s.totalBytes), this.perMeshFloorBytes = Math.max(
2757
2791
  0,
2758
- Math.floor(i.perMeshFloorBytes ?? Ft)
2759
- ), this.minIntervalMs = Math.max(0, i.minIntervalMs ?? Bt), this.deadband = Math.max(0, i.deadband ?? Et);
2792
+ Math.floor(s.perMeshFloorBytes ?? Ft)
2793
+ ), this.minIntervalMs = Math.max(0, s.minIntervalMs ?? Bt), this.deadband = Math.max(0, s.deadband ?? Pt);
2760
2794
  }
2761
2795
  /** Bytes shared across every registered mesh. */
2762
2796
  get totalBytes() {
@@ -2766,10 +2800,10 @@ class Ht {
2766
2800
  * Resizes the scene envelope and re-splits immediately. For a host reacting
2767
2801
  * to a quality change or a device-memory signal.
2768
2802
  */
2769
- setTotalBytes(i) {
2770
- if (!Number.isFinite(i) || i <= 0)
2803
+ setTotalBytes(s) {
2804
+ if (!Number.isFinite(s) || s <= 0)
2771
2805
  throw new RangeError("Chunk cache totalBytes must be a positive finite number.");
2772
- const e = Math.floor(i);
2806
+ const e = Math.floor(s);
2773
2807
  e !== this.totalBytesValue && (this.totalBytesValue = e, this.allocate());
2774
2808
  }
2775
2809
  /** Meshes currently registered. */
@@ -2780,18 +2814,18 @@ class Ht {
2780
2814
  * Adds a mesh and re-splits at once, so the caller can read its opening
2781
2815
  * allowance out of {@link allowanceFor} before posting worker init.
2782
2816
  */
2783
- register(i) {
2784
- const e = { client: i, allowance: 0, live: !0 };
2817
+ register(s) {
2818
+ const e = { client: s, allowance: 0, live: !0 };
2785
2819
  return this.entries.add(e), this.allocate({ force: !0, silentFor: e }), e;
2786
2820
  }
2787
2821
  /** Drops a mesh and hands its bytes back to the siblings. */
2788
- unregister(i) {
2789
- const e = i;
2822
+ unregister(s) {
2823
+ const e = s;
2790
2824
  this.entries.delete(e) && (e.live = !1, e.allowance = 0, this.allocate({ force: !0 }));
2791
2825
  }
2792
2826
  /** This mesh's current allowance in bytes, or 0 once unregistered. */
2793
- allowanceFor(i) {
2794
- const e = i;
2827
+ allowanceFor(s) {
2828
+ const e = s;
2795
2829
  return e.live ? e.allowance : 0;
2796
2830
  }
2797
2831
  /**
@@ -2801,8 +2835,8 @@ class Ht {
2801
2835
  *
2802
2836
  * Rate-limited and dead-banded; calling it every frame is the intended use.
2803
2837
  */
2804
- weightsChanged(i = Date.now()) {
2805
- this.disposed || i - this.lastAllocationMs < this.minIntervalMs || (this.lastAllocationMs = i, this.allocate());
2838
+ weightsChanged(s = Date.now()) {
2839
+ this.disposed || s - this.lastAllocationMs < this.minIntervalMs || (this.lastAllocationMs = s, this.allocate());
2806
2840
  }
2807
2841
  /**
2808
2842
  * Releases every registration. Meshes are not disposed - the budget is shared
@@ -2811,8 +2845,8 @@ class Ht {
2811
2845
  */
2812
2846
  dispose() {
2813
2847
  this.disposed = !0;
2814
- for (const i of this.entries)
2815
- i.live = !1, i.allowance = 0;
2848
+ for (const s of this.entries)
2849
+ s.live = !1, s.allowance = 0;
2816
2850
  this.entries.clear();
2817
2851
  }
2818
2852
  /**
@@ -2826,34 +2860,34 @@ class Ht {
2826
2860
  * silently overcommitting, because a budget that can be exceeded by
2827
2861
  * registering more meshes is the bug this class exists to fix.
2828
2862
  */
2829
- allocate(i = {}) {
2863
+ allocate(s = {}) {
2830
2864
  if (this.disposed) return;
2831
2865
  const e = [...this.entries];
2832
2866
  if (e.length === 0) return;
2833
- const t = this.totalBytesValue, s = Math.min(this.perMeshFloorBytes, Math.floor(t / e.length)), n = /* @__PURE__ */ new Map(), r = new Set(e);
2834
- let a = t;
2835
- for (let l = 0; l <= e.length && r.size > 0; l++) {
2836
- const c = Math.max(0, a - s * r.size);
2867
+ const t = this.totalBytesValue, i = Math.min(this.perMeshFloorBytes, Math.floor(t / e.length)), n = /* @__PURE__ */ new Map(), a = new Set(e);
2868
+ let r = t;
2869
+ for (let l = 0; l <= e.length && a.size > 0; l++) {
2870
+ const c = Math.max(0, r - i * a.size);
2837
2871
  let h = 0;
2838
- for (const u of r) h += Te(u.client.weight());
2872
+ for (const d of a) h += Te(d.client.weight());
2839
2873
  const f = [];
2840
- for (const u of r) {
2841
- const g = Te(u.client.weight()), v = h > 0 ? c * g / h : c / r.size, m = kt(u.client.ceilingBytes), b = Math.floor(s + v);
2842
- b >= m ? (n.set(u, m), f.push(u)) : n.set(u, b);
2874
+ for (const d of a) {
2875
+ const g = Te(d.client.weight()), v = h > 0 ? c * g / h : c / a.size, m = kt(d.client.ceilingBytes), b = Math.floor(i + v);
2876
+ b >= m ? (n.set(d, m), f.push(d)) : n.set(d, b);
2843
2877
  }
2844
2878
  if (f.length === 0) break;
2845
- for (const u of f)
2846
- r.delete(u), a -= n.get(u) ?? 0;
2847
- a = Math.max(0, a);
2879
+ for (const d of f)
2880
+ a.delete(d), r -= n.get(d) ?? 0;
2881
+ r = Math.max(0, r);
2848
2882
  }
2849
2883
  for (const l of e) {
2850
2884
  const c = n.get(l) ?? 0, h = l.allowance;
2851
- l.allowance = c, l !== i.silentFor && (!i.force && !this.movedEnough(h, c) || h !== c && l.client.onAllowanceChanged(c));
2885
+ l.allowance = c, l !== s.silentFor && (!s.force && !this.movedEnough(h, c) || h !== c && l.client.onAllowanceChanged(c));
2852
2886
  }
2853
2887
  }
2854
2888
  /** Suppresses reposts for changes too small to alter any mesh's behaviour. */
2855
- movedEnough(i, e) {
2856
- return i === e ? !1 : i === 0 || e === 0 ? !0 : Math.abs(e - i) / i >= this.deadband;
2889
+ movedEnough(s, e) {
2890
+ return s === e ? !1 : s === 0 || e === 0 ? !0 : Math.abs(e - s) / s >= this.deadband;
2857
2891
  }
2858
2892
  }
2859
2893
  function Te(o) {
@@ -2864,14 +2898,14 @@ function kt(o) {
2864
2898
  }
2865
2899
  export {
2866
2900
  Tt as BudgetGovernor,
2867
- Ot as CameraBudgetGovernor,
2901
+ zt as CameraBudgetGovernor,
2868
2902
  Ht as ChunkCacheBudget,
2869
2903
  Ut as ChunkFetchScheduler,
2870
2904
  q as SplatLoadError,
2871
2905
  Y as StreamedSplatMesh,
2872
2906
  ot as createLocalDataset,
2873
2907
  nt as httpDatasetSource,
2874
- G as isAbortError,
2908
+ N as isAbortError,
2875
2909
  Be as resolveCpuCacheBytes
2876
2910
  };
2877
2911
  //# sourceMappingURL=streaming.js.map