@needle-tools/gltf-progressive 3.6.0 → 3.6.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/CHANGELOG.md +4 -0
- package/gltf-progressive.js +520 -507
- package/gltf-progressive.min.js +9 -9
- package/gltf-progressive.umd.cjs +9 -9
- package/lib/extension.d.ts +2 -0
- package/lib/extension.js +29 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
package/gltf-progressive.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as Xe from "three";
|
|
2
|
-
import { RedFormat as je, RedIntegerFormat as Ke, RGFormat as Ye, RGIntegerFormat as He, RGBFormat as Qe, RGBAFormat as Je, RGBAIntegerFormat as Ze, BufferGeometry as
|
|
3
|
-
import { GLTFLoader as
|
|
2
|
+
import { RedFormat as je, RedIntegerFormat as Ke, RGFormat as Ye, RGIntegerFormat as He, RGBFormat as Qe, RGBAFormat as Je, RGBAIntegerFormat as Ze, BufferGeometry as Y, Mesh as H, Box3 as fe, Vector3 as A, Sphere as Ie, CompressedTexture as et, Texture as W, Matrix3 as tt, InterleavedBuffer as st, InterleavedBufferAttribute as rt, BufferAttribute as nt, TextureLoader as it, Color as $e, Matrix4 as Ge } from "three";
|
|
3
|
+
import { GLTFLoader as Me } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
4
4
|
import { MeshoptDecoder as ot } from "three/examples/jsm/libs/meshopt_decoder.module.js";
|
|
5
5
|
import { DRACOLoader as at } from "three/examples/jsm/loaders/DRACOLoader.js";
|
|
6
6
|
import { KTX2Loader as lt } from "three/examples/jsm/loaders/KTX2Loader.js";
|
|
7
7
|
const ut = "";
|
|
8
8
|
globalThis.GLTF_PROGRESSIVE_VERSION = ut;
|
|
9
9
|
console.debug("[gltf-progressive] version -");
|
|
10
|
-
let
|
|
11
|
-
const ct =
|
|
10
|
+
let B = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", Q = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
|
|
11
|
+
const ct = B, ft = Q, Be = new URL(B + "draco_decoder.js");
|
|
12
12
|
Be.searchParams.append("range", "true");
|
|
13
13
|
fetch(Be, {
|
|
14
14
|
method: "GET",
|
|
@@ -16,39 +16,39 @@ fetch(Be, {
|
|
|
16
16
|
Range: "bytes=0-1"
|
|
17
17
|
}
|
|
18
18
|
}).catch((i) => {
|
|
19
|
-
console.debug(`Failed to fetch remote Draco decoder from ${
|
|
19
|
+
console.debug(`Failed to fetch remote Draco decoder from ${B} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), B === ct && ht("./include/draco/"), Q === ft && gt("./include/ktx2/");
|
|
20
20
|
}).finally(() => {
|
|
21
|
-
|
|
21
|
+
We();
|
|
22
22
|
});
|
|
23
23
|
const dt = () => ({
|
|
24
|
-
dracoDecoderPath:
|
|
25
|
-
ktx2TranscoderPath:
|
|
24
|
+
dracoDecoderPath: B,
|
|
25
|
+
ktx2TranscoderPath: Q
|
|
26
26
|
});
|
|
27
27
|
function ht(i) {
|
|
28
|
-
|
|
28
|
+
B = i, C && C[xe] != B ? (console.debug("Updating Draco decoder path to " + i), C[xe] = B, C.setDecoderPath(B), C.preload()) : console.debug("Setting Draco decoder path to " + i);
|
|
29
29
|
}
|
|
30
30
|
function gt(i) {
|
|
31
|
-
|
|
31
|
+
Q = i, q && q.transcoderPath != Q ? (console.debug("Updating KTX2 transcoder path to " + i), q.setTranscoderPath(Q), q.init()) : console.debug("Setting KTX2 transcoder path to " + i);
|
|
32
32
|
}
|
|
33
33
|
function _e(i) {
|
|
34
|
-
return
|
|
34
|
+
return We(), i ? q.detectSupport(i) : i !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: C, ktx2Loader: q, meshoptDecoder: ce };
|
|
35
35
|
}
|
|
36
|
-
function
|
|
37
|
-
i.dracoLoader || i.setDRACOLoader(C), i.ktx2Loader || i.setKTX2Loader(
|
|
36
|
+
function qe(i) {
|
|
37
|
+
i.dracoLoader || i.setDRACOLoader(C), i.ktx2Loader || i.setKTX2Loader(q), i.meshoptDecoder || i.setMeshoptDecoder(ce);
|
|
38
38
|
}
|
|
39
|
-
const
|
|
40
|
-
let C,
|
|
41
|
-
function
|
|
42
|
-
C || (C = new at(), C[
|
|
39
|
+
const xe = /* @__PURE__ */ Symbol("dracoDecoderPath");
|
|
40
|
+
let C, ce, q;
|
|
41
|
+
function We() {
|
|
42
|
+
C || (C = new at(), C[xe] = B, C.setDecoderPath(B), C.setDecoderConfig({ type: "js" }), C.preload()), q || (q = new lt(), q.setTranscoderPath(Q), q.init()), ce || (ce = ot);
|
|
43
43
|
}
|
|
44
|
-
const
|
|
45
|
-
function
|
|
46
|
-
let e =
|
|
47
|
-
e ? e = Object.assign(e, t) : e = t,
|
|
44
|
+
const we = /* @__PURE__ */ new WeakMap();
|
|
45
|
+
function Fe(i, t) {
|
|
46
|
+
let e = we.get(i);
|
|
47
|
+
e ? e = Object.assign(e, t) : e = t, we.set(i, e);
|
|
48
48
|
}
|
|
49
|
-
const pt =
|
|
49
|
+
const pt = Me.prototype.load;
|
|
50
50
|
function mt(...i) {
|
|
51
|
-
const t =
|
|
51
|
+
const t = we.get(this);
|
|
52
52
|
let e = i[0];
|
|
53
53
|
const s = yt(e);
|
|
54
54
|
if (s?.hostname.endsWith("needle.tools")) {
|
|
@@ -57,7 +57,7 @@ function mt(...i) {
|
|
|
57
57
|
}
|
|
58
58
|
return i[0] = e, pt?.call(this, ...i);
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
Me.prototype.load = mt;
|
|
61
61
|
function yt(i) {
|
|
62
62
|
try {
|
|
63
63
|
if (i instanceof URL)
|
|
@@ -68,7 +68,7 @@ function yt(i) {
|
|
|
68
68
|
return null;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
function
|
|
71
|
+
function Oe(i) {
|
|
72
72
|
return i != null && i.data != null;
|
|
73
73
|
}
|
|
74
74
|
function Le(i) {
|
|
@@ -79,21 +79,21 @@ function xt(i) {
|
|
|
79
79
|
const t = i.image;
|
|
80
80
|
return t != null && typeof t == "object" ? t : null;
|
|
81
81
|
}
|
|
82
|
-
function
|
|
82
|
+
function ve(i) {
|
|
83
83
|
const t = xt(i), e = Le(i);
|
|
84
84
|
return {
|
|
85
85
|
width: t?.width || e?.width || 0,
|
|
86
86
|
height: t?.height || e?.height || 0
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
|
-
|
|
90
|
-
function
|
|
89
|
+
X("debugprogressive");
|
|
90
|
+
function X(i) {
|
|
91
91
|
const t = globalThis.location?.href;
|
|
92
92
|
if (!t) return !1;
|
|
93
93
|
const s = new URL(t).searchParams.get(i);
|
|
94
94
|
return s == null || s === "0" || s === "false" ? !1 : s === "" ? !0 : s;
|
|
95
95
|
}
|
|
96
|
-
function
|
|
96
|
+
function wt(i, t) {
|
|
97
97
|
if (t === void 0 || i === void 0 || t.startsWith("./") || t.startsWith("http") || t.startsWith("data:") || t.startsWith("blob:"))
|
|
98
98
|
return t;
|
|
99
99
|
const e = i.lastIndexOf("/");
|
|
@@ -104,19 +104,19 @@ function Lt(i, t) {
|
|
|
104
104
|
}
|
|
105
105
|
return t;
|
|
106
106
|
}
|
|
107
|
-
function
|
|
108
|
-
if (
|
|
107
|
+
function be() {
|
|
108
|
+
if (se !== void 0) return se;
|
|
109
109
|
const i = globalThis.navigator?.userAgent || "";
|
|
110
|
-
return
|
|
110
|
+
return se = /iPhone|iPad|iPod|Android|IEMobile/i.test(i), X("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", se), se;
|
|
111
111
|
}
|
|
112
|
-
let
|
|
113
|
-
function
|
|
112
|
+
let se;
|
|
113
|
+
function Ue() {
|
|
114
114
|
const i = globalThis.location?.href;
|
|
115
115
|
if (!i) return !1;
|
|
116
116
|
const t = new URL(i), e = t.hostname === "localhost" || /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(t.hostname);
|
|
117
117
|
return t.hostname === "127.0.0.1" || e;
|
|
118
118
|
}
|
|
119
|
-
class
|
|
119
|
+
class Lt {
|
|
120
120
|
constructor(t, e = {}) {
|
|
121
121
|
this.maxConcurrent = t, this.debug = e.debug ?? !1, typeof globalThis.requestAnimationFrame == "function" ? globalThis.requestAnimationFrame(this.tick) : setTimeout(this.tick, 0);
|
|
122
122
|
}
|
|
@@ -162,71 +162,71 @@ function Dt(i) {
|
|
|
162
162
|
const r = i.type;
|
|
163
163
|
return r === 1009 || r === 1010 ? s = 1 : r === 1011 || r === 1012 ? s = 2 : r === 1013 || r === 1014 || r === 1015 ? s = 4 : r === 1016 && (s = 2), t * s;
|
|
164
164
|
}
|
|
165
|
-
const
|
|
166
|
-
function
|
|
167
|
-
return i?.[
|
|
165
|
+
const Mt = typeof window > "u" && typeof document > "u", De = /* @__PURE__ */ Symbol("needle:raycast-mesh");
|
|
166
|
+
function ae(i) {
|
|
167
|
+
return i?.[De] instanceof Y ? i[De] : null;
|
|
168
168
|
}
|
|
169
|
-
function
|
|
170
|
-
if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !
|
|
169
|
+
function _t(i, t) {
|
|
170
|
+
if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !ae(i)) {
|
|
171
171
|
const s = Tt(t);
|
|
172
|
-
s.userData = { isRaycastMesh: !0 }, i[
|
|
172
|
+
s.userData = { isRaycastMesh: !0 }, i[De] = s;
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
function bt(i = !0) {
|
|
176
176
|
if (i) {
|
|
177
|
-
if (
|
|
178
|
-
const t =
|
|
179
|
-
|
|
180
|
-
const r = this, n =
|
|
177
|
+
if (re) return;
|
|
178
|
+
const t = re = H.prototype.raycast;
|
|
179
|
+
H.prototype.raycast = function(e, s) {
|
|
180
|
+
const r = this, n = ae(r);
|
|
181
181
|
let o;
|
|
182
182
|
n && r.isMesh && (o = r.geometry, r.geometry = n), t.call(this, e, s), o && (r.geometry = o);
|
|
183
183
|
};
|
|
184
184
|
} else {
|
|
185
|
-
if (!
|
|
186
|
-
|
|
185
|
+
if (!re) return;
|
|
186
|
+
H.prototype.raycast = re, re = null;
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
|
-
let
|
|
189
|
+
let re = null;
|
|
190
190
|
function Tt(i) {
|
|
191
|
-
const t = new
|
|
191
|
+
const t = new Y();
|
|
192
192
|
for (const e in i.attributes)
|
|
193
193
|
t.setAttribute(e, i.getAttribute(e));
|
|
194
194
|
return t.setIndex(i.getIndex()), t;
|
|
195
195
|
}
|
|
196
|
-
const
|
|
197
|
-
let
|
|
198
|
-
if (
|
|
196
|
+
const U = new Array(), g = X("debugprogressive");
|
|
197
|
+
let oe, K = -1;
|
|
198
|
+
if (g && typeof window < "u") {
|
|
199
199
|
let i = function() {
|
|
200
|
-
|
|
200
|
+
K += 1, K >= t && (K = -1), console.log(`Toggle LOD level [${K}]`);
|
|
201
201
|
};
|
|
202
202
|
const t = 6;
|
|
203
203
|
window.addEventListener("keyup", (e) => {
|
|
204
|
-
e.key === "p" && i(), e.key === "w" && (
|
|
204
|
+
e.key === "p" && i(), e.key === "w" && (oe = !oe, console.log(`Toggle wireframe [${oe}]`));
|
|
205
205
|
const s = parseInt(e.key);
|
|
206
|
-
!isNaN(s) && s >= 0 && (
|
|
206
|
+
!isNaN(s) && s >= 0 && (K = s, console.log(`Set LOD level to [${K}]`));
|
|
207
207
|
});
|
|
208
208
|
}
|
|
209
|
-
function
|
|
210
|
-
if (
|
|
209
|
+
function ze(i) {
|
|
210
|
+
if (g && oe !== void 0)
|
|
211
211
|
if (Array.isArray(i))
|
|
212
212
|
for (const t of i)
|
|
213
|
-
|
|
214
|
-
else i && "wireframe" in i && (i.wireframe =
|
|
213
|
+
ze(t);
|
|
214
|
+
else i && "wireframe" in i && (i.wireframe = oe === !0);
|
|
215
215
|
}
|
|
216
|
-
const
|
|
216
|
+
const ne = new Array();
|
|
217
217
|
let Ot = 0;
|
|
218
|
-
const St =
|
|
218
|
+
const St = be() ? 2 : 10;
|
|
219
219
|
function Rt(i) {
|
|
220
|
-
if (
|
|
221
|
-
const s =
|
|
222
|
-
|
|
223
|
-
const r =
|
|
224
|
-
return
|
|
225
|
-
}
|
|
226
|
-
const t = Ot++ %
|
|
227
|
-
return
|
|
220
|
+
if (ne.length < St) {
|
|
221
|
+
const s = ne.length;
|
|
222
|
+
g && console.warn(`[Worker] Creating new worker #${s}`);
|
|
223
|
+
const r = Te.createWorker(i || {});
|
|
224
|
+
return ne.push(r), r;
|
|
225
|
+
}
|
|
226
|
+
const t = Ot++ % ne.length;
|
|
227
|
+
return ne[t];
|
|
228
228
|
}
|
|
229
|
-
class
|
|
229
|
+
class Te {
|
|
230
230
|
constructor(t, e) {
|
|
231
231
|
this.worker = t, this._debug = e.debug ?? !1, t.onmessage = (s) => {
|
|
232
232
|
const r = s.data;
|
|
@@ -253,7 +253,7 @@ class be {
|
|
|
253
253
|
), {
|
|
254
254
|
type: "module"
|
|
255
255
|
});
|
|
256
|
-
return new
|
|
256
|
+
return new Te(e, t);
|
|
257
257
|
}
|
|
258
258
|
_running = [];
|
|
259
259
|
_webglRenderer = null;
|
|
@@ -264,7 +264,7 @@ class be {
|
|
|
264
264
|
const { WebGLRenderer: u } = await import("three");
|
|
265
265
|
return new u();
|
|
266
266
|
})(), r = await this._webglRenderer);
|
|
267
|
-
const
|
|
267
|
+
const l = _e(r).ktx2Loader.workerConfig;
|
|
268
268
|
if (t instanceof URL)
|
|
269
269
|
t = t.toString();
|
|
270
270
|
else if (t.startsWith("file:"))
|
|
@@ -273,14 +273,14 @@ class be {
|
|
|
273
273
|
const u = globalThis.location?.href;
|
|
274
274
|
u && (t = new URL(t, u).toString());
|
|
275
275
|
}
|
|
276
|
-
const
|
|
276
|
+
const a = {
|
|
277
277
|
type: "load",
|
|
278
278
|
url: t,
|
|
279
279
|
dracoDecoderPath: s.dracoDecoderPath,
|
|
280
280
|
ktx2TranscoderPath: s.ktx2TranscoderPath,
|
|
281
|
-
ktx2LoaderConfig:
|
|
281
|
+
ktx2LoaderConfig: l
|
|
282
282
|
};
|
|
283
|
-
return this._debug && console.debug("[Worker] Sending load request",
|
|
283
|
+
return this._debug && console.debug("[Worker] Sending load request", a), this.worker.postMessage(a), new Promise((u) => {
|
|
284
284
|
this._running.push({
|
|
285
285
|
url: t.toString(),
|
|
286
286
|
resolve: u
|
|
@@ -291,30 +291,30 @@ class be {
|
|
|
291
291
|
}
|
|
292
292
|
function Ct(i) {
|
|
293
293
|
for (const t of i.geometries) {
|
|
294
|
-
const e = t.geometry, s = new
|
|
294
|
+
const e = t.geometry, s = new Y();
|
|
295
295
|
if (s.name = e.name || "", e.index) {
|
|
296
296
|
const r = e.index;
|
|
297
|
-
s.setIndex(
|
|
297
|
+
s.setIndex(de(r));
|
|
298
298
|
}
|
|
299
299
|
for (const r in e.attributes) {
|
|
300
|
-
const n = e.attributes[r], o =
|
|
300
|
+
const n = e.attributes[r], o = de(n);
|
|
301
301
|
s.setAttribute(r, o);
|
|
302
302
|
}
|
|
303
303
|
if (e.morphAttributes)
|
|
304
304
|
for (const r in e.morphAttributes) {
|
|
305
|
-
const o = e.morphAttributes[r].map((
|
|
305
|
+
const o = e.morphAttributes[r].map((l) => de(l));
|
|
306
306
|
s.morphAttributes[r] = o;
|
|
307
307
|
}
|
|
308
|
-
if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new
|
|
308
|
+
if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new fe(), s.boundingBox.min = new A(
|
|
309
309
|
e.boundingBox?.min.x,
|
|
310
310
|
e.boundingBox?.min.y,
|
|
311
311
|
e.boundingBox?.min.z
|
|
312
|
-
), s.boundingBox.max = new
|
|
312
|
+
), s.boundingBox.max = new A(
|
|
313
313
|
e.boundingBox?.max.x,
|
|
314
314
|
e.boundingBox?.max.y,
|
|
315
315
|
e.boundingBox?.max.z
|
|
316
|
-
), s.boundingSphere = new
|
|
317
|
-
new
|
|
316
|
+
), s.boundingSphere = new Ie(
|
|
317
|
+
new A(
|
|
318
318
|
e.boundingSphere?.center.x,
|
|
319
319
|
e.boundingSphere?.center.y,
|
|
320
320
|
e.boundingSphere?.center.z
|
|
@@ -329,7 +329,7 @@ function Ct(i) {
|
|
|
329
329
|
const e = t.texture;
|
|
330
330
|
let s = null;
|
|
331
331
|
if (e.isCompressedTexture) {
|
|
332
|
-
const r = e.mipmaps, { width: n, height: o } =
|
|
332
|
+
const r = e.mipmaps, { width: n, height: o } = ve(e);
|
|
333
333
|
s = new et(
|
|
334
334
|
r,
|
|
335
335
|
n,
|
|
@@ -345,7 +345,7 @@ function Ct(i) {
|
|
|
345
345
|
e.colorSpace
|
|
346
346
|
);
|
|
347
347
|
} else
|
|
348
|
-
s = new
|
|
348
|
+
s = new W(
|
|
349
349
|
e.image,
|
|
350
350
|
e.mapping,
|
|
351
351
|
e.wrapS,
|
|
@@ -365,7 +365,7 @@ function Ct(i) {
|
|
|
365
365
|
}
|
|
366
366
|
return i;
|
|
367
367
|
}
|
|
368
|
-
function
|
|
368
|
+
function de(i) {
|
|
369
369
|
let t = i;
|
|
370
370
|
if ("isInterleavedBufferAttribute" in i && i.isInterleavedBufferAttribute) {
|
|
371
371
|
const e = i.data, s = e.array, r = new st(s, e.stride);
|
|
@@ -373,13 +373,13 @@ function fe(i) {
|
|
|
373
373
|
} else "isBufferAttribute" in i && i.isBufferAttribute && (t = new nt(i.array, i.itemSize, i.normalized), t.usage = i.usage, t.gpuType = i.gpuType, t.updateRanges = i.updateRanges);
|
|
374
374
|
return t;
|
|
375
375
|
}
|
|
376
|
-
const Pt =
|
|
377
|
-
|
|
378
|
-
const
|
|
379
|
-
class
|
|
376
|
+
const Pt = X("gltf-progressive-worker");
|
|
377
|
+
X("gltf-progressive-reduce-mipmaps");
|
|
378
|
+
const ie = X("gltf-progressive-gc"), he = /* @__PURE__ */ Symbol("needle-progressive-texture"), z = "NEEDLE_progressive";
|
|
379
|
+
class p {
|
|
380
380
|
/** The name of the extension */
|
|
381
381
|
get name() {
|
|
382
|
-
return
|
|
382
|
+
return z;
|
|
383
383
|
}
|
|
384
384
|
// #region PUBLIC API
|
|
385
385
|
/**
|
|
@@ -421,33 +421,33 @@ class g {
|
|
|
421
421
|
max_count: 0,
|
|
422
422
|
lods: []
|
|
423
423
|
}), Array.isArray(t)) {
|
|
424
|
-
for (const
|
|
425
|
-
this.getMaterialMinMaxLODsCount(
|
|
424
|
+
for (const l of t)
|
|
425
|
+
this.getMaterialMinMaxLODsCount(l, e);
|
|
426
426
|
return t[r] = e, e;
|
|
427
427
|
}
|
|
428
|
-
if (
|
|
429
|
-
const
|
|
430
|
-
for (const
|
|
431
|
-
const u =
|
|
428
|
+
if (g === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
|
|
429
|
+
const l = t;
|
|
430
|
+
for (const a of Object.keys(l.uniforms)) {
|
|
431
|
+
const u = l.uniforms[a].value;
|
|
432
432
|
u?.isTexture === !0 && o(u, e);
|
|
433
433
|
}
|
|
434
434
|
} else if (t.isMaterial)
|
|
435
|
-
for (const
|
|
436
|
-
const
|
|
437
|
-
|
|
435
|
+
for (const l of Object.keys(t)) {
|
|
436
|
+
const a = t[l];
|
|
437
|
+
a?.isTexture === !0 && o(a, e);
|
|
438
438
|
}
|
|
439
439
|
else
|
|
440
|
-
|
|
440
|
+
g && console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);
|
|
441
441
|
return t[r] = e, e;
|
|
442
|
-
function o(
|
|
443
|
-
const u = s.getAssignedLODInformation(
|
|
442
|
+
function o(l, a) {
|
|
443
|
+
const u = s.getAssignedLODInformation(l);
|
|
444
444
|
if (u) {
|
|
445
|
-
const
|
|
446
|
-
if (
|
|
447
|
-
|
|
448
|
-
for (let c = 0; c <
|
|
449
|
-
const
|
|
450
|
-
|
|
445
|
+
const d = s.lodInfos.get(u.key);
|
|
446
|
+
if (d && d.lods) {
|
|
447
|
+
a.min_count = Math.min(a.min_count, d.lods.length), a.max_count = Math.max(a.max_count, d.lods.length);
|
|
448
|
+
for (let c = 0; c < d.lods.length; c++) {
|
|
449
|
+
const f = d.lods[c];
|
|
450
|
+
f.width && (a.lods[c] = a.lods[c] || { min_height: 1 / 0, max_height: 0 }, a.lods[c].min_height = Math.min(a.lods[c].min_height, f.height), a.lods[c].max_height = Math.max(a.lods[c].max_height, f.height));
|
|
451
451
|
}
|
|
452
452
|
}
|
|
453
453
|
}
|
|
@@ -501,25 +501,25 @@ class g {
|
|
|
501
501
|
*/
|
|
502
502
|
static assignMeshLOD(t, e, s) {
|
|
503
503
|
if (!t) return Promise.resolve(null);
|
|
504
|
-
if (t instanceof
|
|
504
|
+
if (t instanceof H || t.isMesh === !0) {
|
|
505
505
|
const r = t.geometry, n = this.getAssignedLODInformation(r);
|
|
506
506
|
if (!n)
|
|
507
507
|
return Promise.resolve(null);
|
|
508
|
-
for (const
|
|
509
|
-
|
|
508
|
+
for (const l of U)
|
|
509
|
+
l.onBeforeGetLODMesh?.(t, e);
|
|
510
510
|
t["LOD:requested level"] = e;
|
|
511
511
|
const o = () => t["LOD:requested level"] === e || this.shouldApplyStaleMeshLOD(t, e);
|
|
512
|
-
return
|
|
512
|
+
return p.getOrLoadLOD(r, e, {
|
|
513
513
|
isCurrent: o
|
|
514
|
-
}).then((
|
|
515
|
-
if (Array.isArray(
|
|
514
|
+
}).then((l) => {
|
|
515
|
+
if (Array.isArray(l)) {
|
|
516
516
|
const u = n.index || 0;
|
|
517
|
-
|
|
517
|
+
l = l[u];
|
|
518
518
|
}
|
|
519
|
-
const
|
|
520
|
-
return (
|
|
521
|
-
}).catch((
|
|
522
|
-
} else
|
|
519
|
+
const a = t["LOD:requested level"] === e;
|
|
520
|
+
return (a || this.shouldApplyStaleMeshLOD(t, e)) && (a && delete t["LOD:requested level"], l && r != l && (l?.isBufferGeometry ? typeof s?.apply == "function" ? s.apply(l, e, t) : s?.apply !== !1 && (t.geometry = l) : g && console.error("Invalid LOD geometry", l))), l;
|
|
521
|
+
}).catch((l) => (console.error("Error loading mesh LOD", t, l), null));
|
|
522
|
+
} else g && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
|
|
523
523
|
return Promise.resolve(null);
|
|
524
524
|
}
|
|
525
525
|
static assignTextureLOD(t, e = 0, s) {
|
|
@@ -529,48 +529,48 @@ class g {
|
|
|
529
529
|
const n = t;
|
|
530
530
|
if (Array.isArray(n.material)) {
|
|
531
531
|
const o = new Array();
|
|
532
|
-
for (const
|
|
533
|
-
const
|
|
534
|
-
o.push(
|
|
532
|
+
for (const l of n.material) {
|
|
533
|
+
const a = this.assignTextureLOD(l, e, s);
|
|
534
|
+
o.push(a);
|
|
535
535
|
}
|
|
536
|
-
return Promise.all(o).then((
|
|
537
|
-
const
|
|
538
|
-
for (const u of
|
|
539
|
-
Array.isArray(u) &&
|
|
540
|
-
return
|
|
536
|
+
return Promise.all(o).then((l) => {
|
|
537
|
+
const a = new Array();
|
|
538
|
+
for (const u of l)
|
|
539
|
+
Array.isArray(u) && a.push(...u);
|
|
540
|
+
return a;
|
|
541
541
|
});
|
|
542
542
|
} else
|
|
543
543
|
return this.assignTextureLOD(n.material, e, s);
|
|
544
544
|
}
|
|
545
545
|
if (t.isMaterial === !0) {
|
|
546
|
-
const n = t, o = [],
|
|
546
|
+
const n = t, o = [], l = new Array();
|
|
547
547
|
if (this.trackCurrentMaterialTextureSlots(n), n.uniforms && (n.isRawShaderMaterial || n.isShaderMaterial === !0)) {
|
|
548
|
-
const
|
|
549
|
-
for (const u of Object.keys(
|
|
550
|
-
const
|
|
551
|
-
if (
|
|
552
|
-
const c = this.assignTextureLODForSlot(
|
|
553
|
-
o.push(c),
|
|
548
|
+
const a = n;
|
|
549
|
+
for (const u of Object.keys(a.uniforms)) {
|
|
550
|
+
const d = a.uniforms[u].value;
|
|
551
|
+
if (d?.isTexture === !0) {
|
|
552
|
+
const c = this.assignTextureLODForSlot(d, e, n, u, r).then((f) => (f && a.uniforms[u].value != f && (a.uniforms[u].value = f, a.uniformsNeedUpdate = !0), f));
|
|
553
|
+
o.push(c), l.push(u);
|
|
554
554
|
}
|
|
555
555
|
}
|
|
556
556
|
} else
|
|
557
|
-
for (const
|
|
558
|
-
const u = n[
|
|
557
|
+
for (const a of Object.keys(n)) {
|
|
558
|
+
const u = n[a];
|
|
559
559
|
if (u?.isTexture === !0) {
|
|
560
|
-
const
|
|
561
|
-
o.push(
|
|
560
|
+
const d = this.assignTextureLODForSlot(u, e, n, a, r);
|
|
561
|
+
o.push(d), l.push(a);
|
|
562
562
|
}
|
|
563
563
|
}
|
|
564
|
-
return Promise.all(o).then((
|
|
564
|
+
return Promise.all(o).then((a) => {
|
|
565
565
|
const u = new Array();
|
|
566
|
-
for (let
|
|
567
|
-
const c =
|
|
568
|
-
c && c.isTexture === !0 ? u.push({ material: n, slot:
|
|
566
|
+
for (let d = 0; d < a.length; d++) {
|
|
567
|
+
const c = a[d], f = l[d];
|
|
568
|
+
c && c.isTexture === !0 ? u.push({ material: n, slot: f, texture: c, level: e }) : u.push({ material: n, slot: f, texture: null, level: e });
|
|
569
569
|
}
|
|
570
570
|
return u;
|
|
571
571
|
});
|
|
572
572
|
}
|
|
573
|
-
if (t instanceof
|
|
573
|
+
if (t instanceof W || t.isTexture === !0) {
|
|
574
574
|
const n = t;
|
|
575
575
|
return this.assignTextureLODForSlot(n, e, null, null, r);
|
|
576
576
|
}
|
|
@@ -581,10 +581,10 @@ class g {
|
|
|
581
581
|
* @default 50 on desktop, 20 on mobile devices
|
|
582
582
|
*/
|
|
583
583
|
static set maxConcurrentLoadingTasks(t) {
|
|
584
|
-
|
|
584
|
+
p.queue.maxConcurrent = t;
|
|
585
585
|
}
|
|
586
586
|
static get maxConcurrentLoadingTasks() {
|
|
587
|
-
return
|
|
587
|
+
return p.queue.maxConcurrent;
|
|
588
588
|
}
|
|
589
589
|
// #region INTERNAL
|
|
590
590
|
static assignTextureLODForSlot(t, e, s, r, n) {
|
|
@@ -600,27 +600,27 @@ class g {
|
|
|
600
600
|
if (c && c.level === e && c.force === n)
|
|
601
601
|
return c.promise;
|
|
602
602
|
}
|
|
603
|
-
const
|
|
603
|
+
const l = s && r ? this.nextTextureSlotRequestId(s, r, e, n) : 0, a = () => !s || !r || this.getLatestTextureSlotRequest(s, r)?.id === l, u = () => a() || this.shouldApplyStaleTextureSlotLOD(s, r, e, n), d = p.getOrLoadLOD(t, e, {
|
|
604
604
|
isCurrent: u
|
|
605
605
|
}).then((c) => {
|
|
606
|
-
if (!
|
|
606
|
+
if (!a() && !this.shouldApplyStaleTextureSlotLOD(s, r, e, n)) return null;
|
|
607
607
|
if (Array.isArray(c))
|
|
608
608
|
return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen..."), null;
|
|
609
609
|
if (c?.isTexture === !0) {
|
|
610
610
|
if (c != t && s && r) {
|
|
611
|
-
const
|
|
612
|
-
if (
|
|
613
|
-
const
|
|
614
|
-
if (
|
|
615
|
-
return
|
|
611
|
+
const f = this.getMaterialTextureSlot(s, r) ?? t;
|
|
612
|
+
if (f && !n) {
|
|
613
|
+
const h = this.getAssignedLODInformation(f);
|
|
614
|
+
if (h && h?.level < e)
|
|
615
|
+
return g === "verbose" && console.warn("Assigned texture level is already higher: ", h.level, e, s, f, c), null;
|
|
616
616
|
}
|
|
617
617
|
this.assignTrackedTextureSlot(s, r, c);
|
|
618
618
|
}
|
|
619
619
|
return c;
|
|
620
|
-
} else
|
|
620
|
+
} else g == "verbose" && console.warn("No LOD found for", t, e);
|
|
621
621
|
return null;
|
|
622
622
|
}).catch((c) => (console.error("Error loading LOD", t, c), null));
|
|
623
|
-
return s && r && this.setPendingTextureSlotRequest(s, r, e, n,
|
|
623
|
+
return s && r && this.setPendingTextureSlotRequest(s, r, e, n, l, d), d;
|
|
624
624
|
}
|
|
625
625
|
// Track material slots, not just texture objects. A shared fallback texture can be
|
|
626
626
|
// referenced by many slots and should only be disposed after every slot moved away.
|
|
@@ -656,8 +656,8 @@ class g {
|
|
|
656
656
|
}
|
|
657
657
|
static shouldApplyStaleTextureSlotLOD(t, e, s, r) {
|
|
658
658
|
if (!t || !e) return !1;
|
|
659
|
-
const n = this.getLatestTextureSlotRequest(t, e), o = this.getMaterialTextureSlot(t, e),
|
|
660
|
-
return s >=
|
|
659
|
+
const n = this.getLatestTextureSlotRequest(t, e), o = this.getMaterialTextureSlot(t, e), l = this.getAssignedLODInformation(o)?.level ?? 1 / 0;
|
|
660
|
+
return s >= l ? !1 : r ? n ? s >= n.level : !1 : !0;
|
|
661
661
|
}
|
|
662
662
|
static shouldApplyStaleMeshLOD(t, e) {
|
|
663
663
|
const s = t["LOD:requested level"];
|
|
@@ -666,11 +666,11 @@ class g {
|
|
|
666
666
|
return e < r && e >= s;
|
|
667
667
|
}
|
|
668
668
|
static setPendingTextureSlotRequest(t, e, s, r, n, o) {
|
|
669
|
-
let
|
|
670
|
-
|
|
671
|
-
const
|
|
672
|
-
|
|
673
|
-
|
|
669
|
+
let l = this.pendingTextureSlotRequests.get(t);
|
|
670
|
+
l || (l = /* @__PURE__ */ new Map(), this.pendingTextureSlotRequests.set(t, l));
|
|
671
|
+
const a = { level: s, force: r, id: n, promise: o };
|
|
672
|
+
l.set(e, a), o.finally(() => {
|
|
673
|
+
l.get(e)?.id === n && l.delete(e);
|
|
674
674
|
});
|
|
675
675
|
}
|
|
676
676
|
static getMaterialTextureSlot(t, e) {
|
|
@@ -703,7 +703,7 @@ class g {
|
|
|
703
703
|
}
|
|
704
704
|
static releaseTrackedTextureSlot(t, e, s) {
|
|
705
705
|
const r = this.trackedTextureSlots.get(t);
|
|
706
|
-
if (r?.get(e) === s && r.delete(e), this.untrackTextureUsage(s) && (
|
|
706
|
+
if (r?.get(e) === s && r.delete(e), this.untrackTextureUsage(s) && (g || ie)) {
|
|
707
707
|
const o = this.getAssignedLODInformation(s);
|
|
708
708
|
console.log(`[gltf-progressive] Disposed old texture LOD ${o?.level ?? "?"} for ${t.name || t.type}.${e}`, s.uuid);
|
|
709
709
|
}
|
|
@@ -712,13 +712,13 @@ class g {
|
|
|
712
712
|
url;
|
|
713
713
|
constructor(t) {
|
|
714
714
|
const e = t.options.path;
|
|
715
|
-
|
|
715
|
+
g && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
|
|
716
716
|
}
|
|
717
717
|
_isLoadingMesh;
|
|
718
718
|
loadMesh = (t) => {
|
|
719
719
|
if (this._isLoadingMesh) return null;
|
|
720
|
-
const e = this.parser.json.meshes[t]?.extensions?.[
|
|
721
|
-
return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s &&
|
|
720
|
+
const e = this.parser.json.meshes[t]?.extensions?.[z];
|
|
721
|
+
return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s && p.registerMesh(this.url, e.guid, s, e.lods?.length, 0, e), s))) : null;
|
|
722
722
|
};
|
|
723
723
|
// private _isLoadingTexture;
|
|
724
724
|
// loadTexture = (textureIndex: number) => {
|
|
@@ -735,30 +735,30 @@ class g {
|
|
|
735
735
|
// });
|
|
736
736
|
// }
|
|
737
737
|
afterRoot(t) {
|
|
738
|
-
return
|
|
738
|
+
return g && console.log("AFTER", this.url, t), this.parser.json.textures?.forEach((e, s) => {
|
|
739
739
|
if (e?.extensions) {
|
|
740
|
-
const r = e?.extensions[
|
|
740
|
+
const r = e?.extensions[z];
|
|
741
741
|
if (r) {
|
|
742
742
|
if (!r.lods) {
|
|
743
|
-
|
|
743
|
+
g && console.warn("Texture has no LODs", r);
|
|
744
744
|
return;
|
|
745
745
|
}
|
|
746
746
|
let n = !1;
|
|
747
747
|
for (const o of this.parser.associations.keys())
|
|
748
|
-
o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (n = !0,
|
|
748
|
+
o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (n = !0, p.registerTexture(this.url, o, r.lods?.length, s, r));
|
|
749
749
|
n || this.parser.getDependency("texture", s).then((o) => {
|
|
750
|
-
o &&
|
|
750
|
+
o && p.registerTexture(this.url, o, r.lods?.length, s, r);
|
|
751
751
|
});
|
|
752
752
|
}
|
|
753
753
|
}
|
|
754
754
|
}), this.parser.json.meshes?.forEach((e, s) => {
|
|
755
755
|
if (e?.extensions) {
|
|
756
|
-
const r = e?.extensions[
|
|
756
|
+
const r = e?.extensions[z];
|
|
757
757
|
if (r && r.lods) {
|
|
758
758
|
for (const n of this.parser.associations.keys())
|
|
759
759
|
if (n.isMesh) {
|
|
760
760
|
const o = this.parser.associations.get(n);
|
|
761
|
-
o?.meshes === s &&
|
|
761
|
+
o?.meshes === s && p.registerMesh(this.url, r.guid, n, r.lods.length, o.primitives, r);
|
|
762
762
|
}
|
|
763
763
|
}
|
|
764
764
|
}
|
|
@@ -777,16 +777,16 @@ class g {
|
|
|
777
777
|
*/
|
|
778
778
|
static registerTexture = (t, e, s, r, n) => {
|
|
779
779
|
if (!e) {
|
|
780
|
-
|
|
780
|
+
g && console.error("!! gltf-progressive: Called register texture without texture");
|
|
781
781
|
return;
|
|
782
782
|
}
|
|
783
|
-
if (
|
|
784
|
-
const { width:
|
|
785
|
-
console.log(`> gltf-progressive: register texture[${r}] "${e.name || e.uuid}", Current: ${
|
|
783
|
+
if (g) {
|
|
784
|
+
const { width: l, height: a } = ve(e);
|
|
785
|
+
console.log(`> gltf-progressive: register texture[${r}] "${e.name || e.uuid}", Current: ${l}x${a}, Max: ${n.lods[0]?.width}x${n.lods[0]?.height}, uuid: ${e.uuid}`, n, e);
|
|
786
786
|
}
|
|
787
|
-
e.source && (e.source[
|
|
787
|
+
e.source && (e.source[he] = n);
|
|
788
788
|
const o = n.guid;
|
|
789
|
-
|
|
789
|
+
p.assignLODInformation(t, e, o, s, r), p.lodInfos.set(o, n), p.lowresCache.set(o, new WeakRef(e));
|
|
790
790
|
};
|
|
791
791
|
/**
|
|
792
792
|
* Register a mesh with progressive LOD information. This associates the mesh geometry with its LOD extension data
|
|
@@ -802,16 +802,16 @@ class g {
|
|
|
802
802
|
* @param ext - The parsed progressive mesh extension data containing all available LOD levels with vertex/index counts and densities.
|
|
803
803
|
*/
|
|
804
804
|
static registerMesh = (t, e, s, r, n, o) => {
|
|
805
|
-
const
|
|
806
|
-
if (!
|
|
807
|
-
|
|
805
|
+
const l = s.geometry;
|
|
806
|
+
if (!l) {
|
|
807
|
+
g && console.warn("gltf-progressive: Register mesh without geometry");
|
|
808
808
|
return;
|
|
809
809
|
}
|
|
810
|
-
|
|
811
|
-
let u =
|
|
812
|
-
u ? u.push(s.geometry) : u = [s.geometry],
|
|
813
|
-
for (const
|
|
814
|
-
|
|
810
|
+
l.userData || (l.userData = {}), g && console.log("> Progressive: register mesh " + s.name, { index: n, uuid: s.uuid }, o, s), p.assignLODInformation(t, l, e, r, n), p.lodInfos.set(e, o);
|
|
811
|
+
let u = p.lowresCache.get(e)?.deref();
|
|
812
|
+
u ? u.push(s.geometry) : u = [s.geometry], p.lowresCache.set(e, new WeakRef(u)), r > 0 && !ae(s) && _t(s, l);
|
|
813
|
+
for (const d of U)
|
|
814
|
+
d.onRegisteredNewMesh?.(s, o);
|
|
815
815
|
};
|
|
816
816
|
/**
|
|
817
817
|
* Dispose cached resources to free memory.
|
|
@@ -838,7 +838,7 @@ class g {
|
|
|
838
838
|
for (const [s, r] of this.cache)
|
|
839
839
|
s.includes(t) && (this._disposeCacheEntry(r), this.cache.delete(s));
|
|
840
840
|
} else {
|
|
841
|
-
this.lodInfos.clear();
|
|
841
|
+
this.cacheGeneration++, this.lodInfos.clear();
|
|
842
842
|
for (const [, e] of this.lowresCache) {
|
|
843
843
|
const s = e.deref();
|
|
844
844
|
if (s) {
|
|
@@ -861,7 +861,7 @@ class g {
|
|
|
861
861
|
const e = t.deref();
|
|
862
862
|
e && (e.isTexture && this.textureRefCounts.delete(e.uuid), e.dispose());
|
|
863
863
|
} else
|
|
864
|
-
t.then((e) => {
|
|
864
|
+
this.disposedRequests.add(t), t.then((e) => {
|
|
865
865
|
if (e)
|
|
866
866
|
if (Array.isArray(e))
|
|
867
867
|
for (const s of e) s.dispose();
|
|
@@ -884,16 +884,16 @@ class g {
|
|
|
884
884
|
* The held value is the cache key string used in `previouslyLoaded`.
|
|
885
885
|
*/
|
|
886
886
|
static _resourceRegistry = new FinalizationRegistry((t) => {
|
|
887
|
-
const e =
|
|
888
|
-
(
|
|
889
|
-
${t}`), e instanceof WeakRef && (e.deref() || (
|
|
887
|
+
const e = p.cache.get(t);
|
|
888
|
+
(g || ie) && console.debug(`[gltf-progressive] Memory: Resource GC'd
|
|
889
|
+
${t}`), e instanceof WeakRef && (e.deref() || (p.cache.delete(t), (g || ie) && console.log("[gltf-progressive] ↪ Cache entry deleted (GC)")));
|
|
890
890
|
});
|
|
891
891
|
/**
|
|
892
892
|
* Track texture usage by incrementing reference count
|
|
893
893
|
*/
|
|
894
894
|
static trackTextureUsage(t) {
|
|
895
895
|
const e = t.uuid, s = this.textureRefCounts.get(e) || 0;
|
|
896
|
-
this.textureRefCounts.set(e, s + 1),
|
|
896
|
+
this.textureRefCounts.set(e, s + 1), g === "verbose" && console.log(`[gltf-progressive] Track texture ${e}, refCount: ${s} → ${s + 1}`);
|
|
897
897
|
}
|
|
898
898
|
/**
|
|
899
899
|
* Untrack texture usage by decrementing reference count.
|
|
@@ -903,155 +903,166 @@ ${t}`), e instanceof WeakRef && (e.deref() || (g.cache.delete(t), (h || se) && c
|
|
|
903
903
|
static untrackTextureUsage(t) {
|
|
904
904
|
const e = t.uuid, s = this.textureRefCounts.get(e);
|
|
905
905
|
if (!s)
|
|
906
|
-
return (
|
|
906
|
+
return (g === "verbose" || ie) && n("[gltf-progressive] Memory: Untrack untracked texture (dispose immediately)", 0), t.dispose(), !0;
|
|
907
907
|
const r = s - 1;
|
|
908
908
|
if (r <= 0)
|
|
909
|
-
return this.textureRefCounts.delete(e), (
|
|
910
|
-
return this.textureRefCounts.set(e, r),
|
|
911
|
-
function n(o,
|
|
912
|
-
let { width:
|
|
913
|
-
const
|
|
909
|
+
return this.textureRefCounts.delete(e), (g || ie) && n("[gltf-progressive] Memory: Dispose texture", r), t.dispose(), !0;
|
|
910
|
+
return this.textureRefCounts.set(e, r), g === "verbose" && n("[gltf-progressive] Memory: Untrack texture", r), !1;
|
|
911
|
+
function n(o, l) {
|
|
912
|
+
let { width: a, height: u } = ve(t);
|
|
913
|
+
const d = a && u ? `${a}x${u}` : "N/A";
|
|
914
914
|
let c = "N/A";
|
|
915
|
-
|
|
915
|
+
a && u && (c = `~${(vt(t) / (1024 * 1024)).toFixed(2)} MB`), console.log(`${o} — ${t.name} ${d} (${c}), refCount: ${s} → ${l}
|
|
916
916
|
${e}`);
|
|
917
917
|
}
|
|
918
918
|
}
|
|
919
919
|
static workers = [];
|
|
920
|
+
static cacheGeneration = 0;
|
|
921
|
+
static disposedRequests = /* @__PURE__ */ new WeakSet();
|
|
920
922
|
static _workersIndex = 0;
|
|
921
923
|
static async getOrLoadLOD(t, e, s) {
|
|
922
|
-
const r =
|
|
923
|
-
if (!
|
|
924
|
-
return
|
|
925
|
-
const
|
|
924
|
+
const r = this.cacheGeneration, n = g == "verbose", o = this.getAssignedLODInformation(t);
|
|
925
|
+
if (!o)
|
|
926
|
+
return g && console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`, t), null;
|
|
927
|
+
const l = o?.key;
|
|
926
928
|
let a;
|
|
927
929
|
if (t.isTexture === !0) {
|
|
928
|
-
const
|
|
929
|
-
|
|
930
|
+
const d = t;
|
|
931
|
+
d.source && d.source[he] && (a = d.source[he]);
|
|
930
932
|
}
|
|
931
|
-
if (a || (a =
|
|
932
|
-
|
|
933
|
+
if (a || (a = p.lodInfos.get(l)), !a)
|
|
934
|
+
g && console.warn(`Can not load LOD ${e}: no LOD info found for "${l}" ${t.name}`, t.type, p.lodInfos);
|
|
933
935
|
else {
|
|
934
936
|
if (e > 0) {
|
|
935
|
-
let
|
|
936
|
-
const
|
|
937
|
-
if (
|
|
938
|
-
const
|
|
939
|
-
if (
|
|
940
|
-
const
|
|
941
|
-
if (
|
|
942
|
-
this.lowresCache.delete(
|
|
937
|
+
let f = !1;
|
|
938
|
+
const h = Array.isArray(a.lods);
|
|
939
|
+
if (h && e >= a.lods.length ? f = !0 : h || (f = !0), f) {
|
|
940
|
+
const D = this.lowresCache.get(l);
|
|
941
|
+
if (D) {
|
|
942
|
+
const w = D.deref();
|
|
943
|
+
if (w) return w;
|
|
944
|
+
this.lowresCache.delete(l), g && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${l}`);
|
|
943
945
|
}
|
|
944
946
|
return null;
|
|
945
947
|
}
|
|
946
948
|
}
|
|
947
|
-
const
|
|
948
|
-
if (!
|
|
949
|
-
return
|
|
950
|
-
const
|
|
951
|
-
if (
|
|
949
|
+
const d = Array.isArray(a.lods) ? a.lods[e]?.path : a.lods;
|
|
950
|
+
if (!d)
|
|
951
|
+
return g && !a["missing:uri"] && (a["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, a)), null;
|
|
952
|
+
const c = wt(o.url, d);
|
|
953
|
+
if (c.endsWith(".glb") || c.endsWith(".gltf")) {
|
|
952
954
|
if (!a.guid)
|
|
953
955
|
return console.warn("missing pointer for glb/gltf texture", a), null;
|
|
954
|
-
const
|
|
955
|
-
if (
|
|
956
|
+
const f = c + "_" + a.guid, h = await this.tryResolveLODCacheEntry(this.cache.get(f), f, c, t, e, n);
|
|
957
|
+
if (r !== this.cacheGeneration) return null;
|
|
958
|
+
if (h.found) return h.value;
|
|
956
959
|
if (s?.isCurrent?.() === !1)
|
|
957
|
-
return
|
|
958
|
-
const
|
|
960
|
+
return n && console.log(`Skipping stale LOD ${e} request before queue: ${c}`), null;
|
|
961
|
+
const D = await this.queue.slot(c);
|
|
962
|
+
if (r !== this.cacheGeneration) return null;
|
|
959
963
|
if (s?.isCurrent?.() === !1)
|
|
960
|
-
return
|
|
961
|
-
const
|
|
962
|
-
if (
|
|
963
|
-
if (
|
|
964
|
-
|
|
965
|
-
|
|
964
|
+
return n && console.log(`Skipping stale LOD ${e} request after queue: ${c}`), null;
|
|
965
|
+
const w = await this.tryResolveLODCacheEntry(this.cache.get(f), f, c, t, e, n);
|
|
966
|
+
if (r !== this.cacheGeneration) return null;
|
|
967
|
+
if (w.found) return w.value;
|
|
968
|
+
const x = this.cache.get(f);
|
|
969
|
+
if (x !== void 0) {
|
|
970
|
+
const y = await this.tryResolveLODCacheEntry(x, f, c, t, e, n);
|
|
971
|
+
if (r !== this.cacheGeneration) return null;
|
|
972
|
+
if (y.found) return y.value;
|
|
973
|
+
}
|
|
974
|
+
if (!D.use)
|
|
975
|
+
return g && console.log(`LOD ${e} was aborted: ${c}`), null;
|
|
976
|
+
const L = a, M = new Promise(async (y, O) => {
|
|
966
977
|
if (Pt) {
|
|
967
|
-
const m = await (await Rt({})).load(
|
|
978
|
+
const m = await (await Rt({})).load(c);
|
|
968
979
|
if (m.textures.length > 0)
|
|
969
|
-
for (const
|
|
970
|
-
let
|
|
971
|
-
return
|
|
980
|
+
for (const v of m.textures) {
|
|
981
|
+
let S = v.texture;
|
|
982
|
+
return p.assignLODInformation(o.url, S, l, e, void 0), t instanceof W && (S = this.copySettings(t, S)), S && (S.guid = L.guid), y(S);
|
|
972
983
|
}
|
|
973
984
|
if (m.geometries.length > 0) {
|
|
974
|
-
const
|
|
975
|
-
for (const
|
|
976
|
-
const
|
|
977
|
-
|
|
985
|
+
const v = new Array();
|
|
986
|
+
for (const S of m.geometries) {
|
|
987
|
+
const j = S.geometry;
|
|
988
|
+
p.assignLODInformation(o.url, j, l, e, S.primitiveIndex), v.push(j);
|
|
978
989
|
}
|
|
979
|
-
return
|
|
990
|
+
return y(v);
|
|
980
991
|
}
|
|
981
|
-
return
|
|
992
|
+
return y(null);
|
|
982
993
|
}
|
|
983
|
-
const
|
|
984
|
-
|
|
985
|
-
let
|
|
986
|
-
if (
|
|
987
|
-
const
|
|
988
|
-
|
|
994
|
+
const I = new Me();
|
|
995
|
+
qe(I), g && (await new Promise((b) => setTimeout(b, 1e3)), n && console.warn("Start loading (delayed) " + c, L.guid));
|
|
996
|
+
let P = c;
|
|
997
|
+
if (L && Array.isArray(L.lods)) {
|
|
998
|
+
const b = L.lods[e];
|
|
999
|
+
b.hash && (P += "?v=" + b.hash);
|
|
989
1000
|
}
|
|
990
|
-
const
|
|
991
|
-
`,
|
|
992
|
-
if (!
|
|
993
|
-
return
|
|
994
|
-
const
|
|
995
|
-
|
|
996
|
-
let
|
|
997
|
-
if (
|
|
998
|
-
let
|
|
999
|
-
for (const m of
|
|
1001
|
+
const _ = await I.loadAsync(P).catch((b) => (console.error(`Error loading LOD ${e} from ${c}
|
|
1002
|
+
`, b), y(null)));
|
|
1003
|
+
if (!_)
|
|
1004
|
+
return y(null);
|
|
1005
|
+
const E = _.parser;
|
|
1006
|
+
n && console.log("Loading finished " + c, L.guid);
|
|
1007
|
+
let k = 0;
|
|
1008
|
+
if (_.parser.json.textures) {
|
|
1009
|
+
let b = !1;
|
|
1010
|
+
for (const m of _.parser.json.textures) {
|
|
1000
1011
|
if (m?.extensions) {
|
|
1001
|
-
const
|
|
1002
|
-
if (
|
|
1003
|
-
|
|
1012
|
+
const v = m?.extensions[z];
|
|
1013
|
+
if (v?.guid && v.guid === L.guid) {
|
|
1014
|
+
b = !0;
|
|
1004
1015
|
break;
|
|
1005
1016
|
}
|
|
1006
1017
|
}
|
|
1007
|
-
|
|
1018
|
+
k++;
|
|
1008
1019
|
}
|
|
1009
|
-
if (
|
|
1010
|
-
let m = await
|
|
1011
|
-
return m &&
|
|
1012
|
-
} else
|
|
1020
|
+
if (b) {
|
|
1021
|
+
let m = await E.getDependency("texture", k);
|
|
1022
|
+
return m && p.assignLODInformation(o.url, m, l, e, void 0), n && console.log('change "' + t.name + '" → "' + m.name + '"', c, k, m, f), t instanceof W && (m = this.copySettings(t, m)), m && (m.guid = L.guid), y(m);
|
|
1023
|
+
} else g && console.warn("Could not find texture with guid", L.guid, _.parser.json);
|
|
1013
1024
|
}
|
|
1014
|
-
if (
|
|
1015
|
-
let
|
|
1016
|
-
for (const m of
|
|
1025
|
+
if (k = 0, _.parser.json.meshes) {
|
|
1026
|
+
let b = !1;
|
|
1027
|
+
for (const m of _.parser.json.meshes) {
|
|
1017
1028
|
if (m?.extensions) {
|
|
1018
|
-
const
|
|
1019
|
-
if (
|
|
1020
|
-
|
|
1029
|
+
const v = m?.extensions[z];
|
|
1030
|
+
if (v?.guid && v.guid === L.guid) {
|
|
1031
|
+
b = !0;
|
|
1021
1032
|
break;
|
|
1022
1033
|
}
|
|
1023
1034
|
}
|
|
1024
|
-
|
|
1035
|
+
k++;
|
|
1025
1036
|
}
|
|
1026
|
-
if (
|
|
1027
|
-
const m = await
|
|
1028
|
-
if (
|
|
1029
|
-
const
|
|
1030
|
-
return
|
|
1037
|
+
if (b) {
|
|
1038
|
+
const m = await E.getDependency("mesh", k);
|
|
1039
|
+
if (n && console.log(`Loaded Mesh "${m.name}"`, c, k, m, f), m.isMesh === !0) {
|
|
1040
|
+
const v = m.geometry;
|
|
1041
|
+
return p.assignLODInformation(o.url, v, l, e, 0), y(v);
|
|
1031
1042
|
} else {
|
|
1032
|
-
const
|
|
1033
|
-
for (let
|
|
1034
|
-
const
|
|
1035
|
-
if (
|
|
1036
|
-
const
|
|
1037
|
-
|
|
1043
|
+
const v = new Array();
|
|
1044
|
+
for (let S = 0; S < m.children.length; S++) {
|
|
1045
|
+
const j = m.children[S];
|
|
1046
|
+
if (j.isMesh === !0) {
|
|
1047
|
+
const J = j.geometry;
|
|
1048
|
+
p.assignLODInformation(o.url, J, l, e, S), v.push(J);
|
|
1038
1049
|
}
|
|
1039
1050
|
}
|
|
1040
|
-
return
|
|
1051
|
+
return y(v);
|
|
1041
1052
|
}
|
|
1042
|
-
} else
|
|
1053
|
+
} else g && console.warn("Could not find mesh with guid", L.guid, _.parser.json);
|
|
1043
1054
|
}
|
|
1044
|
-
return
|
|
1055
|
+
return y(null);
|
|
1045
1056
|
});
|
|
1046
|
-
this.cache.set(
|
|
1047
|
-
const
|
|
1048
|
-
return
|
|
1049
|
-
} else if (t instanceof
|
|
1057
|
+
this.cache.set(f, M), D.use(M);
|
|
1058
|
+
const T = await M;
|
|
1059
|
+
return r !== this.cacheGeneration || this.cache.get(f) !== M ? null : (T != null ? T instanceof W ? (this.cache.set(f, new WeakRef(T)), p._resourceRegistry.register(T, f)) : Array.isArray(T) ? this.cache.set(f, Promise.resolve(T)) : this.cache.set(f, Promise.resolve(T)) : this.cache.set(f, Promise.resolve(null)), T);
|
|
1060
|
+
} else if (t instanceof W) {
|
|
1050
1061
|
if (s?.isCurrent?.() === !1)
|
|
1051
|
-
return
|
|
1052
|
-
|
|
1053
|
-
const
|
|
1054
|
-
return s?.isCurrent?.() === !1 ? (
|
|
1062
|
+
return n && console.log(`Skipping stale texture LOD ${e} request: ${c}`), null;
|
|
1063
|
+
n && console.log("Load texture from uri: " + c);
|
|
1064
|
+
const h = await new it().loadAsync(c);
|
|
1065
|
+
return r !== this.cacheGeneration || s?.isCurrent?.() === !1 ? (h?.dispose(), null) : (h ? (h.guid = a.guid, h.flipY = !1, h.needsUpdate = !0, h.colorSpace = t.colorSpace, n && console.log(a, h)) : g && console.warn("failed loading", c), h);
|
|
1055
1066
|
}
|
|
1056
1067
|
}
|
|
1057
1068
|
return null;
|
|
@@ -1062,19 +1073,21 @@ ${e}`);
|
|
|
1062
1073
|
if (o && console.log(`LOD ${n} was already loading/loaded: ${e}`), t instanceof WeakRef) {
|
|
1063
1074
|
const u = t.deref();
|
|
1064
1075
|
if (u) {
|
|
1065
|
-
let
|
|
1066
|
-
if (
|
|
1067
|
-
return { found: !0, value:
|
|
1076
|
+
let d = u, c = !1;
|
|
1077
|
+
if (d instanceof W && r instanceof W ? Oe(d.image) || Le(d) ? d = this.copySettings(r, d) : c = !0 : d instanceof Y && r instanceof Y && (d.attributes.position?.array || (c = !0)), !c)
|
|
1078
|
+
return { found: !0, value: d };
|
|
1068
1079
|
}
|
|
1069
|
-
return this.cache.delete(e),
|
|
1080
|
+
return this.cache.delete(e), g && console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${e}`), { found: !1 };
|
|
1070
1081
|
}
|
|
1071
|
-
let
|
|
1072
|
-
`, u), null))
|
|
1073
|
-
|
|
1082
|
+
let l = await t.catch((u) => (console.error(`Error loading LOD ${n} from ${s}
|
|
1083
|
+
`, u), null));
|
|
1084
|
+
if (this.disposedRequests.has(t)) return { found: !0, value: null };
|
|
1085
|
+
let a = !1;
|
|
1086
|
+
return l == null || (l instanceof W && r instanceof W ? Oe(l.image) || Le(l) ? l = this.copySettings(r, l) : (a = !0, this.cache.delete(e)) : l instanceof Y && r instanceof Y && (l.attributes.position?.array || (a = !0, this.cache.delete(e)))), a ? { found: !1 } : { found: !0, value: l };
|
|
1074
1087
|
}
|
|
1075
1088
|
static _queue;
|
|
1076
1089
|
static get queue() {
|
|
1077
|
-
return this._queue ??= new
|
|
1090
|
+
return this._queue ??= new Lt(be() ? 20 : 50, { debug: g != !1 });
|
|
1078
1091
|
}
|
|
1079
1092
|
static assignLODInformation(t, e, s, r, n) {
|
|
1080
1093
|
if (!e) return;
|
|
@@ -1087,7 +1100,7 @@ ${e}`);
|
|
|
1087
1100
|
}
|
|
1088
1101
|
// private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
|
|
1089
1102
|
static copySettings(t, e) {
|
|
1090
|
-
return e ? (
|
|
1103
|
+
return e ? (g === "verbose" && console.debug(`Copy texture settings
|
|
1091
1104
|
`, t.uuid, `
|
|
1092
1105
|
`, e.uuid), e = e.clone(), e.offset = t.offset, e.repeat = t.repeat, e.colorSpace = t.colorSpace, e.magFilter = t.magFilter, e.minFilter = t.minFilter, e.wrapS = t.wrapS, e.wrapT = t.wrapT, e.flipY = t.flipY, e.anisotropy = t.anisotropy, e.mipmaps || (e.generateMipmaps = t.generateMipmaps), e) : t;
|
|
1093
1106
|
}
|
|
@@ -1103,7 +1116,7 @@ class kt {
|
|
|
1103
1116
|
this.url = t, this.key = e, this.level = s, r != null && (this.index = r);
|
|
1104
1117
|
}
|
|
1105
1118
|
}
|
|
1106
|
-
class
|
|
1119
|
+
class le {
|
|
1107
1120
|
static addPromise = (t, e, s, r) => {
|
|
1108
1121
|
r.forEach((n) => {
|
|
1109
1122
|
n.add(t, e, s);
|
|
@@ -1152,7 +1165,7 @@ class oe {
|
|
|
1152
1165
|
_seen = /* @__PURE__ */ new WeakMap();
|
|
1153
1166
|
add(t, e, s) {
|
|
1154
1167
|
if (this._resolved) {
|
|
1155
|
-
|
|
1168
|
+
g && console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");
|
|
1156
1169
|
return;
|
|
1157
1170
|
}
|
|
1158
1171
|
if (!(this._frame_start !== void 0 && this._currentFrame > this._frame_start + this._frames_to_capture)) {
|
|
@@ -1160,7 +1173,7 @@ class oe {
|
|
|
1160
1173
|
if (this._seen.has(e)) {
|
|
1161
1174
|
const r = this._seen.get(e);
|
|
1162
1175
|
if (r >= this._maxPromisesPerObject) {
|
|
1163
|
-
|
|
1176
|
+
g && console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");
|
|
1164
1177
|
return;
|
|
1165
1178
|
}
|
|
1166
1179
|
this._seen.set(e, r + 1);
|
|
@@ -1179,7 +1192,7 @@ class oe {
|
|
|
1179
1192
|
});
|
|
1180
1193
|
}
|
|
1181
1194
|
}
|
|
1182
|
-
const
|
|
1195
|
+
const $ = X("debugprogressive"), At = $ === "colors", It = X("noprogressive"), ge = /* @__PURE__ */ Symbol("Needle:LODSManager"), pe = /* @__PURE__ */ Symbol("Needle:LODState"), N = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), Se = Xe, R = { mesh_lod: -1, texture_lod: -1 }, $t = new $e(), Re = [
|
|
1183
1196
|
3526751,
|
|
1184
1197
|
11065402,
|
|
1185
1198
|
15978811,
|
|
@@ -1213,14 +1226,14 @@ const A = V("debugprogressive"), At = A === "colors", It = V("noprogressive"), h
|
|
|
1213
1226
|
5083278,
|
|
1214
1227
|
5592405
|
|
1215
1228
|
];
|
|
1216
|
-
function
|
|
1217
|
-
const i =
|
|
1229
|
+
function Gt() {
|
|
1230
|
+
const i = Se.Timer || Se.Clock;
|
|
1218
1231
|
return new i();
|
|
1219
1232
|
}
|
|
1220
|
-
const
|
|
1233
|
+
const me = new fe(), V = new fe(), Ce = new fe(), Bt = new A(), qt = new A(), Wt = new Ge(), F = new A(), Z = new A(), ee = new A(), te = new A();
|
|
1221
1234
|
function Ft(i, t) {
|
|
1222
1235
|
const e = i.min, s = i.max, r = (e.x + s.x) * 0.5, n = (e.y + s.y) * 0.5;
|
|
1223
|
-
return
|
|
1236
|
+
return F.set(r, n, e.z).applyMatrix4(t).z < 0;
|
|
1224
1237
|
}
|
|
1225
1238
|
function Ut(i) {
|
|
1226
1239
|
const {
|
|
@@ -1230,71 +1243,71 @@ function Ut(i) {
|
|
|
1230
1243
|
projectionScreenMatrix: r,
|
|
1231
1244
|
desiredDensity: n,
|
|
1232
1245
|
canvasHeight: o = 0,
|
|
1233
|
-
currentLevel:
|
|
1234
|
-
xrEnabled:
|
|
1246
|
+
currentLevel: l = -1,
|
|
1247
|
+
xrEnabled: a = !1,
|
|
1235
1248
|
debugDrawLine: u,
|
|
1236
|
-
warnMissingPrimitiveDensities:
|
|
1237
|
-
} = i, c =
|
|
1238
|
-
level:
|
|
1239
|
-
primitiveIndex:
|
|
1249
|
+
warnMissingPrimitiveDensities: d = !1
|
|
1250
|
+
} = i, c = p.getMeshLODExtension(t)?.lods, f = p.getPrimitiveIndex(t), h = i.target ?? {
|
|
1251
|
+
level: l,
|
|
1252
|
+
primitiveIndex: f,
|
|
1240
1253
|
screenCoverage: 0,
|
|
1241
|
-
screenspaceVolume: new
|
|
1254
|
+
screenspaceVolume: new A(),
|
|
1242
1255
|
centrality: 1
|
|
1243
1256
|
};
|
|
1244
|
-
|
|
1245
|
-
let
|
|
1246
|
-
if (
|
|
1247
|
-
if (
|
|
1248
|
-
return
|
|
1249
|
-
if (
|
|
1250
|
-
const
|
|
1251
|
-
let
|
|
1252
|
-
const
|
|
1253
|
-
|
|
1254
|
-
const
|
|
1255
|
-
|
|
1256
|
-
}
|
|
1257
|
-
const
|
|
1258
|
-
|
|
1259
|
-
const x =
|
|
1260
|
-
|
|
1261
|
-
const
|
|
1262
|
-
if (
|
|
1257
|
+
h.level = l, h.primitiveIndex = f, h.screenCoverage = 0, h.screenspaceVolume.set(0, 0, 0), h.centrality = 1;
|
|
1258
|
+
let D = i.boundingBox ?? t.boundingBox;
|
|
1259
|
+
if (D || (t.computeBoundingBox(), D = t.boundingBox), !D) return h;
|
|
1260
|
+
if (me.copy(D).applyMatrix4(e), s.isPerspectiveCamera && Ft(me, r))
|
|
1261
|
+
return h.level = 0, h.screenCoverage = 1 / 0, h.screenspaceVolume.set(1 / 0, 1 / 0, 1 / 0), h;
|
|
1262
|
+
if (V.copy(me).applyMatrix4(r), a && s.isPerspectiveCamera && s.fov > 70) {
|
|
1263
|
+
const y = V.min, O = V.max;
|
|
1264
|
+
let I = y.x, P = y.y, _ = O.x, E = O.y;
|
|
1265
|
+
const k = 2, b = 1.5, m = (y.x + O.x) * 0.5, v = (y.y + O.y) * 0.5;
|
|
1266
|
+
I = (I - m) * k + m, P = (P - v) * k + v, _ = (_ - m) * k + m, E = (E - v) * k + v;
|
|
1267
|
+
const S = I < 0 && _ > 0 ? 0 : Math.min(Math.abs(y.x), Math.abs(O.x)), j = P < 0 && E > 0 ? 0 : Math.min(Math.abs(y.y), Math.abs(O.y)), J = Math.max(S, j);
|
|
1268
|
+
h.centrality = (b - J) * (b - J) * (b - J);
|
|
1269
|
+
}
|
|
1270
|
+
const w = V.getSize(Bt);
|
|
1271
|
+
w.multiplyScalar(0.5), globalThis.screen?.availHeight > 0 && o > 0 && w.multiplyScalar(o / globalThis.screen.availHeight), s.isPerspectiveCamera && (w.x *= s.aspect), Ce.copy(D).applyMatrix4(e).applyMatrix4(s.matrixWorldInverse);
|
|
1272
|
+
const x = Ce.getSize(qt), L = Math.max(w.x, w.y), M = Math.max(x.x, x.y);
|
|
1273
|
+
L !== 0 && M !== 0 && (w.z = x.z / M * L);
|
|
1274
|
+
const T = Math.max(w.x, w.y, w.z) * h.centrality;
|
|
1275
|
+
if (h.screenCoverage = T, h.screenspaceVolume.copy(w), T <= 0) return h;
|
|
1263
1276
|
if (u) {
|
|
1264
|
-
const
|
|
1265
|
-
|
|
1266
|
-
const
|
|
1267
|
-
|
|
1277
|
+
const y = Wt.copy(r);
|
|
1278
|
+
y.invert(), F.copy(V.min), Z.copy(V.max), Z.x = F.x, ee.copy(V.max), ee.y = F.y, te.copy(V.max);
|
|
1279
|
+
const O = (F.z + te.z) * 0.5;
|
|
1280
|
+
F.z = Z.z = ee.z = te.z = O, F.applyMatrix4(y), Z.applyMatrix4(y), ee.applyMatrix4(y), te.applyMatrix4(y), u(F, Z, 255), u(F, ee, 255), u(Z, te, 255), u(ee, te, 255);
|
|
1268
1281
|
}
|
|
1269
1282
|
if (c?.length)
|
|
1270
|
-
for (let
|
|
1271
|
-
const
|
|
1272
|
-
if (
|
|
1273
|
-
|
|
1283
|
+
for (let y = 0; y < c.length; y++) {
|
|
1284
|
+
const O = c[y], I = O.densities?.[f] || O.density || 1e-5;
|
|
1285
|
+
if (f > 0 && d && Ue() && !O.densities && !globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] && (globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] = !0, console.warn("[Needle Progressive] Detected usage of mesh without primitive densities. This might cause incorrect LOD level selection: Consider re-optimizing your model by updating your Needle Integration, Needle glTF Pipeline or running optimization again on Needle Cloud.")), I / T < n) {
|
|
1286
|
+
h.level = y;
|
|
1274
1287
|
break;
|
|
1275
1288
|
}
|
|
1276
1289
|
}
|
|
1277
|
-
return
|
|
1290
|
+
return h;
|
|
1278
1291
|
}
|
|
1279
|
-
class
|
|
1292
|
+
class G {
|
|
1280
1293
|
/**
|
|
1281
1294
|
* Assign a function to draw debug lines for the LODs. This function will be called with the start and end position of the line and the color of the line when the `debugprogressive` query parameter is set.
|
|
1282
1295
|
*/
|
|
1283
1296
|
static debugDrawLine;
|
|
1284
1297
|
/** @internal */
|
|
1285
1298
|
static getObjectLODState(t) {
|
|
1286
|
-
return t[
|
|
1299
|
+
return t[pe];
|
|
1287
1300
|
}
|
|
1288
1301
|
static addPlugin(t) {
|
|
1289
|
-
|
|
1302
|
+
U.push(t);
|
|
1290
1303
|
}
|
|
1291
1304
|
static removePlugin(t) {
|
|
1292
|
-
const e =
|
|
1293
|
-
e >= 0 &&
|
|
1305
|
+
const e = U.indexOf(t);
|
|
1306
|
+
e >= 0 && U.splice(e, 1);
|
|
1294
1307
|
}
|
|
1295
1308
|
/** Read-only snapshot of the currently registered plugins, for inspection. Use {@link addPlugin} / {@link removePlugin} to modify the registry. */
|
|
1296
1309
|
static getPlugins() {
|
|
1297
|
-
return
|
|
1310
|
+
return U;
|
|
1298
1311
|
}
|
|
1299
1312
|
/**
|
|
1300
1313
|
* Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
|
|
@@ -1302,20 +1315,20 @@ class I {
|
|
|
1302
1315
|
* @returns The LODsManager instance.
|
|
1303
1316
|
*/
|
|
1304
1317
|
static get(t, e) {
|
|
1305
|
-
if (t[
|
|
1306
|
-
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[
|
|
1307
|
-
const s = new
|
|
1318
|
+
if (t[ge])
|
|
1319
|
+
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[ge];
|
|
1320
|
+
const s = new G(t, {
|
|
1308
1321
|
engine: "unknown",
|
|
1309
1322
|
...e
|
|
1310
1323
|
});
|
|
1311
|
-
return t[
|
|
1324
|
+
return t[ge] = s, s;
|
|
1312
1325
|
}
|
|
1313
1326
|
renderer;
|
|
1314
1327
|
context;
|
|
1315
|
-
projectionScreenMatrix = new
|
|
1328
|
+
projectionScreenMatrix = new Ge();
|
|
1316
1329
|
/** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
|
|
1317
1330
|
get plugins() {
|
|
1318
|
-
return
|
|
1331
|
+
return U;
|
|
1319
1332
|
}
|
|
1320
1333
|
/**
|
|
1321
1334
|
* Force override the LOD level for all objects (meshes + textures) rendered in the scene
|
|
@@ -1380,12 +1393,12 @@ class I {
|
|
|
1380
1393
|
* ```
|
|
1381
1394
|
*/
|
|
1382
1395
|
awaitLoading(t) {
|
|
1383
|
-
const e = this._promiseGroupIds++, s = new
|
|
1396
|
+
const e = this._promiseGroupIds++, s = new le(this.#r, { ...t });
|
|
1384
1397
|
this._newPromiseGroups.push(s);
|
|
1385
1398
|
const r = performance.now();
|
|
1386
1399
|
return s.ready.finally(() => {
|
|
1387
1400
|
const n = this._newPromiseGroups.indexOf(s);
|
|
1388
|
-
n >= 0 && (this._newPromiseGroups.splice(n, 1),
|
|
1401
|
+
n >= 0 && (this._newPromiseGroups.splice(n, 1), Ue() && performance.measure("LODsManager:awaitLoading", {
|
|
1389
1402
|
start: r,
|
|
1390
1403
|
detail: { id: e, name: t?.name, awaited: s.awaitedCount, resolved: s.resolvedCount }
|
|
1391
1404
|
}));
|
|
@@ -1393,7 +1406,7 @@ class I {
|
|
|
1393
1406
|
}
|
|
1394
1407
|
/** Track LOD work started outside this manager so {@link awaitLoading} waits for it too. */
|
|
1395
1408
|
trackLoadingPromise(t, e, s) {
|
|
1396
|
-
return
|
|
1409
|
+
return le.addPromise(t, e, s, this._newPromiseGroups), s;
|
|
1397
1410
|
}
|
|
1398
1411
|
_postprocessPromiseGroups() {
|
|
1399
1412
|
if (this._newPromiseGroups.length !== 0)
|
|
@@ -1445,7 +1458,7 @@ class I {
|
|
|
1445
1458
|
#n = 0;
|
|
1446
1459
|
#o = 0;
|
|
1447
1460
|
#s = 0;
|
|
1448
|
-
#i =
|
|
1461
|
+
#i = Gt();
|
|
1449
1462
|
_fpsBuffer = [60, 60, 60, 60, 60];
|
|
1450
1463
|
/**
|
|
1451
1464
|
* Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
|
|
@@ -1458,7 +1471,7 @@ class I {
|
|
|
1458
1471
|
const e = this;
|
|
1459
1472
|
_e(this.renderer), this.renderer.render = function(s, r) {
|
|
1460
1473
|
const n = e.renderer.getRenderTarget();
|
|
1461
|
-
(n == null || "isXRRenderTarget" in n && n.isXRRenderTarget) && (t = 0, e.#r += 1, e.#i.update?.(), e.#n = Math.max(e.#i.getDelta(), 1 / 1e3), e.#o += e.#n, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#n), e.#s = e._fpsBuffer.reduce((
|
|
1474
|
+
(n == null || "isXRRenderTarget" in n && n.isXRRenderTarget) && (t = 0, e.#r += 1, e.#i.update?.(), e.#n = Math.max(e.#i.getDelta(), 1 / 1e3), e.#o += e.#n, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#n), e.#s = e._fpsBuffer.reduce((l, a) => l + a) / e._fpsBuffer.length, $ && e.#r % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
|
|
1462
1475
|
const o = t++;
|
|
1463
1476
|
e.#t.call(this, s, r), e.onAfterRender(s, r, o);
|
|
1464
1477
|
};
|
|
@@ -1491,11 +1504,11 @@ class I {
|
|
|
1491
1504
|
const n = r.opaque;
|
|
1492
1505
|
let o = !0;
|
|
1493
1506
|
if (n.length === 1) {
|
|
1494
|
-
const
|
|
1495
|
-
(
|
|
1507
|
+
const l = n[0].material;
|
|
1508
|
+
(l.name === "EffectMaterial" || l.name === "CopyShader") && (o = !1);
|
|
1496
1509
|
}
|
|
1497
1510
|
if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (o = !1), o) {
|
|
1498
|
-
if (It || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1,
|
|
1511
|
+
if (It || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1, $ && console.warn("↓ Reducing LOD updates", this.#e, this.#s.toFixed(0))) : this.#s >= 60 && this.#e > 1 && (this.#e -= 1, $ && console.warn("↑ Increasing LOD updates", this.#e, this.#s.toFixed(0))) : this.#e = this.updateInterval, this.#e > 0 && this.#r % this.#e != 0))
|
|
1499
1512
|
return;
|
|
1500
1513
|
this.internalUpdate(t, e), this._postprocessPromiseGroups();
|
|
1501
1514
|
}
|
|
@@ -1509,12 +1522,12 @@ class I {
|
|
|
1509
1522
|
const r = s.opaque;
|
|
1510
1523
|
this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse);
|
|
1511
1524
|
const n = this.targetTriangleDensity;
|
|
1512
|
-
for (const
|
|
1513
|
-
if (
|
|
1514
|
-
|
|
1525
|
+
for (const a of r) {
|
|
1526
|
+
if (a.material && (a.geometry?.type === "BoxGeometry" || a.geometry?.type === "BufferGeometry") && (a.material.name === "SphericalGaussianBlur" || a.material.name == "BackgroundCubeMaterial" || a.material.name === "CubemapFromEquirect" || a.material.name === "EquirectangularToCubeUV")) {
|
|
1527
|
+
$ && (a.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] || (a.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] = !0, console.warn("Ignoring skybox or BLIT object", a, a.material.name, a.material.type)));
|
|
1515
1528
|
continue;
|
|
1516
1529
|
}
|
|
1517
|
-
switch (
|
|
1530
|
+
switch (a.material.type) {
|
|
1518
1531
|
case "LineBasicMaterial":
|
|
1519
1532
|
case "LineDashedMaterial":
|
|
1520
1533
|
case "PointsMaterial":
|
|
@@ -1523,18 +1536,18 @@ class I {
|
|
|
1523
1536
|
case "MeshDepthMaterial":
|
|
1524
1537
|
continue;
|
|
1525
1538
|
}
|
|
1526
|
-
const u =
|
|
1527
|
-
(u instanceof
|
|
1539
|
+
const u = a.object;
|
|
1540
|
+
(u instanceof H || u.isMesh) && this.updateLODs(t, e, u, n);
|
|
1528
1541
|
}
|
|
1529
1542
|
const o = s.transparent;
|
|
1530
|
-
for (const
|
|
1531
|
-
const u =
|
|
1532
|
-
(u instanceof
|
|
1543
|
+
for (const a of o) {
|
|
1544
|
+
const u = a.object;
|
|
1545
|
+
(u instanceof H || u.isMesh) && this.updateLODs(t, e, u, n);
|
|
1533
1546
|
}
|
|
1534
|
-
const
|
|
1535
|
-
for (const
|
|
1536
|
-
const u =
|
|
1537
|
-
(u instanceof
|
|
1547
|
+
const l = s.transmissive;
|
|
1548
|
+
for (const a of l) {
|
|
1549
|
+
const u = a.object;
|
|
1550
|
+
(u instanceof H || u.isMesh) && this.updateLODs(t, e, u, n);
|
|
1538
1551
|
}
|
|
1539
1552
|
}
|
|
1540
1553
|
getRenderList(t, e, s) {
|
|
@@ -1559,15 +1572,15 @@ class I {
|
|
|
1559
1572
|
/** Update the LOD levels for the renderer. */
|
|
1560
1573
|
updateLODs(t, e, s, r) {
|
|
1561
1574
|
s.userData || (s.userData = {});
|
|
1562
|
-
let n = s[
|
|
1563
|
-
if (n || (n = new zt(), s[
|
|
1575
|
+
let n = s[pe];
|
|
1576
|
+
if (n || (n = new zt(), s[pe] = n), n.frames++ < 2)
|
|
1564
1577
|
return;
|
|
1565
|
-
for (const
|
|
1566
|
-
|
|
1567
|
-
const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel :
|
|
1568
|
-
o >= 0 ? (R.mesh_lod = o, R.texture_lod = o) : (this.calculateLodLevel(e, s, n, r, R), R.mesh_lod = Math.round(R.mesh_lod), R.texture_lod = Math.round(R.texture_lod)), R.mesh_lod >= 0 && this.loadProgressiveMeshes(s, R.mesh_lod), s.material && R.texture_lod >= 0 && this.loadProgressiveTextures(s.material, R.texture_lod, o),
|
|
1569
|
-
for (const
|
|
1570
|
-
|
|
1578
|
+
for (const l of U)
|
|
1579
|
+
l.onBeforeUpdateLOD?.(this.renderer, t, e, s);
|
|
1580
|
+
const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel : K;
|
|
1581
|
+
o >= 0 ? (R.mesh_lod = o, R.texture_lod = o) : (this.calculateLodLevel(e, s, n, r, R), R.mesh_lod = Math.round(R.mesh_lod), R.texture_lod = Math.round(R.texture_lod)), R.mesh_lod >= 0 && this.loadProgressiveMeshes(s, R.mesh_lod), s.material && R.texture_lod >= 0 && this.loadProgressiveTextures(s.material, R.texture_lod, o), g && s.material && !s.isGizmo && ze(s.material), At && s.material && !s.isGizmo && !s.isBatchedMesh && Ee(s.material, R.mesh_lod);
|
|
1582
|
+
for (const l of U)
|
|
1583
|
+
l.onAfterUpdatedLOD?.(this.renderer, t, e, s, R);
|
|
1571
1584
|
n.lastLodLevel_Mesh = R.mesh_lod, n.lastLodLevel_Texture = R.texture_lod;
|
|
1572
1585
|
}
|
|
1573
1586
|
/** Load progressive textures for the given material
|
|
@@ -1583,14 +1596,14 @@ class I {
|
|
|
1583
1596
|
return;
|
|
1584
1597
|
}
|
|
1585
1598
|
let r = !1;
|
|
1586
|
-
(t[
|
|
1599
|
+
(t[N] === void 0 || e < t[N]) && (r = !0);
|
|
1587
1600
|
const n = s !== void 0 && s >= 0;
|
|
1588
|
-
if (n && (r = t[
|
|
1589
|
-
t[
|
|
1590
|
-
const o = n ? { force: !0 } : void 0,
|
|
1601
|
+
if (n && (r = t[N] != s, e = s), r) {
|
|
1602
|
+
t[N] = e;
|
|
1603
|
+
const o = n ? { force: !0 } : void 0, l = p.assignTextureLOD(t, e, o).then((a) => {
|
|
1591
1604
|
this._lodchangedlisteners.forEach((u) => u({ type: "texture", level: e, object: t }));
|
|
1592
1605
|
});
|
|
1593
|
-
|
|
1606
|
+
le.addPromise("texture", t, l, this._newPromiseGroups);
|
|
1594
1607
|
}
|
|
1595
1608
|
}
|
|
1596
1609
|
/** Load progressive meshes for the given mesh
|
|
@@ -1601,18 +1614,18 @@ class I {
|
|
|
1601
1614
|
*/
|
|
1602
1615
|
loadProgressiveMeshes(t, e) {
|
|
1603
1616
|
if (!t) return Promise.resolve(null);
|
|
1604
|
-
let s = t[
|
|
1617
|
+
let s = t[N] !== e;
|
|
1605
1618
|
const r = t["DEBUG:LOD"];
|
|
1606
|
-
if (r != null && (s = t[
|
|
1607
|
-
t[
|
|
1608
|
-
const n = t.geometry, o =
|
|
1609
|
-
return
|
|
1619
|
+
if (r != null && (s = t[N] != r, e = r), s) {
|
|
1620
|
+
t[N] = e;
|
|
1621
|
+
const n = t.geometry, o = p.assignMeshLOD(t, e).then((l) => (l && t[N] == e && n != t.geometry && this._lodchangedlisteners.forEach((a) => a({ type: "mesh", level: e, object: t })), l));
|
|
1622
|
+
return le.addPromise("mesh", t, o, this._newPromiseGroups), o;
|
|
1610
1623
|
}
|
|
1611
1624
|
return Promise.resolve(null);
|
|
1612
1625
|
}
|
|
1613
1626
|
// private testIfLODLevelsAreAvailable() {
|
|
1614
|
-
_sphere = new
|
|
1615
|
-
_tempWorldPosition = new
|
|
1627
|
+
_sphere = new Ie();
|
|
1628
|
+
_tempWorldPosition = new A();
|
|
1616
1629
|
static skinnedMeshBoundsFrameOffsetCounter = 0;
|
|
1617
1630
|
static $skinnedMeshBoundsOffset = /* @__PURE__ */ Symbol("gltf-progressive-skinnedMeshBoundsOffset");
|
|
1618
1631
|
// #region calculateLodLevel
|
|
@@ -1625,39 +1638,39 @@ class I {
|
|
|
1625
1638
|
n.mesh_lod = -1, n.texture_lod = -1;
|
|
1626
1639
|
return;
|
|
1627
1640
|
}
|
|
1628
|
-
let
|
|
1629
|
-
if (
|
|
1641
|
+
let l = 10 + 1, a = !1;
|
|
1642
|
+
if ($ && e["DEBUG:LOD"] != null)
|
|
1630
1643
|
return e["DEBUG:LOD"];
|
|
1631
|
-
const u =
|
|
1632
|
-
if (!c && !
|
|
1644
|
+
const u = p.getMeshLODExtension(e.geometry)?.lods, d = p.getPrimitiveIndex(e.geometry), c = u && u.length > 0, f = p.getMaterialMinMaxLODsCount(e.material), h = f.min_count !== 1 / 0 && f.min_count >= 0 && f.max_count >= 0;
|
|
1645
|
+
if (!c && !h) {
|
|
1633
1646
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1634
1647
|
return;
|
|
1635
1648
|
}
|
|
1636
|
-
c || (
|
|
1637
|
-
const
|
|
1638
|
-
let
|
|
1649
|
+
c || (a = !0, l = 0);
|
|
1650
|
+
const D = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
|
|
1651
|
+
let w = e.geometry.boundingBox;
|
|
1639
1652
|
if (e.type === "SkinnedMesh") {
|
|
1640
1653
|
const x = e;
|
|
1641
1654
|
if (!x.boundingBox)
|
|
1642
1655
|
x.computeBoundingBox();
|
|
1643
1656
|
else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
|
|
1644
|
-
if (!x[
|
|
1645
|
-
const
|
|
1646
|
-
x[
|
|
1657
|
+
if (!x[G.$skinnedMeshBoundsOffset]) {
|
|
1658
|
+
const M = G.skinnedMeshBoundsFrameOffsetCounter++;
|
|
1659
|
+
x[G.$skinnedMeshBoundsOffset] = M;
|
|
1647
1660
|
}
|
|
1648
|
-
const
|
|
1649
|
-
if ((s.frames +
|
|
1650
|
-
const
|
|
1651
|
-
|
|
1661
|
+
const L = x[G.$skinnedMeshBoundsOffset];
|
|
1662
|
+
if ((s.frames + L) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
|
|
1663
|
+
const M = ae(x), T = x.geometry;
|
|
1664
|
+
M && (x.geometry = M), x.computeBoundingBox(), x.geometry = T;
|
|
1652
1665
|
}
|
|
1653
1666
|
}
|
|
1654
|
-
|
|
1667
|
+
w = x.boundingBox;
|
|
1655
1668
|
}
|
|
1656
|
-
if (
|
|
1669
|
+
if (w) {
|
|
1657
1670
|
if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
|
|
1658
1671
|
this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
|
|
1659
|
-
const
|
|
1660
|
-
if (this._sphere.containsPoint(
|
|
1672
|
+
const M = t.getWorldPosition(this._tempWorldPosition);
|
|
1673
|
+
if (this._sphere.containsPoint(M)) {
|
|
1661
1674
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1662
1675
|
return;
|
|
1663
1676
|
}
|
|
@@ -1668,43 +1681,43 @@ class I {
|
|
|
1668
1681
|
camera: t,
|
|
1669
1682
|
projectionScreenMatrix: this.projectionScreenMatrix,
|
|
1670
1683
|
desiredDensity: r,
|
|
1671
|
-
canvasHeight:
|
|
1684
|
+
canvasHeight: D,
|
|
1672
1685
|
currentLevel: s.lastLodLevel_Mesh,
|
|
1673
|
-
boundingBox:
|
|
1686
|
+
boundingBox: w,
|
|
1674
1687
|
xrEnabled: this.renderer.xr.enabled,
|
|
1675
|
-
debugDrawLine:
|
|
1688
|
+
debugDrawLine: $ ? G.debugDrawLine : void 0,
|
|
1676
1689
|
warnMissingPrimitiveDensities: !0
|
|
1677
1690
|
});
|
|
1678
1691
|
if (s.lastCentrality = x.centrality, s.lastScreenCoverage = x.screenCoverage, s.lastScreenspaceVolume.copy(x.screenspaceVolume), x.screenCoverage === 1 / 0) {
|
|
1679
1692
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1680
1693
|
return;
|
|
1681
1694
|
}
|
|
1682
|
-
x.level >= 0 && x.level <
|
|
1695
|
+
x.level >= 0 && x.level < l && (l = x.level, a = !0);
|
|
1683
1696
|
}
|
|
1684
|
-
if (
|
|
1685
|
-
const
|
|
1686
|
-
|
|
1697
|
+
if (a ? n.mesh_lod = l : n.mesh_lod = s.lastLodLevel_Mesh, $ && n.mesh_lod != s.lastLodLevel_Mesh) {
|
|
1698
|
+
const L = u?.[n.mesh_lod];
|
|
1699
|
+
L && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${L.densities?.[d].toFixed(0)}) | ${e.name}`);
|
|
1687
1700
|
}
|
|
1688
|
-
if (
|
|
1701
|
+
if (h) {
|
|
1689
1702
|
const x = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
|
|
1690
1703
|
if (s.lastLodLevel_Texture < 0) {
|
|
1691
|
-
if (n.texture_lod =
|
|
1692
|
-
const
|
|
1693
|
-
|
|
1704
|
+
if (n.texture_lod = f.max_count - 1, $) {
|
|
1705
|
+
const L = f.lods[f.max_count - 1];
|
|
1706
|
+
$ && console.log(`First Texture LOD ${n.texture_lod} (${L.max_height}px) - ${e.name}`);
|
|
1694
1707
|
}
|
|
1695
1708
|
} else {
|
|
1696
|
-
const
|
|
1697
|
-
let
|
|
1698
|
-
this.context?.engine === "model-viewer" && (
|
|
1699
|
-
const
|
|
1700
|
-
let
|
|
1701
|
-
for (let P =
|
|
1702
|
-
const
|
|
1703
|
-
if (!(x &&
|
|
1704
|
-
if (
|
|
1705
|
-
const
|
|
1706
|
-
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${
|
|
1707
|
-
Screensize: ${
|
|
1709
|
+
const L = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
|
|
1710
|
+
let M = s.lastScreenCoverage * 4;
|
|
1711
|
+
this.context?.engine === "model-viewer" && (M *= 1.5);
|
|
1712
|
+
const T = this.renderer.getPixelRatio?.() || globalThis.devicePixelRatio || 1, O = D / T * M;
|
|
1713
|
+
let I = !1;
|
|
1714
|
+
for (let P = f.lods.length - 1; P >= 0; P--) {
|
|
1715
|
+
const _ = f.lods[P];
|
|
1716
|
+
if (!(x && _.max_height >= 2048) && !(be() && _.max_height > 4096) && (_.max_height > O || !I && P === 0)) {
|
|
1717
|
+
if (I = !0, n.texture_lod = P, $ && n.texture_lod < s.lastLodLevel_Texture) {
|
|
1718
|
+
const E = _.max_height;
|
|
1719
|
+
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${E}px
|
|
1720
|
+
Screensize: ${O.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${L.toFixed(1)}
|
|
1708
1721
|
${e.name}`);
|
|
1709
1722
|
}
|
|
1710
1723
|
break;
|
|
@@ -1720,69 +1733,69 @@ class zt {
|
|
|
1720
1733
|
lastLodLevel_Mesh = -1;
|
|
1721
1734
|
lastLodLevel_Texture = -1;
|
|
1722
1735
|
lastScreenCoverage = 0;
|
|
1723
|
-
lastScreenspaceVolume = new
|
|
1736
|
+
lastScreenspaceVolume = new A();
|
|
1724
1737
|
lastCentrality = 0;
|
|
1725
1738
|
}
|
|
1726
|
-
function
|
|
1739
|
+
function Ee(i, t) {
|
|
1727
1740
|
if (!(t < 0)) {
|
|
1728
1741
|
if (Array.isArray(i)) {
|
|
1729
1742
|
for (const e of i)
|
|
1730
|
-
|
|
1743
|
+
Ee(e, t);
|
|
1731
1744
|
return;
|
|
1732
1745
|
}
|
|
1733
|
-
"color" in i && i.color instanceof
|
|
1746
|
+
"color" in i && i.color instanceof $e && (i.color.copy(Et(t, $t)), i.needsUpdate = !0);
|
|
1734
1747
|
}
|
|
1735
1748
|
}
|
|
1736
1749
|
function Et(i, t) {
|
|
1737
|
-
const e = Math.max(0, Math.min(
|
|
1738
|
-
return t.setHex(
|
|
1750
|
+
const e = Math.max(0, Math.min(Re.length - 1, Math.floor(i)));
|
|
1751
|
+
return t.setHex(Re[e]);
|
|
1739
1752
|
}
|
|
1740
|
-
const
|
|
1741
|
-
let
|
|
1742
|
-
function
|
|
1753
|
+
const Pe = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), ue = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
|
|
1754
|
+
let ye = null;
|
|
1755
|
+
function Ne() {
|
|
1743
1756
|
const i = Nt();
|
|
1744
1757
|
i && (i.mapURLs(function(t) {
|
|
1745
|
-
return
|
|
1746
|
-
}),
|
|
1758
|
+
return ke(), t;
|
|
1759
|
+
}), ke(), ye?.disconnect(), ye = new MutationObserver((t) => {
|
|
1747
1760
|
t.forEach((e) => {
|
|
1748
1761
|
e.addedNodes.forEach((s) => {
|
|
1749
|
-
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" &&
|
|
1762
|
+
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Ve(s);
|
|
1750
1763
|
});
|
|
1751
1764
|
});
|
|
1752
|
-
}),
|
|
1765
|
+
}), ye.observe(document, { childList: !0, subtree: !0 }));
|
|
1753
1766
|
}
|
|
1754
1767
|
function Nt() {
|
|
1755
1768
|
if (typeof customElements > "u") return null;
|
|
1756
1769
|
const i = customElements.get("model-viewer");
|
|
1757
1770
|
return i || (customElements.whenDefined("model-viewer").then(() => {
|
|
1758
|
-
console.debug("[gltf-progressive] model-viewer defined"),
|
|
1771
|
+
console.debug("[gltf-progressive] model-viewer defined"), Ne();
|
|
1759
1772
|
}), null);
|
|
1760
1773
|
}
|
|
1761
|
-
function
|
|
1774
|
+
function ke() {
|
|
1762
1775
|
if (typeof document > "u") return;
|
|
1763
1776
|
document.querySelectorAll("model-viewer").forEach((t) => {
|
|
1764
|
-
|
|
1777
|
+
Ve(t);
|
|
1765
1778
|
});
|
|
1766
1779
|
}
|
|
1767
|
-
const
|
|
1780
|
+
const Ae = /* @__PURE__ */ new WeakSet();
|
|
1768
1781
|
let Vt = 0;
|
|
1769
|
-
function
|
|
1770
|
-
if (!i ||
|
|
1782
|
+
function Ve(i) {
|
|
1783
|
+
if (!i || Ae.has(i))
|
|
1771
1784
|
return null;
|
|
1772
|
-
|
|
1785
|
+
Ae.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++Vt + `
|
|
1773
1786
|
`, i.getAttribute("src"));
|
|
1774
1787
|
let t = null, e = null, s = null;
|
|
1775
1788
|
for (let r = i; r != null; r = Object.getPrototypeOf(r)) {
|
|
1776
|
-
const n = Object.getOwnPropertySymbols(r), o = n.find((u) => u.toString() == "Symbol(renderer)"),
|
|
1777
|
-
!t && o != null && (t = i[o].threeRenderer), !e &&
|
|
1789
|
+
const n = Object.getOwnPropertySymbols(r), o = n.find((u) => u.toString() == "Symbol(renderer)"), l = n.find((u) => u.toString() == "Symbol(scene)"), a = n.find((u) => u.toString() == "Symbol(needsRender)");
|
|
1790
|
+
!t && o != null && (t = i[o].threeRenderer), !e && l != null && (e = i[l]), !s && a != null && (s = i[a]);
|
|
1778
1791
|
}
|
|
1779
1792
|
if (t && e) {
|
|
1780
1793
|
let r = function() {
|
|
1781
1794
|
if (s) {
|
|
1782
1795
|
let o = 0;
|
|
1783
|
-
const
|
|
1796
|
+
const l = setInterval(() => {
|
|
1784
1797
|
if (o++ > 5) {
|
|
1785
|
-
clearInterval(
|
|
1798
|
+
clearInterval(l);
|
|
1786
1799
|
return;
|
|
1787
1800
|
}
|
|
1788
1801
|
s?.call(i);
|
|
@@ -1790,8 +1803,8 @@ function Ne(i) {
|
|
|
1790
1803
|
}
|
|
1791
1804
|
};
|
|
1792
1805
|
console.debug("[gltf-progressive] setup model-viewer");
|
|
1793
|
-
const n =
|
|
1794
|
-
return
|
|
1806
|
+
const n = G.get(t, { engine: "model-viewer" });
|
|
1807
|
+
return G.addPlugin(new Xt()), n.enable(), n.addEventListener("changed", () => {
|
|
1795
1808
|
s?.call(i);
|
|
1796
1809
|
}), i.addEventListener("model-visibility", (o) => {
|
|
1797
1810
|
o.detail.visible && s?.call(i);
|
|
@@ -1821,46 +1834,46 @@ class Xt {
|
|
|
1821
1834
|
return t.element;
|
|
1822
1835
|
}
|
|
1823
1836
|
tryParseTextureLOD(t, e) {
|
|
1824
|
-
if (e[
|
|
1825
|
-
e[
|
|
1837
|
+
if (e[ue] == !0) return;
|
|
1838
|
+
e[ue] = !0;
|
|
1826
1839
|
const s = this.tryGetCurrentGLTF(t), r = this.tryGetCurrentModelViewer(t), n = this.getUrl(r);
|
|
1827
1840
|
if (n && s && e.material) {
|
|
1828
|
-
let o = function(
|
|
1829
|
-
if (
|
|
1830
|
-
|
|
1831
|
-
const u = Object.keys(
|
|
1832
|
-
for (let
|
|
1833
|
-
const c = u[
|
|
1834
|
-
if (
|
|
1835
|
-
const
|
|
1836
|
-
if (
|
|
1837
|
-
const
|
|
1838
|
-
if (!
|
|
1839
|
-
console.warn("Texture data not found for texture index " +
|
|
1841
|
+
let o = function(a) {
|
|
1842
|
+
if (a[ue] == !0) return;
|
|
1843
|
+
a[ue] = !0, a.userData && (a.userData.LOD = -1);
|
|
1844
|
+
const u = Object.keys(a);
|
|
1845
|
+
for (let d = 0; d < u.length; d++) {
|
|
1846
|
+
const c = u[d], f = a[c];
|
|
1847
|
+
if (f?.isTexture === !0) {
|
|
1848
|
+
const h = f.userData?.associations?.textures;
|
|
1849
|
+
if (h == null) continue;
|
|
1850
|
+
const D = s.parser.json.textures[h];
|
|
1851
|
+
if (!D) {
|
|
1852
|
+
console.warn("Texture data not found for texture index " + h);
|
|
1840
1853
|
continue;
|
|
1841
1854
|
}
|
|
1842
|
-
if (
|
|
1843
|
-
const
|
|
1844
|
-
|
|
1855
|
+
if (D?.extensions?.[z]) {
|
|
1856
|
+
const w = D.extensions[z];
|
|
1857
|
+
w && n && p.registerTexture(n, f, w.lods.length, h, w);
|
|
1845
1858
|
}
|
|
1846
1859
|
}
|
|
1847
1860
|
}
|
|
1848
1861
|
};
|
|
1849
|
-
const
|
|
1850
|
-
if (Array.isArray(
|
|
1851
|
-
else o(
|
|
1862
|
+
const l = e.material;
|
|
1863
|
+
if (Array.isArray(l)) for (const a of l) o(a);
|
|
1864
|
+
else o(l);
|
|
1852
1865
|
}
|
|
1853
1866
|
}
|
|
1854
1867
|
tryParseMeshLOD(t, e) {
|
|
1855
|
-
if (e[
|
|
1856
|
-
e[
|
|
1868
|
+
if (e[Pe] == !0) return;
|
|
1869
|
+
e[Pe] = !0;
|
|
1857
1870
|
const s = this.tryGetCurrentModelViewer(t), r = this.getUrl(s);
|
|
1858
1871
|
if (!r)
|
|
1859
1872
|
return;
|
|
1860
|
-
const n = e.userData?.gltfExtensions?.[
|
|
1873
|
+
const n = e.userData?.gltfExtensions?.[z];
|
|
1861
1874
|
if (n && r) {
|
|
1862
1875
|
const o = e.uuid;
|
|
1863
|
-
|
|
1876
|
+
p.registerMesh(r, o, e, 0, n.lods.length, n);
|
|
1864
1877
|
}
|
|
1865
1878
|
}
|
|
1866
1879
|
}
|
|
@@ -1879,21 +1892,21 @@ function jt(...i) {
|
|
|
1879
1892
|
default:
|
|
1880
1893
|
throw new Error("Invalid arguments");
|
|
1881
1894
|
}
|
|
1882
|
-
_e(e),
|
|
1895
|
+
_e(e), qe(s), Fe(s, {
|
|
1883
1896
|
progressive: !0,
|
|
1884
1897
|
...r?.hints
|
|
1885
|
-
}), s.register((o) => new
|
|
1886
|
-
const n =
|
|
1898
|
+
}), s.register((o) => new p(o));
|
|
1899
|
+
const n = G.get(e);
|
|
1887
1900
|
return r?.enableLODsManager !== !1 && n.enable(), n;
|
|
1888
1901
|
}
|
|
1889
|
-
|
|
1890
|
-
if (!
|
|
1902
|
+
Ne();
|
|
1903
|
+
if (!Mt) {
|
|
1891
1904
|
const i = {
|
|
1892
1905
|
gltfProgressive: {
|
|
1893
1906
|
useNeedleProgressive: jt,
|
|
1894
|
-
LODsManager:
|
|
1895
|
-
configureLoader:
|
|
1896
|
-
getRaycastMesh:
|
|
1907
|
+
LODsManager: G,
|
|
1908
|
+
configureLoader: Fe,
|
|
1909
|
+
getRaycastMesh: ae,
|
|
1897
1910
|
useRaycastMeshes: bt
|
|
1898
1911
|
}
|
|
1899
1912
|
};
|
|
@@ -1904,19 +1917,19 @@ if (!_t) {
|
|
|
1904
1917
|
globalThis.Needle[t] = i[t];
|
|
1905
1918
|
}
|
|
1906
1919
|
export {
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1920
|
+
z as EXTENSION_NAME,
|
|
1921
|
+
G as LODsManager,
|
|
1922
|
+
p as NEEDLE_progressive,
|
|
1910
1923
|
ut as VERSION,
|
|
1911
|
-
|
|
1924
|
+
qe as addDracoAndKTX2Loaders,
|
|
1912
1925
|
Ut as calculateMeshLODLevel,
|
|
1913
|
-
|
|
1926
|
+
Fe as configureLoader,
|
|
1914
1927
|
_e as createLoaders,
|
|
1915
1928
|
Et as getLODColor,
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1929
|
+
ae as getRaycastMesh,
|
|
1930
|
+
Re as lodDebugColors,
|
|
1931
|
+
Ne as patchModelViewer,
|
|
1932
|
+
_t as registerRaycastMesh,
|
|
1920
1933
|
ht as setDracoDecoderLocation,
|
|
1921
1934
|
gt as setKTX2TranscoderLocation,
|
|
1922
1935
|
jt as useNeedleProgressive,
|