@speridlabs/visus 2.1.0 → 2.1.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.d.ts +2 -2
- package/dist/main.es.js +255 -251
- package/dist/main.umd.js +5 -5
- package/dist/react.es.js +356 -352
- package/package.json +1 -1
package/dist/main.es.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
var pt = Object.defineProperty;
|
|
2
2
|
var ft = (k, t, o) => t in k ? pt(k, t, { enumerable: !0, configurable: !0, writable: !0, value: o }) : k[t] = o;
|
|
3
3
|
var h = (k, t, o) => ft(k, typeof t != "symbol" ? t + "" : t, o);
|
|
4
|
-
import * as
|
|
4
|
+
import * as i from "three";
|
|
5
5
|
class ct {
|
|
6
6
|
constructor() {
|
|
7
|
-
h(this, "min", new
|
|
8
|
-
h(this, "max", new
|
|
9
|
-
h(this, "center", new
|
|
7
|
+
h(this, "min", new i.Vector3(1 / 0, 1 / 0, 1 / 0));
|
|
8
|
+
h(this, "max", new i.Vector3(-1 / 0, -1 / 0, -1 / 0));
|
|
9
|
+
h(this, "center", new i.Vector3());
|
|
10
10
|
/** Half extents (size/2) */
|
|
11
|
-
h(this, "halfExtents", new
|
|
11
|
+
h(this, "halfExtents", new i.Vector3());
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Reset the bounding box to its initial state
|
|
@@ -49,7 +49,7 @@ class ct {
|
|
|
49
49
|
* @returns THREE.Box3 representation
|
|
50
50
|
*/
|
|
51
51
|
toBox3() {
|
|
52
|
-
return new
|
|
52
|
+
return new i.Box3().set(this.min, this.max);
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
55
|
* Create a clone of this bounding box
|
|
@@ -84,13 +84,13 @@ class mt {
|
|
|
84
84
|
* @param color Color
|
|
85
85
|
* @param opacity Opacity value
|
|
86
86
|
*/
|
|
87
|
-
setSplat(t, o, e,
|
|
87
|
+
setSplat(t, o, e, r, s, n) {
|
|
88
88
|
if (t >= this.numSplats)
|
|
89
89
|
throw new Error(
|
|
90
90
|
`Splat index out of bounds: ${t} >= ${this.numSplats}`
|
|
91
91
|
);
|
|
92
|
-
const
|
|
93
|
-
this.positions[
|
|
92
|
+
const a = t * 3, l = t * 4, x = t * 3, b = t * 3;
|
|
93
|
+
this.positions[a] = o.x, this.positions[a + 1] = o.y, this.positions[a + 2] = o.z, this.rotations[l] = e.x, this.rotations[l + 1] = e.y, this.rotations[l + 2] = e.z, this.rotations[l + 3] = e.w, this.scales[x] = r.x, this.scales[x + 1] = r.y, this.scales[x + 2] = r.z, this.colors[b] = s.r, this.colors[b + 1] = s.g, this.colors[b + 2] = s.b, this.opacities[t] = n;
|
|
94
94
|
}
|
|
95
95
|
/**
|
|
96
96
|
* Get a splat's data
|
|
@@ -102,29 +102,29 @@ class mt {
|
|
|
102
102
|
throw new Error(
|
|
103
103
|
`Splat index out of bounds: ${t} >= ${this.numSplats}`
|
|
104
104
|
);
|
|
105
|
-
const o = t * 3, e = t * 4,
|
|
105
|
+
const o = t * 3, e = t * 4, r = t * 3, s = t * 3;
|
|
106
106
|
return {
|
|
107
|
-
position: new
|
|
107
|
+
position: new i.Vector3(
|
|
108
108
|
this.positions[o],
|
|
109
109
|
this.positions[o + 1],
|
|
110
110
|
this.positions[o + 2]
|
|
111
111
|
),
|
|
112
|
-
rotation: new
|
|
112
|
+
rotation: new i.Quaternion(
|
|
113
113
|
this.rotations[e],
|
|
114
114
|
this.rotations[e + 1],
|
|
115
115
|
this.rotations[e + 2],
|
|
116
116
|
this.rotations[e + 3]
|
|
117
117
|
),
|
|
118
118
|
// Convert log scale back to linear scale for external use
|
|
119
|
-
scale: new
|
|
120
|
-
Math.exp(this.scales[
|
|
121
|
-
Math.exp(this.scales[
|
|
122
|
-
Math.exp(this.scales[
|
|
119
|
+
scale: new i.Vector3(
|
|
120
|
+
Math.exp(this.scales[r]),
|
|
121
|
+
Math.exp(this.scales[r + 1]),
|
|
122
|
+
Math.exp(this.scales[r + 2])
|
|
123
123
|
),
|
|
124
|
-
color: new
|
|
125
|
-
this.colors[
|
|
126
|
-
this.colors[
|
|
127
|
-
this.colors[
|
|
124
|
+
color: new i.Color(
|
|
125
|
+
this.colors[s],
|
|
126
|
+
this.colors[s + 1],
|
|
127
|
+
this.colors[s + 2]
|
|
128
128
|
),
|
|
129
129
|
opacity: this.opacities[t]
|
|
130
130
|
};
|
|
@@ -135,7 +135,7 @@ class mt {
|
|
|
135
135
|
*/
|
|
136
136
|
calculateBoundingBox() {
|
|
137
137
|
this.boundingBox.reset();
|
|
138
|
-
const t = new
|
|
138
|
+
const t = new i.Vector3();
|
|
139
139
|
for (let o = 0; o < this.numSplats; o++) {
|
|
140
140
|
const e = o * 3;
|
|
141
141
|
t.set(
|
|
@@ -151,37 +151,37 @@ class mt {
|
|
|
151
151
|
* This is for visualization/debugging purposes only, not for rendering
|
|
152
152
|
*/
|
|
153
153
|
createDebugGeometry() {
|
|
154
|
-
const t = new
|
|
154
|
+
const t = new i.BufferGeometry();
|
|
155
155
|
t.setAttribute(
|
|
156
156
|
"position",
|
|
157
|
-
new
|
|
157
|
+
new i.BufferAttribute(this.positions, 3)
|
|
158
158
|
);
|
|
159
|
-
const o = new Float32Array(this.numSplats * 3), e = new
|
|
160
|
-
for (let
|
|
161
|
-
const n =
|
|
159
|
+
const o = new Float32Array(this.numSplats * 3), e = new i.Quaternion(), r = new i.Euler();
|
|
160
|
+
for (let s = 0; s < this.numSplats; s++) {
|
|
161
|
+
const n = s * 4, a = s * 3;
|
|
162
162
|
e.set(
|
|
163
163
|
this.rotations[n],
|
|
164
164
|
this.rotations[n + 1],
|
|
165
165
|
this.rotations[n + 2],
|
|
166
166
|
this.rotations[n + 3]
|
|
167
|
-
),
|
|
167
|
+
), r.setFromQuaternion(e), o[a] = r.x, o[a + 1] = r.y, o[a + 2] = r.z;
|
|
168
168
|
}
|
|
169
169
|
return t.setAttribute(
|
|
170
170
|
"rotation",
|
|
171
|
-
new
|
|
171
|
+
new i.BufferAttribute(o, 3)
|
|
172
172
|
), t.setAttribute(
|
|
173
173
|
"scale",
|
|
174
|
-
new
|
|
174
|
+
new i.BufferAttribute(this.scales, 3)
|
|
175
175
|
), t.setAttribute(
|
|
176
176
|
"color",
|
|
177
|
-
new
|
|
177
|
+
new i.BufferAttribute(this.colors, 3)
|
|
178
178
|
), t.setAttribute(
|
|
179
179
|
"opacity",
|
|
180
|
-
new
|
|
180
|
+
new i.BufferAttribute(this.opacities, 1)
|
|
181
181
|
), t;
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
|
-
class xt extends
|
|
184
|
+
class xt extends i.EventDispatcher {
|
|
185
185
|
constructor() {
|
|
186
186
|
super();
|
|
187
187
|
h(this, "worker");
|
|
@@ -189,8 +189,8 @@ class xt extends a.EventDispatcher {
|
|
|
189
189
|
h(this, "orderTexture", null);
|
|
190
190
|
/** Bounding box data for optimization */
|
|
191
191
|
h(this, "chunks", null);
|
|
192
|
-
h(this, "lastCameraPosition", new
|
|
193
|
-
h(this, "lastCameraDirection", new
|
|
192
|
+
h(this, "lastCameraPosition", new i.Vector3());
|
|
193
|
+
h(this, "lastCameraDirection", new i.Vector3());
|
|
194
194
|
const o = this.createWorkerCode(), e = new Blob([o], { type: "application/javascript" });
|
|
195
195
|
this.worker = new Worker(URL.createObjectURL(e)), this.worker.onmessage = this.onWorkerMessage.bind(this);
|
|
196
196
|
}
|
|
@@ -201,14 +201,14 @@ class xt extends a.EventDispatcher {
|
|
|
201
201
|
onWorkerMessage(o) {
|
|
202
202
|
if (!this.orderTexture || !this.orderTexture.image)
|
|
203
203
|
return console.error("SplatSorter: Order texture not initialized!");
|
|
204
|
-
const { order: e, count:
|
|
205
|
-
if (!(
|
|
204
|
+
const { order: e, count: r } = o.data, s = this.orderTexture.image.data;
|
|
205
|
+
if (!(s instanceof Uint32Array))
|
|
206
206
|
return console.error(
|
|
207
207
|
"SplatSorter: Order texture data is not a Uint32Array!"
|
|
208
208
|
);
|
|
209
|
-
|
|
210
|
-
const n =
|
|
211
|
-
this.worker.postMessage(
|
|
209
|
+
s.set(new Uint32Array(e)), this.orderTexture.source.data.updateRanges || (this.orderTexture.source.data.updateRanges = []), this.orderTexture.needsUpdate = !0;
|
|
210
|
+
const n = s.buffer.slice(0), a = { order: n };
|
|
211
|
+
this.worker.postMessage(a, [n]), this.dispatchEvent({ type: "updated", count: r });
|
|
212
212
|
}
|
|
213
213
|
/**
|
|
214
214
|
* Initializes the sorter with necessary data and textures.
|
|
@@ -217,27 +217,31 @@ class xt extends a.EventDispatcher {
|
|
|
217
217
|
* @param chunks Optional: A Float32Array containing bounding box chunk data [minX, minY, minZ, maxX, maxY, maxZ, ...] for optimization.
|
|
218
218
|
* @param transferOwnership Optional: If true, transfers ownership of centers buffer to worker (saves memory, main thread loses access). Default: false.
|
|
219
219
|
*/
|
|
220
|
-
init(o, e,
|
|
220
|
+
init(o, e, r, s = !1) {
|
|
221
221
|
if (!o || !(o.image.data instanceof Uint32Array))
|
|
222
222
|
throw new Error("SplatSorter: Invalid orderTexture provided. Must be DataTexture with Uint32Array data.");
|
|
223
223
|
if (!e || e.length % 3 !== 0)
|
|
224
224
|
throw new Error("SplatSorter: Invalid centers array provided. Length must be multiple of 3.");
|
|
225
225
|
if (o.image.data.length < e.length / 3)
|
|
226
226
|
throw new Error("SplatSorter: orderTexture data buffer is smaller than the number of splats.");
|
|
227
|
+
if (e.buffer.byteLength === 0)
|
|
228
|
+
throw new Error(
|
|
229
|
+
"SplatSorter: positions buffer is detached (likely React StrictMode + cached asset). "
|
|
230
|
+
);
|
|
227
231
|
const n = e.length / 3;
|
|
228
|
-
this.orderTexture = o,
|
|
229
|
-
const
|
|
230
|
-
for (let u = 0; u < n; u++)
|
|
231
|
-
this.orderTexture.needsUpdate = !0;
|
|
232
|
-
const l =
|
|
232
|
+
this.orderTexture = o, s ? this.centers = null : this.centers = e.slice();
|
|
233
|
+
const a = this.orderTexture.image.data;
|
|
234
|
+
for (let u = 0; u < n; u++) a[u] = u;
|
|
235
|
+
this.orderTexture.source.data.updateRanges || (this.orderTexture.source.data.updateRanges = []), this.orderTexture.needsUpdate = !0;
|
|
236
|
+
const l = a.buffer.slice(0), x = s ? e.buffer : e.buffer.slice(0), b = {
|
|
233
237
|
order: l,
|
|
234
238
|
centers: x
|
|
235
239
|
}, C = [
|
|
236
240
|
l,
|
|
237
241
|
x
|
|
238
242
|
];
|
|
239
|
-
if (
|
|
240
|
-
this.chunks =
|
|
243
|
+
if (r) {
|
|
244
|
+
this.chunks = r.slice();
|
|
241
245
|
const u = this.chunks.buffer.slice(0);
|
|
242
246
|
b.chunks = u, C.push(u);
|
|
243
247
|
}
|
|
@@ -259,15 +263,15 @@ class xt extends a.EventDispatcher {
|
|
|
259
263
|
"SplatSorter: Cannot set mapping before initialization."
|
|
260
264
|
);
|
|
261
265
|
let e;
|
|
262
|
-
const
|
|
266
|
+
const r = [];
|
|
263
267
|
if (!o) {
|
|
264
268
|
const l = this.centers.buffer.slice(0);
|
|
265
269
|
return e = {
|
|
266
270
|
centers: l,
|
|
267
271
|
mapping: null
|
|
268
|
-
},
|
|
272
|
+
}, r.push(l), this.worker.postMessage(e, r);
|
|
269
273
|
}
|
|
270
|
-
const
|
|
274
|
+
const s = new Float32Array(o.length * 3);
|
|
271
275
|
for (let l = 0; l < o.length; l++) {
|
|
272
276
|
const x = o[l];
|
|
273
277
|
if (x * 3 + 2 >= this.centers.length) {
|
|
@@ -277,13 +281,13 @@ class xt extends a.EventDispatcher {
|
|
|
277
281
|
continue;
|
|
278
282
|
}
|
|
279
283
|
const b = x * 3, C = l * 3;
|
|
280
|
-
|
|
284
|
+
s[C + 0] = this.centers[b + 0], s[C + 1] = this.centers[b + 1], s[C + 2] = this.centers[b + 2];
|
|
281
285
|
}
|
|
282
|
-
const n =
|
|
286
|
+
const n = s.buffer.slice(0), a = o.buffer.slice(0);
|
|
283
287
|
e = {
|
|
284
288
|
centers: n,
|
|
285
|
-
mapping:
|
|
286
|
-
},
|
|
289
|
+
mapping: a
|
|
290
|
+
}, r.push(n, a), this.worker.postMessage(e, r);
|
|
287
291
|
}
|
|
288
292
|
/**
|
|
289
293
|
* Updates the camera parameters used for sorting.
|
|
@@ -291,8 +295,8 @@ class xt extends a.EventDispatcher {
|
|
|
291
295
|
* @param direction The camera's forward direction in the sorter's local coordinate space.
|
|
292
296
|
*/
|
|
293
297
|
setCamera(o, e) {
|
|
294
|
-
const
|
|
295
|
-
if (!
|
|
298
|
+
const r = this.lastCameraPosition.distanceToSquared(o) > 1e-7, s = this.lastCameraDirection.dot(e) < 0.9999;
|
|
299
|
+
if (!r && !s)
|
|
296
300
|
return;
|
|
297
301
|
this.lastCameraPosition.copy(o), this.lastCameraDirection.copy(e);
|
|
298
302
|
const n = {
|
|
@@ -313,10 +317,10 @@ class xt extends a.EventDispatcher {
|
|
|
313
317
|
*/
|
|
314
318
|
createWorkerCode() {
|
|
315
319
|
return `(${(function() {
|
|
316
|
-
let e = null,
|
|
317
|
-
const b = { x: 0, y: 0, z: 0 }, C = { x: 0, y: 0, z: 0 }, u = { x: 0, y: 0, z: 0 },
|
|
320
|
+
let e = null, r = null, s = null, n = null, a = null, l = null, x = !1;
|
|
321
|
+
const b = { x: 0, y: 0, z: 0 }, C = { x: 0, y: 0, z: 0 }, u = { x: 0, y: 0, z: 0 }, y = { x: 0, y: 0, z: 0 };
|
|
318
322
|
let v = null, S = null;
|
|
319
|
-
const I = 32,
|
|
323
|
+
const I = 32, q = new Array(I).fill(0), Y = new Array(I).fill(0), W = new Array(I).fill(0), ot = (w, d, P) => {
|
|
320
324
|
for (; w <= d; ) {
|
|
321
325
|
const M = d + w >> 1, f = P(M);
|
|
322
326
|
if (f > 0) w = M + 1;
|
|
@@ -325,9 +329,9 @@ class xt extends a.EventDispatcher {
|
|
|
325
329
|
}
|
|
326
330
|
return ~w;
|
|
327
331
|
}, L = () => {
|
|
328
|
-
if (!e || !
|
|
332
|
+
if (!e || !r || !a || !l)
|
|
329
333
|
return;
|
|
330
|
-
if (
|
|
334
|
+
if (r.length === 0) {
|
|
331
335
|
const c = {
|
|
332
336
|
order: e.buffer,
|
|
333
337
|
count: 0
|
|
@@ -335,27 +339,27 @@ class xt extends a.EventDispatcher {
|
|
|
335
339
|
self.postMessage(c, [e.buffer]), e = null;
|
|
336
340
|
return;
|
|
337
341
|
}
|
|
338
|
-
const w =
|
|
342
|
+
const w = a.x, d = a.y, P = a.z, M = l.x, f = l.y, A = l.z, T = 1e-4, j = Math.abs(w - b.x) > T || Math.abs(d - b.y) > T || Math.abs(P - b.z) > T, J = Math.abs(M - C.x) > T || Math.abs(f - C.y) > T || Math.abs(A - C.z) > T;
|
|
339
343
|
if (!x && !j && !J)
|
|
340
344
|
return;
|
|
341
345
|
x = !1, b.x = w, b.y = d, b.z = P, C.x = M, C.y = f, C.z = A;
|
|
342
346
|
let $ = 1 / 0, D = -1 / 0;
|
|
343
347
|
for (let c = 0; c < 8; ++c) {
|
|
344
|
-
const
|
|
348
|
+
const g = c & 1 ? u.x : y.x, B = c & 2 ? u.y : y.y, m = c & 4 ? u.z : y.z, z = g * M + B * f + m * A;
|
|
345
349
|
$ = Math.min($, z), D = Math.max(D, z);
|
|
346
350
|
}
|
|
347
|
-
const _ =
|
|
351
|
+
const _ = r.length / 3, N = D - $, R = (1 << Math.max(
|
|
348
352
|
10,
|
|
349
353
|
Math.min(20, Math.ceil(Math.log2(_ / 4)))
|
|
350
354
|
)) + 1;
|
|
351
|
-
if ((!v || v.length !== _) && (v = new Uint32Array(_)), !S || S.length !==
|
|
355
|
+
if ((!v || v.length !== _) && (v = new Uint32Array(_)), !S || S.length !== R ? S = new Uint32Array(R) : S.fill(0), N < 1e-7) {
|
|
352
356
|
for (let c = 0; c < _; ++c) v[c] = 0;
|
|
353
357
|
S[0] = _;
|
|
354
|
-
} else if (
|
|
355
|
-
const c =
|
|
356
|
-
|
|
358
|
+
} else if (s && s.length > 0) {
|
|
359
|
+
const c = s.length / 6;
|
|
360
|
+
q.fill(0);
|
|
357
361
|
for (let m = 0; m < c; ++m) {
|
|
358
|
-
const z = m * 6,
|
|
362
|
+
const z = m * 6, E = s[z + 0], U = s[z + 1], O = s[z + 2], F = s[z + 3], V = E * M + U * f + O * A - $, X = V - F, Z = V + F, K = Math.max(
|
|
359
363
|
0,
|
|
360
364
|
Math.floor(X * I / N)
|
|
361
365
|
), Q = Math.min(
|
|
@@ -363,45 +367,45 @@ class xt extends a.EventDispatcher {
|
|
|
363
367
|
Math.ceil(Z * I / N)
|
|
364
368
|
);
|
|
365
369
|
for (let H = K; H < Q; ++H)
|
|
366
|
-
|
|
370
|
+
q[H]++;
|
|
367
371
|
}
|
|
368
|
-
let
|
|
369
|
-
for (let m = 0; m < I; ++m)
|
|
372
|
+
let g = 0;
|
|
373
|
+
for (let m = 0; m < I; ++m) g += q[m];
|
|
370
374
|
W[0] = 0, Y[0] = 0;
|
|
371
375
|
for (let m = 1; m < I; ++m)
|
|
372
|
-
W[m - 1] =
|
|
373
|
-
W[I - 1] =
|
|
376
|
+
W[m - 1] = q[m - 1] / g * R >>> 0, Y[m] = Y[m - 1] + W[m - 1];
|
|
377
|
+
W[I - 1] = q[I - 1] / g * R >>> 0;
|
|
374
378
|
const B = N / I;
|
|
375
379
|
for (let m = 0; m < _; ++m) {
|
|
376
|
-
const z = m * 3,
|
|
380
|
+
const z = m * 3, E = r[z + 0], U = r[z + 1], O = r[z + 2], F = E * M + U * f + O * A, X = (D - F) / B, Z = Math.max(
|
|
377
381
|
0,
|
|
378
382
|
Math.min(
|
|
379
383
|
I - 1,
|
|
380
384
|
Math.floor(X)
|
|
381
385
|
)
|
|
382
|
-
), K = X - Z, Q = Y[Z] + W[Z] * K >>> 0, H = Math.min(Q,
|
|
386
|
+
), K = X - Z, Q = Y[Z] + W[Z] * K >>> 0, H = Math.min(Q, R - 1);
|
|
383
387
|
v[m] = H, S[H]++;
|
|
384
388
|
}
|
|
385
389
|
} else {
|
|
386
|
-
const c = (
|
|
387
|
-
for (let
|
|
388
|
-
const B =
|
|
389
|
-
v[
|
|
390
|
+
const c = (R - 1) / N;
|
|
391
|
+
for (let g = 0; g < _; ++g) {
|
|
392
|
+
const B = g * 3, m = r[B + 0], z = r[B + 1], E = r[B + 2], U = m * M + z * f + E * A, F = (D - U) * c >>> 0, V = Math.min(F, R - 1);
|
|
393
|
+
v[g] = V, S[V]++;
|
|
390
394
|
}
|
|
391
395
|
}
|
|
392
|
-
for (let c = 1; c <
|
|
396
|
+
for (let c = 1; c < R; c++)
|
|
393
397
|
S[c] += S[c - 1];
|
|
394
398
|
for (let c = _ - 1; c >= 0; c--) {
|
|
395
|
-
const
|
|
399
|
+
const g = v[c], B = --S[g];
|
|
396
400
|
e[B] = n ? n[c] : c;
|
|
397
401
|
}
|
|
398
402
|
const st = w * M + d * f + P * A, tt = (c) => {
|
|
399
403
|
if (!e) return -1 / 0;
|
|
400
|
-
const
|
|
401
|
-
if (!
|
|
404
|
+
const g = e[c], B = g;
|
|
405
|
+
if (!r || B * 3 + 2 >= r.length)
|
|
402
406
|
return -1 / 0;
|
|
403
407
|
const m = B * 3;
|
|
404
|
-
return
|
|
408
|
+
return r[m] * M + r[m + 1] * f + r[m + 2] * A - st;
|
|
405
409
|
};
|
|
406
410
|
let et = _;
|
|
407
411
|
if (_ > 0 && tt(_ - 1) < 0) {
|
|
@@ -422,45 +426,47 @@ class xt extends a.EventDispatcher {
|
|
|
422
426
|
const d = w.data;
|
|
423
427
|
d.order && (e = new Uint32Array(d.order));
|
|
424
428
|
let P = !1;
|
|
425
|
-
if (d.centers && (
|
|
426
|
-
if (
|
|
427
|
-
for (let M = 0; M <
|
|
428
|
-
const f = M * 6, A =
|
|
429
|
-
|
|
429
|
+
if (d.centers && (r = new Float32Array(d.centers), P = !0, x = !0), Object.prototype.hasOwnProperty.call(d, "mapping") && (n = d.mapping ? new Uint32Array(d.mapping) : null, x = !0), d.chunks) {
|
|
430
|
+
if (s = new Float32Array(d.chunks), s.length > 0 && s[3] > 0)
|
|
431
|
+
for (let M = 0; M < s.length / 6; ++M) {
|
|
432
|
+
const f = M * 6, A = s[f + 0], T = s[f + 1], j = s[f + 2], J = s[f + 3], $ = s[f + 4], D = s[f + 5];
|
|
433
|
+
s[f + 0] = (A + J) * 0.5, s[f + 1] = (T + $) * 0.5, s[f + 2] = (j + D) * 0.5, s[f + 3] = Math.sqrt(
|
|
430
434
|
(J - A) ** 2 + ($ - T) ** 2 + (D - j) ** 2
|
|
431
435
|
) * 0.5;
|
|
432
436
|
}
|
|
433
437
|
x = !0;
|
|
434
438
|
}
|
|
435
|
-
if (P &&
|
|
436
|
-
u.x =
|
|
437
|
-
for (let M = 1; M <
|
|
439
|
+
if (P && r && r.length > 0) {
|
|
440
|
+
u.x = y.x = r[0], u.y = y.y = r[1], u.z = y.z = r[2];
|
|
441
|
+
for (let M = 1; M < r.length / 3; M++) {
|
|
438
442
|
const f = M * 3;
|
|
439
|
-
u.x = Math.min(u.x,
|
|
443
|
+
u.x = Math.min(u.x, r[f + 0]), y.x = Math.max(y.x, r[f + 0]), u.y = Math.min(u.y, r[f + 1]), y.y = Math.max(y.y, r[f + 1]), u.z = Math.min(u.z, r[f + 2]), y.z = Math.max(y.z, r[f + 2]);
|
|
440
444
|
}
|
|
441
|
-
} else P &&
|
|
442
|
-
d.cameraPosition && (
|
|
445
|
+
} else P && r && r.length === 0 && (u.x = y.x = u.y = y.y = u.z = y.z = 0);
|
|
446
|
+
d.cameraPosition && (a = d.cameraPosition), d.cameraDirection && (l = d.cameraDirection), L();
|
|
443
447
|
};
|
|
444
448
|
}).toString()})();`;
|
|
445
449
|
}
|
|
446
450
|
}
|
|
447
|
-
const
|
|
451
|
+
const gt = (k, t) => {
|
|
448
452
|
const o = ht(k), e = ht(t);
|
|
449
453
|
return o | e << 16;
|
|
450
454
|
};
|
|
451
455
|
function ht(k) {
|
|
452
456
|
const t = new Float32Array([k]), e = new Int32Array(t.buffer)[0];
|
|
453
|
-
let
|
|
457
|
+
let r = e >> 16 & 32768, s = e >> 12 & 2047;
|
|
454
458
|
const n = e >> 23 & 255;
|
|
455
|
-
return n < 103 ?
|
|
459
|
+
return n < 103 ? r : n > 142 ? (r |= 31744, r |= (n === 255 ? 0 : 1) && e & 8388607, r) : n < 113 ? (s |= 2048, r |= (s >> 114 - n) + (s >> 113 - n & 1), r) : (r |= n - 112 << 10 | s >> 1, r += s & 1, r);
|
|
456
460
|
}
|
|
457
|
-
const
|
|
461
|
+
const yt = new ArrayBuffer(4), ut = new DataView(yt), vt = (k) => (ut.setUint32(0, k, !0), ut.getFloat32(0, !0));
|
|
458
462
|
class wt {
|
|
459
463
|
/**
|
|
460
464
|
* Create a new TextureManager for a set of splats
|
|
461
465
|
* @param splatData The splat data to manage textures for
|
|
462
466
|
*/
|
|
463
467
|
constructor(t) {
|
|
468
|
+
h(this, "textureWidth");
|
|
469
|
+
h(this, "textureHeight");
|
|
464
470
|
h(this, "transformA");
|
|
465
471
|
// position xyz and rotation quaternion y,z components
|
|
466
472
|
h(this, "transformB");
|
|
@@ -468,8 +474,6 @@ class wt {
|
|
|
468
474
|
h(this, "colorTexture");
|
|
469
475
|
// color an opacity
|
|
470
476
|
h(this, "orderTexture");
|
|
471
|
-
h(this, "textureWidth");
|
|
472
|
-
h(this, "textureHeight");
|
|
473
477
|
const o = t.numSplats;
|
|
474
478
|
this.textureWidth = Math.ceil(Math.sqrt(o)), this.textureHeight = Math.ceil(o / this.textureWidth), this.transformA = this.createTransformATexture(t), this.transformB = this.createTransformBTexture(t), this.colorTexture = this.createColorTexture(t), this.orderTexture = this.createOrderTexture(o);
|
|
475
479
|
}
|
|
@@ -482,21 +486,21 @@ class wt {
|
|
|
482
486
|
const o = t.numSplats, e = new Float32Array(
|
|
483
487
|
this.textureWidth * this.textureHeight * 4
|
|
484
488
|
);
|
|
485
|
-
for (let
|
|
486
|
-
const n =
|
|
487
|
-
e[n] = t.positions[
|
|
488
|
-
const x = t.rotations[l + 0], b = t.rotations[l + 1], C =
|
|
489
|
+
for (let s = 0; s < o; s++) {
|
|
490
|
+
const n = s * 4, a = s * 3, l = s * 4;
|
|
491
|
+
e[n] = t.positions[a], e[n + 1] = t.positions[a + 1], e[n + 2] = t.positions[a + 2];
|
|
492
|
+
const x = t.rotations[l + 0], b = t.rotations[l + 1], C = gt(x, b);
|
|
489
493
|
e[n + 3] = vt(C);
|
|
490
494
|
}
|
|
491
|
-
const
|
|
495
|
+
const r = new i.DataTexture(
|
|
492
496
|
e,
|
|
493
497
|
this.textureWidth,
|
|
494
498
|
this.textureHeight,
|
|
495
|
-
|
|
496
|
-
|
|
499
|
+
i.RGBAFormat,
|
|
500
|
+
i.FloatType
|
|
497
501
|
// Store as Float32, shader will reinterpret bits
|
|
498
502
|
);
|
|
499
|
-
return
|
|
503
|
+
return r.magFilter = i.NearestFilter, r.minFilter = i.NearestFilter, r.source.data.updateRanges || (r.source.data.updateRanges = []), r.needsUpdate = !0, r;
|
|
500
504
|
}
|
|
501
505
|
/**
|
|
502
506
|
* Create the transform B texture (scale and rotation xyz)
|
|
@@ -507,18 +511,18 @@ class wt {
|
|
|
507
511
|
const o = t.numSplats, e = new Float32Array(
|
|
508
512
|
this.textureWidth * this.textureHeight * 4
|
|
509
513
|
);
|
|
510
|
-
for (let
|
|
511
|
-
const n =
|
|
512
|
-
e[n] = t.scales[
|
|
514
|
+
for (let s = 0; s < o; s++) {
|
|
515
|
+
const n = s * 4, a = s * 3, l = s * 4;
|
|
516
|
+
e[n] = t.scales[a], e[n + 1] = t.scales[a + 1], e[n + 2] = t.scales[a + 2], e[n + 3] = t.rotations[l + 2];
|
|
513
517
|
}
|
|
514
|
-
const
|
|
518
|
+
const r = new i.DataTexture(
|
|
515
519
|
e,
|
|
516
520
|
this.textureWidth,
|
|
517
521
|
this.textureHeight,
|
|
518
|
-
|
|
519
|
-
|
|
522
|
+
i.RGBAFormat,
|
|
523
|
+
i.FloatType
|
|
520
524
|
);
|
|
521
|
-
return
|
|
525
|
+
return r.magFilter = i.NearestFilter, r.minFilter = i.NearestFilter, r.source.data.updateRanges || (r.source.data.updateRanges = []), r.needsUpdate = !0, r;
|
|
522
526
|
}
|
|
523
527
|
/**
|
|
524
528
|
* Create the color texture (RGB and opacity)
|
|
@@ -529,18 +533,18 @@ class wt {
|
|
|
529
533
|
const o = t.numSplats, e = new Float32Array(
|
|
530
534
|
this.textureWidth * this.textureHeight * 4
|
|
531
535
|
);
|
|
532
|
-
for (let
|
|
533
|
-
const n =
|
|
534
|
-
e[n] = t.colors[
|
|
536
|
+
for (let s = 0; s < o; s++) {
|
|
537
|
+
const n = s * 4, a = s * 3;
|
|
538
|
+
e[n] = t.colors[a], e[n + 1] = t.colors[a + 1], e[n + 2] = t.colors[a + 2], e[n + 3] = t.opacities[s];
|
|
535
539
|
}
|
|
536
|
-
const
|
|
540
|
+
const r = new i.DataTexture(
|
|
537
541
|
e,
|
|
538
542
|
this.textureWidth,
|
|
539
543
|
this.textureHeight,
|
|
540
|
-
|
|
541
|
-
|
|
544
|
+
i.RGBAFormat,
|
|
545
|
+
i.FloatType
|
|
542
546
|
);
|
|
543
|
-
return
|
|
547
|
+
return r.source.data.updateRanges || (r.source.data.updateRanges = []), r.needsUpdate = !0, r;
|
|
544
548
|
}
|
|
545
549
|
/**
|
|
546
550
|
* Create the order texture for sorting
|
|
@@ -549,16 +553,16 @@ class wt {
|
|
|
549
553
|
*/
|
|
550
554
|
createOrderTexture(t) {
|
|
551
555
|
const o = new Uint32Array(this.textureWidth * this.textureHeight);
|
|
552
|
-
for (let
|
|
553
|
-
o[
|
|
554
|
-
const e = new
|
|
556
|
+
for (let r = 0; r < t; r++)
|
|
557
|
+
o[r] = r;
|
|
558
|
+
const e = new i.DataTexture(
|
|
555
559
|
o,
|
|
556
560
|
this.textureWidth,
|
|
557
561
|
this.textureHeight,
|
|
558
|
-
|
|
559
|
-
|
|
562
|
+
i.RedIntegerFormat,
|
|
563
|
+
i.UnsignedIntType
|
|
560
564
|
);
|
|
561
|
-
return e.needsUpdate = !0, e;
|
|
565
|
+
return e.source.data.updateRanges || (e.source.data.updateRanges = []), e.needsUpdate = !0, e;
|
|
562
566
|
}
|
|
563
567
|
dispose() {
|
|
564
568
|
this.transformA.dispose(), this.transformB.dispose(), this.colorTexture.dispose(), this.orderTexture.dispose();
|
|
@@ -856,7 +860,7 @@ void main(void) {
|
|
|
856
860
|
}
|
|
857
861
|
`
|
|
858
862
|
);
|
|
859
|
-
class Ct extends
|
|
863
|
+
class Ct extends i.ShaderMaterial {
|
|
860
864
|
constructor(t = {}) {
|
|
861
865
|
const o = {
|
|
862
866
|
// Textures (values set via methods)
|
|
@@ -865,7 +869,7 @@ class Ct extends a.ShaderMaterial {
|
|
|
865
869
|
splatColor: { value: null },
|
|
866
870
|
splatOrder: { value: null },
|
|
867
871
|
// Other uniforms
|
|
868
|
-
viewport: { value: new
|
|
872
|
+
viewport: { value: new i.Vector2(1, 1) },
|
|
869
873
|
// Will be updated
|
|
870
874
|
numSplats: { value: 0 }
|
|
871
875
|
// Max splats to render (updated by sorter)
|
|
@@ -875,29 +879,29 @@ class Ct extends a.ShaderMaterial {
|
|
|
875
879
|
fragmentShader: Mt,
|
|
876
880
|
uniforms: o,
|
|
877
881
|
transparent: !0,
|
|
878
|
-
blending:
|
|
882
|
+
blending: i.CustomBlending,
|
|
879
883
|
// Premultiplied alpha blending:
|
|
880
884
|
// color = src_color * src_alpha + dst_color * (1 - src_alpha)
|
|
881
885
|
// alpha = src_alpha * 1 + dst_alpha * (1 - src_alpha)
|
|
882
|
-
blendSrc:
|
|
886
|
+
blendSrc: i.OneFactor,
|
|
883
887
|
// Using ONE because shader outputs premultiplied color (color * alpha)
|
|
884
|
-
blendDst:
|
|
885
|
-
blendSrcAlpha:
|
|
888
|
+
blendDst: i.OneMinusSrcAlphaFactor,
|
|
889
|
+
blendSrcAlpha: i.OneFactor,
|
|
886
890
|
// source alpha comes from shader
|
|
887
|
-
blendDstAlpha:
|
|
888
|
-
blendEquation:
|
|
889
|
-
blendEquationAlpha:
|
|
891
|
+
blendDstAlpha: i.OneMinusSrcAlphaFactor,
|
|
892
|
+
blendEquation: i.AddEquation,
|
|
893
|
+
blendEquationAlpha: i.AddEquation,
|
|
890
894
|
depthTest: !0,
|
|
891
895
|
depthWrite: !1,
|
|
892
896
|
// Disable depth write for transparency
|
|
893
|
-
side:
|
|
897
|
+
side: i.DoubleSide,
|
|
894
898
|
// Render both sides (or CULLFACE_NONE equivalent)
|
|
895
899
|
// Optional settings from constructor
|
|
896
900
|
alphaTest: t.alphaTest !== void 0 ? t.alphaTest : 0,
|
|
897
901
|
// Typically 0 for blending
|
|
898
902
|
toneMapped: t.toneMapped !== void 0 ? t.toneMapped : !1
|
|
899
903
|
// prettier-ignore
|
|
900
|
-
}), t.alphaHash && (this.alphaHash = !0, this.depthWrite = !0, this.blending =
|
|
904
|
+
}), t.alphaHash && (this.alphaHash = !0, this.depthWrite = !0, this.blending = i.NoBlending);
|
|
901
905
|
}
|
|
902
906
|
/**
|
|
903
907
|
* Update the viewport size
|
|
@@ -943,7 +947,7 @@ class Ct extends a.ShaderMaterial {
|
|
|
943
947
|
this.uniforms.numSplats.value = t;
|
|
944
948
|
}
|
|
945
949
|
}
|
|
946
|
-
const rt = class rt extends
|
|
950
|
+
const rt = class rt extends i.Mesh {
|
|
947
951
|
// Match shader constant
|
|
948
952
|
/**
|
|
949
953
|
* Create a new SplatMesh for rendering Gaussian splats
|
|
@@ -951,30 +955,30 @@ const rt = class rt extends a.Mesh {
|
|
|
951
955
|
* @param options Rendering options
|
|
952
956
|
*/
|
|
953
957
|
constructor(o, e = {}) {
|
|
954
|
-
const
|
|
955
|
-
super(
|
|
958
|
+
const r = new Ct(e), s = rt.createInstancedGeometry(o.numSplats, rt.INSTANCE_SIZE);
|
|
959
|
+
super(s, r);
|
|
956
960
|
h(this, "sorter");
|
|
957
961
|
h(this, "splatData");
|
|
958
962
|
h(this, "options");
|
|
959
963
|
h(this, "textureManager");
|
|
960
964
|
h(this, "material");
|
|
961
965
|
h(this, "geometry");
|
|
962
|
-
h(this, "lastCameraPositionLocal", new
|
|
963
|
-
h(this, "lastCameraDirectionLocal", new
|
|
964
|
-
h(this, "invModelMatrix", new
|
|
966
|
+
h(this, "lastCameraPositionLocal", new i.Vector3());
|
|
967
|
+
h(this, "lastCameraDirectionLocal", new i.Vector3());
|
|
968
|
+
h(this, "invModelMatrix", new i.Matrix4());
|
|
965
969
|
// Cached inverse matrix
|
|
966
970
|
h(this, "_vpW", -1);
|
|
967
971
|
h(this, "_vpH", -1);
|
|
968
|
-
h(this, "_size", new
|
|
969
|
-
h(this, "_camPosW", new
|
|
970
|
-
h(this, "_camDirW", new
|
|
971
|
-
h(this, "_camPosL", new
|
|
972
|
-
h(this, "_camDirL", new
|
|
972
|
+
h(this, "_size", new i.Vector2());
|
|
973
|
+
h(this, "_camPosW", new i.Vector3());
|
|
974
|
+
h(this, "_camDirW", new i.Vector3());
|
|
975
|
+
h(this, "_camPosL", new i.Vector3());
|
|
976
|
+
h(this, "_camDirL", new i.Vector3());
|
|
973
977
|
h(this, "onSorterUpdated", (o) => {
|
|
974
978
|
const e = o.count;
|
|
975
979
|
this.geometry.instanceCount = Math.ceil(e / rt.INSTANCE_SIZE), this.material.setNumSplats(e);
|
|
976
980
|
});
|
|
977
|
-
this.geometry =
|
|
981
|
+
this.geometry = s, this.material = r, this.splatData = o, this.frustumCulled = !1, this.options = {
|
|
978
982
|
autoSort: !0,
|
|
979
983
|
...e
|
|
980
984
|
}, this.textureManager = new wt(o), this.sorter = new xt();
|
|
@@ -984,7 +988,7 @@ const rt = class rt extends a.Mesh {
|
|
|
984
988
|
this.splatData.positions,
|
|
985
989
|
n ?? void 0,
|
|
986
990
|
!this.options.keepSplatData
|
|
987
|
-
), 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
|
|
991
|
+
), 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 i.Sphere(), this.geometry.boundingBox.getBoundingSphere(this.geometry.boundingSphere), this.options.keepSplatData || (this.splatData = null);
|
|
988
992
|
}
|
|
989
993
|
/**
|
|
990
994
|
* Creates the instanced geometry for rendering splats.
|
|
@@ -993,7 +997,7 @@ const rt = class rt extends a.Mesh {
|
|
|
993
997
|
* @returns InstancedBufferGeometry
|
|
994
998
|
*/
|
|
995
999
|
static createInstancedGeometry(o, e) {
|
|
996
|
-
const
|
|
1000
|
+
const r = Math.ceil(o / e), s = new i.BufferGeometry(), n = new Float32Array([
|
|
997
1001
|
// x, y, splat_index_in_instance
|
|
998
1002
|
-1,
|
|
999
1003
|
-1,
|
|
@@ -1007,24 +1011,24 @@ const rt = class rt extends a.Mesh {
|
|
|
1007
1011
|
-1,
|
|
1008
1012
|
1,
|
|
1009
1013
|
0
|
|
1010
|
-
]),
|
|
1014
|
+
]), a = new Uint16Array([0, 1, 2, 0, 2, 3]), l = new Float32Array(4 * 3 * e);
|
|
1011
1015
|
for (let u = 0; u < e; u++) {
|
|
1012
|
-
const
|
|
1016
|
+
const y = u * 4 * 3;
|
|
1013
1017
|
for (let v = 0; v < 4; v++)
|
|
1014
|
-
l[
|
|
1018
|
+
l[y + v * 3 + 0] = n[v * 3 + 0], l[y + v * 3 + 1] = n[v * 3 + 1], l[y + v * 3 + 2] = u;
|
|
1015
1019
|
}
|
|
1016
1020
|
const x = new Uint32Array(6 * e);
|
|
1017
1021
|
for (let u = 0; u < e; u++) {
|
|
1018
|
-
const
|
|
1019
|
-
x[
|
|
1022
|
+
const y = u * 6, v = u * 4;
|
|
1023
|
+
x[y + 0] = a[0] + v, x[y + 1] = a[1] + v, x[y + 2] = a[2] + v, x[y + 3] = a[3] + v, x[y + 4] = a[4] + v, x[y + 5] = a[5] + v;
|
|
1020
1024
|
}
|
|
1021
|
-
|
|
1022
|
-
const b = new
|
|
1023
|
-
b.index =
|
|
1024
|
-
const C = new Uint32Array(
|
|
1025
|
-
for (let u = 0; u <
|
|
1025
|
+
s.setAttribute("position", new i.BufferAttribute(l, 3)), s.setIndex(new i.BufferAttribute(x, 1));
|
|
1026
|
+
const b = new i.InstancedBufferGeometry();
|
|
1027
|
+
b.index = s.index, b.setAttribute("position", s.getAttribute("position"));
|
|
1028
|
+
const C = new Uint32Array(r);
|
|
1029
|
+
for (let u = 0; u < r; u++)
|
|
1026
1030
|
C[u] = u * e;
|
|
1027
|
-
return b.setAttribute("splatInstanceIndex", new
|
|
1031
|
+
return b.setAttribute("splatInstanceIndex", new i.InstancedBufferAttribute(C, 1, !1)), b.instanceCount = 0, b;
|
|
1028
1032
|
}
|
|
1029
1033
|
/**
|
|
1030
1034
|
* Create chunks data (bounding box min/max) for the sorter.
|
|
@@ -1057,8 +1061,8 @@ const rt = class rt extends a.Mesh {
|
|
|
1057
1061
|
*/
|
|
1058
1062
|
sort(o) {
|
|
1059
1063
|
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);
|
|
1060
|
-
const e = this.lastCameraPositionLocal.distanceToSquared(this._camPosL) > 1e-6,
|
|
1061
|
-
this.options.autoSort && (e ||
|
|
1064
|
+
const e = this.lastCameraPositionLocal.distanceToSquared(this._camPosL) > 1e-6, r = this.lastCameraDirectionLocal.dot(this._camDirL) < 0.999;
|
|
1065
|
+
this.options.autoSort && (e || r) && (this.lastCameraPositionLocal.copy(this._camPosL), this.lastCameraDirectionLocal.copy(this._camDirL), this.sorter.setCamera(this._camPosL, this._camDirL));
|
|
1062
1066
|
}
|
|
1063
1067
|
/**
|
|
1064
1068
|
* THREE.js hook called before rendering the object.
|
|
@@ -1069,8 +1073,8 @@ const rt = class rt extends a.Mesh {
|
|
|
1069
1073
|
*/
|
|
1070
1074
|
// prettier-ignore
|
|
1071
1075
|
// @ts-expect-error scene is not used
|
|
1072
|
-
onBeforeRender(o, e,
|
|
1073
|
-
this.sort(
|
|
1076
|
+
onBeforeRender(o, e, r) {
|
|
1077
|
+
this.sort(r), o.getSize(this._size), this.updateViewport(this._size.x, this._size.y);
|
|
1074
1078
|
}
|
|
1075
1079
|
/**
|
|
1076
1080
|
* Dispose of resources
|
|
@@ -1082,37 +1086,37 @@ const rt = class rt extends a.Mesh {
|
|
|
1082
1086
|
/** Number of splats combined into a single instanced draw call. */
|
|
1083
1087
|
h(rt, "INSTANCE_SIZE", 128);
|
|
1084
1088
|
let dt = rt;
|
|
1085
|
-
class At extends
|
|
1089
|
+
class At extends i.Loader {
|
|
1086
1090
|
constructor(o) {
|
|
1087
1091
|
super(o);
|
|
1088
1092
|
h(this, "requestId", 0);
|
|
1089
1093
|
h(this, "worker");
|
|
1090
1094
|
h(this, "pendingCallbacks", /* @__PURE__ */ new Map());
|
|
1091
|
-
const e = this.createWorkerCode(),
|
|
1092
|
-
this.worker = new Worker(URL.createObjectURL(
|
|
1095
|
+
const e = this.createWorkerCode(), r = new Blob([e], { type: "application/javascript" });
|
|
1096
|
+
this.worker = new Worker(URL.createObjectURL(r)), this.worker.onmessage = this.onWorkerMessage.bind(this);
|
|
1093
1097
|
}
|
|
1094
1098
|
/**
|
|
1095
1099
|
* Handles messages received from the parsing worker
|
|
1096
1100
|
* @param event The message event from the worker
|
|
1097
1101
|
*/
|
|
1098
1102
|
onWorkerMessage(o) {
|
|
1099
|
-
const { requestId: e, error:
|
|
1103
|
+
const { requestId: e, error: r, result: s } = o.data, n = this.pendingCallbacks.get(e);
|
|
1100
1104
|
if (!n) return console.warn(`PlyLoader: Received response for unknown request ${e}`);
|
|
1101
|
-
if (this.pendingCallbacks.delete(e),
|
|
1102
|
-
if (!
|
|
1105
|
+
if (this.pendingCallbacks.delete(e), r) return n.reject(new Error(r));
|
|
1106
|
+
if (!s) return n.reject(new Error("Worker returned no result"));
|
|
1103
1107
|
try {
|
|
1104
|
-
const
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
),
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
), n.resolve(
|
|
1114
|
-
} catch (
|
|
1115
|
-
n.reject(
|
|
1108
|
+
const a = new mt(0);
|
|
1109
|
+
a.numSplats = s.numSplats, a.positions = new Float32Array(s.positions), a.rotations = new Float32Array(s.rotations), a.scales = new Float32Array(s.scales), a.colors = new Float32Array(s.colors), a.opacities = new Float32Array(s.opacities), a.boundingBox.min.set(
|
|
1110
|
+
s.boundingBox.minX,
|
|
1111
|
+
s.boundingBox.minY,
|
|
1112
|
+
s.boundingBox.minZ
|
|
1113
|
+
), a.boundingBox.max.set(
|
|
1114
|
+
s.boundingBox.maxX,
|
|
1115
|
+
s.boundingBox.maxY,
|
|
1116
|
+
s.boundingBox.maxZ
|
|
1117
|
+
), this.worker.terminate(), n.resolve(a);
|
|
1118
|
+
} catch (a) {
|
|
1119
|
+
n.reject(a);
|
|
1116
1120
|
}
|
|
1117
1121
|
}
|
|
1118
1122
|
/**
|
|
@@ -1122,19 +1126,19 @@ class At extends a.Loader {
|
|
|
1122
1126
|
* @param onProgress Optional progress callback
|
|
1123
1127
|
* @param onError Optional error callback
|
|
1124
1128
|
*/
|
|
1125
|
-
load(o, e,
|
|
1126
|
-
const n = new
|
|
1129
|
+
load(o, e, r, s) {
|
|
1130
|
+
const n = new i.FileLoader(this.manager);
|
|
1127
1131
|
n.setResponseType("arraybuffer"), n.setRequestHeader(this.requestHeader), n.setPath(this.path), n.setWithCredentials(this.withCredentials), n.load(
|
|
1128
1132
|
o,
|
|
1129
|
-
(
|
|
1130
|
-
this.parseAsync(
|
|
1133
|
+
(a) => {
|
|
1134
|
+
this.parseAsync(a).then((l) => {
|
|
1131
1135
|
e && e(l);
|
|
1132
1136
|
}).catch((l) => {
|
|
1133
|
-
|
|
1137
|
+
s ? s(l) : console.error(l), this.manager.itemError(o);
|
|
1134
1138
|
});
|
|
1135
1139
|
},
|
|
1136
|
-
|
|
1137
|
-
|
|
1140
|
+
r,
|
|
1141
|
+
s
|
|
1138
1142
|
);
|
|
1139
1143
|
}
|
|
1140
1144
|
/**
|
|
@@ -1144,18 +1148,18 @@ class At extends a.Loader {
|
|
|
1144
1148
|
* @returns A Promise that resolves with the parsed SplatData
|
|
1145
1149
|
*/
|
|
1146
1150
|
loadAsync(o, e) {
|
|
1147
|
-
return new Promise((
|
|
1148
|
-
const n = new
|
|
1151
|
+
return new Promise((r, s) => {
|
|
1152
|
+
const n = new i.FileLoader(this.manager);
|
|
1149
1153
|
n.setResponseType("arraybuffer"), n.setRequestHeader(this.requestHeader), n.setPath(this.path), n.setWithCredentials(this.withCredentials), n.load(
|
|
1150
1154
|
o,
|
|
1151
|
-
(
|
|
1152
|
-
this.parseAsync(
|
|
1153
|
-
|
|
1155
|
+
(a) => {
|
|
1156
|
+
this.parseAsync(a).then(r).catch((l) => {
|
|
1157
|
+
s(l), this.manager.itemError(o);
|
|
1154
1158
|
});
|
|
1155
1159
|
},
|
|
1156
1160
|
e,
|
|
1157
|
-
(
|
|
1158
|
-
|
|
1161
|
+
(a) => {
|
|
1162
|
+
s(a), this.manager.itemError(o);
|
|
1159
1163
|
}
|
|
1160
1164
|
);
|
|
1161
1165
|
});
|
|
@@ -1166,11 +1170,11 @@ class At extends a.Loader {
|
|
|
1166
1170
|
* @returns Promise that resolves with parsed SplatData
|
|
1167
1171
|
*/
|
|
1168
1172
|
parseAsync(o) {
|
|
1169
|
-
return new Promise((e,
|
|
1170
|
-
const
|
|
1171
|
-
this.pendingCallbacks.set(
|
|
1173
|
+
return new Promise((e, r) => {
|
|
1174
|
+
const s = this.requestId++;
|
|
1175
|
+
this.pendingCallbacks.set(s, { resolve: e, reject: r });
|
|
1172
1176
|
const n = {
|
|
1173
|
-
requestId:
|
|
1177
|
+
requestId: s,
|
|
1174
1178
|
buffer: o
|
|
1175
1179
|
};
|
|
1176
1180
|
this.worker.postMessage(n, [o]);
|
|
@@ -1188,42 +1192,42 @@ class At extends a.Loader {
|
|
|
1188
1192
|
*/
|
|
1189
1193
|
createWorkerCode() {
|
|
1190
1194
|
return `(${(function() {
|
|
1191
|
-
self.onmessage = (
|
|
1192
|
-
const { requestId:
|
|
1195
|
+
self.onmessage = (r) => {
|
|
1196
|
+
const { requestId: s, buffer: n } = r.data;
|
|
1193
1197
|
try {
|
|
1194
|
-
const
|
|
1195
|
-
requestId:
|
|
1196
|
-
result:
|
|
1198
|
+
const a = e(n), l = {
|
|
1199
|
+
requestId: s,
|
|
1200
|
+
result: a
|
|
1197
1201
|
};
|
|
1198
1202
|
self.postMessage(l, [
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1203
|
+
a.positions,
|
|
1204
|
+
a.rotations,
|
|
1205
|
+
a.scales,
|
|
1206
|
+
a.colors,
|
|
1207
|
+
a.opacities
|
|
1204
1208
|
]);
|
|
1205
|
-
} catch (
|
|
1209
|
+
} catch (a) {
|
|
1206
1210
|
const l = {
|
|
1207
|
-
requestId:
|
|
1208
|
-
error:
|
|
1211
|
+
requestId: s,
|
|
1212
|
+
error: a instanceof Error ? a.message : String(a)
|
|
1209
1213
|
};
|
|
1210
1214
|
self.postMessage(l);
|
|
1211
1215
|
}
|
|
1212
1216
|
};
|
|
1213
|
-
function e(
|
|
1214
|
-
const
|
|
1217
|
+
function e(r) {
|
|
1218
|
+
const s = new TextDecoder(), n = new Uint8Array(r), a = [112, 108, 121, 10], l = `
|
|
1215
1219
|
end_header
|
|
1216
1220
|
`;
|
|
1217
|
-
for (let p = 0; p <
|
|
1218
|
-
if (n[p] !==
|
|
1221
|
+
for (let p = 0; p < a.length; p++)
|
|
1222
|
+
if (n[p] !== a[p])
|
|
1219
1223
|
throw new Error(
|
|
1220
1224
|
"Invalid PLY file: Missing magic bytes"
|
|
1221
1225
|
);
|
|
1222
1226
|
let x = 0;
|
|
1223
1227
|
for (let p = 0; p < n.length - l.length; p++) {
|
|
1224
1228
|
let c = !0;
|
|
1225
|
-
for (let
|
|
1226
|
-
if (n[p +
|
|
1229
|
+
for (let g = 0; g < l.length; g++)
|
|
1230
|
+
if (n[p + g] !== l.charCodeAt(g)) {
|
|
1227
1231
|
c = !1;
|
|
1228
1232
|
break;
|
|
1229
1233
|
}
|
|
@@ -1236,23 +1240,23 @@ end_header
|
|
|
1236
1240
|
throw new Error(
|
|
1237
1241
|
"Invalid PLY file: Could not find end of header"
|
|
1238
1242
|
);
|
|
1239
|
-
const C =
|
|
1243
|
+
const C = s.decode(
|
|
1240
1244
|
n.subarray(0, x)
|
|
1241
1245
|
).split(`
|
|
1242
1246
|
`), u = [];
|
|
1243
|
-
let
|
|
1247
|
+
let y = null;
|
|
1244
1248
|
for (let p = 1; p < C.length; p++) {
|
|
1245
1249
|
const c = C[p].trim();
|
|
1246
1250
|
if (c === "" || c === "end_header") continue;
|
|
1247
|
-
const
|
|
1248
|
-
switch (
|
|
1251
|
+
const g = c.split(" ");
|
|
1252
|
+
switch (g[0]) {
|
|
1249
1253
|
case "format":
|
|
1250
|
-
|
|
1254
|
+
y = g[1];
|
|
1251
1255
|
break;
|
|
1252
1256
|
case "element":
|
|
1253
1257
|
u.push({
|
|
1254
|
-
name:
|
|
1255
|
-
count: parseInt(
|
|
1258
|
+
name: g[1],
|
|
1259
|
+
count: parseInt(g[2], 10),
|
|
1256
1260
|
properties: []
|
|
1257
1261
|
});
|
|
1258
1262
|
break;
|
|
@@ -1262,20 +1266,20 @@ end_header
|
|
|
1262
1266
|
"Invalid PLY file: Property without element"
|
|
1263
1267
|
);
|
|
1264
1268
|
u[u.length - 1].properties.push({
|
|
1265
|
-
type:
|
|
1266
|
-
name:
|
|
1269
|
+
type: g[1],
|
|
1270
|
+
name: g[2]
|
|
1267
1271
|
});
|
|
1268
1272
|
break;
|
|
1269
1273
|
}
|
|
1270
1274
|
}
|
|
1271
|
-
if (
|
|
1272
|
-
throw new Error(`Unsupported PLY format: ${
|
|
1275
|
+
if (y !== "binary_little_endian")
|
|
1276
|
+
throw new Error(`Unsupported PLY format: ${y}`);
|
|
1273
1277
|
const v = u.find((p) => p.name === "vertex");
|
|
1274
1278
|
if (!v)
|
|
1275
1279
|
throw new Error(
|
|
1276
1280
|
"Invalid PLY file: No vertex element found"
|
|
1277
1281
|
);
|
|
1278
|
-
const S = v.count, I = new Float32Array(S * 3),
|
|
1282
|
+
const S = v.count, I = new Float32Array(S * 3), q = new Float32Array(S * 4), Y = new Float32Array(S * 3), W = new Float32Array(S * 3), ot = new Float32Array(S), L = new DataView(r);
|
|
1279
1283
|
let w = x;
|
|
1280
1284
|
const d = (p) => v.properties.findIndex(
|
|
1281
1285
|
(c) => c.name === p
|
|
@@ -1310,11 +1314,11 @@ end_header
|
|
|
1310
1314
|
const c = Math.exp(p);
|
|
1311
1315
|
return c / (1 + c);
|
|
1312
1316
|
};
|
|
1313
|
-
let N = 1 / 0, nt = 1 / 0,
|
|
1317
|
+
let N = 1 / 0, nt = 1 / 0, R = 1 / 0, st = -1 / 0, tt = -1 / 0, et = -1 / 0;
|
|
1314
1318
|
for (let p = 0; p < S; p++) {
|
|
1315
1319
|
const c = [];
|
|
1316
|
-
for (let
|
|
1317
|
-
const lt = v.properties[
|
|
1320
|
+
for (let it = 0; it < v.properties.length; it++) {
|
|
1321
|
+
const lt = v.properties[it].type;
|
|
1318
1322
|
let G;
|
|
1319
1323
|
switch (lt) {
|
|
1320
1324
|
case "char":
|
|
@@ -1348,33 +1352,33 @@ end_header
|
|
|
1348
1352
|
}
|
|
1349
1353
|
c.push(G);
|
|
1350
1354
|
}
|
|
1351
|
-
const
|
|
1352
|
-
I[z] =
|
|
1353
|
-
let
|
|
1354
|
-
const
|
|
1355
|
-
|
|
1355
|
+
const g = c[P], B = c[M], m = c[f], z = p * 3;
|
|
1356
|
+
I[z] = g, I[z + 1] = B, I[z + 2] = m, N = Math.min(N, g), nt = Math.min(nt, B), R = Math.min(R, m), st = Math.max(st, g), tt = Math.max(tt, B), et = Math.max(et, m);
|
|
1357
|
+
let E = c[A[1]], U = c[A[2]], O = c[A[3]], F = c[A[0]];
|
|
1358
|
+
const V = Math.sqrt(
|
|
1359
|
+
E * E + U * U + O * O + F * F
|
|
1356
1360
|
);
|
|
1357
|
-
|
|
1361
|
+
V > 0 && (E /= V, U /= V, O /= V, F /= V), F < 0 && (E = -E, U = -U, O = -O, F = -F);
|
|
1358
1362
|
const X = p * 4;
|
|
1359
|
-
|
|
1363
|
+
q[X] = E, q[X + 1] = U, q[X + 2] = O, q[X + 3] = F;
|
|
1360
1364
|
const Z = p * 3;
|
|
1361
1365
|
Y[Z] = c[T[0]], Y[Z + 1] = c[T[1]], Y[Z + 2] = c[T[2]];
|
|
1362
1366
|
let K = 0.5 + c[j[0]] * D, Q = 0.5 + c[j[1]] * D, H = 0.5 + c[j[2]] * D;
|
|
1363
1367
|
K = Math.max(0, Math.min(1, K)), Q = Math.max(0, Math.min(1, Q)), H = Math.max(0, Math.min(1, H));
|
|
1364
|
-
const
|
|
1365
|
-
W[
|
|
1368
|
+
const at = p * 3;
|
|
1369
|
+
W[at] = K, W[at + 1] = Q, W[at + 2] = H, ot[p] = _(c[J]);
|
|
1366
1370
|
}
|
|
1367
1371
|
return {
|
|
1368
1372
|
numSplats: S,
|
|
1369
1373
|
positions: I.buffer,
|
|
1370
|
-
rotations:
|
|
1374
|
+
rotations: q.buffer,
|
|
1371
1375
|
scales: Y.buffer,
|
|
1372
1376
|
colors: W.buffer,
|
|
1373
1377
|
opacities: ot.buffer,
|
|
1374
1378
|
boundingBox: {
|
|
1375
1379
|
minX: N,
|
|
1376
1380
|
minY: nt,
|
|
1377
|
-
minZ:
|
|
1381
|
+
minZ: R,
|
|
1378
1382
|
maxX: st,
|
|
1379
1383
|
maxY: tt,
|
|
1380
1384
|
maxZ: et
|