@speridlabs/visus 2.3.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.es.js CHANGED
@@ -1,9 +1,9 @@
1
- var be = Object.defineProperty;
2
- var Se = (x, e, o) => e in x ? be(x, e, { enumerable: !0, configurable: !0, writable: !0, value: o }) : x[e] = o;
3
- var f = (x, e, o) => Se(x, typeof e != "symbol" ? e + "" : e, o);
4
- import Me, { useState as Ce, useRef as Ae, useEffect as Te } from "react";
5
- import * as l from "three";
6
- var ce = { exports: {} }, ae = {};
1
+ var Ye = Object.defineProperty;
2
+ var $e = (n, e, t) => e in n ? Ye(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
3
+ var M = (n, e, t) => $e(n, typeof e != "symbol" ? e + "" : e, t);
4
+ import He, { useState as Xe, useRef as Ze, useEffect as Je } from "react";
5
+ import * as h from "three";
6
+ var we = { exports: {} }, pe = {};
7
7
  /**
8
8
  * @license React
9
9
  * react-jsx-runtime.production.js
@@ -13,29 +13,29 @@ var ce = { exports: {} }, ae = {};
13
13
  * This source code is licensed under the MIT license found in the
14
14
  * LICENSE file in the root directory of this source tree.
15
15
  */
16
- var me;
17
- function _e() {
18
- if (me) return ae;
19
- me = 1;
20
- var x = Symbol.for("react.transitional.element"), e = Symbol.for("react.fragment");
21
- function o(t, r, n) {
22
- var a = null;
23
- if (n !== void 0 && (a = "" + n), r.key !== void 0 && (a = "" + r.key), "key" in r) {
24
- n = {};
25
- for (var i in r)
26
- i !== "key" && (n[i] = r[i]);
27
- } else n = r;
28
- return r = n.ref, {
29
- $$typeof: x,
30
- type: t,
31
- key: a,
32
- ref: r !== void 0 ? r : null,
33
- props: n
16
+ var Pe;
17
+ function Qe() {
18
+ if (Pe) return pe;
19
+ Pe = 1;
20
+ var n = Symbol.for("react.transitional.element"), e = Symbol.for("react.fragment");
21
+ function t(r, s, a) {
22
+ var o = null;
23
+ if (a !== void 0 && (o = "" + a), s.key !== void 0 && (o = "" + s.key), "key" in s) {
24
+ a = {};
25
+ for (var i in s)
26
+ i !== "key" && (a[i] = s[i]);
27
+ } else a = s;
28
+ return s = a.ref, {
29
+ $$typeof: n,
30
+ type: r,
31
+ key: o,
32
+ ref: s !== void 0 ? s : null,
33
+ props: a
34
34
  };
35
35
  }
36
- return ae.Fragment = e, ae.jsx = o, ae.jsxs = o, ae;
36
+ return pe.Fragment = e, pe.jsx = t, pe.jsxs = t, pe;
37
37
  }
38
- var ie = {};
38
+ var xe = {};
39
39
  /**
40
40
  * @license React
41
41
  * react-jsx-runtime.development.js
@@ -45,251 +45,251 @@ var ie = {};
45
45
  * This source code is licensed under the MIT license found in the
46
46
  * LICENSE file in the root directory of this source tree.
47
47
  */
48
- var xe;
49
- function ke() {
50
- return xe || (xe = 1, process.env.NODE_ENV !== "production" && function() {
51
- function x(s) {
52
- if (s == null) return null;
53
- if (typeof s == "function")
54
- return s.$$typeof === v ? null : s.displayName || s.name || null;
55
- if (typeof s == "string") return s;
56
- switch (s) {
57
- case I:
48
+ var Be;
49
+ function Ke() {
50
+ return Be || (Be = 1, process.env.NODE_ENV !== "production" && function() {
51
+ function n(c) {
52
+ if (c == null) return null;
53
+ if (typeof c == "function")
54
+ return c.$$typeof === p ? null : c.displayName || c.name || null;
55
+ if (typeof c == "string") return c;
56
+ switch (c) {
57
+ case v:
58
58
  return "Fragment";
59
- case j:
59
+ case E:
60
60
  return "Profiler";
61
- case P:
61
+ case b:
62
62
  return "StrictMode";
63
63
  case L:
64
64
  return "Suspense";
65
65
  case A:
66
66
  return "SuspenseList";
67
- case T:
67
+ case w:
68
68
  return "Activity";
69
69
  }
70
- if (typeof s == "object")
71
- switch (typeof s.tag == "number" && console.error(
70
+ if (typeof c == "object")
71
+ switch (typeof c.tag == "number" && console.error(
72
72
  "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
73
- ), s.$$typeof) {
74
- case S:
73
+ ), c.$$typeof) {
74
+ case g:
75
75
  return "Portal";
76
- case W:
77
- return (s.displayName || "Context") + ".Provider";
76
+ case P:
77
+ return (c.displayName || "Context") + ".Provider";
78
+ case T:
79
+ return (c._context.displayName || "Context") + ".Consumer";
78
80
  case H:
79
- return (s._context.displayName || "Context") + ".Consumer";
80
- case oe:
81
- var p = s.render;
82
- return s = s.displayName, s || (s = p.displayName || p.name || "", s = s !== "" ? "ForwardRef(" + s + ")" : "ForwardRef"), s;
83
- case g:
84
- return p = s.displayName || null, p !== null ? p : x(s.type) || "Memo";
85
- case D:
86
- p = s._payload, s = s._init;
81
+ var k = c.render;
82
+ return c = c.displayName, c || (c = k.displayName || k.name || "", c = c !== "" ? "ForwardRef(" + c + ")" : "ForwardRef"), c;
83
+ case C:
84
+ return k = c.displayName || null, k !== null ? k : n(c.type) || "Memo";
85
+ case _:
86
+ k = c._payload, c = c._init;
87
87
  try {
88
- return x(s(p));
88
+ return n(c(k));
89
89
  } catch {
90
90
  }
91
91
  }
92
92
  return null;
93
93
  }
94
- function e(s) {
95
- return "" + s;
94
+ function e(c) {
95
+ return "" + c;
96
96
  }
97
- function o(s) {
97
+ function t(c) {
98
98
  try {
99
- e(s);
100
- var p = !1;
99
+ e(c);
100
+ var k = !1;
101
101
  } catch {
102
- p = !0;
102
+ k = !0;
103
103
  }
104
- if (p) {
105
- p = console;
106
- var M = p.error, E = typeof Symbol == "function" && Symbol.toStringTag && s[Symbol.toStringTag] || s.constructor.name || "Object";
107
- return M.call(
108
- p,
104
+ if (k) {
105
+ k = console;
106
+ var B = k.error, F = typeof Symbol == "function" && Symbol.toStringTag && c[Symbol.toStringTag] || c.constructor.name || "Object";
107
+ return B.call(
108
+ k,
109
109
  "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
110
- E
111
- ), e(s);
110
+ F
111
+ ), e(c);
112
112
  }
113
113
  }
114
- function t(s) {
115
- if (s === I) return "<>";
116
- if (typeof s == "object" && s !== null && s.$$typeof === D)
114
+ function r(c) {
115
+ if (c === v) return "<>";
116
+ if (typeof c == "object" && c !== null && c.$$typeof === _)
117
117
  return "<...>";
118
118
  try {
119
- var p = x(s);
120
- return p ? "<" + p + ">" : "<...>";
119
+ var k = n(c);
120
+ return k ? "<" + k + ">" : "<...>";
121
121
  } catch {
122
122
  return "<...>";
123
123
  }
124
124
  }
125
- function r() {
126
- var s = R.A;
127
- return s === null ? null : s.getOwner();
125
+ function s() {
126
+ var c = R.A;
127
+ return c === null ? null : c.getOwner();
128
128
  }
129
- function n() {
129
+ function a() {
130
130
  return Error("react-stack-top-frame");
131
131
  }
132
- function a(s) {
133
- if (B.call(s, "key")) {
134
- var p = Object.getOwnPropertyDescriptor(s, "key").get;
135
- if (p && p.isReactWarning) return !1;
132
+ function o(c) {
133
+ if (q.call(c, "key")) {
134
+ var k = Object.getOwnPropertyDescriptor(c, "key").get;
135
+ if (k && k.isReactWarning) return !1;
136
136
  }
137
- return s.key !== void 0;
137
+ return c.key !== void 0;
138
138
  }
139
- function i(s, p) {
140
- function M() {
141
- Z || (Z = !0, console.error(
139
+ function i(c, k) {
140
+ function B() {
141
+ V || (V = !0, console.error(
142
142
  "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
143
- p
143
+ k
144
144
  ));
145
145
  }
146
- M.isReactWarning = !0, Object.defineProperty(s, "key", {
147
- get: M,
146
+ B.isReactWarning = !0, Object.defineProperty(c, "key", {
147
+ get: B,
148
148
  configurable: !0
149
149
  });
150
150
  }
151
- function u() {
152
- var s = x(this.type);
153
- return U[s] || (U[s] = !0, console.error(
151
+ function m() {
152
+ var c = n(this.type);
153
+ return D[c] || (D[c] = !0, console.error(
154
154
  "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
155
- )), s = this.props.ref, s !== void 0 ? s : null;
155
+ )), c = this.props.ref, c !== void 0 ? c : null;
156
156
  }
157
- function w(s, p, M, E, m, c, y, z) {
158
- return M = c.ref, s = {
159
- $$typeof: b,
160
- type: s,
161
- key: p,
162
- props: c,
163
- _owner: m
164
- }, (M !== void 0 ? M : null) !== null ? Object.defineProperty(s, "ref", {
157
+ function f(c, k, B, F, I, d, z, W) {
158
+ return B = d.ref, c = {
159
+ $$typeof: x,
160
+ type: c,
161
+ key: k,
162
+ props: d,
163
+ _owner: I
164
+ }, (B !== void 0 ? B : null) !== null ? Object.defineProperty(c, "ref", {
165
165
  enumerable: !1,
166
- get: u
167
- }) : Object.defineProperty(s, "ref", { enumerable: !1, value: null }), s._store = {}, Object.defineProperty(s._store, "validated", {
166
+ get: m
167
+ }) : Object.defineProperty(c, "ref", { enumerable: !1, value: null }), c._store = {}, Object.defineProperty(c._store, "validated", {
168
168
  configurable: !1,
169
169
  enumerable: !1,
170
170
  writable: !0,
171
171
  value: 0
172
- }), Object.defineProperty(s, "_debugInfo", {
172
+ }), Object.defineProperty(c, "_debugInfo", {
173
173
  configurable: !1,
174
174
  enumerable: !1,
175
175
  writable: !0,
176
176
  value: null
177
- }), Object.defineProperty(s, "_debugStack", {
177
+ }), Object.defineProperty(c, "_debugStack", {
178
178
  configurable: !1,
179
179
  enumerable: !1,
180
180
  writable: !0,
181
- value: y
182
- }), Object.defineProperty(s, "_debugTask", {
181
+ value: z
182
+ }), Object.defineProperty(c, "_debugTask", {
183
183
  configurable: !1,
184
184
  enumerable: !1,
185
185
  writable: !0,
186
- value: z
187
- }), Object.freeze && (Object.freeze(s.props), Object.freeze(s)), s;
186
+ value: W
187
+ }), Object.freeze && (Object.freeze(c.props), Object.freeze(c)), c;
188
188
  }
189
- function C(s, p, M, E, m, c, y, z) {
190
- var d = p.children;
191
- if (d !== void 0)
192
- if (E)
193
- if ($(d)) {
194
- for (E = 0; E < d.length; E++)
195
- _(d[E]);
196
- Object.freeze && Object.freeze(d);
189
+ function y(c, k, B, F, I, d, z, W) {
190
+ var S = k.children;
191
+ if (S !== void 0)
192
+ if (F)
193
+ if (j(S)) {
194
+ for (F = 0; F < S.length; F++)
195
+ l(S[F]);
196
+ Object.freeze && Object.freeze(S);
197
197
  } else
198
198
  console.error(
199
199
  "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
200
200
  );
201
- else _(d);
202
- if (B.call(p, "key")) {
203
- d = x(s);
204
- var k = Object.keys(p).filter(function(q) {
205
- return q !== "key";
201
+ else l(S);
202
+ if (q.call(k, "key")) {
203
+ S = n(c);
204
+ var U = Object.keys(k).filter(function(X) {
205
+ return X !== "key";
206
206
  });
207
- E = 0 < k.length ? "{key: someKey, " + k.join(": ..., ") + ": ...}" : "{key: someKey}", te[d + E] || (k = 0 < k.length ? "{" + k.join(": ..., ") + ": ...}" : "{}", console.error(
207
+ F = 0 < U.length ? "{key: someKey, " + U.join(": ..., ") + ": ...}" : "{key: someKey}", N[S + F] || (U = 0 < U.length ? "{" + U.join(": ..., ") + ": ...}" : "{}", console.error(
208
208
  `A props object containing a "key" prop is being spread into JSX:
209
209
  let props = %s;
210
210
  <%s {...props} />
211
211
  React keys must be passed directly to JSX without using spread:
212
212
  let props = %s;
213
213
  <%s key={someKey} {...props} />`,
214
- E,
215
- d,
216
- k,
217
- d
218
- ), te[d + E] = !0);
214
+ F,
215
+ S,
216
+ U,
217
+ S
218
+ ), N[S + F] = !0);
219
219
  }
220
- if (d = null, M !== void 0 && (o(M), d = "" + M), a(p) && (o(p.key), d = "" + p.key), "key" in p) {
221
- M = {};
222
- for (var O in p)
223
- O !== "key" && (M[O] = p[O]);
224
- } else M = p;
225
- return d && i(
226
- M,
227
- typeof s == "function" ? s.displayName || s.name || "Unknown" : s
228
- ), w(
229
- s,
230
- d,
220
+ if (S = null, B !== void 0 && (t(B), S = "" + B), o(k) && (t(k.key), S = "" + k.key), "key" in k) {
221
+ B = {};
222
+ for (var $ in k)
223
+ $ !== "key" && (B[$] = k[$]);
224
+ } else B = k;
225
+ return S && i(
226
+ B,
227
+ typeof c == "function" ? c.displayName || c.name || "Unknown" : c
228
+ ), f(
231
229
  c,
232
- m,
233
- r(),
234
- M,
235
- y,
236
- z
230
+ S,
231
+ d,
232
+ I,
233
+ s(),
234
+ B,
235
+ z,
236
+ W
237
237
  );
238
238
  }
239
- function _(s) {
240
- typeof s == "object" && s !== null && s.$$typeof === b && s._store && (s._store.validated = 1);
239
+ function l(c) {
240
+ typeof c == "object" && c !== null && c.$$typeof === x && c._store && (c._store.validated = 1);
241
241
  }
242
- var h = Me, b = Symbol.for("react.transitional.element"), S = Symbol.for("react.portal"), I = Symbol.for("react.fragment"), P = Symbol.for("react.strict_mode"), j = Symbol.for("react.profiler"), H = Symbol.for("react.consumer"), W = Symbol.for("react.context"), oe = Symbol.for("react.forward_ref"), L = Symbol.for("react.suspense"), A = Symbol.for("react.suspense_list"), g = Symbol.for("react.memo"), D = Symbol.for("react.lazy"), T = Symbol.for("react.activity"), v = Symbol.for("react.client.reference"), R = h.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, B = Object.prototype.hasOwnProperty, $ = Array.isArray, X = console.createTask ? console.createTask : function() {
242
+ var u = He, x = Symbol.for("react.transitional.element"), g = Symbol.for("react.portal"), v = Symbol.for("react.fragment"), b = Symbol.for("react.strict_mode"), E = Symbol.for("react.profiler"), T = Symbol.for("react.consumer"), P = Symbol.for("react.context"), H = Symbol.for("react.forward_ref"), L = Symbol.for("react.suspense"), A = Symbol.for("react.suspense_list"), C = Symbol.for("react.memo"), _ = Symbol.for("react.lazy"), w = Symbol.for("react.activity"), p = Symbol.for("react.client.reference"), R = u.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, q = Object.prototype.hasOwnProperty, j = Array.isArray, Y = console.createTask ? console.createTask : function() {
243
243
  return null;
244
244
  };
245
- h = {
246
- "react-stack-bottom-frame": function(s) {
247
- return s();
245
+ u = {
246
+ "react-stack-bottom-frame": function(c) {
247
+ return c();
248
248
  }
249
249
  };
250
- var Z, U = {}, F = h["react-stack-bottom-frame"].bind(
251
- h,
252
- n
253
- )(), N = X(t(n)), te = {};
254
- ie.Fragment = I, ie.jsx = function(s, p, M, E, m) {
255
- var c = 1e4 > R.recentlyCreatedOwnerStacks++;
256
- return C(
257
- s,
258
- p,
259
- M,
250
+ var V, D = {}, O = u["react-stack-bottom-frame"].bind(
251
+ u,
252
+ a
253
+ )(), J = Y(r(a)), N = {};
254
+ xe.Fragment = v, xe.jsx = function(c, k, B, F, I) {
255
+ var d = 1e4 > R.recentlyCreatedOwnerStacks++;
256
+ return y(
257
+ c,
258
+ k,
259
+ B,
260
260
  !1,
261
- E,
262
- m,
263
- c ? Error("react-stack-top-frame") : F,
264
- c ? X(t(s)) : N
261
+ F,
262
+ I,
263
+ d ? Error("react-stack-top-frame") : O,
264
+ d ? Y(r(c)) : J
265
265
  );
266
- }, ie.jsxs = function(s, p, M, E, m) {
267
- var c = 1e4 > R.recentlyCreatedOwnerStacks++;
268
- return C(
269
- s,
270
- p,
271
- M,
266
+ }, xe.jsxs = function(c, k, B, F, I) {
267
+ var d = 1e4 > R.recentlyCreatedOwnerStacks++;
268
+ return y(
269
+ c,
270
+ k,
271
+ B,
272
272
  !0,
273
- E,
274
- m,
275
- c ? Error("react-stack-top-frame") : F,
276
- c ? X(t(s)) : N
273
+ F,
274
+ I,
275
+ d ? Error("react-stack-top-frame") : O,
276
+ d ? Y(r(c)) : J
277
277
  );
278
278
  };
279
- }()), ie;
279
+ }()), xe;
280
280
  }
281
- var ge;
282
- function Ee() {
283
- return ge || (ge = 1, process.env.NODE_ENV === "production" ? ce.exports = _e() : ce.exports = ke()), ce.exports;
281
+ var De;
282
+ function et() {
283
+ return De || (De = 1, process.env.NODE_ENV === "production" ? we.exports = Qe() : we.exports = Ke()), we.exports;
284
284
  }
285
- var Ie = Ee();
286
- class fe {
285
+ var tt = et();
286
+ class be {
287
287
  constructor() {
288
- f(this, "min", new l.Vector3(1 / 0, 1 / 0, 1 / 0));
289
- f(this, "max", new l.Vector3(-1 / 0, -1 / 0, -1 / 0));
290
- f(this, "center", new l.Vector3());
288
+ M(this, "min", new h.Vector3(1 / 0, 1 / 0, 1 / 0));
289
+ M(this, "max", new h.Vector3(-1 / 0, -1 / 0, -1 / 0));
290
+ M(this, "center", new h.Vector3());
291
291
  /** Half extents (size/2) */
292
- f(this, "halfExtents", new l.Vector3());
292
+ M(this, "halfExtents", new h.Vector3());
293
293
  }
294
294
  /**
295
295
  * Reset the bounding box to its initial state
@@ -330,27 +330,26 @@ class fe {
330
330
  * @returns THREE.Box3 representation
331
331
  */
332
332
  toBox3() {
333
- return new l.Box3().set(this.min, this.max);
333
+ return new h.Box3().set(this.min, this.max);
334
334
  }
335
335
  /**
336
336
  * Create a clone of this bounding box
337
337
  * @returns New bounding box with the same values
338
338
  */
339
339
  clone() {
340
- const e = new fe();
340
+ const e = new be();
341
341
  return e.min.copy(this.min), e.max.copy(this.max), e.center.copy(this.center), e.halfExtents.copy(this.halfExtents), e;
342
342
  }
343
343
  }
344
- class Re {
345
- // TODO: there is no sh spherical harmonics
344
+ class rt {
346
345
  constructor(e = 0) {
347
- f(this, "numSplats", 0);
348
- f(this, "positions");
349
- f(this, "rotations");
350
- f(this, "scales");
351
- f(this, "colors");
352
- f(this, "opacities");
353
- f(this, "boundingBox", new fe());
346
+ M(this, "numSplats", 0);
347
+ M(this, "positions");
348
+ M(this, "rotations");
349
+ M(this, "scales");
350
+ M(this, "colors");
351
+ M(this, "opacities");
352
+ M(this, "boundingBox", new be());
354
353
  this.numSplats = e, this.allocateBuffers(e);
355
354
  }
356
355
  allocateBuffers(e) {
@@ -365,13 +364,13 @@ class Re {
365
364
  * @param color Color
366
365
  * @param opacity Opacity value
367
366
  */
368
- setSplat(e, o, t, r, n, a) {
367
+ setSplat(e, t, r, s, a, o) {
369
368
  if (e >= this.numSplats)
370
369
  throw new Error(
371
370
  `Splat index out of bounds: ${e} >= ${this.numSplats}`
372
371
  );
373
- const i = e * 3, u = e * 4, w = e * 3, C = e * 3;
374
- this.positions[i] = o.x, this.positions[i + 1] = o.y, this.positions[i + 2] = o.z, this.rotations[u] = t.x, this.rotations[u + 1] = t.y, this.rotations[u + 2] = t.z, this.rotations[u + 3] = t.w, this.scales[w] = r.x, this.scales[w + 1] = r.y, this.scales[w + 2] = r.z, this.colors[C] = n.r, this.colors[C + 1] = n.g, this.colors[C + 2] = n.b, this.opacities[e] = a;
372
+ const i = e * 3, m = e * 4, f = e * 3, y = e * 3;
373
+ this.positions[i] = t.x, this.positions[i + 1] = t.y, this.positions[i + 2] = t.z, this.rotations[m] = r.x, this.rotations[m + 1] = r.y, this.rotations[m + 2] = r.z, this.rotations[m + 3] = r.w, this.scales[f] = s.x, this.scales[f + 1] = s.y, this.scales[f + 2] = s.z, this.colors[y] = a.r, this.colors[y + 1] = a.g, this.colors[y + 2] = a.b, this.opacities[e] = o;
375
374
  }
376
375
  /**
377
376
  * Get a splat's data
@@ -383,29 +382,29 @@ class Re {
383
382
  throw new Error(
384
383
  `Splat index out of bounds: ${e} >= ${this.numSplats}`
385
384
  );
386
- const o = e * 3, t = e * 4, r = e * 3, n = e * 3;
385
+ const t = e * 3, r = e * 4, s = e * 3, a = e * 3;
387
386
  return {
388
- position: new l.Vector3(
389
- this.positions[o],
390
- this.positions[o + 1],
391
- this.positions[o + 2]
387
+ position: new h.Vector3(
388
+ this.positions[t],
389
+ this.positions[t + 1],
390
+ this.positions[t + 2]
392
391
  ),
393
- rotation: new l.Quaternion(
394
- this.rotations[t],
395
- this.rotations[t + 1],
396
- this.rotations[t + 2],
397
- this.rotations[t + 3]
392
+ rotation: new h.Quaternion(
393
+ this.rotations[r],
394
+ this.rotations[r + 1],
395
+ this.rotations[r + 2],
396
+ this.rotations[r + 3]
398
397
  ),
399
398
  // Convert log scale back to linear scale for external use
400
- scale: new l.Vector3(
401
- Math.exp(this.scales[r]),
402
- Math.exp(this.scales[r + 1]),
403
- Math.exp(this.scales[r + 2])
399
+ scale: new h.Vector3(
400
+ Math.exp(this.scales[s]),
401
+ Math.exp(this.scales[s + 1]),
402
+ Math.exp(this.scales[s + 2])
404
403
  ),
405
- color: new l.Color(
406
- this.colors[n],
407
- this.colors[n + 1],
408
- this.colors[n + 2]
404
+ color: new h.Color(
405
+ this.colors[a],
406
+ this.colors[a + 1],
407
+ this.colors[a + 2]
409
408
  ),
410
409
  opacity: this.opacities[e]
411
410
  };
@@ -416,13 +415,13 @@ class Re {
416
415
  */
417
416
  calculateBoundingBox() {
418
417
  this.boundingBox.reset();
419
- const e = new l.Vector3();
420
- for (let o = 0; o < this.numSplats; o++) {
421
- const t = o * 3;
418
+ const e = new h.Vector3();
419
+ for (let t = 0; t < this.numSplats; t++) {
420
+ const r = t * 3;
422
421
  e.set(
423
- this.positions[t],
424
- this.positions[t + 1],
425
- this.positions[t + 2]
422
+ this.positions[r],
423
+ this.positions[r + 1],
424
+ this.positions[r + 2]
426
425
  ), this.boundingBox.expandByPoint(e);
427
426
  }
428
427
  return this.boundingBox;
@@ -432,68 +431,265 @@ class Re {
432
431
  * This is for visualization/debugging purposes only, not for rendering
433
432
  */
434
433
  createDebugGeometry() {
435
- const e = new l.BufferGeometry();
434
+ const e = new h.BufferGeometry();
436
435
  e.setAttribute(
437
436
  "position",
438
- new l.BufferAttribute(this.positions, 3)
437
+ new h.BufferAttribute(this.positions, 3)
439
438
  );
440
- const o = new Float32Array(this.numSplats * 3), t = new l.Quaternion(), r = new l.Euler();
441
- for (let n = 0; n < this.numSplats; n++) {
442
- const a = n * 4, i = n * 3;
443
- t.set(
444
- this.rotations[a],
445
- this.rotations[a + 1],
446
- this.rotations[a + 2],
447
- this.rotations[a + 3]
448
- ), r.setFromQuaternion(t), o[i] = r.x, o[i + 1] = r.y, o[i + 2] = r.z;
439
+ const t = new Float32Array(this.numSplats * 3), r = new h.Quaternion(), s = new h.Euler();
440
+ for (let a = 0; a < this.numSplats; a++) {
441
+ const o = a * 4, i = a * 3;
442
+ r.set(
443
+ this.rotations[o],
444
+ this.rotations[o + 1],
445
+ this.rotations[o + 2],
446
+ this.rotations[o + 3]
447
+ ), s.setFromQuaternion(r), t[i] = s.x, t[i + 1] = s.y, t[i + 2] = s.z;
449
448
  }
450
449
  return e.setAttribute(
451
450
  "rotation",
452
- new l.BufferAttribute(o, 3)
451
+ new h.BufferAttribute(t, 3)
453
452
  ), e.setAttribute(
454
453
  "scale",
455
- new l.BufferAttribute(this.scales, 3)
454
+ new h.BufferAttribute(this.scales, 3)
456
455
  ), e.setAttribute(
457
456
  "color",
458
- new l.BufferAttribute(this.colors, 3)
457
+ new h.BufferAttribute(this.colors, 3)
459
458
  ), e.setAttribute(
460
459
  "opacity",
461
- new l.BufferAttribute(this.opacities, 1)
460
+ new h.BufferAttribute(this.opacities, 1)
462
461
  ), e;
463
462
  }
463
+ dispose() {
464
+ this.numSplats = 0, this.scales = new Float32Array(0), this.colors = new Float32Array(0), this.positions = new Float32Array(0), this.rotations = new Float32Array(0), this.opacities = new Float32Array(0);
465
+ }
466
+ }
467
+ class Fe {
468
+ // Upper 8 bits of 16-bit means
469
+ constructor(e, t, r) {
470
+ M(this, "ranges");
471
+ M(this, "numSplats", 0);
472
+ M(this, "boundingBox", new be());
473
+ // Original SOGS textures
474
+ M(this, "sh0");
475
+ // SH DC coefficients + alpha
476
+ M(this, "quats");
477
+ // Quaternion components + mode
478
+ M(this, "scales");
479
+ // Scale values (8-bit)
480
+ M(this, "means_l");
481
+ // Lower 8 bits of 16-bit means
482
+ M(this, "means_u");
483
+ this.ranges = t, this.numSplats = e, this.sh0 = r.sh0, this.quats = r.quats, this.scales = r.scales, this.means_l = r.means_l, this.means_u = r.means_u, this.boundingBox = this.calculateBoundingBox();
484
+ }
485
+ calculateBoundingBox() {
486
+ this.boundingBox.reset();
487
+ const { mins: e, maxs: t } = this.ranges.means, r = (s) => Math.sign(s) * (Math.exp(Math.abs(s)) - 1);
488
+ return this.boundingBox.center.set(
489
+ (r(e[0]) + r(t[0])) * 0.5,
490
+ (r(e[1]) + r(t[1])) * 0.5,
491
+ (r(e[2]) + r(t[2])) * 0.5
492
+ ), this.boundingBox.halfExtents.set(
493
+ (r(t[0]) - r(e[0])) * 0.5,
494
+ (r(t[1]) - r(e[1])) * 0.5,
495
+ (r(t[2]) - r(e[2])) * 0.5
496
+ ), this.boundingBox;
497
+ }
498
+ dispose() {
499
+ this.sh0.dispose(), this.quats.dispose(), this.scales.dispose(), this.means_l.dispose(), this.means_u.dispose();
500
+ }
501
+ }
502
+ class qe {
503
+ // RGBA32UI - (Position + Rotation + Scale)
504
+ // RGBA32UI Texture Content:
505
+ // .r = Means Lower (RGB)
506
+ // .g = Means Upper (RGB)
507
+ // .b = Rotation (RGBA)
508
+ // .a = Scale (RGB)
509
+ constructor(e, t, r, s, a, o, i, m) {
510
+ // Info data - cpu
511
+ M(this, "numSplats");
512
+ M(this, "textureWidth");
513
+ M(this, "textureHeight");
514
+ M(this, "ranges");
515
+ M(this, "centers");
516
+ // TODO: see if necesary or can be compressed somehow
517
+ M(this, "boundingBox");
518
+ // GPU Textures
519
+ M(this, "packedColor");
520
+ // RGBA8 - (Color + Opacity)
521
+ // RGBA8 Texture Content:
522
+ // .rgb = Color, .a = Opacity
523
+ M(this, "packedGeometry");
524
+ this.numSplats = e, this.textureWidth = t, this.textureHeight = r, this.boundingBox = m, this.ranges = i, this.centers = s, this.packedColor = o, this.packedGeometry = a;
525
+ }
526
+ /**
527
+ * Optional: Reconstruct a full JS object for a specific splat.
528
+ * Useful for raycasting or debugging.
529
+ */
530
+ // public getSplat(index: number) {
531
+ // throw new Error('Not implemented yet');
532
+ // }
533
+ dispose() {
534
+ this.centers = new Float32Array(0), this.packedColor = new Uint8Array(0), this.packedGeometry = new Uint32Array(0);
535
+ }
536
+ // public abstract deserialize(): ISplat;
537
+ // public abstract returnPacked(): ISplat;
538
+ }
539
+ const me = 0.28209479177387814;
540
+ class Ce {
541
+ /**
542
+ * Packs PLY data (Float32) into the Unified SOGS-like Format.
543
+ */
544
+ // prettier-ignore
545
+ static packPly(e) {
546
+ const t = e.numSplats, r = Math.ceil(Math.sqrt(t)), s = Math.ceil(t / r), a = r * s, { ranges: o, colorScale: i } = this.calculatePlyRanges(e), m = new Uint32Array(a * 4), f = new Uint8Array(a * 4), y = new h.Quaternion();
547
+ for (let l = 0; l < t; l++) {
548
+ const u = l * 4, x = l * 3, g = l * 4, v = e.positions[x + 0], b = e.positions[x + 1], E = e.positions[x + 2], T = this.clamp01(this.norm(v, o.means.min.x, o.means.max.x)), P = this.clamp01(this.norm(b, o.means.min.y, o.means.max.y)), H = this.clamp01(this.norm(E, o.means.min.z, o.means.max.z)), L = T * 65535 | 0, A = P * 65535 | 0, C = H * 65535 | 0;
549
+ m[u + 0] = this.pack4Bytes(L & 255, A & 255, C & 255, 0), m[u + 1] = this.pack4Bytes(L >> 8, A >> 8, C >> 8, 0), y.set(e.rotations[g], e.rotations[g + 1], e.rotations[g + 2], e.rotations[g + 3]).normalize();
550
+ let _ = y.w, w = y.x, p = y.y, R = y.z;
551
+ const q = Math.abs(_), j = Math.abs(w), Y = Math.abs(p), V = Math.abs(R);
552
+ let D = 0, O = q;
553
+ j > O && (O = j, D = 1), Y > O && (O = Y, D = 2), V > O && (O = V, D = 3), (D === 0 ? _ : D === 1 ? w : D === 2 ? p : R) < 0 && (_ = -_, w = -w, p = -p, R = -R);
554
+ let N = 0, c = 0, k = 0;
555
+ D === 0 && (N = w, c = p, k = R), D === 1 && (N = _, c = p, k = R), D === 2 && (N = _, c = w, k = R), D === 3 && (N = _, c = w, k = p);
556
+ const B = (se) => Math.min(255, Math.max(0, Math.round((0.5 + se / Math.SQRT2) * 255)));
557
+ m[u + 2] = this.pack4Bytes(B(N), B(c), B(k), D);
558
+ const F = this.norm(e.scales[x + 0], o.scales.min.x, o.scales.max.x), I = this.norm(e.scales[x + 1], o.scales.min.y, o.scales.max.y), d = this.norm(e.scales[x + 2], o.scales.min.z, o.scales.max.z);
559
+ m[u + 3] = this.pack4Bytes(Math.floor(F * 255), Math.floor(I * 255), Math.floor(d * 255), 0);
560
+ const z = this.clamp01(e.colors[x + 0] * i), W = this.clamp01(e.colors[x + 1] * i), S = this.clamp01(e.colors[x + 2] * i), U = (z - 0.5) / me, $ = (W - 0.5) / me, X = (S - 0.5) / me, Q = this.clamp01(this.norm(U, o.sh0.min.x, o.sh0.max.x)), Z = this.clamp01(this.norm($, o.sh0.min.y, o.sh0.max.y)), K = this.clamp01(this.norm(X, o.sh0.min.z, o.sh0.max.z)), re = this.clamp01(e.opacities[l]);
561
+ f[u + 0] = Math.round(Q * 255), f[u + 1] = Math.round(Z * 255), f[u + 2] = Math.round(K * 255), f[u + 3] = Math.round(re * 255);
562
+ }
563
+ return new qe(t, r, s, e.positions, m, f, o, e.boundingBox);
564
+ }
565
+ /**
566
+ * Packs SOGS data.
567
+ * Interleaves the separate textures into the Unified RGBA32UI buffer.
568
+ * Decodes centers for sorting.
569
+ */
570
+ // prettier-ignore
571
+ static packSogs(e) {
572
+ const t = e.numSplats, r = Math.ceil(Math.sqrt(t)), s = Math.ceil(t / r), a = r * s, o = this.convertSogsRanges(e.ranges), i = e.ranges.means.mins[0], m = e.ranges.means.mins[1], f = e.ranges.means.mins[2], y = e.ranges.means.maxs[0], l = e.ranges.means.maxs[1], u = e.ranges.means.maxs[2], x = (w) => Math.sign(w) * (Math.exp(Math.abs(w)) - 1), g = new h.Vector3(
573
+ x(i),
574
+ x(m),
575
+ x(f)
576
+ ), v = new h.Vector3(
577
+ x(y),
578
+ x(l),
579
+ x(u)
580
+ );
581
+ o.means.min.copy(g), o.means.max.copy(v);
582
+ const b = e, E = this.getPixels(b.means_l), T = this.getPixels(b.means_u), P = this.getPixels(b.quats), H = this.getPixels(b.scales), L = this.getPixels(b.sh0), A = new Uint32Array(a * 4), C = new Uint8Array(a * 4), _ = new Float32Array(t * 3);
583
+ for (let w = 0; w < t; w++) {
584
+ const p = w * 4, R = T[p + 0], q = E[p + 0], j = T[p + 1], Y = E[p + 1], V = T[p + 2], D = E[p + 2], O = (R << 8 | q) / 65535, J = (j << 8 | Y) / 65535, N = (V << 8 | D) / 65535, c = this.sogsDecode(O, i, y), k = this.sogsDecode(J, m, l), B = this.sogsDecode(N, f, u);
585
+ _[w * 3 + 0] = c, _[w * 3 + 1] = k, _[w * 3 + 2] = B;
586
+ const F = this.clamp01(this.norm(c, g.x, v.x)) * 65535 | 0, I = this.clamp01(this.norm(k, g.y, v.y)) * 65535 | 0, d = this.clamp01(this.norm(B, g.z, v.z)) * 65535 | 0;
587
+ A[p + 0] = this.pack4Bytes(F & 255, I & 255, d & 255, 0), A[p + 1] = this.pack4Bytes(F >> 8, I >> 8, d >> 8, 0), A[p + 3] = this.pack4Bytes(H[p], H[p + 1], H[p + 2], 0);
588
+ const W = P[p + 3] - 252;
589
+ A[p + 2] = this.pack4Bytes(P[p + 0], P[p + 1], P[p + 2], W), C[p + 0] = L[p], C[p + 1] = L[p + 1], C[p + 2] = L[p + 2];
590
+ const S = L[p + 3] / 255, U = e.ranges.sh0.mins[3] + (e.ranges.sh0.maxs[3] - e.ranges.sh0.mins[3]) * S, $ = 1 / (1 + Math.exp(-U));
591
+ C[p + 3] = Math.round(Math.max(0, Math.min(1, $)) * 255);
592
+ }
593
+ return new qe(t, r, s, _, A, C, o, e.boundingBox);
594
+ }
595
+ // --- Helpers ---
596
+ // prettier-ignore
597
+ static pack4Bytes(e, t, r, s) {
598
+ return (e & 255) << 24 | (t & 255) << 16 | (r & 255) << 8 | s & 255;
599
+ }
600
+ // prettier-ignore
601
+ static getPixels(e) {
602
+ const t = e.image, r = t.width, s = t.height;
603
+ if (t.data && (t.data instanceof Uint8Array || t.data instanceof Uint8ClampedArray)) return new Uint8Array(t.data);
604
+ const a = document.createElement("canvas");
605
+ a.width = r, a.height = s;
606
+ const o = a.getContext("2d", { willReadFrequently: !0 });
607
+ if (!o) throw new Error("Canvas init failed");
608
+ return o.drawImage(t, 0, 0), new Uint8Array(o.getImageData(0, 0, r, s).data);
609
+ }
610
+ static convertSogsRanges(e) {
611
+ const t = (r) => new h.Vector3(r[0], r[1], r[2]);
612
+ return {
613
+ sh0: { min: t(e.sh0.mins), max: t(e.sh0.maxs) },
614
+ means: { min: t(e.means.mins), max: t(e.means.maxs) },
615
+ scales: { min: t(e.scales.mins), max: t(e.scales.maxs) }
616
+ };
617
+ }
618
+ static calculatePlyRanges(e) {
619
+ const t = new h.Vector3(1 / 0, 1 / 0, 1 / 0), r = new h.Vector3(-1 / 0, -1 / 0, -1 / 0), s = new h.Vector3(1 / 0, 1 / 0, 1 / 0), a = new h.Vector3(-1 / 0, -1 / 0, -1 / 0), o = new h.Vector3(1 / 0, 1 / 0, 1 / 0), i = new h.Vector3(-1 / 0, -1 / 0, -1 / 0);
620
+ let m = 0;
621
+ for (let y = 0; y < e.numSplats; y++) {
622
+ const l = y * 3, u = e.positions[l + 0], x = e.positions[l + 1], g = e.positions[l + 2];
623
+ t.x = Math.min(t.x, u), r.x = Math.max(r.x, u), t.y = Math.min(t.y, x), r.y = Math.max(r.y, x), t.z = Math.min(t.z, g), r.z = Math.max(r.z, g), s.x = Math.min(s.x, e.scales[l]), a.x = Math.max(a.x, e.scales[l]), s.y = Math.min(s.y, e.scales[l + 1]), a.y = Math.max(a.y, e.scales[l + 1]), s.z = Math.min(s.z, e.scales[l + 2]), a.z = Math.max(a.z, e.scales[l + 2]), m = Math.max(
624
+ m,
625
+ e.colors[l],
626
+ e.colors[l + 1],
627
+ e.colors[l + 2]
628
+ );
629
+ }
630
+ const f = m > 1.5 ? 1 / 255 : 1;
631
+ for (let y = 0; y < e.numSplats; y++) {
632
+ const l = y * 3, u = this.clamp01(e.colors[l + 0] * f), x = this.clamp01(e.colors[l + 1] * f), g = this.clamp01(e.colors[l + 2] * f), v = (u - 0.5) / me, b = (x - 0.5) / me, E = (g - 0.5) / me;
633
+ o.x = Math.min(o.x, v), i.x = Math.max(i.x, v), o.y = Math.min(o.y, b), i.y = Math.max(i.y, b), o.z = Math.min(o.z, E), i.z = Math.max(i.z, E);
634
+ }
635
+ return {
636
+ colorScale: f,
637
+ ranges: {
638
+ sh0: { min: o, max: i },
639
+ means: { min: t, max: r },
640
+ scales: { min: s, max: a }
641
+ }
642
+ };
643
+ }
644
+ static clamp01(e) {
645
+ return Math.max(0, Math.min(1, e));
646
+ }
647
+ // prettier-ignore
648
+ // private static lerp(a: number, b: number, t: number) { return a + (b - a) * t; } // prettier-ignore
649
+ // private static invSogsMap(v: number) { return Math.sign(v) * Math.log(Math.abs(v) + 1) } // prettier-ignore
650
+ static norm(e, t, r) {
651
+ return (e - t) / (r - t || 1);
652
+ }
653
+ // prettier-ignore
654
+ static sogsDecode(e, t, r) {
655
+ const s = t + (r - t) * e;
656
+ return Math.sign(s) * (Math.exp(Math.abs(s)) - 1);
657
+ }
464
658
  }
465
- class ze extends l.Loader {
466
- constructor(o) {
467
- super(o);
468
- f(this, "requestId", 0);
469
- f(this, "worker");
470
- f(this, "pendingCallbacks", /* @__PURE__ */ new Map());
659
+ class st extends h.Loader {
660
+ constructor(t) {
661
+ super(t);
662
+ M(this, "requestId", 0);
663
+ M(this, "worker");
664
+ M(this, "pendingCallbacks", /* @__PURE__ */ new Map());
471
665
  this.withCredentials = !0;
472
- const t = this.createWorkerCode(), r = new Blob([t], { type: "application/javascript" });
473
- this.worker = new Worker(URL.createObjectURL(r)), this.worker.onmessage = this.onWorkerMessage.bind(this);
666
+ const r = this.createWorkerCode(), s = new Blob([r], { type: "application/javascript" });
667
+ this.worker = new Worker(URL.createObjectURL(s)), this.worker.onmessage = this.onWorkerMessage.bind(this);
474
668
  }
475
669
  /**
476
670
  * Handles messages received from the parsing worker
477
671
  * @param event The message event from the worker
478
672
  */
479
- onWorkerMessage(o) {
480
- const { requestId: t, error: r, result: n } = o.data, a = this.pendingCallbacks.get(t);
481
- if (!a) return console.warn(`PlyLoader: Received response for unknown request ${t}`);
482
- if (this.pendingCallbacks.delete(t), r) return a.reject(new Error(r));
483
- if (!n) return a.reject(new Error("Worker returned no result"));
673
+ onWorkerMessage(t) {
674
+ const { requestId: r, error: s, result: a } = t.data, o = this.pendingCallbacks.get(r);
675
+ if (!o) return console.warn(`PlyLoader: Received response for unknown request ${r}`);
676
+ if (this.pendingCallbacks.delete(r), s) return o.reject(new Error(s));
677
+ if (!a) return o.reject(new Error("Worker returned no result"));
484
678
  try {
485
- const i = new Re(0);
486
- i.numSplats = n.numSplats, i.positions = new Float32Array(n.positions), i.rotations = new Float32Array(n.rotations), i.scales = new Float32Array(n.scales), i.colors = new Float32Array(n.colors), i.opacities = new Float32Array(n.opacities), i.boundingBox.min.set(
487
- n.boundingBox.minX,
488
- n.boundingBox.minY,
489
- n.boundingBox.minZ
679
+ const i = new rt(0);
680
+ i.numSplats = a.numSplats, i.positions = new Float32Array(a.positions), i.rotations = new Float32Array(a.rotations), i.scales = new Float32Array(a.scales), i.colors = new Float32Array(a.colors), i.opacities = new Float32Array(a.opacities), i.boundingBox.min.set(
681
+ a.boundingBox.minX,
682
+ a.boundingBox.minY,
683
+ a.boundingBox.minZ
490
684
  ), i.boundingBox.max.set(
491
- n.boundingBox.maxX,
492
- n.boundingBox.maxY,
493
- n.boundingBox.maxZ
494
- ), this.worker.terminate(), a.resolve(i);
685
+ a.boundingBox.maxX,
686
+ a.boundingBox.maxY,
687
+ a.boundingBox.maxZ
688
+ ), this.worker.terminate();
689
+ const m = Ce.packPly(i);
690
+ i.dispose(), o.resolve(m);
495
691
  } catch (i) {
496
- a.reject(i);
692
+ o.reject(i);
497
693
  }
498
694
  }
499
695
  /**
@@ -503,19 +699,19 @@ class ze extends l.Loader {
503
699
  * @param onProgress Optional progress callback
504
700
  * @param onError Optional error callback
505
701
  */
506
- load(o, t, r, n) {
507
- const a = new l.FileLoader(this.manager);
508
- a.setResponseType("arraybuffer"), a.setRequestHeader(this.requestHeader), a.setPath(this.path), a.setWithCredentials(this.withCredentials), a.load(
509
- o,
702
+ load(t, r, s, a) {
703
+ const o = new h.FileLoader(this.manager);
704
+ o.setResponseType("arraybuffer"), o.setRequestHeader(this.requestHeader), o.setPath(this.path), o.setWithCredentials(this.withCredentials), o.load(
705
+ t,
510
706
  (i) => {
511
- this.parseAsync(i).then((u) => {
512
- t && t(u);
513
- }).catch((u) => {
514
- n ? n(u) : console.error(u), this.manager.itemError(o);
707
+ this.parseAsync(i).then((m) => {
708
+ r && r(m);
709
+ }).catch((m) => {
710
+ a ? a(m) : console.error(m), this.manager.itemError(t);
515
711
  });
516
712
  },
517
- r,
518
- n
713
+ s,
714
+ a
519
715
  );
520
716
  }
521
717
  /**
@@ -524,19 +720,19 @@ class ze extends l.Loader {
524
720
  * @param onProgress Optional progress callback
525
721
  * @returns A Promise that resolves with the parsed SplatData
526
722
  */
527
- loadAsync(o, t) {
528
- return new Promise((r, n) => {
529
- const a = new l.FileLoader(this.manager);
530
- a.setResponseType("arraybuffer"), a.setRequestHeader(this.requestHeader), a.setPath(this.path), a.setWithCredentials(this.withCredentials), a.load(
531
- o,
723
+ loadAsync(t, r) {
724
+ return new Promise((s, a) => {
725
+ const o = new h.FileLoader(this.manager);
726
+ o.setResponseType("arraybuffer"), o.setRequestHeader(this.requestHeader), o.setPath(this.path), o.setWithCredentials(this.withCredentials), o.load(
727
+ t,
532
728
  (i) => {
533
- this.parseAsync(i).then(r).catch((u) => {
534
- n(u), this.manager.itemError(o);
729
+ this.parseAsync(i).then(s).catch((m) => {
730
+ a(m), this.manager.itemError(t);
535
731
  });
536
732
  },
537
- t,
733
+ r,
538
734
  (i) => {
539
- n(i), this.manager.itemError(o);
735
+ a(i), this.manager.itemError(t);
540
736
  }
541
737
  );
542
738
  });
@@ -546,15 +742,15 @@ class ze extends l.Loader {
546
742
  * @param buffer ArrayBuffer containing PLY data
547
743
  * @returns Promise that resolves with parsed SplatData
548
744
  */
549
- parseAsync(o) {
550
- return new Promise((t, r) => {
551
- const n = this.requestId++;
552
- this.pendingCallbacks.set(n, { resolve: t, reject: r });
553
- const a = {
554
- requestId: n,
555
- buffer: o
745
+ parseAsync(t) {
746
+ return new Promise((r, s) => {
747
+ const a = this.requestId++;
748
+ this.pendingCallbacks.set(a, { resolve: r, reject: s });
749
+ const o = {
750
+ requestId: a,
751
+ buffer: t
556
752
  };
557
- this.worker.postMessage(a, [o]);
753
+ this.worker.postMessage(o, [t]);
558
754
  });
559
755
  }
560
756
  /**
@@ -569,14 +765,14 @@ class ze extends l.Loader {
569
765
  */
570
766
  createWorkerCode() {
571
767
  return `(${(function() {
572
- self.onmessage = (r) => {
573
- const { requestId: n, buffer: a } = r.data;
768
+ self.onmessage = (s) => {
769
+ const { requestId: a, buffer: o } = s.data;
574
770
  try {
575
- const i = t(a), u = {
576
- requestId: n,
771
+ const i = r(o), m = {
772
+ requestId: a,
577
773
  result: i
578
774
  };
579
- self.postMessage(u, [
775
+ self.postMessage(m, [
580
776
  i.positions,
581
777
  i.rotations,
582
778
  i.scales,
@@ -584,215 +780,750 @@ class ze extends l.Loader {
584
780
  i.opacities
585
781
  ]);
586
782
  } catch (i) {
587
- const u = {
588
- requestId: n,
783
+ const m = {
784
+ requestId: a,
589
785
  error: i instanceof Error ? i.message : String(i)
590
786
  };
591
- self.postMessage(u);
787
+ self.postMessage(m);
592
788
  }
593
789
  };
594
- function t(r) {
595
- const n = new TextDecoder(), a = new Uint8Array(r), i = [112, 108, 121, 10], u = `
790
+ function r(s) {
791
+ const a = new TextDecoder(), o = new Uint8Array(s), i = [112, 108, 121, 10], m = `
596
792
  end_header
597
793
  `;
598
- for (let m = 0; m < i.length; m++)
599
- if (a[m] !== i[m])
794
+ for (let I = 0; I < i.length; I++)
795
+ if (o[I] !== i[I])
600
796
  throw new Error(
601
797
  "Invalid PLY file: Missing magic bytes"
602
798
  );
603
- let w = 0;
604
- for (let m = 0; m < a.length - u.length; m++) {
605
- let c = !0;
606
- for (let y = 0; y < u.length; y++)
607
- if (a[m + y] !== u.charCodeAt(y)) {
608
- c = !1;
799
+ let f = 0;
800
+ for (let I = 0; I < o.length - m.length; I++) {
801
+ let d = !0;
802
+ for (let z = 0; z < m.length; z++)
803
+ if (o[I + z] !== m.charCodeAt(z)) {
804
+ d = !1;
609
805
  break;
610
806
  }
611
- if (c) {
612
- w = m + u.length;
807
+ if (d) {
808
+ f = I + m.length;
613
809
  break;
614
810
  }
615
811
  }
616
- if (w === 0)
812
+ if (f === 0)
617
813
  throw new Error(
618
814
  "Invalid PLY file: Could not find end of header"
619
815
  );
620
- const _ = n.decode(
621
- a.subarray(0, w)
816
+ const l = a.decode(
817
+ o.subarray(0, f)
622
818
  ).split(`
623
- `), h = [];
624
- let b = null;
625
- for (let m = 1; m < _.length; m++) {
626
- const c = _[m].trim();
627
- if (c === "" || c === "end_header") continue;
628
- const y = c.split(" ");
629
- switch (y[0]) {
819
+ `), u = [];
820
+ let x = null;
821
+ for (let I = 1; I < l.length; I++) {
822
+ const d = l[I].trim();
823
+ if (d === "" || d === "end_header") continue;
824
+ const z = d.split(" ");
825
+ switch (z[0]) {
630
826
  case "format":
631
- b = y[1];
827
+ x = z[1];
632
828
  break;
633
829
  case "element":
634
- h.push({
635
- name: y[1],
636
- count: parseInt(y[2], 10),
830
+ u.push({
831
+ name: z[1],
832
+ count: parseInt(z[2], 10),
637
833
  properties: []
638
834
  });
639
835
  break;
640
836
  case "property":
641
- if (h.length === 0)
837
+ if (u.length === 0)
642
838
  throw new Error(
643
839
  "Invalid PLY file: Property without element"
644
840
  );
645
- h[h.length - 1].properties.push({
646
- type: y[1],
647
- name: y[2]
841
+ u[u.length - 1].properties.push({
842
+ type: z[1],
843
+ name: z[2]
648
844
  });
649
845
  break;
650
846
  }
651
847
  }
652
- if (b !== "binary_little_endian")
653
- throw new Error(`Unsupported PLY format: ${b}`);
654
- const S = h.find((m) => m.name === "vertex");
655
- if (!S)
848
+ if (x !== "binary_little_endian")
849
+ throw new Error(`Unsupported PLY format: ${x}`);
850
+ const g = u.find((I) => I.name === "vertex");
851
+ if (!g)
656
852
  throw new Error(
657
853
  "Invalid PLY file: No vertex element found"
658
854
  );
659
- const I = S.count, P = new Float32Array(I * 3), j = new Float32Array(I * 4), H = new Float32Array(I * 3), W = new Float32Array(I * 3), oe = new Float32Array(I), L = new DataView(r);
660
- let A = w;
661
- const g = (m) => S.properties.findIndex(
662
- (c) => c.name === m
663
- ), D = g("x"), T = g("y"), v = g("z"), R = [
664
- g("rot_0"),
665
- g("rot_1"),
666
- g("rot_2"),
667
- g("rot_3")
668
- ], B = [
669
- g("scale_0"),
670
- g("scale_1"),
671
- g("scale_2")
672
- ], $ = [
673
- g("f_dc_0"),
674
- g("f_dc_1"),
675
- g("f_dc_2")
676
- ], X = g("opacity");
855
+ const v = g.count, b = new Float32Array(v * 3), E = new Float32Array(v * 4), T = new Float32Array(v * 3), P = new Float32Array(v * 3), H = new Float32Array(v), L = new DataView(s);
856
+ let A = f;
857
+ const C = (I) => g.properties.findIndex(
858
+ (d) => d.name === I
859
+ ), _ = C("x"), w = C("y"), p = C("z"), R = [
860
+ C("rot_0"),
861
+ C("rot_1"),
862
+ C("rot_2"),
863
+ C("rot_3")
864
+ ], q = [
865
+ C("scale_0"),
866
+ C("scale_1"),
867
+ C("scale_2")
868
+ ], j = [
869
+ C("f_dc_0"),
870
+ C("f_dc_1"),
871
+ C("f_dc_2")
872
+ ], Y = C("opacity");
677
873
  if ([
678
- D,
679
- T,
680
- v,
874
+ _,
875
+ w,
876
+ p,
681
877
  ...R,
682
- ...B,
683
- ...$,
684
- X
685
- ].some((m) => m === -1))
878
+ ...q,
879
+ ...j,
880
+ Y
881
+ ].some((I) => I === -1))
686
882
  throw new Error(
687
883
  "Invalid PLY file: Missing required properties"
688
884
  );
689
- const U = 0.28209479177387814, F = (m) => {
690
- if (m > 0) return 1 / (1 + Math.exp(-m));
691
- const c = Math.exp(m);
692
- return c / (1 + c);
885
+ const D = 0.28209479177387814, O = (I) => {
886
+ if (I > 0) return 1 / (1 + Math.exp(-I));
887
+ const d = Math.exp(I);
888
+ return d / (1 + d);
693
889
  };
694
- let N = 1 / 0, te = 1 / 0, s = 1 / 0, p = -1 / 0, M = -1 / 0, E = -1 / 0;
695
- for (let m = 0; m < I; m++) {
696
- const c = [];
697
- for (let he = 0; he < S.properties.length; he++) {
698
- const pe = S.properties[he].type;
699
- let ee;
700
- switch (pe) {
890
+ let J = 1 / 0, N = 1 / 0, c = 1 / 0, k = -1 / 0, B = -1 / 0, F = -1 / 0;
891
+ for (let I = 0; I < v; I++) {
892
+ const d = [];
893
+ for (let Se = 0; Se < g.properties.length; Se++) {
894
+ const ze = g.properties[Se].type;
895
+ let ce;
896
+ switch (ze) {
701
897
  case "char":
702
- ee = L.getInt8(A), A += 1;
898
+ ce = L.getInt8(A), A += 1;
703
899
  break;
704
900
  case "uchar":
705
- ee = L.getUint8(A), A += 1;
901
+ ce = L.getUint8(A), A += 1;
706
902
  break;
707
903
  case "short":
708
- ee = L.getInt16(A, !0), A += 2;
904
+ ce = L.getInt16(A, !0), A += 2;
709
905
  break;
710
906
  case "ushort":
711
- ee = L.getUint16(A, !0), A += 2;
907
+ ce = L.getUint16(A, !0), A += 2;
712
908
  break;
713
909
  case "int":
714
- ee = L.getInt32(A, !0), A += 4;
910
+ ce = L.getInt32(A, !0), A += 4;
715
911
  break;
716
912
  case "uint":
717
- ee = L.getUint32(A, !0), A += 4;
913
+ ce = L.getUint32(A, !0), A += 4;
718
914
  break;
719
915
  case "float":
720
- ee = L.getFloat32(A, !0), A += 4;
916
+ ce = L.getFloat32(A, !0), A += 4;
721
917
  break;
722
918
  case "double":
723
- ee = L.getFloat64(A, !0), A += 8;
919
+ ce = L.getFloat64(A, !0), A += 8;
724
920
  break;
725
921
  default:
726
922
  throw new Error(
727
- `Unsupported property type: ${pe}`
923
+ `Unsupported property type: ${ze}`
728
924
  );
729
925
  }
730
- c.push(ee);
926
+ d.push(ce);
731
927
  }
732
- const y = c[D], z = c[T], d = c[v], k = m * 3;
733
- P[k] = y, P[k + 1] = z, P[k + 2] = d, N = Math.min(N, y), te = Math.min(te, z), s = Math.min(s, d), p = Math.max(p, y), M = Math.max(M, z), E = Math.max(E, d);
734
- let O = c[R[1]], q = c[R[2]], G = c[R[3]], V = c[R[0]];
735
- const Y = Math.sqrt(
736
- O * O + q * q + G * G + V * V
928
+ const z = d[_], W = d[w], S = d[p], U = I * 3;
929
+ b[U] = z, b[U + 1] = W, b[U + 2] = S, J = Math.min(J, z), N = Math.min(N, W), c = Math.min(c, S), k = Math.max(k, z), B = Math.max(B, W), F = Math.max(F, S);
930
+ let $ = d[R[1]], X = d[R[2]], Q = d[R[3]], Z = d[R[0]];
931
+ const K = Math.sqrt(
932
+ $ * $ + X * X + Q * Q + Z * Z
737
933
  );
738
- Y > 0 && (O /= Y, q /= Y, G /= Y, V /= Y), V < 0 && (O = -O, q = -q, G = -G, V = -V);
739
- const K = m * 4;
740
- j[K] = O, j[K + 1] = q, j[K + 2] = G, j[K + 3] = V;
741
- const Q = m * 3;
742
- H[Q] = c[B[0]], H[Q + 1] = c[B[1]], H[Q + 2] = c[B[2]];
743
- let re = 0.5 + c[$[0]] * U, ne = 0.5 + c[$[1]] * U, J = 0.5 + c[$[2]] * U;
744
- re = Math.max(0, Math.min(1, re)), ne = Math.max(0, Math.min(1, ne)), J = Math.max(0, Math.min(1, J));
745
- const ue = m * 3;
746
- W[ue] = re, W[ue + 1] = ne, W[ue + 2] = J, oe[m] = F(c[X]);
934
+ K > 0 && ($ /= K, X /= K, Q /= K, Z /= K), Z < 0 && ($ = -$, X = -X, Q = -Q, Z = -Z);
935
+ const re = I * 4;
936
+ E[re] = $, E[re + 1] = X, E[re + 2] = Q, E[re + 3] = Z;
937
+ const se = I * 3;
938
+ T[se] = d[q[0]], T[se + 1] = d[q[1]], T[se + 2] = d[q[2]];
939
+ let ue = 0.5 + d[j[0]] * D, he = 0.5 + d[j[1]] * D, oe = 0.5 + d[j[2]] * D;
940
+ ue = Math.max(0, Math.min(1, ue)), he = Math.max(0, Math.min(1, he)), oe = Math.max(0, Math.min(1, oe));
941
+ const Me = I * 3;
942
+ P[Me] = ue, P[Me + 1] = he, P[Me + 2] = oe, H[I] = O(d[Y]);
747
943
  }
748
944
  return {
749
- numSplats: I,
750
- positions: P.buffer,
751
- rotations: j.buffer,
752
- scales: H.buffer,
753
- colors: W.buffer,
754
- opacities: oe.buffer,
945
+ numSplats: v,
946
+ positions: b.buffer,
947
+ rotations: E.buffer,
948
+ scales: T.buffer,
949
+ colors: P.buffer,
950
+ opacities: H.buffer,
755
951
  boundingBox: {
756
- minX: N,
757
- minY: te,
758
- minZ: s,
759
- maxX: p,
760
- maxY: M,
761
- maxZ: E
952
+ minX: J,
953
+ minY: N,
954
+ minZ: c,
955
+ maxX: k,
956
+ maxY: B,
957
+ maxZ: F
762
958
  }
763
959
  };
764
960
  }
765
961
  }).toString()})();`;
766
962
  }
767
963
  }
768
- class Pe extends l.EventDispatcher {
964
+ var ee = Uint8Array, fe = Uint16Array, nt = Int32Array, Ue = new ee([
965
+ 0,
966
+ 0,
967
+ 0,
968
+ 0,
969
+ 0,
970
+ 0,
971
+ 0,
972
+ 0,
973
+ 1,
974
+ 1,
975
+ 1,
976
+ 1,
977
+ 2,
978
+ 2,
979
+ 2,
980
+ 2,
981
+ 3,
982
+ 3,
983
+ 3,
984
+ 3,
985
+ 4,
986
+ 4,
987
+ 4,
988
+ 4,
989
+ 5,
990
+ 5,
991
+ 5,
992
+ 5,
993
+ 0,
994
+ /* unused */
995
+ 0,
996
+ 0,
997
+ /* impossible */
998
+ 0
999
+ ]), Ve = new ee([
1000
+ 0,
1001
+ 0,
1002
+ 0,
1003
+ 0,
1004
+ 1,
1005
+ 1,
1006
+ 2,
1007
+ 2,
1008
+ 3,
1009
+ 3,
1010
+ 4,
1011
+ 4,
1012
+ 5,
1013
+ 5,
1014
+ 6,
1015
+ 6,
1016
+ 7,
1017
+ 7,
1018
+ 8,
1019
+ 8,
1020
+ 9,
1021
+ 9,
1022
+ 10,
1023
+ 10,
1024
+ 11,
1025
+ 11,
1026
+ 12,
1027
+ 12,
1028
+ 13,
1029
+ 13,
1030
+ /* unused */
1031
+ 0,
1032
+ 0
1033
+ ]), at = new ee([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]), Le = function(n, e) {
1034
+ for (var t = new fe(31), r = 0; r < 31; ++r)
1035
+ t[r] = e += 1 << n[r - 1];
1036
+ for (var s = new nt(t[30]), r = 1; r < 30; ++r)
1037
+ for (var a = t[r]; a < t[r + 1]; ++a)
1038
+ s[a] = a - t[r] << 5 | r;
1039
+ return { b: t, r: s };
1040
+ }, je = Le(Ue, 2), We = je.b, ot = je.r;
1041
+ We[28] = 258, ot[258] = 28;
1042
+ var it = Le(Ve, 0), ct = it.b, Ie = new fe(32768);
1043
+ for (var G = 0; G < 32768; ++G) {
1044
+ var le = (G & 43690) >> 1 | (G & 21845) << 1;
1045
+ le = (le & 52428) >> 2 | (le & 13107) << 2, le = (le & 61680) >> 4 | (le & 3855) << 4, Ie[G] = ((le & 65280) >> 8 | (le & 255) << 8) >> 1;
1046
+ }
1047
+ var ye = function(n, e, t) {
1048
+ for (var r = n.length, s = 0, a = new fe(e); s < r; ++s)
1049
+ n[s] && ++a[n[s] - 1];
1050
+ var o = new fe(e);
1051
+ for (s = 1; s < e; ++s)
1052
+ o[s] = o[s - 1] + a[s - 1] << 1;
1053
+ var i;
1054
+ if (t) {
1055
+ i = new fe(1 << e);
1056
+ var m = 15 - e;
1057
+ for (s = 0; s < r; ++s)
1058
+ if (n[s])
1059
+ for (var f = s << 4 | n[s], y = e - n[s], l = o[n[s] - 1]++ << y, u = l | (1 << y) - 1; l <= u; ++l)
1060
+ i[Ie[l] >> m] = f;
1061
+ } else
1062
+ for (i = new fe(r), s = 0; s < r; ++s)
1063
+ n[s] && (i[s] = Ie[o[n[s] - 1]++] >> 15 - n[s]);
1064
+ return i;
1065
+ }, ge = new ee(288);
1066
+ for (var G = 0; G < 144; ++G)
1067
+ ge[G] = 8;
1068
+ for (var G = 144; G < 256; ++G)
1069
+ ge[G] = 9;
1070
+ for (var G = 256; G < 280; ++G)
1071
+ ge[G] = 7;
1072
+ for (var G = 280; G < 288; ++G)
1073
+ ge[G] = 8;
1074
+ var Ge = new ee(32);
1075
+ for (var G = 0; G < 32; ++G)
1076
+ Ge[G] = 5;
1077
+ var lt = /* @__PURE__ */ ye(ge, 9, 1), ut = /* @__PURE__ */ ye(Ge, 5, 1), Ae = function(n) {
1078
+ for (var e = n[0], t = 1; t < n.length; ++t)
1079
+ n[t] > e && (e = n[t]);
1080
+ return e;
1081
+ }, ne = function(n, e, t) {
1082
+ var r = e / 8 | 0;
1083
+ return (n[r] | n[r + 1] << 8) >> (e & 7) & t;
1084
+ }, ke = function(n, e) {
1085
+ var t = e / 8 | 0;
1086
+ return (n[t] | n[t + 1] << 8 | n[t + 2] << 16) >> (e & 7);
1087
+ }, ht = function(n) {
1088
+ return (n + 7) / 8 | 0;
1089
+ }, _e = function(n, e, t) {
1090
+ return (e == null || e < 0) && (e = 0), (t == null || t > n.length) && (t = n.length), new ee(n.subarray(e, t));
1091
+ }, mt = [
1092
+ "unexpected EOF",
1093
+ "invalid block type",
1094
+ "invalid length/literal",
1095
+ "invalid distance",
1096
+ "stream finished",
1097
+ "no stream handler",
1098
+ ,
1099
+ "no callback",
1100
+ "invalid UTF-8 data",
1101
+ "extra field too long",
1102
+ "date not in range 1980-2099",
1103
+ "filename too long",
1104
+ "stream finishing",
1105
+ "invalid zip data"
1106
+ // determined by unknown compression method
1107
+ ], te = function(n, e, t) {
1108
+ var r = new Error(e || mt[n]);
1109
+ if (r.code = n, Error.captureStackTrace && Error.captureStackTrace(r, te), !t)
1110
+ throw r;
1111
+ return r;
1112
+ }, ft = function(n, e, t, r) {
1113
+ var s = n.length, a = r ? r.length : 0;
1114
+ if (!s || e.f && !e.l)
1115
+ return t || new ee(0);
1116
+ var o = !t, i = o || e.i != 2, m = e.i;
1117
+ o && (t = new ee(s * 3));
1118
+ var f = function(X) {
1119
+ var Q = t.length;
1120
+ if (X > Q) {
1121
+ var Z = new ee(Math.max(Q * 2, X));
1122
+ Z.set(t), t = Z;
1123
+ }
1124
+ }, y = e.f || 0, l = e.p || 0, u = e.b || 0, x = e.l, g = e.d, v = e.m, b = e.n, E = s * 8;
1125
+ do {
1126
+ if (!x) {
1127
+ y = ne(n, l, 1);
1128
+ var T = ne(n, l + 1, 3);
1129
+ if (l += 3, T)
1130
+ if (T == 1)
1131
+ x = lt, g = ut, v = 9, b = 5;
1132
+ else if (T == 2) {
1133
+ var A = ne(n, l, 31) + 257, C = ne(n, l + 10, 15) + 4, _ = A + ne(n, l + 5, 31) + 1;
1134
+ l += 14;
1135
+ for (var w = new ee(_), p = new ee(19), R = 0; R < C; ++R)
1136
+ p[at[R]] = ne(n, l + R * 3, 7);
1137
+ l += C * 3;
1138
+ for (var q = Ae(p), j = (1 << q) - 1, Y = ye(p, q, 1), R = 0; R < _; ) {
1139
+ var V = Y[ne(n, l, j)];
1140
+ l += V & 15;
1141
+ var P = V >> 4;
1142
+ if (P < 16)
1143
+ w[R++] = P;
1144
+ else {
1145
+ var D = 0, O = 0;
1146
+ for (P == 16 ? (O = 3 + ne(n, l, 3), l += 2, D = w[R - 1]) : P == 17 ? (O = 3 + ne(n, l, 7), l += 3) : P == 18 && (O = 11 + ne(n, l, 127), l += 7); O--; )
1147
+ w[R++] = D;
1148
+ }
1149
+ }
1150
+ var J = w.subarray(0, A), N = w.subarray(A);
1151
+ v = Ae(J), b = Ae(N), x = ye(J, v, 1), g = ye(N, b, 1);
1152
+ } else
1153
+ te(1);
1154
+ else {
1155
+ var P = ht(l) + 4, H = n[P - 4] | n[P - 3] << 8, L = P + H;
1156
+ if (L > s) {
1157
+ m && te(0);
1158
+ break;
1159
+ }
1160
+ i && f(u + H), t.set(n.subarray(P, L), u), e.b = u += H, e.p = l = L * 8, e.f = y;
1161
+ continue;
1162
+ }
1163
+ if (l > E) {
1164
+ m && te(0);
1165
+ break;
1166
+ }
1167
+ }
1168
+ i && f(u + 131072);
1169
+ for (var c = (1 << v) - 1, k = (1 << b) - 1, B = l; ; B = l) {
1170
+ var D = x[ke(n, l) & c], F = D >> 4;
1171
+ if (l += D & 15, l > E) {
1172
+ m && te(0);
1173
+ break;
1174
+ }
1175
+ if (D || te(2), F < 256)
1176
+ t[u++] = F;
1177
+ else if (F == 256) {
1178
+ B = l, x = null;
1179
+ break;
1180
+ } else {
1181
+ var I = F - 254;
1182
+ if (F > 264) {
1183
+ var R = F - 257, d = Ue[R];
1184
+ I = ne(n, l, (1 << d) - 1) + We[R], l += d;
1185
+ }
1186
+ var z = g[ke(n, l) & k], W = z >> 4;
1187
+ z || te(3), l += z & 15;
1188
+ var N = ct[W];
1189
+ if (W > 3) {
1190
+ var d = Ve[W];
1191
+ N += ke(n, l) & (1 << d) - 1, l += d;
1192
+ }
1193
+ if (l > E) {
1194
+ m && te(0);
1195
+ break;
1196
+ }
1197
+ i && f(u + 131072);
1198
+ var S = u + I;
1199
+ if (u < N) {
1200
+ var U = a - N, $ = Math.min(N, S);
1201
+ for (U + u < 0 && te(3); u < $; ++u)
1202
+ t[u] = r[U + u];
1203
+ }
1204
+ for (; u < S; ++u)
1205
+ t[u] = t[u - N];
1206
+ }
1207
+ }
1208
+ e.l = x, e.p = B, e.b = u, e.f = y, x && (y = 1, e.m = v, e.d = g, e.n = b);
1209
+ } while (!y);
1210
+ return u != t.length && o ? _e(t, 0, u) : t.subarray(0, u);
1211
+ }, dt = /* @__PURE__ */ new ee(0), ie = function(n, e) {
1212
+ return n[e] | n[e + 1] << 8;
1213
+ }, ae = function(n, e) {
1214
+ return (n[e] | n[e + 1] << 8 | n[e + 2] << 16 | n[e + 3] << 24) >>> 0;
1215
+ }, Ee = function(n, e) {
1216
+ return ae(n, e) + ae(n, e + 4) * 4294967296;
1217
+ };
1218
+ function pt(n, e) {
1219
+ return ft(n, { i: 2 }, e && e.out, e && e.dictionary);
1220
+ }
1221
+ var Re = typeof TextDecoder < "u" && /* @__PURE__ */ new TextDecoder(), xt = 0;
1222
+ try {
1223
+ Re.decode(dt, { stream: !0 }), xt = 1;
1224
+ } catch {
1225
+ }
1226
+ var yt = function(n) {
1227
+ for (var e = "", t = 0; ; ) {
1228
+ var r = n[t++], s = (r > 127) + (r > 223) + (r > 239);
1229
+ if (t + s > n.length)
1230
+ return { s: e, r: _e(n, t - 1) };
1231
+ s ? s == 3 ? (r = ((r & 15) << 18 | (n[t++] & 63) << 12 | (n[t++] & 63) << 6 | n[t++] & 63) - 65536, e += String.fromCharCode(55296 | r >> 10, 56320 | r & 1023)) : s & 1 ? e += String.fromCharCode((r & 31) << 6 | n[t++] & 63) : e += String.fromCharCode((r & 15) << 12 | (n[t++] & 63) << 6 | n[t++] & 63) : e += String.fromCharCode(r);
1232
+ }
1233
+ };
1234
+ function gt(n, e) {
1235
+ if (e) {
1236
+ for (var t = "", r = 0; r < n.length; r += 16384)
1237
+ t += String.fromCharCode.apply(null, n.subarray(r, r + 16384));
1238
+ return t;
1239
+ } else {
1240
+ if (Re)
1241
+ return Re.decode(n);
1242
+ var s = yt(n), a = s.s, t = s.r;
1243
+ return t.length && te(8), a;
1244
+ }
1245
+ }
1246
+ var wt = function(n, e) {
1247
+ return e + 30 + ie(n, e + 26) + ie(n, e + 28);
1248
+ }, vt = function(n, e, t) {
1249
+ var r = ie(n, e + 28), s = gt(n.subarray(e + 46, e + 46 + r), !(ie(n, e + 8) & 2048)), a = e + 46 + r, o = ae(n, e + 20), i = t && o == 4294967295 ? bt(n, a) : [o, ae(n, e + 24), ae(n, e + 42)], m = i[0], f = i[1], y = i[2];
1250
+ return [ie(n, e + 10), m, f, s, a + ie(n, e + 30) + ie(n, e + 32), y];
1251
+ }, bt = function(n, e) {
1252
+ for (; ie(n, e) != 1; e += 4 + ie(n, e + 2))
1253
+ ;
1254
+ return [Ee(n, e + 12), Ee(n, e + 4), Ee(n, e + 20)];
1255
+ };
1256
+ function Mt(n, e) {
1257
+ for (var t = {}, r = n.length - 22; ae(n, r) != 101010256; --r)
1258
+ (!r || n.length - r > 65558) && te(13);
1259
+ var s = ie(n, r + 8);
1260
+ if (!s)
1261
+ return {};
1262
+ var a = ae(n, r + 16), o = a == 4294967295 || s == 65535;
1263
+ if (o) {
1264
+ var i = ae(n, r - 12);
1265
+ o = ae(n, i) == 101075792, o && (s = ae(n, i + 32), a = ae(n, i + 48));
1266
+ }
1267
+ for (var m = 0; m < s; ++m) {
1268
+ var f = vt(n, a, o), y = f[0], l = f[1], u = f[2], x = f[3], g = f[4], v = f[5], b = wt(n, v);
1269
+ a = g, y ? y == 8 ? t[x] = pt(n.subarray(b, b + l), { out: new ee(u) }) : te(14, "unknown compression type " + y) : t[x] = _e(n, b, b + l);
1270
+ }
1271
+ return t;
1272
+ }
1273
+ const Oe = (n) => {
1274
+ if (typeof n != "object" || n === null) throw new Error("Invalid SOGS metadata: not an object");
1275
+ const e = n, t = e.version ?? 1;
1276
+ if (t !== 1) throw new Error(`Unsupported SOGS version: ${String(t)}`);
1277
+ const r = (v) => {
1278
+ const b = e[v];
1279
+ if (typeof b != "object" || b === null) throw new Error(`Invalid SOGS metadata section: ${v}`);
1280
+ return b;
1281
+ }, s = r("means"), a = r("sh0"), o = r("quats"), i = r("scales"), m = typeof e.count == "number" && Number.isFinite(e.count) ? e.count : void 0, f = Array.isArray(s.shape) ? s.shape : void 0, y = f && typeof f[0] == "number" ? f[0] : void 0;
1282
+ if (m === void 0 && y === void 0)
1283
+ throw new Error(
1284
+ "Invalid SOGS metadata: unable to determine splat count"
1285
+ );
1286
+ if (m !== void 0 && y !== void 0 && m !== y)
1287
+ throw new Error(
1288
+ "Inconsistent SOGS metadata: count does not match means.shape[0]"
1289
+ );
1290
+ const l = m ?? y, u = (v, b) => {
1291
+ const E = v.mins, T = v.maxs;
1292
+ if (!Array.isArray(E) || E.length !== 3)
1293
+ throw new Error(`${b}.mins must be length-3`);
1294
+ if (!Array.isArray(T) || T.length !== 3)
1295
+ throw new Error(`${b}.maxs must be length-3`);
1296
+ if (![...E, ...T].every(
1297
+ (P) => typeof P == "number" && Number.isFinite(P)
1298
+ ))
1299
+ throw new Error(`${b}.mins/maxs must be finite numbers`);
1300
+ return {
1301
+ mins: [E[0], E[1], E[2]],
1302
+ maxs: [T[0], T[1], T[2]]
1303
+ };
1304
+ }, x = (v, b) => {
1305
+ const E = v.mins, T = v.maxs;
1306
+ if (!Array.isArray(E) || E.length !== 4)
1307
+ throw new Error(`${b}.mins must be length-4`);
1308
+ if (!Array.isArray(T) || T.length !== 4)
1309
+ throw new Error(`${b}.maxs must be length-4`);
1310
+ if (![...E, ...T].every(
1311
+ (P) => typeof P == "number" && Number.isFinite(P)
1312
+ ))
1313
+ throw new Error(`${b}.mins/maxs must be finite numbers`);
1314
+ return {
1315
+ mins: [E[0], E[1], E[2], E[3]],
1316
+ maxs: [T[0], T[1], T[2], T[3]]
1317
+ };
1318
+ }, g = (v, b) => {
1319
+ const E = v.files;
1320
+ if (!Array.isArray(E)) throw new Error(`${b}.files is not an array`);
1321
+ if (!E.every((T) => typeof T == "string")) throw new Error(`${b}.files contains non-strings`);
1322
+ return E;
1323
+ };
1324
+ return {
1325
+ numSplats: l,
1326
+ files: {
1327
+ sh0: g(a, "sh0"),
1328
+ means: g(s, "means"),
1329
+ quats: g(o, "quats"),
1330
+ scales: g(i, "scales")
1331
+ },
1332
+ ranges: {
1333
+ sh0: x(a, "sh0"),
1334
+ means: u(s, "means"),
1335
+ scales: u(i, "scales")
1336
+ }
1337
+ };
1338
+ };
1339
+ class St extends h.Loader {
1340
+ constructor(e) {
1341
+ super(e), this.withCredentials = !0;
1342
+ }
1343
+ /**
1344
+ * Detect if a buffer is a ZIP file by checking magic bytes
1345
+ * ZIP files start with signature: PK\x03\x04 (0x50 0x4B 0x03 0x04)
1346
+ */
1347
+ isZipBuffer(e) {
1348
+ if (e.byteLength < 4) return !1;
1349
+ const t = new Uint8Array(e, 0, 4);
1350
+ return t[0] === 80 && t[1] === 75 && t[2] === 3 && t[3] === 4;
1351
+ }
1352
+ /**
1353
+ * Load a SOGS file (meta.json + textures)
1354
+ * @param url URL of the meta.json file
1355
+ * @param onLoad Optional callback when loading is complete
1356
+ * @param onProgress Optional progress callback
1357
+ * @param onError Optional error callback
1358
+ */
1359
+ load(e, t, r, s) {
1360
+ const a = new h.FileLoader(this.manager);
1361
+ a.setResponseType("arraybuffer"), a.setRequestHeader(this.requestHeader), a.setPath(this.path), a.setWithCredentials(this.withCredentials), a.load(
1362
+ e,
1363
+ (o) => {
1364
+ this.parseAsync(e, o).then((i) => {
1365
+ t && t(i);
1366
+ }).catch((i) => {
1367
+ this.manager.itemError(e), s && s(i), console.error("Error loading SOGS meta:", i);
1368
+ });
1369
+ },
1370
+ r,
1371
+ s
1372
+ );
1373
+ }
1374
+ /**
1375
+ * Load a SOGS file asynchronously and return a Promise
1376
+ * @param url URL of the meta.json file
1377
+ * @param onProgress Optional progress callback
1378
+ * @returns A Promise that resolves with the parsed SplatData
1379
+ */
1380
+ loadAsync(e, t) {
1381
+ return new Promise((r, s) => {
1382
+ const a = new h.FileLoader(this.manager);
1383
+ a.setResponseType("arraybuffer"), a.setRequestHeader(this.requestHeader), a.setPath(this.path), a.setWithCredentials(this.withCredentials), a.load(
1384
+ e,
1385
+ (o) => {
1386
+ this.parseAsync(e, o).then(r).catch((i) => {
1387
+ s(i), this.manager.itemError(e);
1388
+ });
1389
+ },
1390
+ t,
1391
+ (o) => {
1392
+ s(o), this.manager.itemError(e);
1393
+ }
1394
+ );
1395
+ });
1396
+ }
1397
+ async parseAsync(e, t) {
1398
+ if (!(t instanceof ArrayBuffer)) throw new Error("SOGS loader: expected ArrayBuffer payload");
1399
+ if (this.isZipBuffer(t)) return this.parseZipAsync(t);
1400
+ const s = new TextDecoder("utf-8").decode(t), a = JSON.parse(s);
1401
+ return this.parseMetaAsync(e, a);
1402
+ }
1403
+ async parseMetaAsync(e, t) {
1404
+ const { numSplats: r, files: s, ranges: a } = Oe(t), o = new h.TextureLoader(this.manager);
1405
+ o.setPath(this.path), o.setRequestHeader(this.requestHeader), o.setWithCredentials(this.withCredentials);
1406
+ const i = (E, T) => {
1407
+ try {
1408
+ return new URL(T, E).toString();
1409
+ } catch {
1410
+ return E.substring(0, E.lastIndexOf("/") + 1) + T;
1411
+ }
1412
+ }, m = (E, T) => {
1413
+ const P = i(e, E);
1414
+ return new Promise((H, L) => {
1415
+ o.load(
1416
+ P,
1417
+ (A) => {
1418
+ A.generateMipmaps = !1, A.magFilter = h.NearestFilter, A.minFilter = h.NearestFilter, A.flipY = !1, H(A);
1419
+ },
1420
+ void 0,
1421
+ (A) => {
1422
+ const C = A instanceof Error ? A.message : String(A);
1423
+ L(
1424
+ new Error(
1425
+ `SOGS loader: failed to load ${T} (${E}): ${C}`
1426
+ )
1427
+ );
1428
+ }
1429
+ );
1430
+ });
1431
+ };
1432
+ if (!Array.isArray(s.sh0) || s.sh0.length < 1) throw new Error("SOGS loader: files.sh0 must have at least 1 entry (sh0)");
1433
+ if (!Array.isArray(s.means) || s.means.length < 2) throw new Error("SOGS loader: files.means must have at least 2 entries (means_l, means_u)");
1434
+ if (!Array.isArray(s.quats) || s.quats.length < 1) throw new Error("SOGS loader: files.quats must have at least 1 entry");
1435
+ if (!Array.isArray(s.scales) || s.scales.length < 1) throw new Error("SOGS loader: files.scales must have at least 1 entry");
1436
+ const [f, y, l, u, x] = await Promise.all([
1437
+ m(s.means[0], "means_l"),
1438
+ m(s.means[1], "means_u"),
1439
+ m(s.quats[0], "quats"),
1440
+ m(s.scales[0], "scales"),
1441
+ m(s.sh0[0], "sh0")
1442
+ ]), g = { means_l: f, means_u: y, quats: l, scales: u, sh0: x }, v = new Fe(r, a, g), b = Ce.packSogs(v);
1443
+ return v.dispose(), b;
1444
+ }
1445
+ async parseZipAsync(e) {
1446
+ const t = Mt(new Uint8Array(e)), r = Object.keys(t), s = r.find((_) => _.toLowerCase().endsWith("meta.json")) ?? null;
1447
+ if (!s) throw new Error("SOGS loader: zip missing meta.json");
1448
+ const a = s.includes("/") ? s.slice(0, s.lastIndexOf("/") + 1) : "", o = new TextDecoder(), i = JSON.parse(o.decode(t[s])), { numSplats: m, files: f, ranges: y } = Oe(i), l = (_) => _.replace(/\\/g, "/").replace(/^\.?\//, ""), u = (_) => {
1449
+ const w = l(_), p = [l(a + w), w];
1450
+ for (const j of p) {
1451
+ const Y = t[j];
1452
+ if (Y) return Y;
1453
+ }
1454
+ const R = w.split("/").pop(), q = r.find((j) => l(j).endsWith("/" + w)) ?? r.find((j) => l(j).endsWith("/" + R)) ?? r.find((j) => l(j) === R) ?? null;
1455
+ if (q) return t[q];
1456
+ throw new Error(`SOGS loader: zip missing file "${_}"`);
1457
+ }, x = (_) => {
1458
+ const w = _.toLowerCase();
1459
+ return w.endsWith(".png") ? "image/png" : w.endsWith(".jpg") || w.endsWith(".jpeg") ? "image/jpeg" : w.endsWith(".webp") ? "image/webp" : "application/octet-stream";
1460
+ }, g = new h.TextureLoader(this.manager);
1461
+ g.setRequestHeader(this.requestHeader), g.setWithCredentials(this.withCredentials);
1462
+ const v = (_, w) => {
1463
+ const p = u(_), R = new Blob([p], {
1464
+ type: x(_)
1465
+ }), q = URL.createObjectURL(R);
1466
+ return new Promise((j, Y) => {
1467
+ g.load(
1468
+ q,
1469
+ (V) => {
1470
+ URL.revokeObjectURL(q), V.generateMipmaps = !1, V.magFilter = h.NearestFilter, V.minFilter = h.NearestFilter, V.flipY = !1, j(V);
1471
+ },
1472
+ void 0,
1473
+ (V) => {
1474
+ URL.revokeObjectURL(q);
1475
+ const D = V instanceof Error ? V.message : String(V);
1476
+ Y(
1477
+ new Error(
1478
+ `SOGS loader: failed to load ${w} from zip (${_}): ${D}`
1479
+ )
1480
+ );
1481
+ }
1482
+ );
1483
+ });
1484
+ };
1485
+ if (!Array.isArray(f.sh0) || f.sh0.length < 1) throw new Error("SOGS loader: files.sh0 must have at least 1 entry (sh0)");
1486
+ if (!Array.isArray(f.means) || f.means.length < 2) throw new Error("SOGS loader: files.means must have at least 2 entries (means_l, means_u)");
1487
+ if (!Array.isArray(f.quats) || f.quats.length < 1) throw new Error("SOGS loader: files.quats must have at least 1 entry");
1488
+ if (!Array.isArray(f.scales) || f.scales.length < 1) throw new Error("SOGS loader: files.scales must have at least 1 entry");
1489
+ const [b, E, T, P, H] = await Promise.all([
1490
+ v(f.means[0], "means_l"),
1491
+ v(f.means[1], "means_u"),
1492
+ v(f.quats[0], "quats"),
1493
+ v(f.scales[0], "scales"),
1494
+ v(f.sh0[0], "sh0")
1495
+ ]), L = { means_l: b, means_u: E, quats: T, scales: P, sh0: H }, A = new Fe(m, y, L), C = Ce.packSogs(A);
1496
+ return A.dispose(), C;
1497
+ }
1498
+ }
1499
+ class At extends h.EventDispatcher {
769
1500
  constructor() {
770
1501
  super();
771
- f(this, "worker");
772
- f(this, "centers", null);
773
- f(this, "orderTexture", null);
1502
+ M(this, "worker");
1503
+ M(this, "centers", null);
1504
+ M(this, "orderTexture", null);
774
1505
  /** Bounding box data for optimization */
775
- f(this, "chunks", null);
776
- f(this, "lastCameraPosition", new l.Vector3());
777
- f(this, "lastCameraDirection", new l.Vector3());
778
- const o = this.createWorkerCode(), t = new Blob([o], { type: "application/javascript" });
779
- this.worker = new Worker(URL.createObjectURL(t)), this.worker.onmessage = this.onWorkerMessage.bind(this);
1506
+ M(this, "chunks", null);
1507
+ M(this, "lastCameraPosition", new h.Vector3());
1508
+ M(this, "lastCameraDirection", new h.Vector3());
1509
+ const t = this.createWorkerCode(), r = new Blob([t], { type: "application/javascript" });
1510
+ this.worker = new Worker(URL.createObjectURL(r)), this.worker.onmessage = this.onWorkerMessage.bind(this);
780
1511
  }
781
1512
  /**
782
1513
  * Handles messages received from the sorting worker.
783
1514
  * @param event The message event from the worker.
784
1515
  */
785
- onWorkerMessage(o) {
1516
+ onWorkerMessage(t) {
786
1517
  if (!this.orderTexture || !this.orderTexture.image)
787
1518
  return console.error("SplatSorter: Order texture not initialized!");
788
- const { order: t, count: r } = o.data, n = this.orderTexture.image.data;
789
- if (!(n instanceof Uint32Array))
1519
+ const { order: r, count: s } = t.data, a = this.orderTexture.image.data;
1520
+ if (!(a instanceof Uint32Array))
790
1521
  return console.error(
791
1522
  "SplatSorter: Order texture data is not a Uint32Array!"
792
1523
  );
793
- n.set(new Uint32Array(t)), this.orderTexture.source.data.updateRanges || (this.orderTexture.source.data.updateRanges = []), this.orderTexture.needsUpdate = !0;
794
- const a = n.buffer.slice(0), i = { order: a };
795
- this.worker.postMessage(i, [a]), this.dispatchEvent({ type: "updated", count: r });
1524
+ a.set(new Uint32Array(r)), this.orderTexture.source.data.updateRanges || (this.orderTexture.source.data.updateRanges = []), this.orderTexture.needsUpdate = !0;
1525
+ const o = a.buffer.slice(0), i = { order: o };
1526
+ this.worker.postMessage(i, [o]), this.dispatchEvent({ type: "updated", count: s });
796
1527
  }
797
1528
  /**
798
1529
  * Initializes the sorter with necessary data and textures.
@@ -801,38 +1532,38 @@ class Pe extends l.EventDispatcher {
801
1532
  * @param chunks Optional: A Float32Array containing bounding box chunk data [minX, minY, minZ, maxX, maxY, maxZ, ...] for optimization.
802
1533
  * @param transferOwnership Optional: If true, transfers ownership of centers buffer to worker (saves memory, main thread loses access). Default: false.
803
1534
  */
804
- init(o, t, r, n = !1) {
805
- if (!o || !(o.image.data instanceof Uint32Array))
1535
+ init(t, r, s, a = !1) {
1536
+ if (!t || !(t.image.data instanceof Uint32Array))
806
1537
  throw new Error("SplatSorter: Invalid orderTexture provided. Must be DataTexture with Uint32Array data.");
807
- if (!t || t.length % 3 !== 0)
1538
+ if (!r || r.length % 3 !== 0)
808
1539
  throw new Error("SplatSorter: Invalid centers array provided. Length must be multiple of 3.");
809
- if (o.image.data.length < t.length / 3)
1540
+ if (t.image.data.length < r.length / 3)
810
1541
  throw new Error("SplatSorter: orderTexture data buffer is smaller than the number of splats.");
811
- if (t.buffer.byteLength === 0)
1542
+ if (r.buffer.byteLength === 0)
812
1543
  throw new Error(
813
1544
  "SplatSorter: positions buffer is detached (likely React StrictMode + cached asset). "
814
1545
  );
815
- const a = t.length / 3;
816
- this.orderTexture = o, n ? this.centers = null : this.centers = t.slice();
1546
+ const o = r.length / 3;
1547
+ this.orderTexture = t, a ? this.centers = null : this.centers = r.slice();
817
1548
  const i = this.orderTexture.image.data;
818
- for (let h = 0; h < a; h++) i[h] = h;
1549
+ for (let u = 0; u < o; u++) i[u] = u;
819
1550
  this.orderTexture.source.data.updateRanges || (this.orderTexture.source.data.updateRanges = []), this.orderTexture.needsUpdate = !0;
820
- const u = i.buffer.slice(0), w = n ? t.buffer : t.buffer.slice(0), C = {
821
- order: u,
822
- centers: w
823
- }, _ = [
824
- u,
825
- w
1551
+ const m = i.buffer.slice(0), f = a ? r.buffer : r.buffer.slice(0), y = {
1552
+ order: m,
1553
+ centers: f
1554
+ }, l = [
1555
+ m,
1556
+ f
826
1557
  ];
827
- if (r) {
828
- this.chunks = r.slice();
829
- const h = this.chunks.buffer.slice(0);
830
- C.chunks = h, _.push(h);
1558
+ if (s) {
1559
+ this.chunks = s.slice();
1560
+ const u = this.chunks.buffer.slice(0);
1561
+ y.chunks = u, l.push(u);
831
1562
  }
832
- this.worker.postMessage(C, _), queueMicrotask(() => {
1563
+ this.worker.postMessage(y, l), queueMicrotask(() => {
833
1564
  this.dispatchEvent({
834
1565
  type: "updated",
835
- count: a
1566
+ count: o
836
1567
  });
837
1568
  });
838
1569
  }
@@ -841,53 +1572,53 @@ class Pe extends l.EventDispatcher {
841
1572
  * The sorter will only consider splats whose original indices are present in the mapping.
842
1573
  * @param mapping A Uint32Array where each element is the *original* index of a splat to include, or null to reset mapping.
843
1574
  */
844
- setMapping(o) {
1575
+ setMapping(t) {
845
1576
  if (!this.centers)
846
1577
  return console.warn(
847
1578
  "SplatSorter: Cannot set mapping before initialization."
848
1579
  );
849
- let t;
850
- const r = [];
851
- if (!o) {
852
- const u = this.centers.buffer.slice(0);
853
- return t = {
854
- centers: u,
1580
+ let r;
1581
+ const s = [];
1582
+ if (!t) {
1583
+ const m = this.centers.buffer.slice(0);
1584
+ return r = {
1585
+ centers: m,
855
1586
  mapping: null
856
- }, r.push(u), this.worker.postMessage(t, r);
1587
+ }, s.push(m), this.worker.postMessage(r, s);
857
1588
  }
858
- const n = new Float32Array(o.length * 3);
859
- for (let u = 0; u < o.length; u++) {
860
- const w = o[u];
861
- if (w * 3 + 2 >= this.centers.length) {
1589
+ const a = new Float32Array(t.length * 3);
1590
+ for (let m = 0; m < t.length; m++) {
1591
+ const f = t[m];
1592
+ if (f * 3 + 2 >= this.centers.length) {
862
1593
  console.warn(
863
- `SplatSorter: Mapping index ${w} out of bounds.`
1594
+ `SplatSorter: Mapping index ${f} out of bounds.`
864
1595
  );
865
1596
  continue;
866
1597
  }
867
- const C = w * 3, _ = u * 3;
868
- n[_ + 0] = this.centers[C + 0], n[_ + 1] = this.centers[C + 1], n[_ + 2] = this.centers[C + 2];
1598
+ const y = f * 3, l = m * 3;
1599
+ a[l + 0] = this.centers[y + 0], a[l + 1] = this.centers[y + 1], a[l + 2] = this.centers[y + 2];
869
1600
  }
870
- const a = n.buffer.slice(0), i = o.buffer.slice(0);
871
- t = {
872
- centers: a,
1601
+ const o = a.buffer.slice(0), i = t.buffer.slice(0);
1602
+ r = {
1603
+ centers: o,
873
1604
  mapping: i
874
- }, r.push(a, i), this.worker.postMessage(t, r);
1605
+ }, s.push(o, i), this.worker.postMessage(r, s);
875
1606
  }
876
1607
  /**
877
1608
  * Updates the camera parameters used for sorting.
878
1609
  * @param position The camera's position in the sorter's local coordinate space.
879
1610
  * @param direction The camera's forward direction in the sorter's local coordinate space.
880
1611
  */
881
- setCamera(o, t) {
882
- const r = this.lastCameraPosition.distanceToSquared(o) > 1e-7, n = this.lastCameraDirection.dot(t) < 0.9999;
883
- if (!r && !n)
1612
+ setCamera(t, r) {
1613
+ const s = this.lastCameraPosition.distanceToSquared(t) > 1e-7, a = this.lastCameraDirection.dot(r) < 0.9999;
1614
+ if (!s && !a)
884
1615
  return;
885
- this.lastCameraPosition.copy(o), this.lastCameraDirection.copy(t);
886
- const a = {
887
- cameraPosition: { x: o.x, y: o.y, z: o.z },
888
- cameraDirection: { x: t.x, y: t.y, z: t.z }
1616
+ this.lastCameraPosition.copy(t), this.lastCameraDirection.copy(r);
1617
+ const o = {
1618
+ cameraPosition: { x: t.x, y: t.y, z: t.z },
1619
+ cameraDirection: { x: r.x, y: r.y, z: r.z }
889
1620
  };
890
- this.worker.postMessage(a);
1621
+ this.worker.postMessage(o);
891
1622
  }
892
1623
  /**
893
1624
  * Terminates the Web Worker and cleans up resources.
@@ -901,258 +1632,186 @@ class Pe extends l.EventDispatcher {
901
1632
  */
902
1633
  createWorkerCode() {
903
1634
  return `(${(function() {
904
- let t = null, r = null, n = null, a = null, i = null, u = null, w = !1;
905
- const C = { x: 0, y: 0, z: 0 }, _ = { x: 0, y: 0, z: 0 }, h = { x: 0, y: 0, z: 0 }, b = { x: 0, y: 0, z: 0 };
906
- let S = null, I = null;
907
- const P = 32, j = new Array(P).fill(0), H = new Array(P).fill(0), W = new Array(P).fill(0), oe = (A, g, D) => {
908
- for (; A <= g; ) {
909
- const T = g + A >> 1, v = D(T);
910
- if (v > 0) A = T + 1;
911
- else if (v < 0) g = T - 1;
912
- else return T;
1635
+ let r = null, s = null, a = null, o = null, i = null, m = null, f = !1;
1636
+ const y = { x: 0, y: 0, z: 0 }, l = { x: 0, y: 0, z: 0 }, u = { x: 0, y: 0, z: 0 }, x = { x: 0, y: 0, z: 0 };
1637
+ let g = null, v = null;
1638
+ const b = 32, E = new Array(b).fill(0), T = new Array(b).fill(0), P = new Array(b).fill(0), H = (A, C, _) => {
1639
+ for (; A <= C; ) {
1640
+ const w = C + A >> 1, p = _(w);
1641
+ if (p > 0) A = w + 1;
1642
+ else if (p < 0) C = w - 1;
1643
+ else return w;
913
1644
  }
914
1645
  return ~A;
915
1646
  }, L = () => {
916
- if (!t || !r || !i || !u)
1647
+ if (!r || !s || !i || !m)
917
1648
  return;
918
- if (r.length === 0) {
919
- const c = {
920
- order: t.buffer,
1649
+ if (s.length === 0) {
1650
+ const d = {
1651
+ order: r.buffer,
921
1652
  count: 0
922
1653
  };
923
- self.postMessage(c, [t.buffer]), t = null;
1654
+ self.postMessage(d, [r.buffer]), r = null;
924
1655
  return;
925
1656
  }
926
- const A = i.x, g = i.y, D = i.z, T = u.x, v = u.y, R = u.z, B = 1e-4, $ = Math.abs(A - C.x) > B || Math.abs(g - C.y) > B || Math.abs(D - C.z) > B, X = Math.abs(T - _.x) > B || Math.abs(v - _.y) > B || Math.abs(R - _.z) > B;
927
- if (!w && !$ && !X)
1657
+ const A = i.x, C = i.y, _ = i.z, w = m.x, p = m.y, R = m.z, q = 1e-4, j = Math.abs(A - y.x) > q || Math.abs(C - y.y) > q || Math.abs(_ - y.z) > q, Y = Math.abs(w - l.x) > q || Math.abs(p - l.y) > q || Math.abs(R - l.z) > q;
1658
+ if (!f && !j && !Y)
928
1659
  return;
929
- w = !1, C.x = A, C.y = g, C.z = D, _.x = T, _.y = v, _.z = R;
930
- let Z = 1 / 0, U = -1 / 0;
931
- for (let c = 0; c < 8; ++c) {
932
- const y = c & 1 ? h.x : b.x, z = c & 2 ? h.y : b.y, d = c & 4 ? h.z : b.z, k = y * T + z * v + d * R;
933
- Z = Math.min(Z, k), U = Math.max(U, k);
1660
+ f = !1, y.x = A, y.y = C, y.z = _, l.x = w, l.y = p, l.z = R;
1661
+ let V = 1 / 0, D = -1 / 0;
1662
+ for (let d = 0; d < 8; ++d) {
1663
+ const z = d & 1 ? u.x : x.x, W = d & 2 ? u.y : x.y, S = d & 4 ? u.z : x.z, U = z * w + W * p + S * R;
1664
+ V = Math.min(V, U), D = Math.max(D, U);
934
1665
  }
935
- const F = r.length / 3, N = U - Z, s = (1 << Math.max(
1666
+ const O = s.length / 3, J = D - V, c = (1 << Math.max(
936
1667
  10,
937
- Math.min(20, Math.ceil(Math.log2(F / 4)))
1668
+ Math.min(20, Math.ceil(Math.log2(O / 4)))
938
1669
  )) + 1;
939
- if ((!S || S.length !== F) && (S = new Uint32Array(F)), !I || I.length !== s ? I = new Uint32Array(s) : I.fill(0), N < 1e-7) {
940
- for (let c = 0; c < F; ++c) S[c] = 0;
941
- I[0] = F;
942
- } else if (n && n.length > 0) {
943
- const c = n.length / 6;
944
- j.fill(0);
945
- for (let d = 0; d < c; ++d) {
946
- const k = d * 6, O = n[k + 0], q = n[k + 1], G = n[k + 2], V = n[k + 3], Y = O * T + q * v + G * R - Z, K = Y - V, Q = Y + V, re = Math.max(
1670
+ if ((!g || g.length !== O) && (g = new Uint32Array(O)), !v || v.length !== c ? v = new Uint32Array(c) : v.fill(0), J < 1e-7) {
1671
+ for (let d = 0; d < O; ++d) g[d] = 0;
1672
+ v[0] = O;
1673
+ } else if (a && a.length > 0) {
1674
+ const d = a.length / 6;
1675
+ E.fill(0);
1676
+ for (let S = 0; S < d; ++S) {
1677
+ const U = S * 6, $ = a[U + 0], X = a[U + 1], Q = a[U + 2], Z = a[U + 3], K = $ * w + X * p + Q * R - V, re = K - Z, se = K + Z, ue = Math.max(
947
1678
  0,
948
- Math.floor(K * P / N)
949
- ), ne = Math.min(
950
- P,
951
- Math.ceil(Q * P / N)
1679
+ Math.floor(re * b / J)
1680
+ ), he = Math.min(
1681
+ b,
1682
+ Math.ceil(se * b / J)
952
1683
  );
953
- for (let J = re; J < ne; ++J)
954
- j[J]++;
1684
+ for (let oe = ue; oe < he; ++oe)
1685
+ E[oe]++;
955
1686
  }
956
- let y = 0;
957
- for (let d = 0; d < P; ++d) y += j[d];
958
- W[0] = 0, H[0] = 0;
959
- for (let d = 1; d < P; ++d)
960
- W[d - 1] = j[d - 1] / y * s >>> 0, H[d] = H[d - 1] + W[d - 1];
961
- W[P - 1] = j[P - 1] / y * s >>> 0;
962
- const z = N / P;
963
- for (let d = 0; d < F; ++d) {
964
- const k = d * 3, O = r[k + 0], q = r[k + 1], G = r[k + 2], V = O * T + q * v + G * R, K = (U - V) / z, Q = Math.max(
1687
+ let z = 0;
1688
+ for (let S = 0; S < b; ++S) z += E[S];
1689
+ P[0] = 0, T[0] = 0;
1690
+ for (let S = 1; S < b; ++S)
1691
+ P[S - 1] = E[S - 1] / z * c >>> 0, T[S] = T[S - 1] + P[S - 1];
1692
+ P[b - 1] = E[b - 1] / z * c >>> 0;
1693
+ const W = J / b;
1694
+ for (let S = 0; S < O; ++S) {
1695
+ const U = S * 3, $ = s[U + 0], X = s[U + 1], Q = s[U + 2], Z = $ * w + X * p + Q * R, re = (D - Z) / W, se = Math.max(
965
1696
  0,
966
1697
  Math.min(
967
- P - 1,
968
- Math.floor(K)
1698
+ b - 1,
1699
+ Math.floor(re)
969
1700
  )
970
- ), re = K - Q, ne = H[Q] + W[Q] * re >>> 0, J = Math.min(ne, s - 1);
971
- S[d] = J, I[J]++;
1701
+ ), ue = re - se, he = T[se] + P[se] * ue >>> 0, oe = Math.min(he, c - 1);
1702
+ g[S] = oe, v[oe]++;
972
1703
  }
973
1704
  } else {
974
- const c = (s - 1) / N;
975
- for (let y = 0; y < F; ++y) {
976
- const z = y * 3, d = r[z + 0], k = r[z + 1], O = r[z + 2], q = d * T + k * v + O * R, V = (U - q) * c >>> 0, Y = Math.min(V, s - 1);
977
- S[y] = Y, I[Y]++;
1705
+ const d = (c - 1) / J;
1706
+ for (let z = 0; z < O; ++z) {
1707
+ const W = z * 3, S = s[W + 0], U = s[W + 1], $ = s[W + 2], X = S * w + U * p + $ * R, Z = (D - X) * d >>> 0, K = Math.min(Z, c - 1);
1708
+ g[z] = K, v[K]++;
978
1709
  }
979
1710
  }
980
- for (let c = 1; c < s; c++)
981
- I[c] += I[c - 1];
982
- for (let c = F - 1; c >= 0; c--) {
983
- const y = S[c], z = --I[y];
984
- t[z] = a ? a[c] : c;
1711
+ for (let d = 1; d < c; d++)
1712
+ v[d] += v[d - 1];
1713
+ for (let d = O - 1; d >= 0; d--) {
1714
+ const z = g[d], W = --v[z];
1715
+ r[W] = o ? o[d] : d;
985
1716
  }
986
- const p = A * T + g * v + D * R, M = (c) => {
987
- if (!t) return -1 / 0;
988
- const y = t[c], z = y;
989
- if (!r || z * 3 + 2 >= r.length)
1717
+ const k = A * w + C * p + _ * R, B = (d) => {
1718
+ if (!r) return -1 / 0;
1719
+ const z = r[d], W = z;
1720
+ if (!s || W * 3 + 2 >= s.length)
990
1721
  return -1 / 0;
991
- const d = z * 3;
992
- return r[d] * T + r[d + 1] * v + r[d + 2] * R - p;
1722
+ const S = W * 3;
1723
+ return s[S] * w + s[S + 1] * p + s[S + 2] * R - k;
993
1724
  };
994
- let E = F;
995
- if (F > 0 && M(F - 1) < 0) {
996
- const c = oe(
1725
+ let F = O;
1726
+ if (O > 0 && B(O - 1) < 0) {
1727
+ const d = H(
997
1728
  0,
998
- F - 1,
999
- M
1729
+ O - 1,
1730
+ B
1000
1731
  );
1001
- E = c < 0 ? ~c : c;
1732
+ F = d < 0 ? ~d : d;
1002
1733
  }
1003
- const m = {
1004
- order: t.buffer,
1005
- count: E
1734
+ const I = {
1735
+ order: r.buffer,
1736
+ count: F
1006
1737
  };
1007
- self.postMessage(m, [t.buffer]), t = null;
1738
+ self.postMessage(I, [r.buffer]), r = null;
1008
1739
  };
1009
1740
  self.onmessage = (A) => {
1010
- const g = A.data;
1011
- g.order && (t = new Uint32Array(g.order));
1012
- let D = !1;
1013
- if (g.centers && (r = new Float32Array(g.centers), D = !0, w = !0), Object.prototype.hasOwnProperty.call(g, "mapping") && (a = g.mapping ? new Uint32Array(g.mapping) : null, w = !0), g.chunks) {
1014
- if (n = new Float32Array(g.chunks), n.length > 0 && n[3] > 0)
1015
- for (let T = 0; T < n.length / 6; ++T) {
1016
- const v = T * 6, R = n[v + 0], B = n[v + 1], $ = n[v + 2], X = n[v + 3], Z = n[v + 4], U = n[v + 5];
1017
- n[v + 0] = (R + X) * 0.5, n[v + 1] = (B + Z) * 0.5, n[v + 2] = ($ + U) * 0.5, n[v + 3] = Math.sqrt(
1018
- (X - R) ** 2 + (Z - B) ** 2 + (U - $) ** 2
1741
+ const C = A.data;
1742
+ C.order && (r = new Uint32Array(C.order));
1743
+ let _ = !1;
1744
+ if (C.centers && (s = new Float32Array(C.centers), _ = !0, f = !0), Object.prototype.hasOwnProperty.call(C, "mapping") && (o = C.mapping ? new Uint32Array(C.mapping) : null, f = !0), C.chunks) {
1745
+ if (a = new Float32Array(C.chunks), a.length > 0 && a[3] > 0)
1746
+ for (let w = 0; w < a.length / 6; ++w) {
1747
+ const p = w * 6, R = a[p + 0], q = a[p + 1], j = a[p + 2], Y = a[p + 3], V = a[p + 4], D = a[p + 5];
1748
+ a[p + 0] = (R + Y) * 0.5, a[p + 1] = (q + V) * 0.5, a[p + 2] = (j + D) * 0.5, a[p + 3] = Math.sqrt(
1749
+ (Y - R) ** 2 + (V - q) ** 2 + (D - j) ** 2
1019
1750
  ) * 0.5;
1020
1751
  }
1021
- w = !0;
1752
+ f = !0;
1022
1753
  }
1023
- if (D && r && r.length > 0) {
1024
- h.x = b.x = r[0], h.y = b.y = r[1], h.z = b.z = r[2];
1025
- for (let T = 1; T < r.length / 3; T++) {
1026
- const v = T * 3;
1027
- h.x = Math.min(h.x, r[v + 0]), b.x = Math.max(b.x, r[v + 0]), h.y = Math.min(h.y, r[v + 1]), b.y = Math.max(b.y, r[v + 1]), h.z = Math.min(h.z, r[v + 2]), b.z = Math.max(b.z, r[v + 2]);
1754
+ if (_ && s && s.length > 0) {
1755
+ u.x = x.x = s[0], u.y = x.y = s[1], u.z = x.z = s[2];
1756
+ for (let w = 1; w < s.length / 3; w++) {
1757
+ const p = w * 3;
1758
+ u.x = Math.min(u.x, s[p + 0]), x.x = Math.max(x.x, s[p + 0]), u.y = Math.min(u.y, s[p + 1]), x.y = Math.max(x.y, s[p + 1]), u.z = Math.min(u.z, s[p + 2]), x.z = Math.max(x.z, s[p + 2]);
1028
1759
  }
1029
- } else D && r && r.length === 0 && (h.x = b.x = h.y = b.y = h.z = b.z = 0);
1030
- g.cameraPosition && (i = g.cameraPosition), g.cameraDirection && (u = g.cameraDirection), L();
1760
+ } else _ && s && s.length === 0 && (u.x = x.x = u.y = x.y = u.z = x.z = 0);
1761
+ C.cameraPosition && (i = C.cameraPosition), C.cameraDirection && (m = C.cameraDirection), L();
1031
1762
  };
1032
1763
  }).toString()})();`;
1033
1764
  }
1034
1765
  }
1035
- const Be = (x, e) => {
1036
- const o = ye(x), t = ye(e);
1037
- return o | t << 16;
1038
- };
1039
- function ye(x) {
1040
- const e = new Float32Array([x]), t = new Int32Array(e.buffer)[0];
1041
- let r = t >> 16 & 32768, n = t >> 12 & 2047;
1042
- const a = t >> 23 & 255;
1043
- return a < 103 ? r : a > 142 ? (r |= 31744, r |= (a === 255 ? 0 : 1) && t & 8388607, r) : a < 113 ? (n |= 2048, r |= (n >> 114 - a) + (n >> 113 - a & 1), r) : (r |= a - 112 << 10 | n >> 1, r += n & 1, r);
1044
- }
1045
- const Fe = new ArrayBuffer(4), ve = new DataView(Fe), Oe = (x) => (ve.setUint32(0, x, !0), ve.getFloat32(0, !0));
1046
- class De {
1047
- /**
1048
- * Create a new TextureManager for a set of splats
1049
- * @param splatData The splat data to manage textures for
1050
- */
1766
+ class kt {
1051
1767
  constructor(e) {
1052
- f(this, "textureWidth");
1053
- f(this, "textureHeight");
1054
- f(this, "transformA");
1055
- // position xyz and rotation quaternion y,z components
1056
- f(this, "transformB");
1057
- // rotation quaternion x and scale xyz
1058
- f(this, "colorTexture");
1059
- // color an opacity
1060
- f(this, "orderTexture");
1061
- const o = e.numSplats;
1062
- this.textureWidth = Math.ceil(Math.sqrt(o)), this.textureHeight = Math.ceil(o / this.textureWidth), this.transformA = this.createTransformATexture(e), this.transformB = this.createTransformBTexture(e), this.colorTexture = this.createColorTexture(e), this.orderTexture = this.createOrderTexture(o);
1768
+ M(this, "packedGeometry");
1769
+ // RGBA32UI
1770
+ M(this, "packedColor");
1771
+ // RGBA8
1772
+ M(this, "orderTexture");
1773
+ // RB32UI
1774
+ M(this, "width");
1775
+ M(this, "height");
1776
+ this.width = e.textureWidth, this.height = e.textureHeight, this.packedColor = this.createColorTexture(e), this.packedGeometry = this.createGeometryTexture(e), this.orderTexture = this.createOrderTexture(e.numSplats);
1063
1777
  }
1064
- /**
1065
- * Create the transform A texture (positions and quaternion w component)
1066
- * @param splatData The splat data
1067
- * @returns DataTexture containing position data
1068
- */
1069
- createTransformATexture(e) {
1070
- const o = e.numSplats, t = new Float32Array(
1071
- this.textureWidth * this.textureHeight * 4
1072
- );
1073
- for (let n = 0; n < o; n++) {
1074
- const a = n * 4, i = n * 3, u = n * 4;
1075
- t[a] = e.positions[i], t[a + 1] = e.positions[i + 1], t[a + 2] = e.positions[i + 2];
1076
- const w = e.rotations[u + 0], C = e.rotations[u + 1], _ = Be(w, C);
1077
- t[a + 3] = Oe(_);
1078
- }
1079
- const r = new l.DataTexture(
1080
- t,
1081
- this.textureWidth,
1082
- this.textureHeight,
1083
- l.RGBAFormat,
1084
- l.FloatType
1085
- // Store as Float32, shader will reinterpret bits
1086
- );
1087
- return r.magFilter = l.NearestFilter, r.minFilter = l.NearestFilter, r.source.data.updateRanges || (r.source.data.updateRanges = []), r.needsUpdate = !0, r;
1088
- }
1089
- /**
1090
- * Create the transform B texture (scale and rotation xyz)
1091
- * @param splatData The splat data
1092
- * @returns DataTexture containing scale and rotation data
1093
- */
1094
- createTransformBTexture(e) {
1095
- const o = e.numSplats, t = new Float32Array(
1096
- this.textureWidth * this.textureHeight * 4
1097
- );
1098
- for (let n = 0; n < o; n++) {
1099
- const a = n * 4, i = n * 3, u = n * 4;
1100
- t[a] = e.scales[i], t[a + 1] = e.scales[i + 1], t[a + 2] = e.scales[i + 2], t[a + 3] = e.rotations[u + 2];
1101
- }
1102
- const r = new l.DataTexture(
1103
- t,
1104
- this.textureWidth,
1105
- this.textureHeight,
1106
- l.RGBAFormat,
1107
- l.FloatType
1778
+ createGeometryTexture(e) {
1779
+ const t = new h.DataTexture(
1780
+ e.packedGeometry,
1781
+ this.width,
1782
+ this.height,
1783
+ h.RGBAIntegerFormat,
1784
+ h.UnsignedIntType
1108
1785
  );
1109
- return r.magFilter = l.NearestFilter, r.minFilter = l.NearestFilter, r.source.data.updateRanges || (r.source.data.updateRanges = []), r.needsUpdate = !0, r;
1786
+ return t.internalFormat = "RGBA32UI", t.minFilter = h.NearestFilter, t.magFilter = h.NearestFilter, t.needsUpdate = !0, t;
1110
1787
  }
1111
- /**
1112
- * Create the color texture (RGB and opacity)
1113
- * @param splatData The splat data
1114
- * @returns DataTexture containing color data
1115
- */
1116
1788
  createColorTexture(e) {
1117
- const o = e.numSplats, t = new Float32Array(
1118
- this.textureWidth * this.textureHeight * 4
1119
- );
1120
- for (let n = 0; n < o; n++) {
1121
- const a = n * 4, i = n * 3;
1122
- t[a] = e.colors[i], t[a + 1] = e.colors[i + 1], t[a + 2] = e.colors[i + 2], t[a + 3] = e.opacities[n];
1123
- }
1124
- const r = new l.DataTexture(
1125
- t,
1126
- this.textureWidth,
1127
- this.textureHeight,
1128
- l.RGBAFormat,
1129
- l.FloatType
1789
+ const t = new h.DataTexture(
1790
+ e.packedColor,
1791
+ this.width,
1792
+ this.height,
1793
+ h.RGBAFormat,
1794
+ h.UnsignedByteType
1130
1795
  );
1131
- return r.source.data.updateRanges || (r.source.data.updateRanges = []), r.needsUpdate = !0, r;
1796
+ return t.minFilter = h.NearestFilter, t.magFilter = h.NearestFilter, t.needsUpdate = !0, t;
1132
1797
  }
1133
- /**
1134
- * Create the order texture for sorting
1135
- * @param numSplats Number of splats
1136
- * @returns DataTexture for storing order indices
1137
- */
1138
1798
  createOrderTexture(e) {
1139
- const o = new Uint32Array(this.textureWidth * this.textureHeight);
1140
- for (let r = 0; r < e; r++)
1141
- o[r] = r;
1142
- const t = new l.DataTexture(
1143
- o,
1144
- this.textureWidth,
1145
- this.textureHeight,
1146
- l.RedIntegerFormat,
1147
- l.UnsignedIntType
1799
+ const t = new Uint32Array(this.width * this.height);
1800
+ for (let s = 0; s < e; s++) t[s] = s;
1801
+ const r = new h.DataTexture(
1802
+ t,
1803
+ this.width,
1804
+ this.height,
1805
+ h.RedIntegerFormat,
1806
+ h.UnsignedIntType
1148
1807
  );
1149
- return t.source.data.updateRanges || (t.source.data.updateRanges = []), t.needsUpdate = !0, t;
1808
+ return r.minFilter = h.NearestFilter, r.magFilter = h.NearestFilter, r.needsUpdate = !0, r;
1150
1809
  }
1151
1810
  dispose() {
1152
- this.transformA.dispose(), this.transformB.dispose(), this.colorTexture.dispose(), this.orderTexture.dispose();
1811
+ this.packedGeometry.dispose(), this.packedColor.dispose(), this.orderTexture.dispose();
1153
1812
  }
1154
1813
  }
1155
- const Ue = (
1814
+ const Et = (
1156
1815
  /* glsl */
1157
1816
  `
1158
1817
  precision highp float;
@@ -1160,55 +1819,47 @@ precision highp int;
1160
1819
  precision highp usampler2D;
1161
1820
  precision highp sampler2D;
1162
1821
 
1163
- // --- Uniforms (Provided by Three.js) ---
1164
- // uniform mat4 modelViewMatrix; // Don't redeclare
1165
- // uniform mat4 projectionMatrix; // Don't redeclare
1166
- uniform vec2 viewport; // Viewport dimensions (width, height)
1167
- uniform uint numSplats; // Total number of splats potentially renderable by sorter
1822
+ uniform int texWidth;
1823
+ uniform vec2 viewport;
1824
+ uniform uint numSplats;
1168
1825
 
1169
- // Textures
1170
- uniform highp sampler2D transformA; // vec4: pos.xyz, packed_rot.yz
1171
- uniform highp sampler2D transformB; // vec4: log_scale.xyz, rot.x
1172
- uniform highp sampler2D splatColor; // vec4: color.rgb, opacity
1173
- uniform highp usampler2D splatOrder; // uint: original splat index
1826
+ // --- Unified Packed Textures ---
1827
+ uniform usampler2D packedGeometry; // RGBA32UI: Geometry (Pos, Rot, Scale)
1828
+ uniform sampler2D packedColor; // RGBA8: Color (RGB) + Opacity (A)
1829
+ uniform usampler2D splatOrder; // R32UI: Sort Index
1174
1830
 
1175
- // --- Attributes ---
1176
- // Instancing attribute: base index for this block of splats
1177
- attribute uint splatInstanceIndex;
1831
+ // --- Decompression Ranges ---
1832
+ uniform vec3 meansMin;
1833
+ uniform vec3 meansMax;
1834
+ uniform vec3 scalesMin;
1835
+ uniform vec3 scalesMax;
1836
+ uniform vec3 sh0Min;
1837
+ uniform vec3 sh0Max;
1178
1838
 
1179
- // Per-vertex attribute of the quad (Built-in, don't redeclare 'position')
1180
- // attribute vec3 position; // Use the built-in 'position'
1181
- // position.xy: corner coords (-1..1)
1182
- // position.z: index within the instance block (0..INSTANCE_BUFFER_SIZE-1)
1839
+ // --- Attributes ---
1840
+ in uint splatInstanceIndex;
1183
1841
 
1184
- // --- Varyings ---
1185
- varying vec4 vColor;
1186
- varying vec2 vUv; // For gaussian calculation in fragment shader
1842
+ // --- Outputs ---
1843
+ out vec4 vColor;
1844
+ out vec2 vUv;
1187
1845
 
1188
1846
  // --- Constants ---
1189
- #define INSTANCE_BUFFER_SIZE 128.0 // Must match the size in SplatMesh
1847
+ const vec4 DISCARD_VERTEX = vec4(0.0, 0.0, 2.0, 1.0);
1848
+ const float SH_C0 = 0.28209479177387814; // 1/(2*sqrt(pi))
1849
+ const float QUAT_NORM = 1.41421356237; // sqrt(2)
1190
1850
 
1191
1851
  // --- Helper Functions ---
1192
1852
 
1193
- // Use GLSL built-in unpackHalf2x16 for proper half-float unpacking
1194
-
1195
- // Reconstruct quaternion from packed components (xy_packed, z)
1196
- // Returns (w,x,y,z) format for quatToMat3 compatibility
1197
- vec4 unpackRotation(float xy_packed, float z) {
1198
- vec2 xy = unpackHalf2x16(floatBitsToUint(xy_packed));
1199
- float x = xy.x;
1200
- float y = xy.y;
1201
- float w_squared = 1.0 - x*x - y*y - z*z;
1202
- float w = (w_squared < 0.0) ? 0.0 : sqrt(w_squared);
1203
- return vec4(w, x, y, z); // Return (w,x,y,z)
1853
+ // Extract raw bytes as integers (no /255 )
1854
+ uvec4 unpackBytes(uint v) {
1855
+ return (uvec4(v) >> uvec4(24u, 16u, 8u, 0u)) & 0xffu;
1204
1856
  }
1205
1857
 
1206
- // Convert quaternion to 3x3 rotation matrix
1207
1858
  mat3 quatToMat3(vec4 R) {
1208
1859
  vec4 R2 = R + R;
1209
1860
  float X = R2.x * R.w;
1210
- vec4 Y = R2.y * R;
1211
- vec4 Z = R2.z * R;
1861
+ vec4 Y = R2.y * R;
1862
+ vec4 Z = R2.z * R;
1212
1863
  float W = R2.w * R.w;
1213
1864
 
1214
1865
  return mat3(
@@ -1224,199 +1875,176 @@ mat3 quatToMat3(vec4 R) {
1224
1875
  );
1225
1876
  }
1226
1877
 
1227
- // Calculate model-space covariance components
1228
1878
  void getModelCovariance(vec3 scale, vec4 rotation, out vec3 covA, out vec3 covB) {
1229
1879
  mat3 rot = quatToMat3(rotation);
1230
-
1231
- // M = S * R (scale COLUMNS, then transpose)
1232
1880
  mat3 M = transpose(mat3(
1233
- scale.x * rot[0], // scale.x * column 0
1234
- scale.y * rot[1], // scale.y * column 1
1235
- scale.z * rot[2] // scale.z * column 2
1881
+ scale.x * rot[0],
1882
+ scale.y * rot[1],
1883
+ scale.z * rot[2]
1236
1884
  ));
1237
1885
 
1238
1886
  covA = vec3(dot(M[0], M[0]), dot(M[0], M[1]), dot(M[0], M[2]));
1239
1887
  covB = vec3(dot(M[1], M[1]), dot(M[1], M[2]), dot(M[2], M[2]));
1240
1888
  }
1241
1889
 
1242
- // --- Main Function ---
1243
- void main(void) {
1244
- // Calculate the final splat index for this vertex
1245
- uint instanceOffset = uint(position.z); // Read index within instance from Z
1246
- uint orderedSplatIndex = splatInstanceIndex + instanceOffset;
1890
+ // --- Main ---
1891
+ void main() {
1892
+ // Calculate Instance ID & Source Data UV
1893
+ uint instanceOffset = uint(position.z);
1894
+ uint orderIndex = splatInstanceIndex + instanceOffset;
1247
1895
 
1248
- // Discard if this splat index is beyond the sorted count
1249
- if (orderedSplatIndex >= numSplats) {
1250
- gl_Position = vec4(2.0, 2.0, 2.0, 1.0); // Off-screen
1896
+ if (orderIndex >= numSplats) {
1897
+ gl_Position = DISCARD_VERTEX;
1251
1898
  return;
1252
1899
  }
1253
1900
 
1254
- // --- Source Data Lookup ---
1255
- uint texWidth = uint(textureSize(splatOrder, 0).x);
1256
- ivec2 orderUV = ivec2(orderedSplatIndex % texWidth, orderedSplatIndex / texWidth);
1257
- uint originalSplatIndex = texelFetch(splatOrder, orderUV, 0).r;
1901
+ uint w = uint(texWidth);
1902
+ ivec2 orderUV = ivec2(int(orderIndex % w), int(orderIndex / w));
1258
1903
 
1259
- ivec2 dataUV = ivec2(originalSplatIndex % texWidth, originalSplatIndex / texWidth);
1904
+ // Fetch original splat ID from the order texture
1905
+ uint splatID = texelFetch(splatOrder, orderUV, 0).r;
1906
+ ivec2 dataUV = ivec2(int(splatID % w), int(splatID / w));
1260
1907
 
1261
- // Fetch data from textures
1262
- vec4 texTransformA = texelFetch(transformA, dataUV, 0);
1263
- vec4 texTransformB = texelFetch(transformB, dataUV, 0);
1264
- vec4 texColor = texelFetch(splatColor, dataUV, 0);
1908
+ // Fetch Packed Data
1909
+ // x: Means Low, y: Means High, z: Rotation, w: Scale
1910
+ uvec4 geom = texelFetch(packedGeometry, dataUV, 0);
1911
+ vec4 colorRaw = texelFetch(packedColor, dataUV, 0);
1265
1912
 
1266
- vec3 splatPosition = texTransformA.xyz;
1267
- vec3 splatLogScale = texTransformB.xyz; // Assume stored as log scale
1268
- vec4 splatRotation = unpackRotation(texTransformA.w, texTransformB.w); // Unpack rot xy, z
1269
- vec3 splatColor = texColor.rgb;
1270
- float splatOpacity = texColor.a;
1913
+ // Decompress Position (Means) (assume world-space)
1914
+ // Reconstruct 16-bit values from two 8-bit channels
1915
+ uvec3 lo = unpackBytes(geom.x).xyz;
1916
+ uvec3 hi = unpackBytes(geom.y).xyz;
1271
1917
 
1272
- vec3 splatScale = exp(splatLogScale); // Convert log scale to actual scale
1918
+ // (hi << 8) | lo => 0..65535 then normalize
1919
+ vec3 meansNorm = vec3((hi << 8u) | lo) * (1.0 / 65535.0);
1920
+ vec3 modelCenter = mix(meansMin, meansMax, meansNorm);
1273
1921
 
1274
- // --- Center Projection ---
1922
+ // Decompress Rotation (Quaternions)
1923
+ uvec4 qB = unpackBytes(geom.z);
1924
+ vec3 abc = (vec3(qB.xyz) * (1.0 / 255.0) - 0.5) * QUAT_NORM;
1925
+ float d = sqrt(max(0.0, 1.0 - dot(abc, abc)));
1926
+ uint mode = qB.w; // already 0..3
1275
1927
 
1276
- // Compute normalized view-space center
1277
- vec4 centerClipRaw = modelViewMatrix * vec4(splatPosition, 1.0);
1278
- vec3 centerView = centerClipRaw.xyz / centerClipRaw.w;
1279
1928
 
1280
- // Early out if splat is behind the camera
1281
- if (centerView.z > -0.2) { // Use small epsilon
1282
- gl_Position = vec4(2.0, 2.0, 2.0, 1.0);
1283
- return;
1284
- }
1929
+ // Reconstruct Quaternion (x, y, z, w)
1930
+ // quat in (w,x,y,z)
1931
+ vec4 quat;
1932
+ if (mode == 0u) quat = vec4(d, abc); // (w, x, y, z)
1933
+ else if (mode == 1u) quat = vec4(abc.x, d, abc.yz); // stored (w,y,z)
1934
+ else if (mode == 2u) quat = vec4(abc.xy, d, abc.z); // stored (w,x,z)
1935
+ else quat = vec4(abc, d); // stored (w,x,y)
1285
1936
 
1286
- // Project to clip space
1287
- vec4 centerClip = projectionMatrix * centerClipRaw;
1937
+ // Decompress Scale
1938
+ uvec3 sB = unpackBytes(geom.w).xyz;
1939
+ vec3 sNorm = vec3(sB) * (1.0 / 255.0);
1940
+ vec3 sLerp = mix(scalesMin, scalesMax, sNorm);
1941
+ vec3 scale = exp(sLerp); // log scale stored
1288
1942
 
1289
- // --- Covariance Calculation & Projection ---
1943
+ // Decompress Color & Opacity
1944
+ vec4 clr;
1945
+ vec3 sh = mix(sh0Min, sh0Max, colorRaw.rgb);
1946
+ clr.rgb = vec3(0.5) + sh * SH_C0;
1947
+ clr.a = colorRaw.a; // Opacity passed directly (linear or sigmoid handled by loader)
1290
1948
 
1291
- // Calculating model space covariance (Vrk)
1949
+ // --- Standard Gaussian Splat Projection ---
1950
+
1951
+ // View Space Setup
1952
+ mat4 modelView = modelViewMatrix;
1953
+ vec4 centerView = modelView * vec4(modelCenter, 1.0);
1954
+
1955
+ // Cull behind camera
1956
+ if (centerView.z > -0.2) {
1957
+ gl_Position = DISCARD_VERTEX;
1958
+ return;
1959
+ }
1960
+
1961
+ // Covariance in 3D
1292
1962
  vec3 covA, covB;
1293
- getModelCovariance(splatScale, splatRotation, covA, covB);
1294
- mat3 Vrk = mat3(
1295
- covA.x, covA.y, covA.z,
1296
- covA.y, covB.x, covB.y, // covB.x is Vrk[1][1]
1297
- covA.z, covB.y, covB.z // covB.y is Vrk[1][2], covB.z is Vrk[2][2]
1298
- );
1963
+ getModelCovariance(scale, quat, covA, covB);
1299
1964
 
1300
- // Calculate Jacobian J (screen space change wrt view space change)
1301
- // Requres focal lenghts and view-space center depth (tz)
1965
+ // Project to 2D
1302
1966
  float focalX = viewport.x * projectionMatrix[0][0];
1303
1967
  float focalY = viewport.y * projectionMatrix[1][1];
1304
- float tz = centerView.z;
1305
- float tz2 = tz * tz;
1968
+ float J1 = focalX / centerView.z;
1969
+ vec2 J2 = -J1 / centerView.z * centerView.xy;
1306
1970
 
1307
- // Jacobian J = [fx/tz, 0, -fx*tx/tz^2]
1308
- // [0, fy/tz, -fy*ty/tz^2]
1309
1971
  mat3 J = mat3(
1310
- focalX / tz, 0.0, -focalX * centerView.x / tz2,
1311
- 0.0, focalY / tz, -focalY * centerView.y / tz2,
1312
- 0.0, 0.0, 0.0
1972
+ J1, 0.0, J2.x,
1973
+ 0.0, J1, J2.y,
1974
+ 0.0, 0.0, 0.0
1313
1975
  );
1314
1976
 
1315
- // Calculate W
1316
- mat3 W = transpose(mat3(modelViewMatrix));
1317
- // Calculate T = W * J
1977
+ mat3 W = transpose(mat3(modelView));
1318
1978
  mat3 T = W * J;
1319
- // Calculate Projected 2D Covariance: SigmaProj = transpose(T) * Vrk * T
1320
- mat3 SigmaProj = transpose(T) * Vrk * T;
1321
-
1322
- // Extract 2D components and add bias
1323
- float cov2D_11 = SigmaProj[0][0] + 0.3;
1324
- float cov2D_12 = SigmaProj[0][1];
1325
- float cov2D_22 = SigmaProj[1][1] + 0.3;
1326
-
1327
- // --- Calculate 2D Screen Space Rotation & Scale ---
1328
-
1329
- float det = cov2D_11 * cov2D_22 - cov2D_12 * cov2D_12;
1330
- // Ensure determinant is non-negative before sqrt
1331
- if (det <= 0.0) {
1332
- gl_Position = vec4(2.0, 2.0, 2.0, 1.0); // Discard degenerated
1333
- return;
1334
- }
1335
-
1336
- float trace = cov2D_11 + cov2D_22;
1337
- float traceOver2 = 0.5 * trace;
1338
- float discriminantSqrt = sqrt(max(traceOver2 * traceOver2 - det, 0.0)); // Avoid sqrt(negative)
1339
-
1340
- float lambda1 = traceOver2 + discriminantSqrt; // Larger eigenvalue
1341
- float lambda2 = max(0.1, traceOver2 - discriminantSqrt); // Smaller eigenvalue, clamped
1342
-
1343
- // Compute eigenvectors
1344
-
1345
- vec2 v1_eigen, v2_eigen;
1346
-
1347
- // Handle diagonal case
1348
- if(abs(cov2D_12) < 1e-16) {
1349
- v1_eigen = vec2(1.0, 0.0);
1350
- } else {
1351
- v1_eigen = normalize(vec2(cov2D_12, lambda1 - cov2D_11)); // diagonal choice
1352
- }
1979
+ mat3 Vrk = mat3(
1980
+ covA.x, covA.y, covA.z,
1981
+ covA.y, covB.x, covB.y,
1982
+ covA.z, covB.y, covB.z
1983
+ );
1984
+ mat3 cov = transpose(T) * Vrk * T;
1353
1985
 
1354
- v2_eigen = vec2(-v1_eigen.y, v1_eigen.x); // Perpendicular eigenvector
1986
+ // Eigendecomposition for Quad dimensions
1987
+ float diagonal1 = cov[0][0] + 0.3;
1988
+ float offDiagonal = cov[0][1];
1989
+ float diagonal2 = cov[1][1] + 0.3;
1355
1990
 
1356
- // Calculate SCALED vectors (l1, l2, incorparate factor)
1357
- float scaleFactor = 2.0 * sqrt(2.0); // ~2.8284
1358
- float l1 = sqrt(lambda1) * scaleFactor; // scaleX
1359
- float l2 = sqrt(lambda2) * scaleFactor; // scaleY
1991
+ float mid = 0.5 * (diagonal1 + diagonal2);
1992
+ float radius = length(vec2((diagonal1 - diagonal2) * 0.5, offDiagonal));
1993
+ float lambda1 = mid + radius;
1994
+ float lambda2 = max(mid - radius, 0.1);
1360
1995
 
1361
- float vmin = min(512.0, min(viewport.x, viewport.y));
1362
- l1 = min(l1, 2.0 * vmin);
1363
- l2 = min(l2, 2.0 * vmin);
1996
+ // Screen space quad vectors
1997
+ float vmin = min(1024.0, min(viewport.x, viewport.y)); // Safety clamp
1998
+ float l1 = 2.0 * min(sqrt(2.0 * lambda1), vmin);
1999
+ float l2 = 2.0 * min(sqrt(2.0 * lambda2), vmin);
1364
2000
 
1365
- // Early out tiny splats
1366
- if (l1 < 2.0 && l2 < 2.0) { // Check if smaller than ~2 pixel
1367
- gl_Position = vec4(2.0, 2.0, 2.0, 1.0);
1368
- return;
2001
+ // Discard tiny splats
2002
+ if (l1 < 2.0 && l2 < 2.0) {
2003
+ gl_Position = DISCARD_VERTEX;
2004
+ return;
1369
2005
  }
1370
2006
 
1371
- // Scaled eigenvectors for offset calculation
1372
- vec2 v1_scaled = l1 * v1_eigen;
1373
- vec2 v2_scaled = l2 * v2_eigen;
2007
+ vec2 diagVec = normalize(vec2(offDiagonal, lambda1 - diagonal1));
2008
+ vec2 v1 = l1 * diagVec;
2009
+ vec2 v2 = l2 * vec2(diagVec.y, -diagVec.x);
1374
2010
 
1375
- // --- FRUSTUM CHECK (laxo, estilo PlayCanvas) ---
1376
-
1377
- vec2 c = centerClip.ww / viewport; // pixel to clip
1378
- float r = max(l1, l2); // radius in pixels
1379
-
1380
- // Remove if the center - radius is already out of -w..w
1381
- if (any(greaterThan(abs(centerClip.xy) - vec2(r) * c, centerClip.ww))) {
1382
- gl_Position = vec4(2.0, 2.0, 2.0, 1.0);
2011
+ // Vertex Position (Quad Expansion)
2012
+ vec4 centerProj = projectionMatrix * centerView;
2013
+ vec2 c = centerProj.ww / viewport; // Correction for clip space
2014
+
2015
+ // Frustum cull
2016
+ if (any(greaterThan(abs(centerProj.xy) - vec2(max(l1, l2)) * c, centerProj.ww))) {
2017
+ gl_Position = DISCARD_VERTEX;
1383
2018
  return;
1384
2019
  }
1385
2020
 
1386
- // --- END FRUSTUM CHECK ---
1387
-
1388
- // --- Final Vertex Position ---
1389
-
1390
- vec2 cornerOffset = position.xy; // (-1,-1) to (1,1)
1391
-
1392
- // Clip the quad so only high-alpha core is visible
1393
- float alpha = max(splatOpacity, 1e-6); // avoid log(0)
1394
- float clip = min(1.0, sqrt(-log(1.0 / 255.0 / alpha)) / 2.0);
1395
-
1396
- // Apply clip to the corner offset *before* calculating screen space offset
1397
- vec2 clippedCornerOffset = cornerOffset * clip;
1398
- vec2 screenOffsetPixels = clippedCornerOffset.x * v1_scaled + clippedCornerOffset.y * v2_scaled;
1399
-
1400
- // Convert pixel offset to clip space offset
1401
- vec2 clipOffset = screenOffsetPixels * (centerClip.w / viewport);
1402
-
1403
-
1404
- // Apply offset to center clip position
1405
- gl_Position = centerClip + vec4(clipOffset, 0.0, 0.0);
1406
-
1407
- // --- Pass data to Fragment Shader ---
2021
+ // Quad offset based on 'position' attribute (-1 to 1)
2022
+ vec2 offset = (position.x * v1 + position.y * v2) * c;
2023
+
2024
+ // Corner Clipping (for gaussian shape)
2025
+ // Assuming simple linear opacity here, otherwise inverse sigmoid logic required
2026
+ float alpha = max(clr.a, 1.0/255.0);
2027
+ float clip = min(1.0, sqrt(-log(1.0 / 255.0 / alpha)) / 2.0);
2028
+
2029
+ offset *= clip;
2030
+ vec2 clippedUV = position.xy * clip;
1408
2031
 
1409
- vColor = vec4(splatColor, splatOpacity);
1410
- vUv = clippedCornerOffset;
2032
+ gl_Position = centerProj + vec4(offset, 0.0, 0.0);
2033
+
2034
+ // Outputs
2035
+ vUv = clippedUV;
2036
+ vColor = vec4(max(clr.rgb, vec3(0.0)), clr.a);
1411
2037
  }
1412
2038
  `
1413
- ), qe = (
2039
+ ), Ct = (
1414
2040
  /* glsl */
1415
2041
  `
1416
2042
  precision highp float;
1417
2043
 
1418
- varying vec4 vColor; // Color and opacity passed from vertex shader
1419
- varying vec2 vUv; // Quad UV coordinates (-1 to 1) passed from vertex shader
2044
+ in vec4 vColor; // Color and opacity passed from vertex shader
2045
+ in vec2 vUv; // Quad UV coordinates (-1 to 1) passed from vertex shader
2046
+
2047
+ out vec4 fragColor; // Output variable
1420
2048
 
1421
2049
  // Fast approximate e^x based on https://nic.schraudolph.org/pubs/Schraudolph99.pdf
1422
2050
  const float EXP_A = 12102203.0; // ≈ 2^23 / ln(2)
@@ -1440,88 +2068,86 @@ void main(void) {
1440
2068
  if (alpha < 1.0 / 255.0) discard; // Discard fragments with very low alpha
1441
2069
 
1442
2070
  // Premultiply color by alpha (required for correct blending)
1443
- gl_FragColor = vec4(vColor.rgb * alpha, alpha);
2071
+ fragColor = vec4(vColor.rgb * alpha, alpha);
1444
2072
  }
1445
2073
  `
1446
2074
  );
1447
- class Ve extends l.ShaderMaterial {
2075
+ class It extends h.ShaderMaterial {
1448
2076
  constructor(e = {}) {
1449
- const o = {
1450
- // Textures (values set via methods)
1451
- transformA: { value: null },
1452
- transformB: { value: null },
1453
- splatColor: { value: null },
2077
+ const t = {
2078
+ // Packed Textures
2079
+ packedGeometry: { value: null },
2080
+ // RGBA32UI: .r=MeansLow, .g=MeansHigh, .b=Quats, .a=Scales
2081
+ packedColor: { value: null },
2082
+ // RGBA8: .rgb=Color, .a=Opacity
1454
2083
  splatOrder: { value: null },
1455
- // Other uniforms
1456
- viewport: { value: new l.Vector2(1, 1) },
1457
- // Will be updated
2084
+ // Index map
2085
+ // Decompression Ranges
2086
+ meansMin: { value: new h.Vector3() },
2087
+ meansMax: { value: new h.Vector3() },
2088
+ scalesMin: { value: new h.Vector3() },
2089
+ scalesMax: { value: new h.Vector3() },
2090
+ sh0Min: { value: new h.Vector3() },
2091
+ sh0Max: { value: new h.Vector3() },
2092
+ // Render State
2093
+ texWidth: { value: 0 },
2094
+ viewport: { value: new h.Vector2(1, 1) },
1458
2095
  numSplats: { value: 0 }
1459
- // Max splats to render (updated by sorter)
1460
2096
  };
1461
2097
  super({
1462
- vertexShader: Ue,
1463
- fragmentShader: qe,
1464
- uniforms: o,
2098
+ uniforms: t,
2099
+ vertexShader: Et,
2100
+ fragmentShader: Ct,
1465
2101
  transparent: !0,
1466
- blending: l.CustomBlending,
1467
- // Premultiplied alpha blending:
1468
- // color = src_color * src_alpha + dst_color * (1 - src_alpha)
1469
- // alpha = src_alpha * 1 + dst_alpha * (1 - src_alpha)
1470
- blendSrc: l.OneFactor,
1471
- // Using ONE because shader outputs premultiplied color (color * alpha)
1472
- blendDst: l.OneMinusSrcAlphaFactor,
1473
- blendSrcAlpha: l.OneFactor,
1474
- // source alpha comes from shader
1475
- blendDstAlpha: l.OneMinusSrcAlphaFactor,
1476
- blendEquation: l.AddEquation,
1477
- blendEquationAlpha: l.AddEquation,
2102
+ glslVersion: h.GLSL3,
2103
+ blendSrc: h.OneFactor,
2104
+ blendSrcAlpha: h.OneFactor,
2105
+ blending: h.CustomBlending,
2106
+ blendEquation: h.AddEquation,
2107
+ blendEquationAlpha: h.AddEquation,
2108
+ blendDst: h.OneMinusSrcAlphaFactor,
2109
+ blendDstAlpha: h.OneMinusSrcAlphaFactor,
1478
2110
  depthTest: !0,
1479
2111
  depthWrite: !1,
1480
- // Disable depth write for transparency
1481
- side: l.DoubleSide,
1482
- // Render both sides (or CULLFACE_NONE equivalent)
1483
- // Optional settings from constructor
1484
- alphaTest: e.alphaTest !== void 0 ? e.alphaTest : 0,
1485
- // Typically 0 for blending
1486
- toneMapped: e.toneMapped !== void 0 ? e.toneMapped : !1
1487
- // prettier-ignore
1488
- }), e.alphaHash && (this.alphaHash = !0, this.depthWrite = !0, this.blending = l.NoBlending);
2112
+ side: h.DoubleSide,
2113
+ alphaTest: e.alphaTest ?? 0,
2114
+ toneMapped: e.toneMapped ?? !1
2115
+ }), e.alphaHash && (this.alphaHash = !0, this.depthWrite = !0, this.blending = h.NoBlending);
2116
+ }
2117
+ setTexWidth(e) {
2118
+ this.uniforms.texWidth.value = e | 0;
1489
2119
  }
1490
2120
  /**
1491
2121
  * Update the viewport size
1492
2122
  * @param width Viewport width
1493
2123
  * @param height Viewport height
1494
2124
  */
1495
- updateViewport(e, o) {
1496
- this.uniforms.viewport.value.set(e, o);
2125
+ updateViewport(e, t) {
2126
+ this.uniforms.viewport.value.set(e, t);
1497
2127
  }
1498
2128
  /**
1499
- * Set transform texture A (positions)
1500
- * @param texture Texture containing positions
2129
+ * Set the main packed geometry texture (RGBA32UI)
1501
2130
  */
1502
- setTransformA(e) {
1503
- this.uniforms.transformA.value = e;
2131
+ setPackedGeometry(e) {
2132
+ this.uniforms.packedGeometry.value = e;
1504
2133
  }
1505
2134
  /**
1506
- * Set transform texture B (rotation, scale)
1507
- * @param texture Texture containing rotation and scale data
2135
+ * Set the packed color texture (RGBA8)
1508
2136
  */
1509
- setTransformB(e) {
1510
- this.uniforms.transformB.value = e;
2137
+ setPackedColor(e) {
2138
+ this.uniforms.packedColor.value = e;
1511
2139
  }
1512
2140
  /**
1513
- * Set color texture
1514
- * @param texture Texture containing colors
2141
+ * Set order texture for sorting
1515
2142
  */
1516
- setColorTexture(e) {
1517
- this.uniforms.splatColor.value = e;
2143
+ setOrderTexture(e) {
2144
+ this.uniforms.splatOrder.value = e;
1518
2145
  }
1519
2146
  /**
1520
- * Set order texture
1521
- * @param texture Texture containing sort order
2147
+ * Set the ranges needed to decompress the packed floats
1522
2148
  */
1523
- setOrderTexture(e) {
1524
- this.uniforms.splatOrder.value = e;
2149
+ setRanges(e) {
2150
+ this.uniforms.meansMin.value.copy(e.means.min), this.uniforms.meansMax.value.copy(e.means.max), this.uniforms.scalesMin.value.copy(e.scales.min), this.uniforms.scalesMax.value.copy(e.scales.max), this.uniforms.sh0Min.value.copy(e.sh0.min), this.uniforms.sh0Max.value.copy(e.sh0.max);
1525
2151
  }
1526
2152
  /**
1527
2153
  * Set number of splats to render
@@ -1531,48 +2157,40 @@ class Ve extends l.ShaderMaterial {
1531
2157
  this.uniforms.numSplats.value = e;
1532
2158
  }
1533
2159
  }
1534
- const se = class se extends l.Mesh {
2160
+ const de = class de extends h.Mesh {
1535
2161
  // Match shader constant
1536
2162
  /**
1537
2163
  * Create a new SplatMesh for rendering Gaussian splats
1538
2164
  * @param splatData The splat data to render
1539
2165
  * @param options Rendering options
1540
2166
  */
1541
- constructor(o, t = {}) {
1542
- const r = new Ve(t), n = se.createInstancedGeometry(o.numSplats, se.INSTANCE_SIZE);
1543
- super(n, r);
1544
- f(this, "sorter");
1545
- f(this, "splatData");
1546
- f(this, "options");
1547
- f(this, "textureManager");
1548
- f(this, "material");
1549
- f(this, "geometry");
1550
- f(this, "lastCameraPositionLocal", new l.Vector3());
1551
- f(this, "lastCameraDirectionLocal", new l.Vector3());
1552
- f(this, "invModelMatrix", new l.Matrix4());
2167
+ constructor(t, r = {}) {
2168
+ const s = new It(r), a = de.createInstancedGeometry(t.numSplats, de.INSTANCE_SIZE);
2169
+ super(a, s);
2170
+ M(this, "sorter");
2171
+ M(this, "options");
2172
+ M(this, "splatData");
2173
+ M(this, "textureManager");
2174
+ M(this, "material");
2175
+ M(this, "geometry");
2176
+ M(this, "lastCameraPositionLocal", new h.Vector3());
2177
+ M(this, "lastCameraDirectionLocal", new h.Vector3());
2178
+ M(this, "invModelMatrix", new h.Matrix4());
1553
2179
  // Cached inverse matrix
1554
- f(this, "_vpW", -1);
1555
- f(this, "_vpH", -1);
1556
- f(this, "_size", new l.Vector2());
1557
- f(this, "_camPosW", new l.Vector3());
1558
- f(this, "_camDirW", new l.Vector3());
1559
- f(this, "_camPosL", new l.Vector3());
1560
- f(this, "_camDirL", new l.Vector3());
1561
- f(this, "onSorterUpdated", (o) => {
1562
- const t = o.count;
1563
- this.geometry.instanceCount = Math.ceil(t / se.INSTANCE_SIZE), this.material.setNumSplats(t);
2180
+ M(this, "_vpW", -1);
2181
+ M(this, "_vpH", -1);
2182
+ M(this, "_size", new h.Vector2());
2183
+ M(this, "_camPosW", new h.Vector3());
2184
+ M(this, "_camDirW", new h.Vector3());
2185
+ M(this, "_camPosL", new h.Vector3());
2186
+ M(this, "_camDirL", new h.Vector3());
2187
+ M(this, "onSorterUpdated", (t) => {
2188
+ const r = t.count;
2189
+ this.geometry.instanceCount = Math.ceil(r / de.INSTANCE_SIZE), this.material.setNumSplats(r);
1564
2190
  });
1565
- this.geometry = n, this.material = r, this.splatData = o, this.frustumCulled = !1, this.options = {
1566
- autoSort: !0,
1567
- ...t
1568
- }, this.textureManager = new De(o), this.sorter = new Pe();
1569
- let a = this.createChunks() || void 0;
1570
- a === null && console.warn("Visus: Could not create sorter chunks, bounding box might be invalid."), a = void 0, this.sorter.addEventListener("updated", this.onSorterUpdated), this.sorter.init(
1571
- this.textureManager.orderTexture,
1572
- this.splatData.positions,
1573
- a ?? void 0,
1574
- !this.options.keepSplatData
1575
- ), this.material.setTransformA(this.textureManager.transformA), this.material.setTransformB(this.textureManager.transformB), this.material.setColorTexture(this.textureManager.colorTexture), this.material.setOrderTexture(this.textureManager.orderTexture), this.material.setNumSplats(0), this.geometry.boundingBox = o.boundingBox.toBox3(), this.geometry.boundingSphere = new l.Sphere(), this.geometry.boundingBox.getBoundingSphere(this.geometry.boundingSphere), this.options.keepSplatData || (this.splatData = null);
2191
+ this.geometry = a, this.material = s, this.options = { autoSort: !0, ...r }, this.splatData = t, this.frustumCulled = !1, this.sorter = new At(), this.textureManager = new kt(t);
2192
+ let o = this.createChunks() || void 0;
2193
+ o === null && console.warn("Visus: Could not create sorter chunks, bounding box might be invalid."), o = void 0, this.sorter.addEventListener("updated", this.onSorterUpdated), this.sorter.init(this.textureManager.orderTexture, this.splatData.centers, o ?? void 0, !this.options.keepSplatData), this.material.setRanges(t.ranges), this.material.setTexWidth(t.textureWidth), this.material.setPackedColor(this.textureManager.packedColor), this.material.setOrderTexture(this.textureManager.orderTexture), this.material.setPackedGeometry(this.textureManager.packedGeometry), this.material.setNumSplats(0), this.geometry.boundingBox = t.boundingBox.toBox3(), this.geometry.boundingSphere = new h.Sphere(), this.geometry.boundingBox.getBoundingSphere(this.geometry.boundingSphere), this.options.keepSplatData || (this.splatData = null);
1576
2194
  }
1577
2195
  /**
1578
2196
  * Creates the instanced geometry for rendering splats.
@@ -1580,8 +2198,8 @@ const se = class se extends l.Mesh {
1580
2198
  * @param instanceSize Number of splats per instance.
1581
2199
  * @returns InstancedBufferGeometry
1582
2200
  */
1583
- static createInstancedGeometry(o, t) {
1584
- const r = Math.ceil(o / t), n = new l.BufferGeometry(), a = new Float32Array([
2201
+ static createInstancedGeometry(t, r) {
2202
+ const s = Math.ceil(t / r), a = new h.BufferGeometry(), o = new Float32Array([
1585
2203
  // x, y, splat_index_in_instance
1586
2204
  -1,
1587
2205
  -1,
@@ -1595,24 +2213,24 @@ const se = class se extends l.Mesh {
1595
2213
  -1,
1596
2214
  1,
1597
2215
  0
1598
- ]), i = new Uint16Array([0, 1, 2, 0, 2, 3]), u = new Float32Array(4 * 3 * t);
1599
- for (let h = 0; h < t; h++) {
1600
- const b = h * 4 * 3;
1601
- for (let S = 0; S < 4; S++)
1602
- u[b + S * 3 + 0] = a[S * 3 + 0], u[b + S * 3 + 1] = a[S * 3 + 1], u[b + S * 3 + 2] = h;
2216
+ ]), i = new Uint16Array([0, 1, 2, 0, 2, 3]), m = new Float32Array(4 * 3 * r);
2217
+ for (let u = 0; u < r; u++) {
2218
+ const x = u * 4 * 3;
2219
+ for (let g = 0; g < 4; g++)
2220
+ m[x + g * 3 + 0] = o[g * 3 + 0], m[x + g * 3 + 1] = o[g * 3 + 1], m[x + g * 3 + 2] = u;
1603
2221
  }
1604
- const w = new Uint32Array(6 * t);
1605
- for (let h = 0; h < t; h++) {
1606
- const b = h * 6, S = h * 4;
1607
- w[b + 0] = i[0] + S, w[b + 1] = i[1] + S, w[b + 2] = i[2] + S, w[b + 3] = i[3] + S, w[b + 4] = i[4] + S, w[b + 5] = i[5] + S;
2222
+ const f = new Uint32Array(6 * r);
2223
+ for (let u = 0; u < r; u++) {
2224
+ const x = u * 6, g = u * 4;
2225
+ f[x + 0] = i[0] + g, f[x + 1] = i[1] + g, f[x + 2] = i[2] + g, f[x + 3] = i[3] + g, f[x + 4] = i[4] + g, f[x + 5] = i[5] + g;
1608
2226
  }
1609
- n.setAttribute("position", new l.BufferAttribute(u, 3)), n.setIndex(new l.BufferAttribute(w, 1));
1610
- const C = new l.InstancedBufferGeometry();
1611
- C.index = n.index, C.setAttribute("position", n.getAttribute("position"));
1612
- const _ = new Uint32Array(r);
1613
- for (let h = 0; h < r; h++)
1614
- _[h] = h * t;
1615
- return C.setAttribute("splatInstanceIndex", new l.InstancedBufferAttribute(_, 1, !1)), C.instanceCount = 0, C;
2227
+ a.setAttribute("position", new h.BufferAttribute(m, 3)), a.setIndex(new h.BufferAttribute(f, 1));
2228
+ const y = new h.InstancedBufferGeometry();
2229
+ y.index = a.index, y.setAttribute("position", a.getAttribute("position"));
2230
+ const l = new Uint32Array(s);
2231
+ for (let u = 0; u < s; u++)
2232
+ l[u] = u * r;
2233
+ return y.setAttribute("splatInstanceIndex", new h.InstancedBufferAttribute(l, 1, !1)), y.instanceCount = 0, y;
1616
2234
  }
1617
2235
  /**
1618
2236
  * Create chunks data (bounding box min/max) for the sorter.
@@ -1621,14 +2239,14 @@ const se = class se extends l.Mesh {
1621
2239
  createChunks() {
1622
2240
  if (!this.splatData)
1623
2241
  return null;
1624
- const o = this.splatData.boundingBox;
1625
- return o.min.x === 1 / 0 || o.max.x === -1 / 0 ? null : new Float32Array([
1626
- o.min.x,
1627
- o.min.y,
1628
- o.min.z,
1629
- o.max.x,
1630
- o.max.y,
1631
- o.max.z
2242
+ const t = this.splatData.boundingBox;
2243
+ return t.min.x === 1 / 0 || t.max.x === -1 / 0 ? null : new Float32Array([
2244
+ t.min.x,
2245
+ t.min.y,
2246
+ t.min.z,
2247
+ t.max.x,
2248
+ t.max.y,
2249
+ t.max.z
1632
2250
  ]);
1633
2251
  }
1634
2252
  /**
@@ -1636,17 +2254,17 @@ const se = class se extends l.Mesh {
1636
2254
  * @param width Viewport width
1637
2255
  * @param height Viewport height
1638
2256
  */
1639
- updateViewport(o, t) {
1640
- o === this._vpW && t === this._vpH || (this._vpW = o, this._vpH = t, this.material.updateViewport(o, t));
2257
+ updateViewport(t, r) {
2258
+ t === this._vpW && r === this._vpH || (this._vpW = t, this._vpH = r, this.material.updateViewport(t, r));
1641
2259
  }
1642
2260
  /**
1643
2261
  * Sorts splats based on camera position and direction.
1644
2262
  * @param camera The camera to sort against.
1645
2263
  */
1646
- sort(o) {
1647
- o.getWorldPosition(this._camPosW), o.getWorldDirection(this._camDirW), this.invModelMatrix.copy(this.matrixWorld).invert(), this._camPosL.copy(this._camPosW).applyMatrix4(this.invModelMatrix), this._camDirL.copy(this._camDirW).transformDirection(this.invModelMatrix);
1648
- const t = this.lastCameraPositionLocal.distanceToSquared(this._camPosL) > 1e-6, r = this.lastCameraDirectionLocal.dot(this._camDirL) < 0.999;
1649
- this.options.autoSort && (t || r) && (this.lastCameraPositionLocal.copy(this._camPosL), this.lastCameraDirectionLocal.copy(this._camDirL), this.sorter.setCamera(this._camPosL, this._camDirL));
2264
+ sort(t) {
2265
+ t.getWorldPosition(this._camPosW), t.getWorldDirection(this._camDirW), this.invModelMatrix.copy(this.matrixWorld).invert(), this._camPosL.copy(this._camPosW).applyMatrix4(this.invModelMatrix), this._camDirL.copy(this._camDirW).transformDirection(this.invModelMatrix);
2266
+ const r = this.lastCameraPositionLocal.distanceToSquared(this._camPosL) > 1e-6, s = this.lastCameraDirectionLocal.dot(this._camDirL) < 0.999;
2267
+ this.options.autoSort && (r || s) && (this.lastCameraPositionLocal.copy(this._camPosL), this.lastCameraDirectionLocal.copy(this._camDirL), this.sorter.setCamera(this._camPosL, this._camDirL));
1650
2268
  }
1651
2269
  /**
1652
2270
  * THREE.js hook called before rendering the object.
@@ -1657,8 +2275,8 @@ const se = class se extends l.Mesh {
1657
2275
  */
1658
2276
  // prettier-ignore
1659
2277
  // @ts-expect-error scene is not used
1660
- onBeforeRender(o, t, r) {
1661
- this.sort(r), o.getSize(this._size), this.updateViewport(this._size.x, this._size.y);
2278
+ onBeforeRender(t, r, s) {
2279
+ this.sort(s), t.getSize(this._size), this.updateViewport(this._size.x, this._size.y);
1662
2280
  }
1663
2281
  /**
1664
2282
  * Dispose of resources
@@ -1668,39 +2286,51 @@ const se = class se extends l.Mesh {
1668
2286
  }
1669
2287
  };
1670
2288
  /** Number of splats combined into a single instanced draw call. */
1671
- f(se, "INSTANCE_SIZE", 128);
1672
- let de = se;
1673
- const le = /* @__PURE__ */ new Map(), He = ({
1674
- plyUrl: x,
1675
- debug: e = !1,
1676
- splatOptions: o = {},
1677
- ...t
2289
+ M(de, "INSTANCE_SIZE", 128);
2290
+ let Te = de;
2291
+ const ve = /* @__PURE__ */ new Map(), Ft = ({
2292
+ url: n,
2293
+ type: e,
2294
+ debug: t = !1,
2295
+ splatOptions: r = {},
2296
+ ...s
1678
2297
  }) => {
1679
- e && console.debug("SPLAT: rendering", { plyUrl: x, splatOptions: o, meshProps: t });
1680
- const [r, n] = Ce(null), a = Ae(null);
1681
- return Te(() => {
1682
- const i = we(x, o);
1683
- return je(x, o).then(
1684
- (u) => {
1685
- n(u);
2298
+ if (!n) throw new Error('Splat component requires either "url" or "plyUrl" prop');
2299
+ const a = Tt(n, e);
2300
+ t && console.debug("SPLAT: rendering", { url: n, type: a, splatOptions: r, meshProps: s });
2301
+ const [o, i] = Xe(null), m = Ze(null);
2302
+ return Je(() => {
2303
+ const f = Ne(n, a, r);
2304
+ return _t(n, a, r).then(
2305
+ (y) => {
2306
+ i(y);
1686
2307
  }
1687
2308
  ), () => {
1688
- e && console.debug("SPLAT: releasing mesh for", x), We(i);
2309
+ t && console.debug("SPLAT: releasing mesh for", n), zt(f);
1689
2310
  };
1690
- }, [x, o, e]), r ? /* @__PURE__ */ Ie.jsx("primitive", { ref: a, object: r, ...t }) : null;
1691
- }, we = (x, e) => `${x}:${JSON.stringify(e)}`, je = async (x, e) => {
1692
- const o = we(x, e), t = le.get(o);
1693
- if (t)
1694
- return t.refCount++, t.mesh;
1695
- const n = await new ze().loadAsync(x), a = new de(n, e);
1696
- return le.set(o, { mesh: a, refCount: 1 }), a;
2311
+ }, [n, a, r, t]), o ? /* @__PURE__ */ tt.jsx("primitive", { ref: m, object: o, ...s }) : null;
2312
+ }, Rt = (n) => {
2313
+ const e = n.toLowerCase();
2314
+ return e.endsWith(".ply") ? "ply" : e.endsWith(".sogs") || e.endsWith(".zip") || e.endsWith(".json") ? "sogs" : null;
2315
+ }, Tt = (n, e) => {
2316
+ if (e) return e;
2317
+ const t = Rt(n);
2318
+ if (t) return t;
2319
+ throw new Error(`Cannot determine file type from URL: "${n}". `);
2320
+ }, Ne = (n, e, t) => `${n}:${e}:${JSON.stringify(t)}`, _t = async (n, e, t) => {
2321
+ const r = Ne(n, e, t), s = ve.get(r);
2322
+ if (s)
2323
+ return s.refCount++, s.mesh;
2324
+ const o = await (e === "ply" ? new st() : new St()).loadAsync(n), i = new Te(o, t);
2325
+ return ve.set(r, { mesh: i, refCount: 1 }), i;
1697
2326
  };
1698
- function We(x) {
1699
- const e = le.get(x);
1700
- e && (e.refCount--, e.refCount <= 0 && (e.mesh.dispose(), le.delete(x)));
2327
+ function zt(n) {
2328
+ const e = ve.get(n);
2329
+ e && (e.refCount--, e.refCount <= 0 && (e.mesh.dispose(), ve.delete(n)));
1701
2330
  }
1702
2331
  export {
1703
- ze as PlyLoader,
1704
- He as Splat,
1705
- de as SplatMesh
2332
+ st as PlyLoader,
2333
+ St as SogsLoader,
2334
+ Ft as Splat,
2335
+ Te as SplatMesh
1706
2336
  };