@needle-tools/gltf-progressive 3.6.0-canary.5401de9 → 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 +10 -0
- package/README.md +16 -14
- package/examples/modelviewer-multiple.html +4 -4
- package/examples/modelviewer.html +4 -4
- package/examples/offscreen/main.js +39 -7
- package/examples/react-three-fiber/package-lock.json +482 -484
- package/examples/react-three-fiber/package.json +4 -4
- package/examples/react-three-fiber/src/App.tsx +28 -14
- package/examples/shared/example-utils.js +75 -3
- package/examples/shared/example.css +17 -0
- package/examples/shared/runtime.js +2 -1
- package/examples/threejs/index.html +4 -4
- package/examples/webgpu/main.js +42 -7
- package/examples/worker-rendering/main.js +19 -1
- package/examples/worker-rendering/worker.js +108 -19
- package/gltf-progressive.js +508 -494
- 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/loaders.d.ts +8 -1
- package/lib/lods.manager.js +16 -12
- package/lib/utils.d.ts +1 -1
- package/lib/utils.internal.js +8 -2
- package/lib/version.js +1 -1
- package/package.json +3 -3
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,10 +68,10 @@ 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
|
-
function
|
|
74
|
+
function Le(i) {
|
|
75
75
|
const t = i.source?.data;
|
|
76
76
|
return t != null && typeof t == "object" ? t : null;
|
|
77
77
|
}
|
|
@@ -79,15 +79,15 @@ function xt(i) {
|
|
|
79
79
|
const t = i.image;
|
|
80
80
|
return t != null && typeof t == "object" ? t : null;
|
|
81
81
|
}
|
|
82
|
-
function
|
|
83
|
-
const t = xt(i), e =
|
|
82
|
+
function ve(i) {
|
|
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);
|
|
@@ -104,13 +104,13 @@ function wt(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);
|
|
@@ -118,7 +118,7 @@ function Fe() {
|
|
|
118
118
|
}
|
|
119
119
|
class Lt {
|
|
120
120
|
constructor(t, e = {}) {
|
|
121
|
-
this.maxConcurrent = t, this.debug = e.debug ?? !1, typeof
|
|
121
|
+
this.maxConcurrent = t, this.debug = e.debug ?? !1, typeof globalThis.requestAnimationFrame == "function" ? globalThis.requestAnimationFrame(this.tick) : setTimeout(this.tick, 0);
|
|
122
122
|
}
|
|
123
123
|
_running = /* @__PURE__ */ new Map();
|
|
124
124
|
_queue = [];
|
|
@@ -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
|
|
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
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 p {
|
|
|
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 p {
|
|
|
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
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 p {
|
|
|
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
|
}
|
|
@@ -600,27 +600,27 @@ class p {
|
|
|
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 p {
|
|
|
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 p {
|
|
|
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 p {
|
|
|
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,12 +712,12 @@ class p {
|
|
|
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?.[
|
|
720
|
+
const e = this.parser.json.meshes[t]?.extensions?.[z];
|
|
721
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;
|
|
@@ -735,12 +735,12 @@ class p {
|
|
|
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;
|
|
@@ -753,7 +753,7 @@ class p {
|
|
|
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) {
|
|
@@ -777,14 +777,14 @@ class p {
|
|
|
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
|
};
|
|
@@ -802,16 +802,16 @@ class p {
|
|
|
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
|
-
|
|
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
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 && !
|
|
813
|
-
for (const
|
|
814
|
-
|
|
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 p {
|
|
|
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 p {
|
|
|
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();
|
|
@@ -885,15 +885,15 @@ class p {
|
|
|
885
885
|
*/
|
|
886
886
|
static _resourceRegistry = new FinalizationRegistry((t) => {
|
|
887
887
|
const e = p.cache.get(t);
|
|
888
|
-
(
|
|
889
|
-
${t}`), e instanceof WeakRef && (e.deref() || (p.cache.delete(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() || (p.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 = p.lodInfos.get(
|
|
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 p.assignLODInformation(
|
|
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
|
-
p.assignLODInformation(
|
|
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 && p.assignLODInformation(
|
|
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 p.assignLODInformation(
|
|
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
|
-
p.assignLODInformation(
|
|
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 Lt(
|
|
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,70 +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 = p.getMeshLODExtension(t)?.lods,
|
|
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
|
-
L !== 0 &&
|
|
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
|
-
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
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);
|
|
1281
|
+
}
|
|
1282
|
+
if (c?.length)
|
|
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;
|
|
1287
|
+
break;
|
|
1288
|
+
}
|
|
1274
1289
|
}
|
|
1275
|
-
|
|
1276
|
-
return g;
|
|
1290
|
+
return h;
|
|
1277
1291
|
}
|
|
1278
|
-
class
|
|
1292
|
+
class G {
|
|
1279
1293
|
/**
|
|
1280
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.
|
|
1281
1295
|
*/
|
|
1282
1296
|
static debugDrawLine;
|
|
1283
1297
|
/** @internal */
|
|
1284
1298
|
static getObjectLODState(t) {
|
|
1285
|
-
return t[
|
|
1299
|
+
return t[pe];
|
|
1286
1300
|
}
|
|
1287
1301
|
static addPlugin(t) {
|
|
1288
|
-
|
|
1302
|
+
U.push(t);
|
|
1289
1303
|
}
|
|
1290
1304
|
static removePlugin(t) {
|
|
1291
|
-
const e =
|
|
1292
|
-
e >= 0 &&
|
|
1305
|
+
const e = U.indexOf(t);
|
|
1306
|
+
e >= 0 && U.splice(e, 1);
|
|
1293
1307
|
}
|
|
1294
1308
|
/** Read-only snapshot of the currently registered plugins, for inspection. Use {@link addPlugin} / {@link removePlugin} to modify the registry. */
|
|
1295
1309
|
static getPlugins() {
|
|
1296
|
-
return
|
|
1310
|
+
return U;
|
|
1297
1311
|
}
|
|
1298
1312
|
/**
|
|
1299
1313
|
* Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
|
|
@@ -1301,20 +1315,20 @@ class I {
|
|
|
1301
1315
|
* @returns The LODsManager instance.
|
|
1302
1316
|
*/
|
|
1303
1317
|
static get(t, e) {
|
|
1304
|
-
if (t[
|
|
1305
|
-
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[
|
|
1306
|
-
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, {
|
|
1307
1321
|
engine: "unknown",
|
|
1308
1322
|
...e
|
|
1309
1323
|
});
|
|
1310
|
-
return t[
|
|
1324
|
+
return t[ge] = s, s;
|
|
1311
1325
|
}
|
|
1312
1326
|
renderer;
|
|
1313
1327
|
context;
|
|
1314
|
-
projectionScreenMatrix = new
|
|
1328
|
+
projectionScreenMatrix = new Ge();
|
|
1315
1329
|
/** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
|
|
1316
1330
|
get plugins() {
|
|
1317
|
-
return
|
|
1331
|
+
return U;
|
|
1318
1332
|
}
|
|
1319
1333
|
/**
|
|
1320
1334
|
* Force override the LOD level for all objects (meshes + textures) rendered in the scene
|
|
@@ -1379,12 +1393,12 @@ class I {
|
|
|
1379
1393
|
* ```
|
|
1380
1394
|
*/
|
|
1381
1395
|
awaitLoading(t) {
|
|
1382
|
-
const e = this._promiseGroupIds++, s = new
|
|
1396
|
+
const e = this._promiseGroupIds++, s = new le(this.#r, { ...t });
|
|
1383
1397
|
this._newPromiseGroups.push(s);
|
|
1384
1398
|
const r = performance.now();
|
|
1385
1399
|
return s.ready.finally(() => {
|
|
1386
1400
|
const n = this._newPromiseGroups.indexOf(s);
|
|
1387
|
-
n >= 0 && (this._newPromiseGroups.splice(n, 1),
|
|
1401
|
+
n >= 0 && (this._newPromiseGroups.splice(n, 1), Ue() && performance.measure("LODsManager:awaitLoading", {
|
|
1388
1402
|
start: r,
|
|
1389
1403
|
detail: { id: e, name: t?.name, awaited: s.awaitedCount, resolved: s.resolvedCount }
|
|
1390
1404
|
}));
|
|
@@ -1392,7 +1406,7 @@ class I {
|
|
|
1392
1406
|
}
|
|
1393
1407
|
/** Track LOD work started outside this manager so {@link awaitLoading} waits for it too. */
|
|
1394
1408
|
trackLoadingPromise(t, e, s) {
|
|
1395
|
-
return
|
|
1409
|
+
return le.addPromise(t, e, s, this._newPromiseGroups), s;
|
|
1396
1410
|
}
|
|
1397
1411
|
_postprocessPromiseGroups() {
|
|
1398
1412
|
if (this._newPromiseGroups.length !== 0)
|
|
@@ -1444,7 +1458,7 @@ class I {
|
|
|
1444
1458
|
#n = 0;
|
|
1445
1459
|
#o = 0;
|
|
1446
1460
|
#s = 0;
|
|
1447
|
-
#i =
|
|
1461
|
+
#i = Gt();
|
|
1448
1462
|
_fpsBuffer = [60, 60, 60, 60, 60];
|
|
1449
1463
|
/**
|
|
1450
1464
|
* Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
|
|
@@ -1457,7 +1471,7 @@ class I {
|
|
|
1457
1471
|
const e = this;
|
|
1458
1472
|
_e(this.renderer), this.renderer.render = function(s, r) {
|
|
1459
1473
|
const n = e.renderer.getRenderTarget();
|
|
1460
|
-
(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));
|
|
1461
1475
|
const o = t++;
|
|
1462
1476
|
e.#t.call(this, s, r), e.onAfterRender(s, r, o);
|
|
1463
1477
|
};
|
|
@@ -1490,11 +1504,11 @@ class I {
|
|
|
1490
1504
|
const n = r.opaque;
|
|
1491
1505
|
let o = !0;
|
|
1492
1506
|
if (n.length === 1) {
|
|
1493
|
-
const
|
|
1494
|
-
(
|
|
1507
|
+
const l = n[0].material;
|
|
1508
|
+
(l.name === "EffectMaterial" || l.name === "CopyShader") && (o = !1);
|
|
1495
1509
|
}
|
|
1496
1510
|
if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (o = !1), o) {
|
|
1497
|
-
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))
|
|
1498
1512
|
return;
|
|
1499
1513
|
this.internalUpdate(t, e), this._postprocessPromiseGroups();
|
|
1500
1514
|
}
|
|
@@ -1508,12 +1522,12 @@ class I {
|
|
|
1508
1522
|
const r = s.opaque;
|
|
1509
1523
|
this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse);
|
|
1510
1524
|
const n = this.targetTriangleDensity;
|
|
1511
|
-
for (const
|
|
1512
|
-
if (
|
|
1513
|
-
|
|
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)));
|
|
1514
1528
|
continue;
|
|
1515
1529
|
}
|
|
1516
|
-
switch (
|
|
1530
|
+
switch (a.material.type) {
|
|
1517
1531
|
case "LineBasicMaterial":
|
|
1518
1532
|
case "LineDashedMaterial":
|
|
1519
1533
|
case "PointsMaterial":
|
|
@@ -1522,18 +1536,18 @@ class I {
|
|
|
1522
1536
|
case "MeshDepthMaterial":
|
|
1523
1537
|
continue;
|
|
1524
1538
|
}
|
|
1525
|
-
const u =
|
|
1526
|
-
(u instanceof
|
|
1539
|
+
const u = a.object;
|
|
1540
|
+
(u instanceof H || u.isMesh) && this.updateLODs(t, e, u, n);
|
|
1527
1541
|
}
|
|
1528
1542
|
const o = s.transparent;
|
|
1529
|
-
for (const
|
|
1530
|
-
const u =
|
|
1531
|
-
(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);
|
|
1532
1546
|
}
|
|
1533
|
-
const
|
|
1534
|
-
for (const
|
|
1535
|
-
const u =
|
|
1536
|
-
(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);
|
|
1537
1551
|
}
|
|
1538
1552
|
}
|
|
1539
1553
|
getRenderList(t, e, s) {
|
|
@@ -1558,15 +1572,15 @@ class I {
|
|
|
1558
1572
|
/** Update the LOD levels for the renderer. */
|
|
1559
1573
|
updateLODs(t, e, s, r) {
|
|
1560
1574
|
s.userData || (s.userData = {});
|
|
1561
|
-
let n = s[
|
|
1562
|
-
if (n || (n = new zt(), s[
|
|
1575
|
+
let n = s[pe];
|
|
1576
|
+
if (n || (n = new zt(), s[pe] = n), n.frames++ < 2)
|
|
1563
1577
|
return;
|
|
1564
|
-
for (const
|
|
1565
|
-
|
|
1566
|
-
const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel :
|
|
1567
|
-
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),
|
|
1568
|
-
for (const
|
|
1569
|
-
|
|
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);
|
|
1570
1584
|
n.lastLodLevel_Mesh = R.mesh_lod, n.lastLodLevel_Texture = R.texture_lod;
|
|
1571
1585
|
}
|
|
1572
1586
|
/** Load progressive textures for the given material
|
|
@@ -1582,14 +1596,14 @@ class I {
|
|
|
1582
1596
|
return;
|
|
1583
1597
|
}
|
|
1584
1598
|
let r = !1;
|
|
1585
|
-
(t[
|
|
1599
|
+
(t[N] === void 0 || e < t[N]) && (r = !0);
|
|
1586
1600
|
const n = s !== void 0 && s >= 0;
|
|
1587
|
-
if (n && (r = t[
|
|
1588
|
-
t[
|
|
1589
|
-
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) => {
|
|
1590
1604
|
this._lodchangedlisteners.forEach((u) => u({ type: "texture", level: e, object: t }));
|
|
1591
1605
|
});
|
|
1592
|
-
|
|
1606
|
+
le.addPromise("texture", t, l, this._newPromiseGroups);
|
|
1593
1607
|
}
|
|
1594
1608
|
}
|
|
1595
1609
|
/** Load progressive meshes for the given mesh
|
|
@@ -1600,18 +1614,18 @@ class I {
|
|
|
1600
1614
|
*/
|
|
1601
1615
|
loadProgressiveMeshes(t, e) {
|
|
1602
1616
|
if (!t) return Promise.resolve(null);
|
|
1603
|
-
let s = t[
|
|
1617
|
+
let s = t[N] !== e;
|
|
1604
1618
|
const r = t["DEBUG:LOD"];
|
|
1605
|
-
if (r != null && (s = t[
|
|
1606
|
-
t[
|
|
1607
|
-
const n = t.geometry, o = p.assignMeshLOD(t, e).then((
|
|
1608
|
-
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;
|
|
1609
1623
|
}
|
|
1610
1624
|
return Promise.resolve(null);
|
|
1611
1625
|
}
|
|
1612
1626
|
// private testIfLODLevelsAreAvailable() {
|
|
1613
|
-
_sphere = new
|
|
1614
|
-
_tempWorldPosition = new
|
|
1627
|
+
_sphere = new Ie();
|
|
1628
|
+
_tempWorldPosition = new A();
|
|
1615
1629
|
static skinnedMeshBoundsFrameOffsetCounter = 0;
|
|
1616
1630
|
static $skinnedMeshBoundsOffset = /* @__PURE__ */ Symbol("gltf-progressive-skinnedMeshBoundsOffset");
|
|
1617
1631
|
// #region calculateLodLevel
|
|
@@ -1624,39 +1638,39 @@ class I {
|
|
|
1624
1638
|
n.mesh_lod = -1, n.texture_lod = -1;
|
|
1625
1639
|
return;
|
|
1626
1640
|
}
|
|
1627
|
-
let
|
|
1628
|
-
if (
|
|
1641
|
+
let l = 10 + 1, a = !1;
|
|
1642
|
+
if ($ && e["DEBUG:LOD"] != null)
|
|
1629
1643
|
return e["DEBUG:LOD"];
|
|
1630
|
-
const u = p.getMeshLODExtension(e.geometry)?.lods,
|
|
1631
|
-
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) {
|
|
1632
1646
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1633
1647
|
return;
|
|
1634
1648
|
}
|
|
1635
|
-
c || (
|
|
1636
|
-
const
|
|
1637
|
-
let
|
|
1649
|
+
c || (a = !0, l = 0);
|
|
1650
|
+
const D = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
|
|
1651
|
+
let w = e.geometry.boundingBox;
|
|
1638
1652
|
if (e.type === "SkinnedMesh") {
|
|
1639
1653
|
const x = e;
|
|
1640
1654
|
if (!x.boundingBox)
|
|
1641
1655
|
x.computeBoundingBox();
|
|
1642
1656
|
else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
|
|
1643
|
-
if (!x[
|
|
1644
|
-
const
|
|
1645
|
-
x[
|
|
1657
|
+
if (!x[G.$skinnedMeshBoundsOffset]) {
|
|
1658
|
+
const M = G.skinnedMeshBoundsFrameOffsetCounter++;
|
|
1659
|
+
x[G.$skinnedMeshBoundsOffset] = M;
|
|
1646
1660
|
}
|
|
1647
|
-
const L = x[
|
|
1661
|
+
const L = x[G.$skinnedMeshBoundsOffset];
|
|
1648
1662
|
if ((s.frames + L) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
|
|
1649
|
-
const
|
|
1650
|
-
|
|
1663
|
+
const M = ae(x), T = x.geometry;
|
|
1664
|
+
M && (x.geometry = M), x.computeBoundingBox(), x.geometry = T;
|
|
1651
1665
|
}
|
|
1652
1666
|
}
|
|
1653
|
-
|
|
1667
|
+
w = x.boundingBox;
|
|
1654
1668
|
}
|
|
1655
|
-
if (
|
|
1669
|
+
if (w) {
|
|
1656
1670
|
if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
|
|
1657
1671
|
this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
|
|
1658
|
-
const
|
|
1659
|
-
if (this._sphere.containsPoint(
|
|
1672
|
+
const M = t.getWorldPosition(this._tempWorldPosition);
|
|
1673
|
+
if (this._sphere.containsPoint(M)) {
|
|
1660
1674
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1661
1675
|
return;
|
|
1662
1676
|
}
|
|
@@ -1667,43 +1681,43 @@ class I {
|
|
|
1667
1681
|
camera: t,
|
|
1668
1682
|
projectionScreenMatrix: this.projectionScreenMatrix,
|
|
1669
1683
|
desiredDensity: r,
|
|
1670
|
-
canvasHeight:
|
|
1684
|
+
canvasHeight: D,
|
|
1671
1685
|
currentLevel: s.lastLodLevel_Mesh,
|
|
1672
|
-
boundingBox:
|
|
1686
|
+
boundingBox: w,
|
|
1673
1687
|
xrEnabled: this.renderer.xr.enabled,
|
|
1674
|
-
debugDrawLine:
|
|
1688
|
+
debugDrawLine: $ ? G.debugDrawLine : void 0,
|
|
1675
1689
|
warnMissingPrimitiveDensities: !0
|
|
1676
1690
|
});
|
|
1677
1691
|
if (s.lastCentrality = x.centrality, s.lastScreenCoverage = x.screenCoverage, s.lastScreenspaceVolume.copy(x.screenspaceVolume), x.screenCoverage === 1 / 0) {
|
|
1678
1692
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1679
1693
|
return;
|
|
1680
1694
|
}
|
|
1681
|
-
x.level >= 0 && x.level <
|
|
1695
|
+
x.level >= 0 && x.level < l && (l = x.level, a = !0);
|
|
1682
1696
|
}
|
|
1683
|
-
if (
|
|
1697
|
+
if (a ? n.mesh_lod = l : n.mesh_lod = s.lastLodLevel_Mesh, $ && n.mesh_lod != s.lastLodLevel_Mesh) {
|
|
1684
1698
|
const L = u?.[n.mesh_lod];
|
|
1685
|
-
L && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${L.densities?.[
|
|
1699
|
+
L && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${L.densities?.[d].toFixed(0)}) | ${e.name}`);
|
|
1686
1700
|
}
|
|
1687
|
-
if (
|
|
1701
|
+
if (h) {
|
|
1688
1702
|
const x = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
|
|
1689
1703
|
if (s.lastLodLevel_Texture < 0) {
|
|
1690
|
-
if (n.texture_lod =
|
|
1691
|
-
const L =
|
|
1692
|
-
|
|
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}`);
|
|
1693
1707
|
}
|
|
1694
1708
|
} else {
|
|
1695
1709
|
const L = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
|
|
1696
|
-
let
|
|
1697
|
-
this.context?.engine === "model-viewer" && (
|
|
1698
|
-
const
|
|
1699
|
-
let
|
|
1700
|
-
for (let P =
|
|
1701
|
-
const
|
|
1702
|
-
if (!(x &&
|
|
1703
|
-
if (
|
|
1704
|
-
const
|
|
1705
|
-
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${
|
|
1706
|
-
Screensize: ${
|
|
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)}
|
|
1707
1721
|
${e.name}`);
|
|
1708
1722
|
}
|
|
1709
1723
|
break;
|
|
@@ -1719,69 +1733,69 @@ class zt {
|
|
|
1719
1733
|
lastLodLevel_Mesh = -1;
|
|
1720
1734
|
lastLodLevel_Texture = -1;
|
|
1721
1735
|
lastScreenCoverage = 0;
|
|
1722
|
-
lastScreenspaceVolume = new
|
|
1736
|
+
lastScreenspaceVolume = new A();
|
|
1723
1737
|
lastCentrality = 0;
|
|
1724
1738
|
}
|
|
1725
|
-
function
|
|
1739
|
+
function Ee(i, t) {
|
|
1726
1740
|
if (!(t < 0)) {
|
|
1727
1741
|
if (Array.isArray(i)) {
|
|
1728
1742
|
for (const e of i)
|
|
1729
|
-
|
|
1743
|
+
Ee(e, t);
|
|
1730
1744
|
return;
|
|
1731
1745
|
}
|
|
1732
|
-
"color" in i && i.color instanceof
|
|
1746
|
+
"color" in i && i.color instanceof $e && (i.color.copy(Et(t, $t)), i.needsUpdate = !0);
|
|
1733
1747
|
}
|
|
1734
1748
|
}
|
|
1735
1749
|
function Et(i, t) {
|
|
1736
|
-
const e = Math.max(0, Math.min(
|
|
1737
|
-
return t.setHex(
|
|
1750
|
+
const e = Math.max(0, Math.min(Re.length - 1, Math.floor(i)));
|
|
1751
|
+
return t.setHex(Re[e]);
|
|
1738
1752
|
}
|
|
1739
|
-
const
|
|
1740
|
-
let
|
|
1741
|
-
function
|
|
1753
|
+
const Pe = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), ue = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
|
|
1754
|
+
let ye = null;
|
|
1755
|
+
function Ne() {
|
|
1742
1756
|
const i = Nt();
|
|
1743
1757
|
i && (i.mapURLs(function(t) {
|
|
1744
|
-
return
|
|
1745
|
-
}),
|
|
1758
|
+
return ke(), t;
|
|
1759
|
+
}), ke(), ye?.disconnect(), ye = new MutationObserver((t) => {
|
|
1746
1760
|
t.forEach((e) => {
|
|
1747
1761
|
e.addedNodes.forEach((s) => {
|
|
1748
|
-
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" &&
|
|
1762
|
+
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Ve(s);
|
|
1749
1763
|
});
|
|
1750
1764
|
});
|
|
1751
|
-
}),
|
|
1765
|
+
}), ye.observe(document, { childList: !0, subtree: !0 }));
|
|
1752
1766
|
}
|
|
1753
1767
|
function Nt() {
|
|
1754
1768
|
if (typeof customElements > "u") return null;
|
|
1755
1769
|
const i = customElements.get("model-viewer");
|
|
1756
1770
|
return i || (customElements.whenDefined("model-viewer").then(() => {
|
|
1757
|
-
console.debug("[gltf-progressive] model-viewer defined"),
|
|
1771
|
+
console.debug("[gltf-progressive] model-viewer defined"), Ne();
|
|
1758
1772
|
}), null);
|
|
1759
1773
|
}
|
|
1760
|
-
function
|
|
1774
|
+
function ke() {
|
|
1761
1775
|
if (typeof document > "u") return;
|
|
1762
1776
|
document.querySelectorAll("model-viewer").forEach((t) => {
|
|
1763
|
-
|
|
1777
|
+
Ve(t);
|
|
1764
1778
|
});
|
|
1765
1779
|
}
|
|
1766
|
-
const
|
|
1780
|
+
const Ae = /* @__PURE__ */ new WeakSet();
|
|
1767
1781
|
let Vt = 0;
|
|
1768
|
-
function
|
|
1769
|
-
if (!i ||
|
|
1782
|
+
function Ve(i) {
|
|
1783
|
+
if (!i || Ae.has(i))
|
|
1770
1784
|
return null;
|
|
1771
|
-
|
|
1785
|
+
Ae.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++Vt + `
|
|
1772
1786
|
`, i.getAttribute("src"));
|
|
1773
1787
|
let t = null, e = null, s = null;
|
|
1774
1788
|
for (let r = i; r != null; r = Object.getPrototypeOf(r)) {
|
|
1775
|
-
const n = Object.getOwnPropertySymbols(r), o = n.find((u) => u.toString() == "Symbol(renderer)"),
|
|
1776
|
-
!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]);
|
|
1777
1791
|
}
|
|
1778
1792
|
if (t && e) {
|
|
1779
1793
|
let r = function() {
|
|
1780
1794
|
if (s) {
|
|
1781
1795
|
let o = 0;
|
|
1782
|
-
const
|
|
1796
|
+
const l = setInterval(() => {
|
|
1783
1797
|
if (o++ > 5) {
|
|
1784
|
-
clearInterval(
|
|
1798
|
+
clearInterval(l);
|
|
1785
1799
|
return;
|
|
1786
1800
|
}
|
|
1787
1801
|
s?.call(i);
|
|
@@ -1789,8 +1803,8 @@ function Ne(i) {
|
|
|
1789
1803
|
}
|
|
1790
1804
|
};
|
|
1791
1805
|
console.debug("[gltf-progressive] setup model-viewer");
|
|
1792
|
-
const n =
|
|
1793
|
-
return
|
|
1806
|
+
const n = G.get(t, { engine: "model-viewer" });
|
|
1807
|
+
return G.addPlugin(new Xt()), n.enable(), n.addEventListener("changed", () => {
|
|
1794
1808
|
s?.call(i);
|
|
1795
1809
|
}), i.addEventListener("model-visibility", (o) => {
|
|
1796
1810
|
o.detail.visible && s?.call(i);
|
|
@@ -1820,43 +1834,43 @@ class Xt {
|
|
|
1820
1834
|
return t.element;
|
|
1821
1835
|
}
|
|
1822
1836
|
tryParseTextureLOD(t, e) {
|
|
1823
|
-
if (e[
|
|
1824
|
-
e[
|
|
1837
|
+
if (e[ue] == !0) return;
|
|
1838
|
+
e[ue] = !0;
|
|
1825
1839
|
const s = this.tryGetCurrentGLTF(t), r = this.tryGetCurrentModelViewer(t), n = this.getUrl(r);
|
|
1826
1840
|
if (n && s && e.material) {
|
|
1827
|
-
let o = function(
|
|
1828
|
-
if (
|
|
1829
|
-
|
|
1830
|
-
const u = Object.keys(
|
|
1831
|
-
for (let
|
|
1832
|
-
const c = u[
|
|
1833
|
-
if (
|
|
1834
|
-
const
|
|
1835
|
-
if (
|
|
1836
|
-
const
|
|
1837
|
-
if (!
|
|
1838
|
-
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);
|
|
1839
1853
|
continue;
|
|
1840
1854
|
}
|
|
1841
|
-
if (
|
|
1842
|
-
const
|
|
1843
|
-
|
|
1855
|
+
if (D?.extensions?.[z]) {
|
|
1856
|
+
const w = D.extensions[z];
|
|
1857
|
+
w && n && p.registerTexture(n, f, w.lods.length, h, w);
|
|
1844
1858
|
}
|
|
1845
1859
|
}
|
|
1846
1860
|
}
|
|
1847
1861
|
};
|
|
1848
|
-
const
|
|
1849
|
-
if (Array.isArray(
|
|
1850
|
-
else o(
|
|
1862
|
+
const l = e.material;
|
|
1863
|
+
if (Array.isArray(l)) for (const a of l) o(a);
|
|
1864
|
+
else o(l);
|
|
1851
1865
|
}
|
|
1852
1866
|
}
|
|
1853
1867
|
tryParseMeshLOD(t, e) {
|
|
1854
|
-
if (e[
|
|
1855
|
-
e[
|
|
1868
|
+
if (e[Pe] == !0) return;
|
|
1869
|
+
e[Pe] = !0;
|
|
1856
1870
|
const s = this.tryGetCurrentModelViewer(t), r = this.getUrl(s);
|
|
1857
1871
|
if (!r)
|
|
1858
1872
|
return;
|
|
1859
|
-
const n = e.userData?.gltfExtensions?.[
|
|
1873
|
+
const n = e.userData?.gltfExtensions?.[z];
|
|
1860
1874
|
if (n && r) {
|
|
1861
1875
|
const o = e.uuid;
|
|
1862
1876
|
p.registerMesh(r, o, e, 0, n.lods.length, n);
|
|
@@ -1878,21 +1892,21 @@ function jt(...i) {
|
|
|
1878
1892
|
default:
|
|
1879
1893
|
throw new Error("Invalid arguments");
|
|
1880
1894
|
}
|
|
1881
|
-
_e(e),
|
|
1895
|
+
_e(e), qe(s), Fe(s, {
|
|
1882
1896
|
progressive: !0,
|
|
1883
1897
|
...r?.hints
|
|
1884
1898
|
}), s.register((o) => new p(o));
|
|
1885
|
-
const n =
|
|
1899
|
+
const n = G.get(e);
|
|
1886
1900
|
return r?.enableLODsManager !== !1 && n.enable(), n;
|
|
1887
1901
|
}
|
|
1888
|
-
|
|
1889
|
-
if (!
|
|
1902
|
+
Ne();
|
|
1903
|
+
if (!Mt) {
|
|
1890
1904
|
const i = {
|
|
1891
1905
|
gltfProgressive: {
|
|
1892
1906
|
useNeedleProgressive: jt,
|
|
1893
|
-
LODsManager:
|
|
1894
|
-
configureLoader:
|
|
1895
|
-
getRaycastMesh:
|
|
1907
|
+
LODsManager: G,
|
|
1908
|
+
configureLoader: Fe,
|
|
1909
|
+
getRaycastMesh: ae,
|
|
1896
1910
|
useRaycastMeshes: bt
|
|
1897
1911
|
}
|
|
1898
1912
|
};
|
|
@@ -1903,19 +1917,19 @@ if (!_t) {
|
|
|
1903
1917
|
globalThis.Needle[t] = i[t];
|
|
1904
1918
|
}
|
|
1905
1919
|
export {
|
|
1906
|
-
|
|
1907
|
-
|
|
1920
|
+
z as EXTENSION_NAME,
|
|
1921
|
+
G as LODsManager,
|
|
1908
1922
|
p as NEEDLE_progressive,
|
|
1909
1923
|
ut as VERSION,
|
|
1910
|
-
|
|
1924
|
+
qe as addDracoAndKTX2Loaders,
|
|
1911
1925
|
Ut as calculateMeshLODLevel,
|
|
1912
|
-
|
|
1926
|
+
Fe as configureLoader,
|
|
1913
1927
|
_e as createLoaders,
|
|
1914
1928
|
Et as getLODColor,
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1929
|
+
ae as getRaycastMesh,
|
|
1930
|
+
Re as lodDebugColors,
|
|
1931
|
+
Ne as patchModelViewer,
|
|
1932
|
+
_t as registerRaycastMesh,
|
|
1919
1933
|
ht as setDracoDecoderLocation,
|
|
1920
1934
|
gt as setKTX2TranscoderLocation,
|
|
1921
1935
|
jt as useNeedleProgressive,
|