@speridlabs/visus 0.3.0 → 1.0.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/main.umd.js +63 -59
- package/dist/react.es.js +525 -516
- package/package.json +1 -1
- package/dist/main.d.ts +0 -320
- package/dist/main.es.js +0 -1301
package/dist/react.es.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
var me = Object.defineProperty;
|
|
2
|
-
var xe = (
|
|
3
|
-
var
|
|
4
|
-
import ye, { useRef as
|
|
5
|
-
import {
|
|
2
|
+
var xe = (M, e, s) => e in M ? me(M, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : M[e] = s;
|
|
3
|
+
var g = (M, e, s) => xe(M, typeof e != "symbol" ? e + "" : e, s);
|
|
4
|
+
import ye, { useRef as ve, useMemo as ge, useEffect as we } from "react";
|
|
5
|
+
import { useLoader as be } from "@react-three/fiber";
|
|
6
6
|
import * as i from "three";
|
|
7
7
|
var se = { exports: {} }, te = {};
|
|
8
8
|
/**
|
|
@@ -18,19 +18,19 @@ var ue;
|
|
|
18
18
|
function Se() {
|
|
19
19
|
if (ue) return te;
|
|
20
20
|
ue = 1;
|
|
21
|
-
var
|
|
22
|
-
function s(
|
|
21
|
+
var M = Symbol.for("react.transitional.element"), e = Symbol.for("react.fragment");
|
|
22
|
+
function s(n, r, t) {
|
|
23
23
|
var a = null;
|
|
24
|
-
if (t !== void 0 && (a = "" + t),
|
|
24
|
+
if (t !== void 0 && (a = "" + t), r.key !== void 0 && (a = "" + r.key), "key" in r) {
|
|
25
25
|
t = {};
|
|
26
|
-
for (var c in
|
|
27
|
-
c !== "key" && (t[c] =
|
|
28
|
-
} else t =
|
|
29
|
-
return
|
|
30
|
-
$$typeof:
|
|
31
|
-
type:
|
|
26
|
+
for (var c in r)
|
|
27
|
+
c !== "key" && (t[c] = r[c]);
|
|
28
|
+
} else t = r;
|
|
29
|
+
return r = t.ref, {
|
|
30
|
+
$$typeof: M,
|
|
31
|
+
type: n,
|
|
32
32
|
key: a,
|
|
33
|
-
ref:
|
|
33
|
+
ref: r !== void 0 ? r : null,
|
|
34
34
|
props: t
|
|
35
35
|
};
|
|
36
36
|
}
|
|
@@ -46,18 +46,18 @@ var re = {};
|
|
|
46
46
|
* This source code is licensed under the MIT license found in the
|
|
47
47
|
* LICENSE file in the root directory of this source tree.
|
|
48
48
|
*/
|
|
49
|
-
var
|
|
49
|
+
var fe;
|
|
50
50
|
function Te() {
|
|
51
|
-
return
|
|
52
|
-
function
|
|
53
|
-
if (
|
|
54
|
-
if (typeof
|
|
55
|
-
return
|
|
56
|
-
if (typeof
|
|
57
|
-
switch (
|
|
58
|
-
case
|
|
51
|
+
return fe || (fe = 1, process.env.NODE_ENV !== "production" && function() {
|
|
52
|
+
function M(o) {
|
|
53
|
+
if (o == null) return null;
|
|
54
|
+
if (typeof o == "function")
|
|
55
|
+
return o.$$typeof === w ? null : o.displayName || o.name || null;
|
|
56
|
+
if (typeof o == "string") return o;
|
|
57
|
+
switch (o) {
|
|
58
|
+
case T:
|
|
59
59
|
return "Fragment";
|
|
60
|
-
case
|
|
60
|
+
case q:
|
|
61
61
|
return "Profiler";
|
|
62
62
|
case O:
|
|
63
63
|
return "StrictMode";
|
|
@@ -65,232 +65,232 @@ function Te() {
|
|
|
65
65
|
return "Suspense";
|
|
66
66
|
case D:
|
|
67
67
|
return "SuspenseList";
|
|
68
|
-
case
|
|
68
|
+
case E:
|
|
69
69
|
return "Activity";
|
|
70
70
|
}
|
|
71
|
-
if (typeof
|
|
72
|
-
switch (typeof
|
|
71
|
+
if (typeof o == "object")
|
|
72
|
+
switch (typeof o.tag == "number" && console.error(
|
|
73
73
|
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
|
|
74
|
-
),
|
|
75
|
-
case
|
|
74
|
+
), o.$$typeof) {
|
|
75
|
+
case h:
|
|
76
76
|
return "Portal";
|
|
77
|
-
case
|
|
78
|
-
return (
|
|
77
|
+
case j:
|
|
78
|
+
return (o.displayName || "Context") + ".Provider";
|
|
79
79
|
case W:
|
|
80
|
-
return (
|
|
80
|
+
return (o._context.displayName || "Context") + ".Consumer";
|
|
81
81
|
case H:
|
|
82
|
-
var
|
|
83
|
-
return
|
|
82
|
+
var d = o.render;
|
|
83
|
+
return o = o.displayName, o || (o = d.displayName || d.name || "", o = o !== "" ? "ForwardRef(" + o + ")" : "ForwardRef"), o;
|
|
84
84
|
case k:
|
|
85
|
-
return
|
|
86
|
-
case
|
|
87
|
-
|
|
85
|
+
return d = o.displayName || null, d !== null ? d : M(o.type) || "Memo";
|
|
86
|
+
case B:
|
|
87
|
+
d = o._payload, o = o._init;
|
|
88
88
|
try {
|
|
89
|
-
return
|
|
89
|
+
return M(o(d));
|
|
90
90
|
} catch {
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
return null;
|
|
94
94
|
}
|
|
95
|
-
function e(
|
|
96
|
-
return "" +
|
|
95
|
+
function e(o) {
|
|
96
|
+
return "" + o;
|
|
97
97
|
}
|
|
98
|
-
function s(
|
|
98
|
+
function s(o) {
|
|
99
99
|
try {
|
|
100
|
-
e(
|
|
101
|
-
var
|
|
100
|
+
e(o);
|
|
101
|
+
var d = !1;
|
|
102
102
|
} catch {
|
|
103
|
-
|
|
103
|
+
d = !0;
|
|
104
104
|
}
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
var
|
|
108
|
-
return
|
|
109
|
-
|
|
105
|
+
if (d) {
|
|
106
|
+
d = console;
|
|
107
|
+
var A = d.error, z = typeof Symbol == "function" && Symbol.toStringTag && o[Symbol.toStringTag] || o.constructor.name || "Object";
|
|
108
|
+
return A.call(
|
|
109
|
+
d,
|
|
110
110
|
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
|
|
111
|
-
|
|
112
|
-
), e(
|
|
111
|
+
z
|
|
112
|
+
), e(o);
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
function o
|
|
116
|
-
if (
|
|
117
|
-
if (typeof
|
|
115
|
+
function n(o) {
|
|
116
|
+
if (o === T) return "<>";
|
|
117
|
+
if (typeof o == "object" && o !== null && o.$$typeof === B)
|
|
118
118
|
return "<...>";
|
|
119
119
|
try {
|
|
120
|
-
var
|
|
121
|
-
return
|
|
120
|
+
var d = M(o);
|
|
121
|
+
return d ? "<" + d + ">" : "<...>";
|
|
122
122
|
} catch {
|
|
123
123
|
return "<...>";
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
|
-
function
|
|
127
|
-
var
|
|
128
|
-
return
|
|
126
|
+
function r() {
|
|
127
|
+
var o = C.A;
|
|
128
|
+
return o === null ? null : o.getOwner();
|
|
129
129
|
}
|
|
130
130
|
function t() {
|
|
131
131
|
return Error("react-stack-top-frame");
|
|
132
132
|
}
|
|
133
|
-
function a(
|
|
134
|
-
if (
|
|
135
|
-
var
|
|
136
|
-
if (
|
|
133
|
+
function a(o) {
|
|
134
|
+
if (U.call(o, "key")) {
|
|
135
|
+
var d = Object.getOwnPropertyDescriptor(o, "key").get;
|
|
136
|
+
if (d && d.isReactWarning) return !1;
|
|
137
137
|
}
|
|
138
|
-
return
|
|
138
|
+
return o.key !== void 0;
|
|
139
139
|
}
|
|
140
|
-
function c(
|
|
141
|
-
function
|
|
140
|
+
function c(o, d) {
|
|
141
|
+
function A() {
|
|
142
142
|
y || (y = !0, console.error(
|
|
143
143
|
"%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)",
|
|
144
|
-
|
|
144
|
+
d
|
|
145
145
|
));
|
|
146
146
|
}
|
|
147
|
-
|
|
148
|
-
get:
|
|
147
|
+
A.isReactWarning = !0, Object.defineProperty(o, "key", {
|
|
148
|
+
get: A,
|
|
149
149
|
configurable: !0
|
|
150
150
|
});
|
|
151
151
|
}
|
|
152
152
|
function l() {
|
|
153
|
-
var
|
|
154
|
-
return
|
|
153
|
+
var o = M(this.type);
|
|
154
|
+
return _[o] || (_[o] = !0, console.error(
|
|
155
155
|
"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."
|
|
156
|
-
)),
|
|
156
|
+
)), o = this.props.ref, o !== void 0 ? o : null;
|
|
157
157
|
}
|
|
158
|
-
function m(
|
|
159
|
-
return
|
|
158
|
+
function m(o, d, A, z, N, f, P, F) {
|
|
159
|
+
return A = f.ref, o = {
|
|
160
160
|
$$typeof: x,
|
|
161
|
-
type:
|
|
162
|
-
key:
|
|
163
|
-
props:
|
|
161
|
+
type: o,
|
|
162
|
+
key: d,
|
|
163
|
+
props: f,
|
|
164
164
|
_owner: N
|
|
165
|
-
}, (
|
|
165
|
+
}, (A !== void 0 ? A : null) !== null ? Object.defineProperty(o, "ref", {
|
|
166
166
|
enumerable: !1,
|
|
167
167
|
get: l
|
|
168
|
-
}) : Object.defineProperty(
|
|
168
|
+
}) : Object.defineProperty(o, "ref", { enumerable: !1, value: null }), o._store = {}, Object.defineProperty(o._store, "validated", {
|
|
169
169
|
configurable: !1,
|
|
170
170
|
enumerable: !1,
|
|
171
171
|
writable: !0,
|
|
172
172
|
value: 0
|
|
173
|
-
}), Object.defineProperty(
|
|
173
|
+
}), Object.defineProperty(o, "_debugInfo", {
|
|
174
174
|
configurable: !1,
|
|
175
175
|
enumerable: !1,
|
|
176
176
|
writable: !0,
|
|
177
177
|
value: null
|
|
178
|
-
}), Object.defineProperty(
|
|
178
|
+
}), Object.defineProperty(o, "_debugStack", {
|
|
179
179
|
configurable: !1,
|
|
180
180
|
enumerable: !1,
|
|
181
181
|
writable: !0,
|
|
182
|
-
value:
|
|
183
|
-
}), Object.defineProperty(
|
|
182
|
+
value: P
|
|
183
|
+
}), Object.defineProperty(o, "_debugTask", {
|
|
184
184
|
configurable: !1,
|
|
185
185
|
enumerable: !1,
|
|
186
186
|
writable: !0,
|
|
187
|
-
value:
|
|
188
|
-
}), Object.freeze && (Object.freeze(
|
|
187
|
+
value: F
|
|
188
|
+
}), Object.freeze && (Object.freeze(o.props), Object.freeze(o)), o;
|
|
189
189
|
}
|
|
190
|
-
function
|
|
191
|
-
var u =
|
|
190
|
+
function S(o, d, A, z, N, f, P, F) {
|
|
191
|
+
var u = d.children;
|
|
192
192
|
if (u !== void 0)
|
|
193
|
-
if (
|
|
194
|
-
if (
|
|
195
|
-
for (
|
|
196
|
-
b(u[
|
|
193
|
+
if (z)
|
|
194
|
+
if (V(u)) {
|
|
195
|
+
for (z = 0; z < u.length; z++)
|
|
196
|
+
b(u[z]);
|
|
197
197
|
Object.freeze && Object.freeze(u);
|
|
198
198
|
} else
|
|
199
199
|
console.error(
|
|
200
200
|
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
|
|
201
201
|
);
|
|
202
202
|
else b(u);
|
|
203
|
-
if (
|
|
204
|
-
u =
|
|
205
|
-
var
|
|
206
|
-
return
|
|
203
|
+
if (U.call(d, "key")) {
|
|
204
|
+
u = M(o);
|
|
205
|
+
var I = Object.keys(d).filter(function(X) {
|
|
206
|
+
return X !== "key";
|
|
207
207
|
});
|
|
208
|
-
|
|
208
|
+
z = 0 < I.length ? "{key: someKey, " + I.join(": ..., ") + ": ...}" : "{key: someKey}", G[u + z] || (I = 0 < I.length ? "{" + I.join(": ..., ") + ": ...}" : "{}", console.error(
|
|
209
209
|
`A props object containing a "key" prop is being spread into JSX:
|
|
210
210
|
let props = %s;
|
|
211
211
|
<%s {...props} />
|
|
212
212
|
React keys must be passed directly to JSX without using spread:
|
|
213
213
|
let props = %s;
|
|
214
214
|
<%s key={someKey} {...props} />`,
|
|
215
|
-
|
|
215
|
+
z,
|
|
216
216
|
u,
|
|
217
|
-
|
|
217
|
+
I,
|
|
218
218
|
u
|
|
219
|
-
),
|
|
219
|
+
), G[u + z] = !0);
|
|
220
220
|
}
|
|
221
|
-
if (u = null,
|
|
222
|
-
|
|
223
|
-
for (var Y in
|
|
224
|
-
Y !== "key" && (
|
|
225
|
-
} else
|
|
221
|
+
if (u = null, A !== void 0 && (s(A), u = "" + A), a(d) && (s(d.key), u = "" + d.key), "key" in d) {
|
|
222
|
+
A = {};
|
|
223
|
+
for (var Y in d)
|
|
224
|
+
Y !== "key" && (A[Y] = d[Y]);
|
|
225
|
+
} else A = d;
|
|
226
226
|
return u && c(
|
|
227
|
-
|
|
228
|
-
typeof
|
|
227
|
+
A,
|
|
228
|
+
typeof o == "function" ? o.displayName || o.name || "Unknown" : o
|
|
229
229
|
), m(
|
|
230
|
-
|
|
230
|
+
o,
|
|
231
231
|
u,
|
|
232
|
-
|
|
232
|
+
f,
|
|
233
233
|
N,
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
234
|
+
r(),
|
|
235
|
+
A,
|
|
236
|
+
P,
|
|
237
|
+
F
|
|
238
238
|
);
|
|
239
239
|
}
|
|
240
|
-
function b(
|
|
241
|
-
typeof
|
|
240
|
+
function b(o) {
|
|
241
|
+
typeof o == "object" && o !== null && o.$$typeof === x && o._store && (o._store.validated = 1);
|
|
242
242
|
}
|
|
243
|
-
var p = ye, x = Symbol.for("react.transitional.element"),
|
|
243
|
+
var p = ye, x = Symbol.for("react.transitional.element"), h = Symbol.for("react.portal"), T = Symbol.for("react.fragment"), O = Symbol.for("react.strict_mode"), q = Symbol.for("react.profiler"), W = Symbol.for("react.consumer"), j = Symbol.for("react.context"), H = Symbol.for("react.forward_ref"), $ = Symbol.for("react.suspense"), D = Symbol.for("react.suspense_list"), k = Symbol.for("react.memo"), B = Symbol.for("react.lazy"), E = Symbol.for("react.activity"), w = Symbol.for("react.client.reference"), C = p.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, U = Object.prototype.hasOwnProperty, V = Array.isArray, v = console.createTask ? console.createTask : function() {
|
|
244
244
|
return null;
|
|
245
245
|
};
|
|
246
246
|
p = {
|
|
247
|
-
"react-stack-bottom-frame": function(
|
|
248
|
-
return
|
|
247
|
+
"react-stack-bottom-frame": function(o) {
|
|
248
|
+
return o();
|
|
249
249
|
}
|
|
250
250
|
};
|
|
251
|
-
var y,
|
|
251
|
+
var y, _ = {}, R = p["react-stack-bottom-frame"].bind(
|
|
252
252
|
p,
|
|
253
253
|
t
|
|
254
|
-
)(), L =
|
|
255
|
-
re.Fragment =
|
|
256
|
-
var
|
|
257
|
-
return
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
254
|
+
)(), L = v(n(t)), G = {};
|
|
255
|
+
re.Fragment = T, re.jsx = function(o, d, A, z, N) {
|
|
256
|
+
var f = 1e4 > C.recentlyCreatedOwnerStacks++;
|
|
257
|
+
return S(
|
|
258
|
+
o,
|
|
259
|
+
d,
|
|
260
|
+
A,
|
|
261
261
|
!1,
|
|
262
|
-
|
|
262
|
+
z,
|
|
263
263
|
N,
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
f ? Error("react-stack-top-frame") : R,
|
|
265
|
+
f ? v(n(o)) : L
|
|
266
266
|
);
|
|
267
|
-
}, re.jsxs = function(
|
|
268
|
-
var
|
|
269
|
-
return
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
267
|
+
}, re.jsxs = function(o, d, A, z, N) {
|
|
268
|
+
var f = 1e4 > C.recentlyCreatedOwnerStacks++;
|
|
269
|
+
return S(
|
|
270
|
+
o,
|
|
271
|
+
d,
|
|
272
|
+
A,
|
|
273
273
|
!0,
|
|
274
|
-
|
|
274
|
+
z,
|
|
275
275
|
N,
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
f ? Error("react-stack-top-frame") : R,
|
|
277
|
+
f ? v(n(o)) : L
|
|
278
278
|
);
|
|
279
279
|
};
|
|
280
280
|
}()), re;
|
|
281
281
|
}
|
|
282
|
-
var
|
|
282
|
+
var he;
|
|
283
283
|
function Ce() {
|
|
284
|
-
return
|
|
284
|
+
return he || (he = 1, process.env.NODE_ENV === "production" ? se.exports = Se() : se.exports = Te()), se.exports;
|
|
285
285
|
}
|
|
286
|
-
var
|
|
286
|
+
var Me = Ce();
|
|
287
287
|
class le {
|
|
288
288
|
constructor() {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
289
|
+
g(this, "min", new i.Vector3(1 / 0, 1 / 0, 1 / 0));
|
|
290
|
+
g(this, "max", new i.Vector3(-1 / 0, -1 / 0, -1 / 0));
|
|
291
|
+
g(this, "center", new i.Vector3());
|
|
292
292
|
/** Half extents (size/2) */
|
|
293
|
-
|
|
293
|
+
g(this, "halfExtents", new i.Vector3());
|
|
294
294
|
}
|
|
295
295
|
/**
|
|
296
296
|
* Reset the bounding box to its initial state
|
|
@@ -342,17 +342,17 @@ class le {
|
|
|
342
342
|
return e.min.copy(this.min), e.max.copy(this.max), e.center.copy(this.center), e.halfExtents.copy(this.halfExtents), e;
|
|
343
343
|
}
|
|
344
344
|
}
|
|
345
|
-
class
|
|
345
|
+
class Ae {
|
|
346
346
|
// TODO: there is no sh spherical harmonics
|
|
347
347
|
constructor(e = 0) {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
348
|
+
g(this, "numSplats", 0);
|
|
349
|
+
g(this, "positions");
|
|
350
|
+
g(this, "rotations");
|
|
351
|
+
g(this, "scales");
|
|
352
|
+
g(this, "colors");
|
|
353
|
+
g(this, "opacities");
|
|
354
|
+
g(this, "centers");
|
|
355
|
+
g(this, "boundingBox", new le());
|
|
356
356
|
this.numSplats = e, this.allocateBuffers(e);
|
|
357
357
|
}
|
|
358
358
|
allocateBuffers(e) {
|
|
@@ -367,13 +367,13 @@ class ze {
|
|
|
367
367
|
* @param color Color
|
|
368
368
|
* @param opacity Opacity value
|
|
369
369
|
*/
|
|
370
|
-
setSplat(e, s,
|
|
370
|
+
setSplat(e, s, n, r, t, a) {
|
|
371
371
|
if (e >= this.numSplats)
|
|
372
372
|
throw new Error(
|
|
373
373
|
`Splat index out of bounds: ${e} >= ${this.numSplats}`
|
|
374
374
|
);
|
|
375
|
-
const c = e * 3, l = e * 4, m = e * 3,
|
|
376
|
-
this.positions[c] = s.x, this.positions[c + 1] = s.y, this.positions[c + 2] = s.z, this.rotations[l] =
|
|
375
|
+
const c = e * 3, l = e * 4, m = e * 3, S = e * 3;
|
|
376
|
+
this.positions[c] = s.x, this.positions[c + 1] = s.y, this.positions[c + 2] = s.z, this.rotations[l] = n.x, this.rotations[l + 1] = n.y, this.rotations[l + 2] = n.z, this.rotations[l + 3] = n.w, this.scales[m] = r.x, this.scales[m + 1] = r.y, this.scales[m + 2] = r.z, this.colors[S] = t.r, this.colors[S + 1] = t.g, this.colors[S + 2] = t.b, this.opacities[e] = a, this.centers[c] = s.x, this.centers[c + 1] = s.y, this.centers[c + 2] = s.z;
|
|
377
377
|
}
|
|
378
378
|
/**
|
|
379
379
|
* Get a splat's data
|
|
@@ -385,7 +385,7 @@ class ze {
|
|
|
385
385
|
throw new Error(
|
|
386
386
|
`Splat index out of bounds: ${e} >= ${this.numSplats}`
|
|
387
387
|
);
|
|
388
|
-
const s = e * 3,
|
|
388
|
+
const s = e * 3, n = e * 4, r = e * 3, t = e * 3;
|
|
389
389
|
return {
|
|
390
390
|
position: new i.Vector3(
|
|
391
391
|
this.positions[s],
|
|
@@ -393,16 +393,16 @@ class ze {
|
|
|
393
393
|
this.positions[s + 2]
|
|
394
394
|
),
|
|
395
395
|
rotation: new i.Quaternion(
|
|
396
|
-
this.rotations[
|
|
397
|
-
this.rotations[
|
|
398
|
-
this.rotations[
|
|
399
|
-
this.rotations[
|
|
396
|
+
this.rotations[n],
|
|
397
|
+
this.rotations[n + 1],
|
|
398
|
+
this.rotations[n + 2],
|
|
399
|
+
this.rotations[n + 3]
|
|
400
400
|
),
|
|
401
401
|
// Convert log scale back to linear scale for external use
|
|
402
402
|
scale: new i.Vector3(
|
|
403
|
-
Math.exp(this.scales[
|
|
404
|
-
Math.exp(this.scales[
|
|
405
|
-
Math.exp(this.scales[
|
|
403
|
+
Math.exp(this.scales[r]),
|
|
404
|
+
Math.exp(this.scales[r + 1]),
|
|
405
|
+
Math.exp(this.scales[r + 2])
|
|
406
406
|
),
|
|
407
407
|
color: new i.Color(
|
|
408
408
|
this.colors[t],
|
|
@@ -420,11 +420,11 @@ class ze {
|
|
|
420
420
|
this.boundingBox.reset();
|
|
421
421
|
const e = new i.Vector3();
|
|
422
422
|
for (let s = 0; s < this.numSplats; s++) {
|
|
423
|
-
const
|
|
423
|
+
const n = s * 3;
|
|
424
424
|
e.set(
|
|
425
|
-
this.positions[
|
|
426
|
-
this.positions[
|
|
427
|
-
this.positions[
|
|
425
|
+
this.positions[n],
|
|
426
|
+
this.positions[n + 1],
|
|
427
|
+
this.positions[n + 2]
|
|
428
428
|
), this.boundingBox.expandByPoint(e);
|
|
429
429
|
}
|
|
430
430
|
return this.boundingBox;
|
|
@@ -439,15 +439,15 @@ class ze {
|
|
|
439
439
|
"position",
|
|
440
440
|
new i.BufferAttribute(this.positions, 3)
|
|
441
441
|
);
|
|
442
|
-
const s = new Float32Array(this.numSplats * 3),
|
|
442
|
+
const s = new Float32Array(this.numSplats * 3), n = new i.Quaternion(), r = new i.Euler();
|
|
443
443
|
for (let t = 0; t < this.numSplats; t++) {
|
|
444
444
|
const a = t * 4, c = t * 3;
|
|
445
|
-
|
|
445
|
+
n.set(
|
|
446
446
|
this.rotations[a],
|
|
447
447
|
this.rotations[a + 1],
|
|
448
448
|
this.rotations[a + 2],
|
|
449
449
|
this.rotations[a + 3]
|
|
450
|
-
),
|
|
450
|
+
), r.setFromQuaternion(n), s[c] = r.x, s[c + 1] = r.y, s[c + 2] = r.z;
|
|
451
451
|
}
|
|
452
452
|
return e.setAttribute(
|
|
453
453
|
"rotation",
|
|
@@ -464,7 +464,7 @@ class ze {
|
|
|
464
464
|
), e;
|
|
465
465
|
}
|
|
466
466
|
}
|
|
467
|
-
class
|
|
467
|
+
class Ee extends i.Loader {
|
|
468
468
|
/**
|
|
469
469
|
* Load a PLY file with Gaussian Splat data
|
|
470
470
|
* @param url URL of the PLY file
|
|
@@ -472,7 +472,7 @@ class ke extends i.Loader {
|
|
|
472
472
|
* @param onProgress Optional progress callback
|
|
473
473
|
* @param onError Optional error callback
|
|
474
474
|
*/
|
|
475
|
-
load(e, s,
|
|
475
|
+
load(e, s, n, r) {
|
|
476
476
|
const t = new i.FileLoader(this.manager);
|
|
477
477
|
t.setResponseType("arraybuffer"), t.setRequestHeader(this.requestHeader), t.setPath(this.path), t.setWithCredentials(this.withCredentials), t.load(
|
|
478
478
|
e,
|
|
@@ -483,11 +483,11 @@ class ke extends i.Loader {
|
|
|
483
483
|
s(c);
|
|
484
484
|
}
|
|
485
485
|
} catch (c) {
|
|
486
|
-
|
|
486
|
+
r ? r(c) : console.error(c), this.manager.itemError(e);
|
|
487
487
|
}
|
|
488
488
|
},
|
|
489
|
-
|
|
490
|
-
|
|
489
|
+
n,
|
|
490
|
+
r
|
|
491
491
|
);
|
|
492
492
|
}
|
|
493
493
|
/**
|
|
@@ -497,21 +497,21 @@ class ke extends i.Loader {
|
|
|
497
497
|
* @returns A Promise that resolves with the parsed SplatData
|
|
498
498
|
*/
|
|
499
499
|
loadAsync(e, s) {
|
|
500
|
-
return new Promise((
|
|
500
|
+
return new Promise((n, r) => {
|
|
501
501
|
const t = new i.FileLoader(this.manager);
|
|
502
502
|
t.setResponseType("arraybuffer"), t.setRequestHeader(this.requestHeader), t.setPath(this.path), t.setWithCredentials(this.withCredentials), t.load(
|
|
503
503
|
e,
|
|
504
504
|
(a) => {
|
|
505
505
|
try {
|
|
506
506
|
const c = this.parse(a);
|
|
507
|
-
|
|
507
|
+
n(c);
|
|
508
508
|
} catch (c) {
|
|
509
|
-
|
|
509
|
+
r(c), this.manager.itemError(e);
|
|
510
510
|
}
|
|
511
511
|
},
|
|
512
512
|
s,
|
|
513
513
|
(a) => {
|
|
514
|
-
|
|
514
|
+
r(a), this.manager.itemError(e);
|
|
515
515
|
}
|
|
516
516
|
);
|
|
517
517
|
});
|
|
@@ -522,44 +522,44 @@ class ke extends i.Loader {
|
|
|
522
522
|
* @returns Parsed SplatData
|
|
523
523
|
*/
|
|
524
524
|
parse(e) {
|
|
525
|
-
const s = new TextDecoder(),
|
|
525
|
+
const s = new TextDecoder(), n = new Uint8Array(e), r = [112, 108, 121, 10], t = `
|
|
526
526
|
end_header
|
|
527
527
|
`;
|
|
528
|
-
for (let
|
|
529
|
-
if (
|
|
528
|
+
for (let v = 0; v < r.length; v++)
|
|
529
|
+
if (n[v] !== r[v])
|
|
530
530
|
throw new Error("Invalid PLY file: Missing magic bytes");
|
|
531
531
|
let a = 0;
|
|
532
|
-
for (let
|
|
532
|
+
for (let v = 0; v < n.length - t.length; v++) {
|
|
533
533
|
let y = !0;
|
|
534
|
-
for (let
|
|
535
|
-
if (
|
|
534
|
+
for (let _ = 0; _ < t.length; _++)
|
|
535
|
+
if (n[v + _] !== t.charCodeAt(_)) {
|
|
536
536
|
y = !1;
|
|
537
537
|
break;
|
|
538
538
|
}
|
|
539
539
|
if (y) {
|
|
540
|
-
a =
|
|
540
|
+
a = v + t.length;
|
|
541
541
|
break;
|
|
542
542
|
}
|
|
543
543
|
}
|
|
544
544
|
if (a === 0)
|
|
545
545
|
throw new Error("Invalid PLY file: Could not find end of header");
|
|
546
546
|
const l = s.decode(
|
|
547
|
-
|
|
547
|
+
n.slice(0, a)
|
|
548
548
|
).split(`
|
|
549
549
|
`), m = [];
|
|
550
|
-
let
|
|
551
|
-
for (let
|
|
552
|
-
const y = l[
|
|
550
|
+
let S = null;
|
|
551
|
+
for (let v = 1; v < l.length; v++) {
|
|
552
|
+
const y = l[v].trim();
|
|
553
553
|
if (y === "" || y === "end_header") continue;
|
|
554
|
-
const
|
|
555
|
-
switch (
|
|
554
|
+
const _ = y.split(" ");
|
|
555
|
+
switch (_[0]) {
|
|
556
556
|
case "format":
|
|
557
|
-
|
|
557
|
+
S = _[1];
|
|
558
558
|
break;
|
|
559
559
|
case "element":
|
|
560
560
|
m.push({
|
|
561
|
-
name:
|
|
562
|
-
count: parseInt(
|
|
561
|
+
name: _[1],
|
|
562
|
+
count: parseInt(_[2], 10),
|
|
563
563
|
properties: []
|
|
564
564
|
});
|
|
565
565
|
break;
|
|
@@ -569,114 +569,113 @@ end_header
|
|
|
569
569
|
"Invalid PLY file: Property without element"
|
|
570
570
|
);
|
|
571
571
|
m[m.length - 1].properties.push({
|
|
572
|
-
type:
|
|
573
|
-
name:
|
|
572
|
+
type: _[1],
|
|
573
|
+
name: _[2],
|
|
574
574
|
storage: null
|
|
575
575
|
});
|
|
576
576
|
break;
|
|
577
577
|
}
|
|
578
578
|
}
|
|
579
|
-
if (
|
|
580
|
-
throw new Error(`Unsupported PLY format: ${
|
|
581
|
-
const b = m.find((
|
|
579
|
+
if (S !== "binary_little_endian")
|
|
580
|
+
throw new Error(`Unsupported PLY format: ${S}`);
|
|
581
|
+
const b = m.find((v) => v.name === "vertex");
|
|
582
582
|
if (!b)
|
|
583
583
|
throw new Error("Invalid PLY file: No vertex element found");
|
|
584
|
-
const p = new
|
|
585
|
-
let
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
584
|
+
const p = new Ae(b.count), x = new DataView(e);
|
|
585
|
+
let h = a;
|
|
586
|
+
const T = (v) => b.properties.findIndex((y) => y.name === v), O = T("x"), q = T("y"), W = T("z"), j = [
|
|
587
|
+
T("rot_0"),
|
|
588
|
+
T("rot_1"),
|
|
589
|
+
T("rot_2"),
|
|
590
|
+
T("rot_3")
|
|
591
591
|
], H = [
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
592
|
+
T("scale_0"),
|
|
593
|
+
T("scale_1"),
|
|
594
|
+
T("scale_2")
|
|
595
595
|
], $ = [
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
], D =
|
|
596
|
+
T("f_dc_0"),
|
|
597
|
+
T("f_dc_1"),
|
|
598
|
+
T("f_dc_2")
|
|
599
|
+
], D = T("opacity");
|
|
600
600
|
if ([
|
|
601
601
|
O,
|
|
602
|
-
|
|
602
|
+
q,
|
|
603
603
|
W,
|
|
604
|
-
...
|
|
604
|
+
...j,
|
|
605
605
|
...H,
|
|
606
606
|
...$,
|
|
607
607
|
D
|
|
608
|
-
].some((
|
|
608
|
+
].some((v) => v === -1))
|
|
609
609
|
throw new Error("Invalid PLY file: Missing required properties");
|
|
610
|
-
const
|
|
611
|
-
if (
|
|
612
|
-
const y = Math.exp(
|
|
610
|
+
const B = 0.28209479177387814, E = (v) => {
|
|
611
|
+
if (v > 0) return 1 / (1 + Math.exp(-v));
|
|
612
|
+
const y = Math.exp(v);
|
|
613
613
|
return y / (1 + y);
|
|
614
|
-
}, w = new i.Vector3(),
|
|
615
|
-
for (let
|
|
614
|
+
}, w = new i.Vector3(), C = new i.Quaternion(), U = new i.Vector3(), V = new i.Color();
|
|
615
|
+
for (let v = 0; v < b.count; v++) {
|
|
616
616
|
const y = [];
|
|
617
|
-
for (let
|
|
618
|
-
const
|
|
619
|
-
let
|
|
620
|
-
switch (
|
|
617
|
+
for (let R = 0; R < b.properties.length; R++) {
|
|
618
|
+
const G = b.properties[R].type;
|
|
619
|
+
let o;
|
|
620
|
+
switch (G) {
|
|
621
621
|
case "char":
|
|
622
|
-
|
|
622
|
+
o = x.getInt8(h), h += 1;
|
|
623
623
|
break;
|
|
624
624
|
case "uchar":
|
|
625
|
-
|
|
625
|
+
o = x.getUint8(h), h += 1;
|
|
626
626
|
break;
|
|
627
627
|
case "short":
|
|
628
|
-
|
|
628
|
+
o = x.getInt16(h, !0), h += 2;
|
|
629
629
|
break;
|
|
630
630
|
case "ushort":
|
|
631
|
-
|
|
631
|
+
o = x.getUint16(h, !0), h += 2;
|
|
632
632
|
break;
|
|
633
633
|
case "int":
|
|
634
|
-
|
|
634
|
+
o = x.getInt32(h, !0), h += 4;
|
|
635
635
|
break;
|
|
636
636
|
case "uint":
|
|
637
|
-
|
|
637
|
+
o = x.getUint32(h, !0), h += 4;
|
|
638
638
|
break;
|
|
639
639
|
case "float":
|
|
640
|
-
|
|
640
|
+
o = x.getFloat32(h, !0), h += 4;
|
|
641
641
|
break;
|
|
642
642
|
case "double":
|
|
643
|
-
|
|
643
|
+
o = x.getFloat64(h, !0), h += 8;
|
|
644
644
|
break;
|
|
645
645
|
default:
|
|
646
|
-
throw new Error(`Unsupported property type: ${
|
|
646
|
+
throw new Error(`Unsupported property type: ${G}`);
|
|
647
647
|
}
|
|
648
|
-
y.push(
|
|
648
|
+
y.push(o);
|
|
649
649
|
}
|
|
650
650
|
w.set(
|
|
651
651
|
y[O],
|
|
652
|
-
y[
|
|
652
|
+
y[q],
|
|
653
653
|
y[W]
|
|
654
|
-
),
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
y[
|
|
659
|
-
y[
|
|
660
|
-
|
|
661
|
-
).normalize(), V.set(
|
|
654
|
+
), C.set(
|
|
655
|
+
y[j[1]],
|
|
656
|
+
// PLY stores rot 1,2,3,0 (x,y,z,w)
|
|
657
|
+
y[j[2]],
|
|
658
|
+
y[j[3]],
|
|
659
|
+
y[j[0]]
|
|
660
|
+
).normalize(), C.w < 0 && (C.x = -C.x, C.y = -C.y, C.z = -C.z, C.w = -C.w), U.set(
|
|
662
661
|
y[H[0]],
|
|
663
662
|
// Read directly assuming it's log scale
|
|
664
663
|
y[H[1]],
|
|
665
664
|
y[H[2]]
|
|
666
|
-
),
|
|
667
|
-
0.5 + y[$[0]] *
|
|
668
|
-
0.5 + y[$[1]] *
|
|
669
|
-
0.5 + y[$[2]] *
|
|
670
|
-
),
|
|
671
|
-
const
|
|
665
|
+
), V.set(
|
|
666
|
+
0.5 + y[$[0]] * B,
|
|
667
|
+
0.5 + y[$[1]] * B,
|
|
668
|
+
0.5 + y[$[2]] * B
|
|
669
|
+
), V.r = Math.max(0, Math.min(1, V.r)), V.g = Math.max(0, Math.min(1, V.g)), V.b = Math.max(0, Math.min(1, V.b));
|
|
670
|
+
const _ = E(y[D]);
|
|
672
671
|
p.setSplat(
|
|
673
|
-
|
|
672
|
+
v,
|
|
674
673
|
w,
|
|
675
|
-
|
|
676
|
-
V,
|
|
677
|
-
// Pass log scale directly
|
|
674
|
+
C,
|
|
678
675
|
U,
|
|
679
|
-
|
|
676
|
+
// Pass log scale directly
|
|
677
|
+
V,
|
|
678
|
+
_
|
|
680
679
|
);
|
|
681
680
|
}
|
|
682
681
|
return p.calculateBoundingBox(), p;
|
|
@@ -685,15 +684,15 @@ end_header
|
|
|
685
684
|
class _e extends i.EventDispatcher {
|
|
686
685
|
constructor() {
|
|
687
686
|
super();
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
687
|
+
g(this, "worker");
|
|
688
|
+
g(this, "centers", null);
|
|
689
|
+
g(this, "orderTexture", null);
|
|
691
690
|
/** Bounding box data for optimization */
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
const s = this.createWorkerCode(),
|
|
696
|
-
this.worker = new Worker(URL.createObjectURL(
|
|
691
|
+
g(this, "chunks", null);
|
|
692
|
+
g(this, "lastCameraPosition", new i.Vector3());
|
|
693
|
+
g(this, "lastCameraDirection", new i.Vector3());
|
|
694
|
+
const s = this.createWorkerCode(), n = new Blob([s], { type: "application/javascript" });
|
|
695
|
+
this.worker = new Worker(URL.createObjectURL(n)), this.worker.onmessage = this.onWorkerMessage.bind(this);
|
|
697
696
|
}
|
|
698
697
|
/**
|
|
699
698
|
* Handles messages received from the sorting worker.
|
|
@@ -702,14 +701,14 @@ class _e extends i.EventDispatcher {
|
|
|
702
701
|
onWorkerMessage(s) {
|
|
703
702
|
if (!this.orderTexture || !this.orderTexture.image)
|
|
704
703
|
return console.error("SplatSorter: Order texture not initialized!");
|
|
705
|
-
const { order:
|
|
704
|
+
const { order: n, count: r } = s.data, t = this.orderTexture.image.data;
|
|
706
705
|
if (!(t instanceof Uint32Array))
|
|
707
706
|
return console.error(
|
|
708
707
|
"SplatSorter: Order texture data is not a Uint32Array!"
|
|
709
708
|
);
|
|
710
|
-
t.set(new Uint32Array(
|
|
709
|
+
t.set(new Uint32Array(n)), this.orderTexture.needsUpdate = !0;
|
|
711
710
|
const a = t.buffer.slice(0), c = { order: a };
|
|
712
|
-
this.worker.postMessage(c, [a]), this.dispatchEvent({ type: "updated", count:
|
|
711
|
+
this.worker.postMessage(c, [a]), this.dispatchEvent({ type: "updated", count: r });
|
|
713
712
|
}
|
|
714
713
|
/**
|
|
715
714
|
* Initializes the sorter with necessary data and textures.
|
|
@@ -717,31 +716,31 @@ class _e extends i.EventDispatcher {
|
|
|
717
716
|
* @param centers A Float32Array containing the center position (x, y, z) for each splat.
|
|
718
717
|
* @param chunks Optional: A Float32Array containing bounding box chunk data [minX, minY, minZ, maxX, maxY, maxZ, ...] for optimization.
|
|
719
718
|
*/
|
|
720
|
-
init(s,
|
|
719
|
+
init(s, n, r) {
|
|
721
720
|
if (!s || !(s.image.data instanceof Uint32Array))
|
|
722
721
|
throw new Error("SplatSorter: Invalid orderTexture provided. Must be DataTexture with Uint32Array data.");
|
|
723
|
-
if (!
|
|
722
|
+
if (!n || n.length % 3 !== 0)
|
|
724
723
|
throw new Error("SplatSorter: Invalid centers array provided. Length must be multiple of 3.");
|
|
725
|
-
if (s.image.data.length <
|
|
724
|
+
if (s.image.data.length < n.length / 3)
|
|
726
725
|
throw new Error("SplatSorter: orderTexture data buffer is smaller than the number of splats.");
|
|
727
|
-
const t =
|
|
728
|
-
this.orderTexture = s, this.centers =
|
|
726
|
+
const t = n.length / 3;
|
|
727
|
+
this.orderTexture = s, this.centers = n.slice();
|
|
729
728
|
const a = this.orderTexture.image.data;
|
|
730
729
|
for (let b = 0; b < t; b++) a[b] = b;
|
|
731
730
|
this.orderTexture.needsUpdate = !0;
|
|
732
731
|
const c = a.buffer.slice(0), l = this.centers.buffer.slice(0), m = {
|
|
733
732
|
order: c,
|
|
734
733
|
centers: l
|
|
735
|
-
},
|
|
734
|
+
}, S = [
|
|
736
735
|
c,
|
|
737
736
|
l
|
|
738
737
|
];
|
|
739
|
-
if (
|
|
740
|
-
this.chunks =
|
|
738
|
+
if (r) {
|
|
739
|
+
this.chunks = r.slice();
|
|
741
740
|
const b = this.chunks.buffer.slice(0);
|
|
742
|
-
m.chunks = b,
|
|
741
|
+
m.chunks = b, S.push(b);
|
|
743
742
|
}
|
|
744
|
-
this.worker.postMessage(m,
|
|
743
|
+
this.worker.postMessage(m, S);
|
|
745
744
|
}
|
|
746
745
|
/**
|
|
747
746
|
* Applies an optional mapping to filter or reorder splats before sorting.
|
|
@@ -753,14 +752,14 @@ class _e extends i.EventDispatcher {
|
|
|
753
752
|
return console.warn(
|
|
754
753
|
"SplatSorter: Cannot set mapping before initialization."
|
|
755
754
|
);
|
|
756
|
-
let
|
|
757
|
-
const
|
|
755
|
+
let n;
|
|
756
|
+
const r = [];
|
|
758
757
|
if (!s) {
|
|
759
758
|
const l = this.centers.buffer.slice(0);
|
|
760
|
-
return
|
|
759
|
+
return n = {
|
|
761
760
|
centers: l,
|
|
762
761
|
mapping: null
|
|
763
|
-
},
|
|
762
|
+
}, r.push(l), this.worker.postMessage(n, r);
|
|
764
763
|
}
|
|
765
764
|
const t = new Float32Array(s.length * 3);
|
|
766
765
|
for (let l = 0; l < s.length; l++) {
|
|
@@ -771,28 +770,28 @@ class _e extends i.EventDispatcher {
|
|
|
771
770
|
);
|
|
772
771
|
continue;
|
|
773
772
|
}
|
|
774
|
-
const
|
|
775
|
-
t[b + 0] = this.centers[
|
|
773
|
+
const S = m * 3, b = l * 3;
|
|
774
|
+
t[b + 0] = this.centers[S + 0], t[b + 1] = this.centers[S + 1], t[b + 2] = this.centers[S + 2];
|
|
776
775
|
}
|
|
777
776
|
const a = t.buffer.slice(0), c = s.buffer.slice(0);
|
|
778
|
-
|
|
777
|
+
n = {
|
|
779
778
|
centers: a,
|
|
780
779
|
mapping: c
|
|
781
|
-
},
|
|
780
|
+
}, r.push(a, c), this.worker.postMessage(n, r);
|
|
782
781
|
}
|
|
783
782
|
/**
|
|
784
783
|
* Updates the camera parameters used for sorting.
|
|
785
784
|
* @param position The camera's position in the sorter's local coordinate space.
|
|
786
785
|
* @param direction The camera's forward direction in the sorter's local coordinate space.
|
|
787
786
|
*/
|
|
788
|
-
setCamera(s,
|
|
789
|
-
const
|
|
790
|
-
if (!
|
|
787
|
+
setCamera(s, n) {
|
|
788
|
+
const r = this.lastCameraPosition.distanceToSquared(s) > 1e-7, t = this.lastCameraDirection.dot(n) < 0.9999;
|
|
789
|
+
if (!r && !t)
|
|
791
790
|
return;
|
|
792
|
-
this.lastCameraPosition.copy(s), this.lastCameraDirection.copy(
|
|
791
|
+
this.lastCameraPosition.copy(s), this.lastCameraDirection.copy(n);
|
|
793
792
|
const a = {
|
|
794
793
|
cameraPosition: { x: s.x, y: s.y, z: s.z },
|
|
795
|
-
cameraDirection: { x:
|
|
794
|
+
cameraDirection: { x: n.x, y: n.y, z: n.z }
|
|
796
795
|
};
|
|
797
796
|
this.worker.postMessage(a);
|
|
798
797
|
}
|
|
@@ -808,49 +807,49 @@ class _e extends i.EventDispatcher {
|
|
|
808
807
|
*/
|
|
809
808
|
createWorkerCode() {
|
|
810
809
|
return `(${(function() {
|
|
811
|
-
let
|
|
812
|
-
const
|
|
813
|
-
let
|
|
814
|
-
const O = 32,
|
|
810
|
+
let n = null, r = null, t = null, a = null, c = null, l = null, m = !1;
|
|
811
|
+
const S = { x: 0, y: 0, z: 0 }, b = { x: 0, y: 0, z: 0 }, p = { x: 0, y: 0, z: 0 }, x = { x: 0, y: 0, z: 0 };
|
|
812
|
+
let h = null, T = null;
|
|
813
|
+
const O = 32, q = new Array(O).fill(0), W = new Array(O).fill(0), j = new Array(O).fill(0), H = (D, k, B) => {
|
|
815
814
|
for (; D <= k; ) {
|
|
816
|
-
const
|
|
817
|
-
if (w > 0) D =
|
|
818
|
-
else if (w < 0) k =
|
|
819
|
-
else return
|
|
815
|
+
const E = k + D >> 1, w = B(E);
|
|
816
|
+
if (w > 0) D = E + 1;
|
|
817
|
+
else if (w < 0) k = E - 1;
|
|
818
|
+
else return E;
|
|
820
819
|
}
|
|
821
820
|
return ~D;
|
|
822
821
|
}, $ = () => {
|
|
823
|
-
if (!
|
|
822
|
+
if (!n || !r || !c || !l)
|
|
824
823
|
return;
|
|
825
|
-
if (
|
|
826
|
-
const
|
|
827
|
-
order:
|
|
824
|
+
if (r.length === 0) {
|
|
825
|
+
const f = {
|
|
826
|
+
order: n.buffer,
|
|
828
827
|
count: 0
|
|
829
828
|
};
|
|
830
|
-
self.postMessage(
|
|
829
|
+
self.postMessage(f, [n.buffer]), n = null;
|
|
831
830
|
return;
|
|
832
831
|
}
|
|
833
|
-
const D = c.x, k = c.y,
|
|
834
|
-
if (!m && !
|
|
832
|
+
const D = c.x, k = c.y, B = c.z, E = l.x, w = l.y, C = l.z, U = 1e-4, V = Math.abs(D - S.x) > U || Math.abs(k - S.y) > U || Math.abs(B - S.z) > U, v = Math.abs(E - b.x) > U || Math.abs(w - b.y) > U || Math.abs(C - b.z) > U;
|
|
833
|
+
if (!m && !V && !v)
|
|
835
834
|
return;
|
|
836
|
-
m = !1,
|
|
837
|
-
let y = 1 / 0,
|
|
838
|
-
for (let
|
|
839
|
-
const
|
|
840
|
-
y = Math.min(y,
|
|
835
|
+
m = !1, S.x = D, S.y = k, S.z = B, b.x = E, b.y = w, b.z = C;
|
|
836
|
+
let y = 1 / 0, _ = -1 / 0;
|
|
837
|
+
for (let f = 0; f < 8; ++f) {
|
|
838
|
+
const P = f & 1 ? p.x : x.x, F = f & 2 ? p.y : x.y, u = f & 4 ? p.z : x.z, I = P * E + F * w + u * C;
|
|
839
|
+
y = Math.min(y, I), _ = Math.max(_, I);
|
|
841
840
|
}
|
|
842
|
-
const
|
|
841
|
+
const R = r.length / 3, L = _ - y, o = (1 << Math.max(
|
|
843
842
|
10,
|
|
844
|
-
Math.min(20, Math.ceil(Math.log2(
|
|
843
|
+
Math.min(20, Math.ceil(Math.log2(R / 4)))
|
|
845
844
|
)) + 1;
|
|
846
|
-
if ((!
|
|
847
|
-
for (let
|
|
848
|
-
|
|
845
|
+
if ((!h || h.length !== R) && (h = new Uint32Array(R)), !T || T.length !== o ? T = new Uint32Array(o) : T.fill(0), L < 1e-7) {
|
|
846
|
+
for (let f = 0; f < R; ++f) h[f] = 0;
|
|
847
|
+
T[0] = R;
|
|
849
848
|
} else if (t && t.length > 0) {
|
|
850
|
-
const
|
|
851
|
-
|
|
852
|
-
for (let u = 0; u <
|
|
853
|
-
const
|
|
849
|
+
const f = t.length / 6;
|
|
850
|
+
q.fill(0);
|
|
851
|
+
for (let u = 0; u < f; ++u) {
|
|
852
|
+
const I = u * 6, Y = t[I + 0], X = t[I + 1], ne = t[I + 2], Z = t[I + 3], J = Y * E + X * w + ne * C - y, oe = J - Z, ee = J + Z, ie = Math.max(
|
|
854
853
|
0,
|
|
855
854
|
Math.floor(oe * O / L)
|
|
856
855
|
), ce = Math.min(
|
|
@@ -858,112 +857,113 @@ class _e extends i.EventDispatcher {
|
|
|
858
857
|
Math.ceil(ee * O / L)
|
|
859
858
|
);
|
|
860
859
|
for (let Q = ie; Q < ce; ++Q)
|
|
861
|
-
|
|
860
|
+
q[Q]++;
|
|
862
861
|
}
|
|
863
|
-
let
|
|
864
|
-
for (let u = 0; u < O; ++u)
|
|
865
|
-
|
|
862
|
+
let P = 0;
|
|
863
|
+
for (let u = 0; u < O; ++u) P += q[u];
|
|
864
|
+
j[0] = 0, W[0] = 0;
|
|
866
865
|
for (let u = 1; u < O; ++u)
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
const
|
|
870
|
-
for (let u = 0; u <
|
|
871
|
-
const
|
|
866
|
+
j[u - 1] = q[u - 1] / P * o >>> 0, W[u] = W[u - 1] + j[u - 1];
|
|
867
|
+
j[O - 1] = q[O - 1] / P * o >>> 0;
|
|
868
|
+
const F = L / O;
|
|
869
|
+
for (let u = 0; u < R; ++u) {
|
|
870
|
+
const I = u * 3, Y = r[I + 0], X = r[I + 1], ne = r[I + 2], Z = Y * E + X * w + ne * C, oe = (_ - Z) / F, ee = Math.max(
|
|
872
871
|
0,
|
|
873
872
|
Math.min(
|
|
874
873
|
O - 1,
|
|
875
874
|
Math.floor(oe)
|
|
876
875
|
)
|
|
877
|
-
), ie = oe - ee, ce = W[ee] +
|
|
878
|
-
|
|
876
|
+
), ie = oe - ee, ce = W[ee] + j[ee] * ie >>> 0, Q = Math.min(ce, o - 1);
|
|
877
|
+
h[u] = Q, T[Q]++;
|
|
879
878
|
}
|
|
880
879
|
} else {
|
|
881
|
-
const
|
|
882
|
-
for (let
|
|
883
|
-
const
|
|
884
|
-
|
|
880
|
+
const f = (o - 1) / L;
|
|
881
|
+
for (let P = 0; P < R; ++P) {
|
|
882
|
+
const F = P * 3, u = r[F + 0], I = r[F + 1], Y = r[F + 2], X = u * E + I * w + Y * C, Z = (_ - X) * f >>> 0, J = Math.min(Z, o - 1);
|
|
883
|
+
h[P] = J, T[J]++;
|
|
885
884
|
}
|
|
886
885
|
}
|
|
887
|
-
for (let
|
|
888
|
-
|
|
889
|
-
for (let
|
|
890
|
-
const
|
|
891
|
-
|
|
886
|
+
for (let f = 1; f < o; f++)
|
|
887
|
+
T[f] += T[f - 1];
|
|
888
|
+
for (let f = R - 1; f >= 0; f--) {
|
|
889
|
+
const P = h[f], F = --T[P];
|
|
890
|
+
n[F] = a ? a[f] : f;
|
|
892
891
|
}
|
|
893
|
-
const
|
|
894
|
-
if (!
|
|
895
|
-
const
|
|
896
|
-
if (!
|
|
892
|
+
const d = D * E + k * w + B * C, A = (f) => {
|
|
893
|
+
if (!n) return -1 / 0;
|
|
894
|
+
const P = n[f], F = P;
|
|
895
|
+
if (!r || F * 3 + 2 >= r.length)
|
|
897
896
|
return -1 / 0;
|
|
898
|
-
const u =
|
|
899
|
-
return
|
|
897
|
+
const u = F * 3;
|
|
898
|
+
return r[u] * E + r[u + 1] * w + r[u + 2] * C - d;
|
|
900
899
|
};
|
|
901
|
-
let
|
|
902
|
-
if (
|
|
903
|
-
const
|
|
900
|
+
let z = R;
|
|
901
|
+
if (R > 0 && A(R - 1) < 0) {
|
|
902
|
+
const f = H(
|
|
904
903
|
0,
|
|
905
|
-
|
|
906
|
-
|
|
904
|
+
R - 1,
|
|
905
|
+
A
|
|
907
906
|
);
|
|
908
|
-
|
|
907
|
+
z = f < 0 ? ~f : f;
|
|
909
908
|
}
|
|
910
909
|
const N = {
|
|
911
|
-
order:
|
|
912
|
-
count:
|
|
910
|
+
order: n.buffer,
|
|
911
|
+
count: z
|
|
913
912
|
};
|
|
914
|
-
self.postMessage(N, [
|
|
913
|
+
self.postMessage(N, [n.buffer]), n = null;
|
|
915
914
|
};
|
|
916
915
|
self.onmessage = (D) => {
|
|
917
916
|
const k = D.data;
|
|
918
|
-
k.order && (
|
|
919
|
-
let
|
|
920
|
-
if (k.centers && (
|
|
917
|
+
k.order && (n = new Uint32Array(k.order));
|
|
918
|
+
let B = !1;
|
|
919
|
+
if (k.centers && (r = new Float32Array(k.centers), B = !0, m = !0), Object.prototype.hasOwnProperty.call(k, "mapping") && (a = k.mapping ? new Uint32Array(k.mapping) : null, m = !0), k.chunks) {
|
|
921
920
|
if (t = new Float32Array(k.chunks), t.length > 0 && t[3] > 0)
|
|
922
|
-
for (let
|
|
923
|
-
const w =
|
|
924
|
-
t[w + 0] = (
|
|
925
|
-
(
|
|
921
|
+
for (let E = 0; E < t.length / 6; ++E) {
|
|
922
|
+
const w = E * 6, C = t[w + 0], U = t[w + 1], V = t[w + 2], v = t[w + 3], y = t[w + 4], _ = t[w + 5];
|
|
923
|
+
t[w + 0] = (C + v) * 0.5, t[w + 1] = (U + y) * 0.5, t[w + 2] = (V + _) * 0.5, t[w + 3] = Math.sqrt(
|
|
924
|
+
(v - C) ** 2 + (y - U) ** 2 + (_ - V) ** 2
|
|
926
925
|
) * 0.5;
|
|
927
926
|
}
|
|
928
927
|
m = !0;
|
|
929
928
|
}
|
|
930
|
-
if (
|
|
931
|
-
p.x = x.x =
|
|
932
|
-
for (let
|
|
933
|
-
const w =
|
|
934
|
-
p.x = Math.min(p.x,
|
|
929
|
+
if (B && r && r.length > 0) {
|
|
930
|
+
p.x = x.x = r[0], p.y = x.y = r[1], p.z = x.z = r[2];
|
|
931
|
+
for (let E = 1; E < r.length / 3; E++) {
|
|
932
|
+
const w = E * 3;
|
|
933
|
+
p.x = Math.min(p.x, r[w + 0]), x.x = Math.max(x.x, r[w + 0]), p.y = Math.min(p.y, r[w + 1]), x.y = Math.max(x.y, r[w + 1]), p.z = Math.min(p.z, r[w + 2]), x.z = Math.max(x.z, r[w + 2]);
|
|
935
934
|
}
|
|
936
|
-
} else
|
|
935
|
+
} else B && r && r.length === 0 && (p.x = x.x = p.y = x.y = p.z = x.z = 0);
|
|
937
936
|
k.cameraPosition && (c = k.cameraPosition), k.cameraDirection && (l = k.cameraDirection), $();
|
|
938
937
|
};
|
|
939
938
|
}).toString()})();`;
|
|
940
939
|
}
|
|
941
940
|
}
|
|
942
|
-
const
|
|
943
|
-
const s =
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
return
|
|
951
|
-
}
|
|
952
|
-
|
|
941
|
+
const ke = (M, e) => {
|
|
942
|
+
const s = de(M), n = de(e);
|
|
943
|
+
return s | n << 16;
|
|
944
|
+
};
|
|
945
|
+
function de(M) {
|
|
946
|
+
const e = new Float32Array([M]), n = new Int32Array(e.buffer)[0];
|
|
947
|
+
let r = n >> 16 & 32768, t = n >> 12 & 2047;
|
|
948
|
+
const a = n >> 23 & 255;
|
|
949
|
+
return a < 103 ? r : a > 142 ? (r |= 31744, r |= (a === 255 ? 0 : 1) && n & 8388607, r) : a < 113 ? (t |= 2048, r |= (t >> 114 - a) + (t >> 113 - a & 1), r) : (r |= a - 112 << 10 | t >> 1, r += t & 1, r);
|
|
950
|
+
}
|
|
951
|
+
const Ie = new ArrayBuffer(4), pe = new DataView(Ie), Re = (M) => (pe.setUint32(0, M, !0), pe.getFloat32(0, !0));
|
|
952
|
+
class ze {
|
|
953
953
|
/**
|
|
954
954
|
* Create a new TextureManager for a set of splats
|
|
955
955
|
* @param splatData The splat data to manage textures for
|
|
956
956
|
*/
|
|
957
957
|
constructor(e) {
|
|
958
|
-
|
|
958
|
+
g(this, "transformA");
|
|
959
959
|
// position xyz and rotation quaternion y,z components
|
|
960
|
-
|
|
960
|
+
g(this, "transformB");
|
|
961
961
|
// rotation quaternion x and scale xyz
|
|
962
|
-
|
|
962
|
+
g(this, "colorTexture");
|
|
963
963
|
// color an opacity
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
964
|
+
g(this, "orderTexture");
|
|
965
|
+
g(this, "textureWidth");
|
|
966
|
+
g(this, "textureHeight");
|
|
967
967
|
const s = e.numSplats;
|
|
968
968
|
this.textureWidth = Math.ceil(Math.sqrt(s)), this.textureHeight = Math.ceil(s / this.textureWidth), this.transformA = this.createTransformATexture(e), this.transformB = this.createTransformBTexture(e), this.colorTexture = this.createColorTexture(e), this.orderTexture = this.createOrderTexture(s);
|
|
969
969
|
}
|
|
@@ -973,24 +973,24 @@ class Pe {
|
|
|
973
973
|
* @returns DataTexture containing position data
|
|
974
974
|
*/
|
|
975
975
|
createTransformATexture(e) {
|
|
976
|
-
const s = e.numSplats,
|
|
976
|
+
const s = e.numSplats, n = new Float32Array(
|
|
977
977
|
this.textureWidth * this.textureHeight * 4
|
|
978
978
|
);
|
|
979
979
|
for (let t = 0; t < s; t++) {
|
|
980
980
|
const a = t * 4, c = t * 3, l = t * 4;
|
|
981
|
-
|
|
982
|
-
const m = e.rotations[l +
|
|
983
|
-
|
|
981
|
+
n[a] = e.positions[c], n[a + 1] = e.positions[c + 1], n[a + 2] = e.positions[c + 2];
|
|
982
|
+
const m = e.rotations[l + 0], S = e.rotations[l + 1], b = ke(m, S);
|
|
983
|
+
n[a + 3] = Re(b);
|
|
984
984
|
}
|
|
985
|
-
const
|
|
986
|
-
|
|
985
|
+
const r = new i.DataTexture(
|
|
986
|
+
n,
|
|
987
987
|
this.textureWidth,
|
|
988
988
|
this.textureHeight,
|
|
989
989
|
i.RGBAFormat,
|
|
990
990
|
i.FloatType
|
|
991
991
|
// Store as Float32, shader will reinterpret bits
|
|
992
992
|
);
|
|
993
|
-
return
|
|
993
|
+
return r.needsUpdate = !0, r.magFilter = i.NearestFilter, r.minFilter = i.NearestFilter, r;
|
|
994
994
|
}
|
|
995
995
|
/**
|
|
996
996
|
* Create the transform B texture (scale and rotation xyz)
|
|
@@ -998,21 +998,21 @@ class Pe {
|
|
|
998
998
|
* @returns DataTexture containing scale and rotation data
|
|
999
999
|
*/
|
|
1000
1000
|
createTransformBTexture(e) {
|
|
1001
|
-
const s = e.numSplats,
|
|
1001
|
+
const s = e.numSplats, n = new Float32Array(
|
|
1002
1002
|
this.textureWidth * this.textureHeight * 4
|
|
1003
1003
|
);
|
|
1004
1004
|
for (let t = 0; t < s; t++) {
|
|
1005
1005
|
const a = t * 4, c = t * 3, l = t * 4;
|
|
1006
|
-
|
|
1006
|
+
n[a] = e.scales[c], n[a + 1] = e.scales[c + 1], n[a + 2] = e.scales[c + 2], n[a + 3] = e.rotations[l + 2];
|
|
1007
1007
|
}
|
|
1008
|
-
const
|
|
1009
|
-
|
|
1008
|
+
const r = new i.DataTexture(
|
|
1009
|
+
n,
|
|
1010
1010
|
this.textureWidth,
|
|
1011
1011
|
this.textureHeight,
|
|
1012
1012
|
i.RGBAFormat,
|
|
1013
1013
|
i.FloatType
|
|
1014
1014
|
);
|
|
1015
|
-
return
|
|
1015
|
+
return r.needsUpdate = !0, r.magFilter = i.NearestFilter, r.minFilter = i.NearestFilter, r;
|
|
1016
1016
|
}
|
|
1017
1017
|
/**
|
|
1018
1018
|
* Create the color texture (RGB and opacity)
|
|
@@ -1020,21 +1020,21 @@ class Pe {
|
|
|
1020
1020
|
* @returns DataTexture containing color data
|
|
1021
1021
|
*/
|
|
1022
1022
|
createColorTexture(e) {
|
|
1023
|
-
const s = e.numSplats,
|
|
1023
|
+
const s = e.numSplats, n = new Float32Array(
|
|
1024
1024
|
this.textureWidth * this.textureHeight * 4
|
|
1025
1025
|
);
|
|
1026
1026
|
for (let t = 0; t < s; t++) {
|
|
1027
1027
|
const a = t * 4, c = t * 3;
|
|
1028
|
-
|
|
1028
|
+
n[a] = e.colors[c], n[a + 1] = e.colors[c + 1], n[a + 2] = e.colors[c + 2], n[a + 3] = e.opacities[t];
|
|
1029
1029
|
}
|
|
1030
|
-
const
|
|
1031
|
-
|
|
1030
|
+
const r = new i.DataTexture(
|
|
1031
|
+
n,
|
|
1032
1032
|
this.textureWidth,
|
|
1033
1033
|
this.textureHeight,
|
|
1034
1034
|
i.RGBAFormat,
|
|
1035
1035
|
i.FloatType
|
|
1036
1036
|
);
|
|
1037
|
-
return
|
|
1037
|
+
return r.needsUpdate = !0, r;
|
|
1038
1038
|
}
|
|
1039
1039
|
/**
|
|
1040
1040
|
* Create the order texture for sorting
|
|
@@ -1043,22 +1043,22 @@ class Pe {
|
|
|
1043
1043
|
*/
|
|
1044
1044
|
createOrderTexture(e) {
|
|
1045
1045
|
const s = new Uint32Array(this.textureWidth * this.textureHeight);
|
|
1046
|
-
for (let
|
|
1047
|
-
s[
|
|
1048
|
-
const
|
|
1046
|
+
for (let r = 0; r < e; r++)
|
|
1047
|
+
s[r] = r;
|
|
1048
|
+
const n = new i.DataTexture(
|
|
1049
1049
|
s,
|
|
1050
1050
|
this.textureWidth,
|
|
1051
1051
|
this.textureHeight,
|
|
1052
1052
|
i.RedIntegerFormat,
|
|
1053
1053
|
i.UnsignedIntType
|
|
1054
1054
|
);
|
|
1055
|
-
return
|
|
1055
|
+
return n.needsUpdate = !0, n;
|
|
1056
1056
|
}
|
|
1057
1057
|
dispose() {
|
|
1058
1058
|
this.transformA.dispose(), this.transformB.dispose(), this.colorTexture.dispose(), this.orderTexture.dispose();
|
|
1059
1059
|
}
|
|
1060
1060
|
}
|
|
1061
|
-
const
|
|
1061
|
+
const Pe = (
|
|
1062
1062
|
/* glsl */
|
|
1063
1063
|
`
|
|
1064
1064
|
precision highp float;
|
|
@@ -1096,61 +1096,53 @@ varying vec2 vUv; // For gaussian calculation in fragment shader
|
|
|
1096
1096
|
|
|
1097
1097
|
// --- Helper Functions ---
|
|
1098
1098
|
|
|
1099
|
-
//
|
|
1100
|
-
vec2 unpackHalf2x16FromFloat(float packedFloat) {
|
|
1101
|
-
uint packedUInt = floatBitsToUint(packedFloat);
|
|
1102
|
-
uint y_bits = packedUInt >> 16;
|
|
1103
|
-
uint z_bits = packedUInt & uint(0xFFFF);
|
|
1099
|
+
// Use GLSL built-in unpackHalf2x16 for proper half-float unpacking
|
|
1104
1100
|
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
// Reconstruct quaternion from packed components (x, yz_packed)
|
|
1113
|
-
vec4 unpackRotation(float yz_packed, float x) {
|
|
1114
|
-
vec2 yz = unpackHalf2x16FromFloat(yz_packed);
|
|
1115
|
-
float y = yz.x;
|
|
1116
|
-
float z = yz.y;
|
|
1101
|
+
// Reconstruct quaternion from packed components (xy_packed, z)
|
|
1102
|
+
// Returns (w,x,y,z) format for quatToMat3 compatibility
|
|
1103
|
+
vec4 unpackRotation(float xy_packed, float z) {
|
|
1104
|
+
vec2 xy = unpackHalf2x16(floatBitsToUint(xy_packed));
|
|
1105
|
+
float x = xy.x;
|
|
1106
|
+
float y = xy.y;
|
|
1117
1107
|
float w_squared = 1.0 - x*x - y*y - z*z;
|
|
1118
|
-
float w = (w_squared < 0.0) ? 0.0 : sqrt(w_squared);
|
|
1119
|
-
return vec4(x, y, z
|
|
1108
|
+
float w = (w_squared < 0.0) ? 0.0 : sqrt(w_squared);
|
|
1109
|
+
return vec4(w, x, y, z); // Return (w,x,y,z)
|
|
1120
1110
|
}
|
|
1121
1111
|
|
|
1122
1112
|
// Convert quaternion to 3x3 rotation matrix
|
|
1123
|
-
mat3 quatToMat3(vec4
|
|
1124
|
-
|
|
1125
|
-
float
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
float
|
|
1113
|
+
mat3 quatToMat3(vec4 R) {
|
|
1114
|
+
vec4 R2 = R + R;
|
|
1115
|
+
float X = R2.x * R.w;
|
|
1116
|
+
vec4 Y = R2.y * R;
|
|
1117
|
+
vec4 Z = R2.z * R;
|
|
1118
|
+
float W = R2.w * R.w;
|
|
1129
1119
|
|
|
1130
1120
|
return mat3(
|
|
1131
|
-
1.0 -
|
|
1132
|
-
|
|
1133
|
-
|
|
1121
|
+
1.0 - Z.z - W,
|
|
1122
|
+
Y.z + X,
|
|
1123
|
+
Y.w - Z.x,
|
|
1124
|
+
Y.z - X,
|
|
1125
|
+
1.0 - Y.y - W,
|
|
1126
|
+
Z.w + Y.x,
|
|
1127
|
+
Y.w + Z.x,
|
|
1128
|
+
Z.w - Y.x,
|
|
1129
|
+
1.0 - Y.y - Z.z
|
|
1134
1130
|
);
|
|
1135
1131
|
}
|
|
1136
1132
|
|
|
1137
|
-
// Calculate model-space covariance components
|
|
1133
|
+
// Calculate model-space covariance components
|
|
1138
1134
|
void getModelCovariance(vec3 scale, vec4 rotation, out vec3 covA, out vec3 covB) {
|
|
1139
|
-
mat3
|
|
1140
|
-
|
|
1141
|
-
//
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
R[2][0] * scale.x, R[2][1] * scale.y, R[2][2] * scale.z // Row 2 = (R_row2 * S)
|
|
1148
|
-
);
|
|
1135
|
+
mat3 rot = quatToMat3(rotation);
|
|
1136
|
+
|
|
1137
|
+
// M = S * R (scale COLUMNS, then transpose)
|
|
1138
|
+
mat3 M = transpose(mat3(
|
|
1139
|
+
scale.x * rot[0], // scale.x * column 0
|
|
1140
|
+
scale.y * rot[1], // scale.y * column 1
|
|
1141
|
+
scale.z * rot[2] // scale.z * column 2
|
|
1142
|
+
));
|
|
1149
1143
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
covA = vec3(dot(M[0], M[0]), dot(M[0], M[1]), dot(M[0], M[2])); // Vrk[0][0], Vrk[0][1], Vrk[0][2]
|
|
1153
|
-
covB = vec3(dot(M[1], M[1]), dot(M[1], M[2]), dot(M[2], M[2])); // Vrk[1][1], Vrk[1][2], Vrk[2][2]
|
|
1144
|
+
covA = vec3(dot(M[0], M[0]), dot(M[0], M[1]), dot(M[0], M[2]));
|
|
1145
|
+
covB = vec3(dot(M[1], M[1]), dot(M[1], M[2]), dot(M[2], M[2]));
|
|
1154
1146
|
}
|
|
1155
1147
|
|
|
1156
1148
|
// --- Main Function ---
|
|
@@ -1179,7 +1171,7 @@ void main(void) {
|
|
|
1179
1171
|
|
|
1180
1172
|
vec3 splatPosition = texTransformA.xyz;
|
|
1181
1173
|
vec3 splatLogScale = texTransformB.xyz; // Assume stored as log scale
|
|
1182
|
-
vec4 splatRotation = unpackRotation(texTransformA.w, texTransformB.w); // Unpack rot
|
|
1174
|
+
vec4 splatRotation = unpackRotation(texTransformA.w, texTransformB.w); // Unpack rot xy, z
|
|
1183
1175
|
vec3 splatColor = texColor.rgb;
|
|
1184
1176
|
float splatOpacity = texColor.a;
|
|
1185
1177
|
|
|
@@ -1272,6 +1264,10 @@ void main(void) {
|
|
|
1272
1264
|
float l1 = sqrt(lambda1) * scaleFactor; // scaleX
|
|
1273
1265
|
float l2 = sqrt(lambda2) * scaleFactor; // scaleY
|
|
1274
1266
|
|
|
1267
|
+
float vmin = min(512.0, min(viewport.x, viewport.y));
|
|
1268
|
+
l1 = min(l1, 2.0 * vmin);
|
|
1269
|
+
l2 = min(l2, 2.0 * vmin);
|
|
1270
|
+
|
|
1275
1271
|
// Early out tiny splats
|
|
1276
1272
|
if (l1 < 2.0 && l2 < 2.0) { // Check if smaller than ~2 pixel
|
|
1277
1273
|
gl_Position = vec4(2.0, 2.0, 2.0, 1.0);
|
|
@@ -1282,14 +1278,15 @@ void main(void) {
|
|
|
1282
1278
|
vec2 v1_scaled = l1 * v1_eigen;
|
|
1283
1279
|
vec2 v2_scaled = l2 * v2_eigen;
|
|
1284
1280
|
|
|
1285
|
-
// --- FRUSTUM CHECK
|
|
1281
|
+
// --- FRUSTUM CHECK (laxo, estilo PlayCanvas) ---
|
|
1286
1282
|
|
|
1287
|
-
vec2
|
|
1283
|
+
vec2 c = centerClip.ww / viewport; // pixel to clip
|
|
1284
|
+
float r = max(l1, l2); // radius in pixels
|
|
1288
1285
|
|
|
1289
|
-
//
|
|
1290
|
-
if (any(greaterThan(abs(centerClip.xy)
|
|
1291
|
-
|
|
1292
|
-
|
|
1286
|
+
// Remove if the center - radius is already out of -w..w
|
|
1287
|
+
if (any(greaterThan(abs(centerClip.xy) - vec2(r) * c, centerClip.ww))) {
|
|
1288
|
+
gl_Position = vec4(2.0, 2.0, 2.0, 1.0);
|
|
1289
|
+
return;
|
|
1293
1290
|
}
|
|
1294
1291
|
|
|
1295
1292
|
// --- END FRUSTUM CHECK ---
|
|
@@ -1305,7 +1302,6 @@ void main(void) {
|
|
|
1305
1302
|
// Apply clip to the corner offset *before* calculating screen space offset
|
|
1306
1303
|
vec2 clippedCornerOffset = cornerOffset * clip;
|
|
1307
1304
|
vec2 screenOffsetPixels = clippedCornerOffset.x * v1_scaled + clippedCornerOffset.y * v2_scaled;
|
|
1308
|
-
//vec2 screenOffsetPixels = vec2(clippedCornerOffset.x, clippedCornerOffset.y);
|
|
1309
1305
|
|
|
1310
1306
|
// Convert pixel offset to clip space offset
|
|
1311
1307
|
vec2 clipOffset = screenOffsetPixels * (centerClip.w / viewport);
|
|
@@ -1320,7 +1316,7 @@ void main(void) {
|
|
|
1320
1316
|
vUv = clippedCornerOffset;
|
|
1321
1317
|
}
|
|
1322
1318
|
`
|
|
1323
|
-
),
|
|
1319
|
+
), Oe = (
|
|
1324
1320
|
/* glsl */
|
|
1325
1321
|
`
|
|
1326
1322
|
precision highp float;
|
|
@@ -1328,6 +1324,14 @@ precision highp float;
|
|
|
1328
1324
|
varying vec4 vColor; // Color and opacity passed from vertex shader
|
|
1329
1325
|
varying vec2 vUv; // Quad UV coordinates (-1 to 1) passed from vertex shader
|
|
1330
1326
|
|
|
1327
|
+
// Fast approximate e^x based on https://nic.schraudolph.org/pubs/Schraudolph99.pdf
|
|
1328
|
+
const float EXP_A = 12102203.0; // ≈ 2^23 / ln(2)
|
|
1329
|
+
const int EXP_BC_RMS = 1064866808; // (127 << 23) - 60801 * 8
|
|
1330
|
+
float fastExp(float x) {
|
|
1331
|
+
int i = int(EXP_A * x) + EXP_BC_RMS;
|
|
1332
|
+
return intBitsToFloat(i);
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1331
1335
|
void main(void) {
|
|
1332
1336
|
|
|
1333
1337
|
float distSq = dot(vUv, vUv); // Calculate squared distance from center (in the quad's coordinate system)
|
|
@@ -1337,7 +1341,7 @@ void main(void) {
|
|
|
1337
1341
|
// The factor 4.0 corresponds to the original implementation's scaling.
|
|
1338
1342
|
// factor = 1 / (2 * sigma^2), where sigma controls the spread.
|
|
1339
1343
|
// Using 4.0 implies sigma^2 = 1/8.
|
|
1340
|
-
float alpha =
|
|
1344
|
+
float alpha = fastExp(-distSq * 4.0) * vColor.a;
|
|
1341
1345
|
|
|
1342
1346
|
if (alpha < 1.0 / 255.0) discard; // Discard fragments with very low alpha
|
|
1343
1347
|
|
|
@@ -1361,8 +1365,8 @@ class Be extends i.ShaderMaterial {
|
|
|
1361
1365
|
// Max splats to render (updated by sorter)
|
|
1362
1366
|
};
|
|
1363
1367
|
super({
|
|
1364
|
-
vertexShader:
|
|
1365
|
-
fragmentShader:
|
|
1368
|
+
vertexShader: Pe,
|
|
1369
|
+
fragmentShader: Oe,
|
|
1366
1370
|
uniforms: s,
|
|
1367
1371
|
transparent: !0,
|
|
1368
1372
|
blending: i.CustomBlending,
|
|
@@ -1440,19 +1444,19 @@ const K = class K extends i.Mesh {
|
|
|
1440
1444
|
* @param splatData The splat data to render
|
|
1441
1445
|
* @param options Rendering options
|
|
1442
1446
|
*/
|
|
1443
|
-
constructor(s,
|
|
1444
|
-
const
|
|
1445
|
-
super(t,
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
this.geometry = t, this.material =
|
|
1447
|
+
constructor(s, n = {}) {
|
|
1448
|
+
const r = new Be(n), t = K.createInstancedGeometry(s.numSplats, K.INSTANCE_SIZE);
|
|
1449
|
+
super(t, r);
|
|
1450
|
+
g(this, "sorter");
|
|
1451
|
+
g(this, "splatData");
|
|
1452
|
+
g(this, "options");
|
|
1453
|
+
g(this, "textureManager");
|
|
1454
|
+
g(this, "material");
|
|
1455
|
+
g(this, "geometry");
|
|
1456
|
+
g(this, "lastCameraPositionLocal", new i.Vector3());
|
|
1457
|
+
g(this, "lastCameraDirectionLocal", new i.Vector3());
|
|
1458
|
+
g(this, "invModelMatrix", new i.Matrix4());
|
|
1459
|
+
this.geometry = t, this.material = r, this.splatData = s, this.frustumCulled = !1, this.options = { autoSort: !0, ...n }, this.textureManager = new ze(s), this.sorter = new _e();
|
|
1456
1460
|
let a = this.createChunks() || void 0;
|
|
1457
1461
|
a === null && console.warn("Visus: Could not create sorter chunks, bounding box might be invalid."), a = void 0, this.sorter.init(
|
|
1458
1462
|
this.textureManager.orderTexture,
|
|
@@ -1472,8 +1476,8 @@ const K = class K extends i.Mesh {
|
|
|
1472
1476
|
* @param instanceSize Number of splats per instance.
|
|
1473
1477
|
* @returns InstancedBufferGeometry
|
|
1474
1478
|
*/
|
|
1475
|
-
static createInstancedGeometry(s,
|
|
1476
|
-
const
|
|
1479
|
+
static createInstancedGeometry(s, n) {
|
|
1480
|
+
const r = Math.ceil(s / n), t = new i.BufferGeometry(), a = new Float32Array([
|
|
1477
1481
|
// x, y, splat_index_in_instance
|
|
1478
1482
|
-1,
|
|
1479
1483
|
-1,
|
|
@@ -1487,24 +1491,24 @@ const K = class K extends i.Mesh {
|
|
|
1487
1491
|
-1,
|
|
1488
1492
|
1,
|
|
1489
1493
|
0
|
|
1490
|
-
]), c = new Uint16Array([0, 1, 2, 0, 2, 3]), l = new Float32Array(4 * 3 *
|
|
1491
|
-
for (let p = 0; p <
|
|
1494
|
+
]), c = new Uint16Array([0, 1, 2, 0, 2, 3]), l = new Float32Array(4 * 3 * n);
|
|
1495
|
+
for (let p = 0; p < n; p++) {
|
|
1492
1496
|
const x = p * 4 * 3;
|
|
1493
|
-
for (let
|
|
1494
|
-
l[x +
|
|
1497
|
+
for (let h = 0; h < 4; h++)
|
|
1498
|
+
l[x + h * 3 + 0] = a[h * 3 + 0], l[x + h * 3 + 1] = a[h * 3 + 1], l[x + h * 3 + 2] = p;
|
|
1495
1499
|
}
|
|
1496
|
-
const m = new Uint32Array(6 *
|
|
1497
|
-
for (let p = 0; p <
|
|
1498
|
-
const x = p * 6,
|
|
1499
|
-
m[x + 0] = c[0] +
|
|
1500
|
+
const m = new Uint32Array(6 * n);
|
|
1501
|
+
for (let p = 0; p < n; p++) {
|
|
1502
|
+
const x = p * 6, h = p * 4;
|
|
1503
|
+
m[x + 0] = c[0] + h, m[x + 1] = c[1] + h, m[x + 2] = c[2] + h, m[x + 3] = c[3] + h, m[x + 4] = c[4] + h, m[x + 5] = c[5] + h;
|
|
1500
1504
|
}
|
|
1501
1505
|
t.setAttribute("position", new i.BufferAttribute(l, 3)), t.setIndex(new i.BufferAttribute(m, 1));
|
|
1502
|
-
const
|
|
1503
|
-
|
|
1504
|
-
const b = new Uint32Array(
|
|
1505
|
-
for (let p = 0; p <
|
|
1506
|
-
b[p] = p *
|
|
1507
|
-
return
|
|
1506
|
+
const S = new i.InstancedBufferGeometry();
|
|
1507
|
+
S.index = t.index, S.setAttribute("position", t.getAttribute("position"));
|
|
1508
|
+
const b = new Uint32Array(r);
|
|
1509
|
+
for (let p = 0; p < r; p++)
|
|
1510
|
+
b[p] = p * n;
|
|
1511
|
+
return S.setAttribute("splatInstanceIndex", new i.InstancedBufferAttribute(b, 1, !1)), S.instanceCount = 0, S;
|
|
1508
1512
|
}
|
|
1509
1513
|
/**
|
|
1510
1514
|
* Create chunks data (bounding box min/max) for the sorter.
|
|
@@ -1526,17 +1530,17 @@ const K = class K extends i.Mesh {
|
|
|
1526
1530
|
* @param width Viewport width
|
|
1527
1531
|
* @param height Viewport height
|
|
1528
1532
|
*/
|
|
1529
|
-
updateViewport(s,
|
|
1530
|
-
this.material.updateViewport(s,
|
|
1533
|
+
updateViewport(s, n) {
|
|
1534
|
+
this.material.updateViewport(s, n);
|
|
1531
1535
|
}
|
|
1532
1536
|
/**
|
|
1533
1537
|
* Sorts splats based on camera position and direction.
|
|
1534
1538
|
* @param camera The camera to sort against.
|
|
1535
1539
|
*/
|
|
1536
1540
|
sort(s) {
|
|
1537
|
-
const
|
|
1538
|
-
s.getWorldPosition(
|
|
1539
|
-
const t =
|
|
1541
|
+
const n = new i.Vector3(), r = new i.Vector3();
|
|
1542
|
+
s.getWorldPosition(n), s.getWorldDirection(r), this.invModelMatrix.copy(this.matrixWorld).invert();
|
|
1543
|
+
const t = n.applyMatrix4(this.invModelMatrix), a = r.transformDirection(this.invModelMatrix), c = this.lastCameraPositionLocal.distanceToSquared(t) > 1e-6, l = this.lastCameraDirectionLocal.dot(a) < 0.999;
|
|
1540
1544
|
this.options.autoSort && (c || l) && (this.lastCameraPositionLocal.copy(t), this.lastCameraDirectionLocal.copy(a), this.sorter.setCamera(t, a));
|
|
1541
1545
|
}
|
|
1542
1546
|
/**
|
|
@@ -1548,8 +1552,8 @@ const K = class K extends i.Mesh {
|
|
|
1548
1552
|
*/
|
|
1549
1553
|
// prettier-ignore
|
|
1550
1554
|
// @ts-expect-error scene is not used
|
|
1551
|
-
onBeforeRender(s,
|
|
1552
|
-
this.sort(
|
|
1555
|
+
onBeforeRender(s, n, r) {
|
|
1556
|
+
this.sort(r);
|
|
1553
1557
|
const t = s.getSize(new i.Vector2());
|
|
1554
1558
|
let { width: a, height: c } = t;
|
|
1555
1559
|
const l = s.xr;
|
|
@@ -1568,29 +1572,34 @@ const K = class K extends i.Mesh {
|
|
|
1568
1572
|
};
|
|
1569
1573
|
// Cached inverse matrix
|
|
1570
1574
|
/** Number of splats combined into a single instanced draw call. */
|
|
1571
|
-
|
|
1572
|
-
let ae = K
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1575
|
+
g(K, "INSTANCE_SIZE", 128);
|
|
1576
|
+
let ae = K;
|
|
1577
|
+
const Fe = Symbol.for("@speridlabs/visus/SplatMesh");
|
|
1578
|
+
try {
|
|
1579
|
+
Object.defineProperty(ae.prototype, Fe, {
|
|
1580
|
+
value: !0,
|
|
1581
|
+
configurable: !1,
|
|
1582
|
+
enumerable: !1,
|
|
1583
|
+
writable: !1
|
|
1584
|
+
});
|
|
1585
|
+
} catch {
|
|
1586
|
+
console.warn("Couldn't define Visus SplatMesh symbol");
|
|
1587
|
+
}
|
|
1588
|
+
const je = ({
|
|
1589
|
+
plyUrl: M,
|
|
1576
1590
|
splatOptions: e = {},
|
|
1577
1591
|
...s
|
|
1578
1592
|
}) => {
|
|
1579
|
-
const
|
|
1580
|
-
() =>
|
|
1581
|
-
[
|
|
1593
|
+
const n = ve(null), r = be(Ee, M), t = ge(
|
|
1594
|
+
() => new ae(r, e || {}),
|
|
1595
|
+
[r, e]
|
|
1582
1596
|
);
|
|
1583
|
-
return we(() => {
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
"Visus: The 'Splat' component's internal mesh ref is not an instance of the core SplatMesh. This usually means `extend` was not called correctly. Please ensure you have called `extend({ splatPrimitive: SplatMesh })` in your R3F setup, where 'SplatMesh' is the class imported from 'visus' (or 'visus/react')."
|
|
1587
|
-
), () => {
|
|
1588
|
-
a && typeof a.dispose == "function" && a.dispose();
|
|
1589
|
-
};
|
|
1590
|
-
}, []), /* @__PURE__ */ Ae.jsx("splatPrimitive", { ref: o, args: t, ...s });
|
|
1597
|
+
return we(() => () => {
|
|
1598
|
+
typeof (t == null ? void 0 : t.dispose) == "function" && t.dispose();
|
|
1599
|
+
}, [t]), /* @__PURE__ */ Me.jsx("primitive", { ref: n, object: t, ...s });
|
|
1591
1600
|
};
|
|
1592
1601
|
export {
|
|
1593
|
-
|
|
1594
|
-
|
|
1602
|
+
Ee as PlyLoader,
|
|
1603
|
+
je as Splat,
|
|
1595
1604
|
ae as SplatMesh
|
|
1596
1605
|
};
|