@needle-tools/gltf-progressive 3.6.0-alpha.2 → 3.6.0-alpha.3
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 +3 -0
- package/gltf-progressive.js +517 -480
- package/gltf-progressive.min.js +9 -9
- package/gltf-progressive.umd.cjs +9 -9
- package/lib/extension.d.ts +6 -0
- package/lib/extension.js +80 -9
- package/lib/version.js +1 -1
- package/package.json +1 -1
package/gltf-progressive.js
CHANGED
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
import { BufferGeometry as j, Mesh as K, Box3 as
|
|
2
|
-
import { GLTFLoader as
|
|
1
|
+
import { BufferGeometry as j, Mesh as K, Box3 as ue, Vector3 as P, Sphere as Ce, CompressedTexture as ze, Texture as q, Matrix3 as Ee, InterleavedBuffer as Ne, InterleavedBufferAttribute as Ve, BufferAttribute as Xe, TextureLoader as je, Color as ke, Matrix4 as Pe, Clock as Ke } from "three";
|
|
2
|
+
import { GLTFLoader as Le } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
3
3
|
import { MeshoptDecoder as Ye } from "three/examples/jsm/libs/meshopt_decoder.module.js";
|
|
4
4
|
import { DRACOLoader as He } from "three/examples/jsm/loaders/DRACOLoader.js";
|
|
5
5
|
import { KTX2Loader as Qe } from "three/examples/jsm/loaders/KTX2Loader.js";
|
|
6
6
|
const Je = "";
|
|
7
7
|
globalThis.GLTF_PROGRESSIVE_VERSION = Je;
|
|
8
8
|
console.debug("[gltf-progressive] version -");
|
|
9
|
-
let
|
|
10
|
-
const Ze =
|
|
11
|
-
|
|
12
|
-
fetch(
|
|
9
|
+
let $ = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", Y = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
|
|
10
|
+
const Ze = $, et = Y, Re = new URL($ + "draco_decoder.js");
|
|
11
|
+
Re.searchParams.append("range", "true");
|
|
12
|
+
fetch(Re, {
|
|
13
13
|
method: "GET",
|
|
14
14
|
headers: {
|
|
15
15
|
Range: "bytes=0-1"
|
|
16
16
|
}
|
|
17
17
|
}).catch((i) => {
|
|
18
|
-
console.debug(`Failed to fetch remote Draco decoder from ${
|
|
18
|
+
console.debug(`Failed to fetch remote Draco decoder from ${$} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), $ === Ze && st("./include/draco/"), Y === et && rt("./include/ktx2/");
|
|
19
19
|
}).finally(() => {
|
|
20
|
-
|
|
20
|
+
Ie();
|
|
21
21
|
});
|
|
22
22
|
const tt = () => ({
|
|
23
|
-
dracoDecoderPath:
|
|
23
|
+
dracoDecoderPath: $,
|
|
24
24
|
ktx2TranscoderPath: Y
|
|
25
25
|
});
|
|
26
26
|
function st(i) {
|
|
27
|
-
|
|
27
|
+
$ = i, k && k[ye] != $ ? (console.debug("Updating Draco decoder path to " + i), k[ye] = $, k.setDecoderPath($), k.preload()) : console.debug("Setting Draco decoder path to " + i);
|
|
28
28
|
}
|
|
29
29
|
function rt(i) {
|
|
30
|
-
Y = i,
|
|
30
|
+
Y = i, B && B.transcoderPath != Y ? (console.debug("Updating KTX2 transcoder path to " + i), B.setTranscoderPath(Y), B.init()) : console.debug("Setting KTX2 transcoder path to " + i);
|
|
31
31
|
}
|
|
32
|
-
function
|
|
33
|
-
return
|
|
32
|
+
function ve(i) {
|
|
33
|
+
return Ie(), i ? B.detectSupport(i) : i !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: k, ktx2Loader: B, meshoptDecoder: le };
|
|
34
34
|
}
|
|
35
35
|
function Ae(i) {
|
|
36
|
-
i.dracoLoader || i.setDRACOLoader(
|
|
36
|
+
i.dracoLoader || i.setDRACOLoader(k), i.ktx2Loader || i.setKTX2Loader(B), i.meshoptDecoder || i.setMeshoptDecoder(le);
|
|
37
37
|
}
|
|
38
|
-
const
|
|
39
|
-
let
|
|
40
|
-
function
|
|
41
|
-
|
|
38
|
+
const ye = /* @__PURE__ */ Symbol("dracoDecoderPath");
|
|
39
|
+
let k, le, B;
|
|
40
|
+
function Ie() {
|
|
41
|
+
k || (k = new He(), k[ye] = $, k.setDecoderPath($), k.setDecoderConfig({ type: "js" }), k.preload()), B || (B = new Qe(), B.setTranscoderPath(Y), B.init()), le || (le = Ye);
|
|
42
42
|
}
|
|
43
|
-
const
|
|
44
|
-
function
|
|
45
|
-
let e =
|
|
46
|
-
e ? e = Object.assign(e, t) : e = t,
|
|
43
|
+
const xe = /* @__PURE__ */ new WeakMap();
|
|
44
|
+
function $e(i, t) {
|
|
45
|
+
let e = xe.get(i);
|
|
46
|
+
e ? e = Object.assign(e, t) : e = t, xe.set(i, e);
|
|
47
47
|
}
|
|
48
|
-
const nt =
|
|
49
|
-
function
|
|
50
|
-
const t =
|
|
48
|
+
const nt = Le.prototype.load;
|
|
49
|
+
function it(...i) {
|
|
50
|
+
const t = xe.get(this);
|
|
51
51
|
let e = i[0];
|
|
52
52
|
const s = new URL(e, window.location.href);
|
|
53
53
|
if (s.hostname.endsWith("needle.tools")) {
|
|
@@ -56,14 +56,14 @@ function ot(...i) {
|
|
|
56
56
|
}
|
|
57
57
|
return i[0] = e, nt?.call(this, ...i);
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
Le.prototype.load = it;
|
|
60
60
|
N("debugprogressive");
|
|
61
61
|
function N(i) {
|
|
62
62
|
if (typeof window > "u") return !1;
|
|
63
63
|
const e = new URL(window.location.href).searchParams.get(i);
|
|
64
64
|
return e == null || e === "0" || e === "false" ? !1 : e === "" ? !0 : e;
|
|
65
65
|
}
|
|
66
|
-
function
|
|
66
|
+
function ot(i, t) {
|
|
67
67
|
if (t === void 0 || i === void 0 || t.startsWith("./") || t.startsWith("http") || t.startsWith("data:") || t.startsWith("blob:"))
|
|
68
68
|
return t;
|
|
69
69
|
const e = i.lastIndexOf("/");
|
|
@@ -74,11 +74,11 @@ function it(i, t) {
|
|
|
74
74
|
}
|
|
75
75
|
return t;
|
|
76
76
|
}
|
|
77
|
-
function
|
|
77
|
+
function _e() {
|
|
78
78
|
return Z !== void 0 || (Z = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), N("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", Z)), Z;
|
|
79
79
|
}
|
|
80
80
|
let Z;
|
|
81
|
-
function
|
|
81
|
+
function Be() {
|
|
82
82
|
if (typeof window > "u") return !1;
|
|
83
83
|
const i = new URL(window.location.href), t = i.hostname === "localhost" || /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(i.hostname);
|
|
84
84
|
return i.hostname === "127.0.0.1" || t;
|
|
@@ -129,14 +129,14 @@ function ut(i) {
|
|
|
129
129
|
const r = i.type;
|
|
130
130
|
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;
|
|
131
131
|
}
|
|
132
|
-
const ct = typeof window > "u" && typeof document > "u",
|
|
132
|
+
const ct = typeof window > "u" && typeof document > "u", we = /* @__PURE__ */ Symbol("needle:raycast-mesh");
|
|
133
133
|
function ne(i) {
|
|
134
|
-
return i?.[
|
|
134
|
+
return i?.[we] instanceof j ? i[we] : null;
|
|
135
135
|
}
|
|
136
136
|
function dt(i, t) {
|
|
137
137
|
if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !ne(i)) {
|
|
138
138
|
const s = ht(t);
|
|
139
|
-
s.userData = { isRaycastMesh: !0 }, i[
|
|
139
|
+
s.userData = { isRaycastMesh: !0 }, i[we] = s;
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
function ft(i = !0) {
|
|
@@ -160,9 +160,9 @@ function ht(i) {
|
|
|
160
160
|
t.setAttribute(e, i.getAttribute(e));
|
|
161
161
|
return t.setIndex(i.getIndex()), t;
|
|
162
162
|
}
|
|
163
|
-
const E = new Array(),
|
|
163
|
+
const E = new Array(), h = N("debugprogressive");
|
|
164
164
|
let re, X = -1;
|
|
165
|
-
if (
|
|
165
|
+
if (h) {
|
|
166
166
|
let i = function() {
|
|
167
167
|
X += 1, X >= t && (X = -1), console.log(`Toggle LOD level [${X}]`);
|
|
168
168
|
};
|
|
@@ -173,27 +173,27 @@ if (f) {
|
|
|
173
173
|
!isNaN(s) && s >= 0 && (X = s, console.log(`Set LOD level to [${X}]`));
|
|
174
174
|
});
|
|
175
175
|
}
|
|
176
|
-
function
|
|
177
|
-
if (
|
|
176
|
+
function Ge(i) {
|
|
177
|
+
if (h && re !== void 0)
|
|
178
178
|
if (Array.isArray(i))
|
|
179
179
|
for (const t of i)
|
|
180
|
-
|
|
180
|
+
Ge(t);
|
|
181
181
|
else i && "wireframe" in i && (i.wireframe = re === !0);
|
|
182
182
|
}
|
|
183
183
|
const te = new Array();
|
|
184
184
|
let gt = 0;
|
|
185
|
-
const pt =
|
|
185
|
+
const pt = _e() ? 2 : 10;
|
|
186
186
|
function mt(i) {
|
|
187
187
|
if (te.length < pt) {
|
|
188
188
|
const s = te.length;
|
|
189
|
-
|
|
190
|
-
const r =
|
|
189
|
+
h && console.warn(`[Worker] Creating new worker #${s}`);
|
|
190
|
+
const r = De.createWorker(i || {});
|
|
191
191
|
return te.push(r), r;
|
|
192
192
|
}
|
|
193
193
|
const t = gt++ % te.length;
|
|
194
194
|
return te[t];
|
|
195
195
|
}
|
|
196
|
-
class
|
|
196
|
+
class De {
|
|
197
197
|
constructor(t, e) {
|
|
198
198
|
this.worker = t, this._debug = e.debug ?? !1, t.onmessage = (s) => {
|
|
199
199
|
const r = s.data;
|
|
@@ -220,7 +220,7 @@ class _e {
|
|
|
220
220
|
), {
|
|
221
221
|
type: "module"
|
|
222
222
|
});
|
|
223
|
-
return new
|
|
223
|
+
return new De(e, t);
|
|
224
224
|
}
|
|
225
225
|
_running = [];
|
|
226
226
|
_webglRenderer = null;
|
|
@@ -228,22 +228,22 @@ class _e {
|
|
|
228
228
|
const s = tt();
|
|
229
229
|
let r = e?.renderer;
|
|
230
230
|
r || (this._webglRenderer ??= (async () => {
|
|
231
|
-
const { WebGLRenderer:
|
|
232
|
-
return new
|
|
231
|
+
const { WebGLRenderer: u } = await import("three");
|
|
232
|
+
return new u();
|
|
233
233
|
})(), r = await this._webglRenderer);
|
|
234
|
-
const
|
|
234
|
+
const a = ve(r).ktx2Loader.workerConfig;
|
|
235
235
|
t instanceof URL ? t = t.toString() : t.startsWith("file:") ? t = URL.createObjectURL(new Blob([t])) : !t.startsWith("blob:") && !t.startsWith("http:") && !t.startsWith("https:") && (t = new URL(t, window.location.href).toString());
|
|
236
|
-
const
|
|
236
|
+
const l = {
|
|
237
237
|
type: "load",
|
|
238
238
|
url: t,
|
|
239
239
|
dracoDecoderPath: s.dracoDecoderPath,
|
|
240
240
|
ktx2TranscoderPath: s.ktx2TranscoderPath,
|
|
241
|
-
ktx2LoaderConfig:
|
|
241
|
+
ktx2LoaderConfig: a
|
|
242
242
|
};
|
|
243
|
-
return this._debug && console.debug("[Worker] Sending load request",
|
|
243
|
+
return this._debug && console.debug("[Worker] Sending load request", l), this.worker.postMessage(l), new Promise((u) => {
|
|
244
244
|
this._running.push({
|
|
245
245
|
url: t.toString(),
|
|
246
|
-
resolve:
|
|
246
|
+
resolve: u
|
|
247
247
|
});
|
|
248
248
|
});
|
|
249
249
|
}
|
|
@@ -254,27 +254,27 @@ function yt(i) {
|
|
|
254
254
|
const e = t.geometry, s = new j();
|
|
255
255
|
if (s.name = e.name || "", e.index) {
|
|
256
256
|
const r = e.index;
|
|
257
|
-
s.setIndex(
|
|
257
|
+
s.setIndex(de(r));
|
|
258
258
|
}
|
|
259
259
|
for (const r in e.attributes) {
|
|
260
|
-
const n = e.attributes[r], o =
|
|
260
|
+
const n = e.attributes[r], o = de(n);
|
|
261
261
|
s.setAttribute(r, o);
|
|
262
262
|
}
|
|
263
263
|
if (e.morphAttributes)
|
|
264
264
|
for (const r in e.morphAttributes) {
|
|
265
|
-
const o = e.morphAttributes[r].map((
|
|
265
|
+
const o = e.morphAttributes[r].map((a) => de(a));
|
|
266
266
|
s.morphAttributes[r] = o;
|
|
267
267
|
}
|
|
268
|
-
if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new
|
|
268
|
+
if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new ue(), s.boundingBox.min = new P(
|
|
269
269
|
e.boundingBox?.min.x,
|
|
270
270
|
e.boundingBox?.min.y,
|
|
271
271
|
e.boundingBox?.min.z
|
|
272
|
-
), s.boundingBox.max = new
|
|
272
|
+
), s.boundingBox.max = new P(
|
|
273
273
|
e.boundingBox?.max.x,
|
|
274
274
|
e.boundingBox?.max.y,
|
|
275
275
|
e.boundingBox?.max.z
|
|
276
|
-
), s.boundingSphere = new
|
|
277
|
-
new
|
|
276
|
+
), s.boundingSphere = new Ce(
|
|
277
|
+
new P(
|
|
278
278
|
e.boundingSphere?.center.x,
|
|
279
279
|
e.boundingSphere?.center.y,
|
|
280
280
|
e.boundingSphere?.center.z
|
|
@@ -305,7 +305,7 @@ function yt(i) {
|
|
|
305
305
|
e.colorSpace
|
|
306
306
|
);
|
|
307
307
|
} else
|
|
308
|
-
s = new
|
|
308
|
+
s = new q(
|
|
309
309
|
e.image,
|
|
310
310
|
e.mapping,
|
|
311
311
|
e.wrapS,
|
|
@@ -325,7 +325,7 @@ function yt(i) {
|
|
|
325
325
|
}
|
|
326
326
|
return i;
|
|
327
327
|
}
|
|
328
|
-
function
|
|
328
|
+
function de(i) {
|
|
329
329
|
let t = i;
|
|
330
330
|
if ("isInterleavedBufferAttribute" in i && i.isInterleavedBufferAttribute) {
|
|
331
331
|
const e = i.data, s = e.array, r = new Ne(s, e.stride);
|
|
@@ -335,11 +335,11 @@ function ce(i) {
|
|
|
335
335
|
}
|
|
336
336
|
const xt = N("gltf-progressive-worker");
|
|
337
337
|
N("gltf-progressive-reduce-mipmaps");
|
|
338
|
-
const se = N("gltf-progressive-gc"),
|
|
339
|
-
class
|
|
338
|
+
const se = N("gltf-progressive-gc"), fe = /* @__PURE__ */ Symbol("needle-progressive-texture"), U = "NEEDLE_progressive";
|
|
339
|
+
class p {
|
|
340
340
|
/** The name of the extension */
|
|
341
341
|
get name() {
|
|
342
|
-
return
|
|
342
|
+
return U;
|
|
343
343
|
}
|
|
344
344
|
// #region PUBLIC API
|
|
345
345
|
/**
|
|
@@ -381,33 +381,33 @@ class h {
|
|
|
381
381
|
max_count: 0,
|
|
382
382
|
lods: []
|
|
383
383
|
}), Array.isArray(t)) {
|
|
384
|
-
for (const
|
|
385
|
-
this.getMaterialMinMaxLODsCount(
|
|
384
|
+
for (const a of t)
|
|
385
|
+
this.getMaterialMinMaxLODsCount(a, e);
|
|
386
386
|
return t[r] = e, e;
|
|
387
387
|
}
|
|
388
|
-
if (
|
|
389
|
-
const
|
|
390
|
-
for (const
|
|
391
|
-
const
|
|
392
|
-
|
|
388
|
+
if (h === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
|
|
389
|
+
const a = t;
|
|
390
|
+
for (const l of Object.keys(a.uniforms)) {
|
|
391
|
+
const u = a.uniforms[l].value;
|
|
392
|
+
u?.isTexture === !0 && o(u, e);
|
|
393
393
|
}
|
|
394
394
|
} else if (t.isMaterial)
|
|
395
|
-
for (const
|
|
396
|
-
const
|
|
397
|
-
|
|
395
|
+
for (const a of Object.keys(t)) {
|
|
396
|
+
const l = t[a];
|
|
397
|
+
l?.isTexture === !0 && o(l, e);
|
|
398
398
|
}
|
|
399
399
|
else
|
|
400
|
-
|
|
400
|
+
h && console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);
|
|
401
401
|
return t[r] = e, e;
|
|
402
|
-
function o(
|
|
403
|
-
const
|
|
404
|
-
if (
|
|
405
|
-
const
|
|
406
|
-
if (
|
|
407
|
-
|
|
408
|
-
for (let
|
|
409
|
-
const
|
|
410
|
-
|
|
402
|
+
function o(a, l) {
|
|
403
|
+
const u = s.getAssignedLODInformation(a);
|
|
404
|
+
if (u) {
|
|
405
|
+
const d = s.lodInfos.get(u.key);
|
|
406
|
+
if (d && d.lods) {
|
|
407
|
+
l.min_count = Math.min(l.min_count, d.lods.length), l.max_count = Math.max(l.max_count, d.lods.length);
|
|
408
|
+
for (let c = 0; c < d.lods.length; c++) {
|
|
409
|
+
const f = d.lods[c];
|
|
410
|
+
f.width && (l.lods[c] = l.lods[c] || { min_height: 1 / 0, max_height: 0 }, l.lods[c].min_height = Math.min(l.lods[c].min_height, f.height), l.lods[c].max_height = Math.max(l.lods[c].max_height, f.height));
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
413
|
}
|
|
@@ -465,16 +465,21 @@ class h {
|
|
|
465
465
|
const r = t.geometry, n = this.getAssignedLODInformation(r);
|
|
466
466
|
if (!n)
|
|
467
467
|
return Promise.resolve(null);
|
|
468
|
-
for (const
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
468
|
+
for (const a of E)
|
|
469
|
+
a.onBeforeGetLODMesh?.(t, e);
|
|
470
|
+
t["LOD:requested level"] = e;
|
|
471
|
+
const o = () => t["LOD:requested level"] === e || this.shouldApplyStaleMeshLOD(t, e);
|
|
472
|
+
return p.getOrLoadLOD(r, e, {
|
|
473
|
+
isCurrent: o
|
|
474
|
+
}).then((a) => {
|
|
475
|
+
if (Array.isArray(a)) {
|
|
472
476
|
const u = n.index || 0;
|
|
473
|
-
|
|
477
|
+
a = a[u];
|
|
474
478
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
479
|
+
const l = t["LOD:requested level"] === e;
|
|
480
|
+
return (l || this.shouldApplyStaleMeshLOD(t, e)) && (l && delete t["LOD:requested level"], a && r != a && (a?.isBufferGeometry ? typeof s?.apply == "function" ? s.apply(a, e, t) : s?.apply !== !1 && (t.geometry = a) : h && console.error("Invalid LOD geometry", a))), a;
|
|
481
|
+
}).catch((a) => (console.error("Error loading mesh LOD", t, a), null));
|
|
482
|
+
} else h && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
|
|
478
483
|
return Promise.resolve(null);
|
|
479
484
|
}
|
|
480
485
|
static assignTextureLOD(t, e = 0, s) {
|
|
@@ -484,48 +489,48 @@ class h {
|
|
|
484
489
|
const n = t;
|
|
485
490
|
if (Array.isArray(n.material)) {
|
|
486
491
|
const o = new Array();
|
|
487
|
-
for (const
|
|
488
|
-
const
|
|
489
|
-
o.push(
|
|
492
|
+
for (const a of n.material) {
|
|
493
|
+
const l = this.assignTextureLOD(a, e, s);
|
|
494
|
+
o.push(l);
|
|
490
495
|
}
|
|
491
|
-
return Promise.all(o).then((
|
|
492
|
-
const
|
|
493
|
-
for (const
|
|
494
|
-
Array.isArray(
|
|
495
|
-
return
|
|
496
|
+
return Promise.all(o).then((a) => {
|
|
497
|
+
const l = new Array();
|
|
498
|
+
for (const u of a)
|
|
499
|
+
Array.isArray(u) && l.push(...u);
|
|
500
|
+
return l;
|
|
496
501
|
});
|
|
497
502
|
} else
|
|
498
503
|
return this.assignTextureLOD(n.material, e, s);
|
|
499
504
|
}
|
|
500
505
|
if (t.isMaterial === !0) {
|
|
501
|
-
const n = t, o = [],
|
|
506
|
+
const n = t, o = [], a = new Array();
|
|
502
507
|
if (this.trackCurrentMaterialTextureSlots(n), n.uniforms && (n.isRawShaderMaterial || n.isShaderMaterial === !0)) {
|
|
503
|
-
const
|
|
504
|
-
for (const
|
|
505
|
-
const
|
|
506
|
-
if (
|
|
507
|
-
const
|
|
508
|
-
o.push(
|
|
508
|
+
const l = n;
|
|
509
|
+
for (const u of Object.keys(l.uniforms)) {
|
|
510
|
+
const d = l.uniforms[u].value;
|
|
511
|
+
if (d?.isTexture === !0) {
|
|
512
|
+
const c = this.assignTextureLODForSlot(d, e, n, u, r).then((f) => (f && l.uniforms[u].value != f && (l.uniforms[u].value = f, l.uniformsNeedUpdate = !0), f));
|
|
513
|
+
o.push(c), a.push(u);
|
|
509
514
|
}
|
|
510
515
|
}
|
|
511
516
|
} else
|
|
512
|
-
for (const
|
|
513
|
-
const
|
|
514
|
-
if (
|
|
515
|
-
const
|
|
516
|
-
o.push(
|
|
517
|
+
for (const l of Object.keys(n)) {
|
|
518
|
+
const u = n[l];
|
|
519
|
+
if (u?.isTexture === !0) {
|
|
520
|
+
const d = this.assignTextureLODForSlot(u, e, n, l, r);
|
|
521
|
+
o.push(d), a.push(l);
|
|
517
522
|
}
|
|
518
523
|
}
|
|
519
|
-
return Promise.all(o).then((
|
|
520
|
-
const
|
|
521
|
-
for (let
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
+
return Promise.all(o).then((l) => {
|
|
525
|
+
const u = new Array();
|
|
526
|
+
for (let d = 0; d < l.length; d++) {
|
|
527
|
+
const c = l[d], f = a[d];
|
|
528
|
+
c && c.isTexture === !0 ? u.push({ material: n, slot: f, texture: c, level: e }) : u.push({ material: n, slot: f, texture: null, level: e });
|
|
524
529
|
}
|
|
525
|
-
return
|
|
530
|
+
return u;
|
|
526
531
|
});
|
|
527
532
|
}
|
|
528
|
-
if (t instanceof
|
|
533
|
+
if (t instanceof q || t.isTexture === !0) {
|
|
529
534
|
const n = t;
|
|
530
535
|
return this.assignTextureLODForSlot(n, e, null, null, r);
|
|
531
536
|
}
|
|
@@ -536,10 +541,10 @@ class h {
|
|
|
536
541
|
* @default 50 on desktop, 20 on mobile devices
|
|
537
542
|
*/
|
|
538
543
|
static set maxConcurrentLoadingTasks(t) {
|
|
539
|
-
|
|
544
|
+
p.queue.maxConcurrent = t;
|
|
540
545
|
}
|
|
541
546
|
static get maxConcurrentLoadingTasks() {
|
|
542
|
-
return
|
|
547
|
+
return p.queue.maxConcurrent;
|
|
543
548
|
}
|
|
544
549
|
// #region INTERNAL
|
|
545
550
|
static assignTextureLODForSlot(t, e, s, r, n) {
|
|
@@ -551,33 +556,38 @@ class h {
|
|
|
551
556
|
if (o && (o.level === e || !n && o.level < e))
|
|
552
557
|
return Promise.resolve(t);
|
|
553
558
|
if (s && r) {
|
|
554
|
-
const
|
|
555
|
-
if (
|
|
556
|
-
return
|
|
559
|
+
const c = this.getPendingTextureSlotRequest(s, r);
|
|
560
|
+
if (c && c.level === e && c.force === n)
|
|
561
|
+
return c.promise;
|
|
557
562
|
}
|
|
558
|
-
const
|
|
559
|
-
|
|
563
|
+
const a = s && r ? this.nextTextureSlotRequestId(s, r, e, n) : 0, l = () => !s || !r || this.getLatestTextureSlotRequest(s, r)?.id === a, u = () => l() || this.shouldApplyStaleTextureSlotLOD(s, r, e, n), d = p.getOrLoadLOD(t, e, {
|
|
564
|
+
isCurrent: u
|
|
565
|
+
}).then((c) => {
|
|
566
|
+
if (!l() && !this.shouldApplyStaleTextureSlotLOD(s, r, e, n)) return null;
|
|
567
|
+
if (Array.isArray(c))
|
|
560
568
|
return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen..."), null;
|
|
561
|
-
if (
|
|
562
|
-
if (
|
|
563
|
-
const
|
|
564
|
-
if (
|
|
565
|
-
const
|
|
566
|
-
if (
|
|
567
|
-
return
|
|
569
|
+
if (c?.isTexture === !0) {
|
|
570
|
+
if (c != t && s && r) {
|
|
571
|
+
const f = this.getMaterialTextureSlot(s, r) ?? t;
|
|
572
|
+
if (f && !n) {
|
|
573
|
+
const g = this.getAssignedLODInformation(f);
|
|
574
|
+
if (g && g?.level < e)
|
|
575
|
+
return h === "verbose" && console.warn("Assigned texture level is already higher: ", g.level, e, s, f, c), null;
|
|
568
576
|
}
|
|
569
|
-
this.assignTrackedTextureSlot(s, r,
|
|
577
|
+
this.assignTrackedTextureSlot(s, r, c);
|
|
570
578
|
}
|
|
571
|
-
return
|
|
572
|
-
} else
|
|
579
|
+
return c;
|
|
580
|
+
} else h == "verbose" && console.warn("No LOD found for", t, e);
|
|
573
581
|
return null;
|
|
574
|
-
}).catch((
|
|
575
|
-
return s && r && this.setPendingTextureSlotRequest(s, r, e, n,
|
|
582
|
+
}).catch((c) => (console.error("Error loading LOD", t, c), null));
|
|
583
|
+
return s && r && this.setPendingTextureSlotRequest(s, r, e, n, a, d), d;
|
|
576
584
|
}
|
|
577
585
|
// Track material slots, not just texture objects. A shared fallback texture can be
|
|
578
586
|
// referenced by many slots and should only be disposed after every slot moved away.
|
|
579
587
|
static trackedTextureSlots = /* @__PURE__ */ new WeakMap();
|
|
580
588
|
static pendingTextureSlotRequests = /* @__PURE__ */ new WeakMap();
|
|
589
|
+
static latestTextureSlotRequests = /* @__PURE__ */ new WeakMap();
|
|
590
|
+
static textureSlotRequestId = 0;
|
|
581
591
|
static trackCurrentMaterialTextureSlots(t) {
|
|
582
592
|
if (t.uniforms && (t.isRawShaderMaterial || t.isShaderMaterial === !0)) {
|
|
583
593
|
const e = t;
|
|
@@ -595,12 +605,32 @@ class h {
|
|
|
595
605
|
static getPendingTextureSlotRequest(t, e) {
|
|
596
606
|
return this.pendingTextureSlotRequests.get(t)?.get(e);
|
|
597
607
|
}
|
|
598
|
-
static
|
|
599
|
-
let
|
|
600
|
-
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
|
|
608
|
+
static nextTextureSlotRequestId(t, e, s, r) {
|
|
609
|
+
let n = this.latestTextureSlotRequests.get(t);
|
|
610
|
+
n || (n = /* @__PURE__ */ new Map(), this.latestTextureSlotRequests.set(t, n));
|
|
611
|
+
const o = ++this.textureSlotRequestId;
|
|
612
|
+
return n.set(e, { id: o, level: s, force: r }), o;
|
|
613
|
+
}
|
|
614
|
+
static getLatestTextureSlotRequest(t, e) {
|
|
615
|
+
return this.latestTextureSlotRequests.get(t)?.get(e);
|
|
616
|
+
}
|
|
617
|
+
static shouldApplyStaleTextureSlotLOD(t, e, s, r) {
|
|
618
|
+
if (!t || !e) return !1;
|
|
619
|
+
const n = this.getLatestTextureSlotRequest(t, e), o = this.getMaterialTextureSlot(t, e), a = this.getAssignedLODInformation(o)?.level ?? 1 / 0;
|
|
620
|
+
return s >= a ? !1 : r ? n ? s >= n.level : !1 : !0;
|
|
621
|
+
}
|
|
622
|
+
static shouldApplyStaleMeshLOD(t, e) {
|
|
623
|
+
const s = t["LOD:requested level"];
|
|
624
|
+
if (typeof s != "number") return !1;
|
|
625
|
+
const r = this.getAssignedLODInformation(t.geometry)?.level ?? 1 / 0;
|
|
626
|
+
return e < r && e >= s;
|
|
627
|
+
}
|
|
628
|
+
static setPendingTextureSlotRequest(t, e, s, r, n, o) {
|
|
629
|
+
let a = this.pendingTextureSlotRequests.get(t);
|
|
630
|
+
a || (a = /* @__PURE__ */ new Map(), this.pendingTextureSlotRequests.set(t, a));
|
|
631
|
+
const l = { level: s, force: r, id: n, promise: o };
|
|
632
|
+
a.set(e, l), o.finally(() => {
|
|
633
|
+
a.get(e)?.id === n && a.delete(e);
|
|
604
634
|
});
|
|
605
635
|
}
|
|
606
636
|
static getMaterialTextureSlot(t, e) {
|
|
@@ -633,7 +663,7 @@ class h {
|
|
|
633
663
|
}
|
|
634
664
|
static releaseTrackedTextureSlot(t, e, s) {
|
|
635
665
|
const r = this.trackedTextureSlots.get(t);
|
|
636
|
-
if (r?.get(e) === s && r.delete(e), this.untrackTextureUsage(s) && (
|
|
666
|
+
if (r?.get(e) === s && r.delete(e), this.untrackTextureUsage(s) && (h || se)) {
|
|
637
667
|
const o = this.getAssignedLODInformation(s);
|
|
638
668
|
console.log(`[gltf-progressive] Disposed old texture LOD ${o?.level ?? "?"} for ${t.name || t.type}.${e}`, s.uuid);
|
|
639
669
|
}
|
|
@@ -642,13 +672,13 @@ class h {
|
|
|
642
672
|
url;
|
|
643
673
|
constructor(t) {
|
|
644
674
|
const e = t.options.path;
|
|
645
|
-
|
|
675
|
+
h && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
|
|
646
676
|
}
|
|
647
677
|
_isLoadingMesh;
|
|
648
678
|
loadMesh = (t) => {
|
|
649
679
|
if (this._isLoadingMesh) return null;
|
|
650
|
-
const e = this.parser.json.meshes[t]?.extensions?.[
|
|
651
|
-
return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s &&
|
|
680
|
+
const e = this.parser.json.meshes[t]?.extensions?.[U];
|
|
681
|
+
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;
|
|
652
682
|
};
|
|
653
683
|
// private _isLoadingTexture;
|
|
654
684
|
// loadTexture = (textureIndex: number) => {
|
|
@@ -665,30 +695,30 @@ class h {
|
|
|
665
695
|
// });
|
|
666
696
|
// }
|
|
667
697
|
afterRoot(t) {
|
|
668
|
-
return
|
|
698
|
+
return h && console.log("AFTER", this.url, t), this.parser.json.textures?.forEach((e, s) => {
|
|
669
699
|
if (e?.extensions) {
|
|
670
|
-
const r = e?.extensions[
|
|
700
|
+
const r = e?.extensions[U];
|
|
671
701
|
if (r) {
|
|
672
702
|
if (!r.lods) {
|
|
673
|
-
|
|
703
|
+
h && console.warn("Texture has no LODs", r);
|
|
674
704
|
return;
|
|
675
705
|
}
|
|
676
706
|
let n = !1;
|
|
677
707
|
for (const o of this.parser.associations.keys())
|
|
678
|
-
o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (n = !0,
|
|
708
|
+
o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (n = !0, p.registerTexture(this.url, o, r.lods?.length, s, r));
|
|
679
709
|
n || this.parser.getDependency("texture", s).then((o) => {
|
|
680
|
-
o &&
|
|
710
|
+
o && p.registerTexture(this.url, o, r.lods?.length, s, r);
|
|
681
711
|
});
|
|
682
712
|
}
|
|
683
713
|
}
|
|
684
714
|
}), this.parser.json.meshes?.forEach((e, s) => {
|
|
685
715
|
if (e?.extensions) {
|
|
686
|
-
const r = e?.extensions[
|
|
716
|
+
const r = e?.extensions[U];
|
|
687
717
|
if (r && r.lods) {
|
|
688
718
|
for (const n of this.parser.associations.keys())
|
|
689
719
|
if (n.isMesh) {
|
|
690
720
|
const o = this.parser.associations.get(n);
|
|
691
|
-
o?.meshes === s &&
|
|
721
|
+
o?.meshes === s && p.registerMesh(this.url, r.guid, n, r.lods.length, o.primitives, r);
|
|
692
722
|
}
|
|
693
723
|
}
|
|
694
724
|
}
|
|
@@ -707,16 +737,16 @@ class h {
|
|
|
707
737
|
*/
|
|
708
738
|
static registerTexture = (t, e, s, r, n) => {
|
|
709
739
|
if (!e) {
|
|
710
|
-
|
|
740
|
+
h && console.error("!! gltf-progressive: Called register texture without texture");
|
|
711
741
|
return;
|
|
712
742
|
}
|
|
713
|
-
if (
|
|
714
|
-
const
|
|
715
|
-
console.log(`> gltf-progressive: register texture[${r}] "${e.name || e.uuid}", Current: ${
|
|
743
|
+
if (h) {
|
|
744
|
+
const a = e.image?.width || e.source?.data?.width || 0, l = e.image?.height || e.source?.data?.height || 0;
|
|
745
|
+
console.log(`> gltf-progressive: register texture[${r}] "${e.name || e.uuid}", Current: ${a}x${l}, Max: ${n.lods[0]?.width}x${n.lods[0]?.height}, uuid: ${e.uuid}`, n, e);
|
|
716
746
|
}
|
|
717
|
-
e.source && (e.source[
|
|
747
|
+
e.source && (e.source[fe] = n);
|
|
718
748
|
const o = n.guid;
|
|
719
|
-
|
|
749
|
+
p.assignLODInformation(t, e, o, s, r), p.lodInfos.set(o, n), p.lowresCache.set(o, new WeakRef(e));
|
|
720
750
|
};
|
|
721
751
|
/**
|
|
722
752
|
* Register a mesh with progressive LOD information. This associates the mesh geometry with its LOD extension data
|
|
@@ -732,16 +762,16 @@ class h {
|
|
|
732
762
|
* @param ext - The parsed progressive mesh extension data containing all available LOD levels with vertex/index counts and densities.
|
|
733
763
|
*/
|
|
734
764
|
static registerMesh = (t, e, s, r, n, o) => {
|
|
735
|
-
const
|
|
736
|
-
if (!
|
|
737
|
-
|
|
765
|
+
const a = s.geometry;
|
|
766
|
+
if (!a) {
|
|
767
|
+
h && console.warn("gltf-progressive: Register mesh without geometry");
|
|
738
768
|
return;
|
|
739
769
|
}
|
|
740
|
-
|
|
741
|
-
let
|
|
742
|
-
|
|
743
|
-
for (const
|
|
744
|
-
|
|
770
|
+
a.userData || (a.userData = {}), h && console.log("> Progressive: register mesh " + s.name, { index: n, uuid: s.uuid }, o, s), p.assignLODInformation(t, a, e, r, n), p.lodInfos.set(e, o);
|
|
771
|
+
let u = p.lowresCache.get(e)?.deref();
|
|
772
|
+
u ? u.push(s.geometry) : u = [s.geometry], p.lowresCache.set(e, new WeakRef(u)), r > 0 && !ne(s) && dt(s, a);
|
|
773
|
+
for (const d of E)
|
|
774
|
+
d.onRegisteredNewMesh?.(s, o);
|
|
745
775
|
};
|
|
746
776
|
/**
|
|
747
777
|
* Dispose cached resources to free memory.
|
|
@@ -782,7 +812,7 @@ class h {
|
|
|
782
812
|
this.lowresCache.clear();
|
|
783
813
|
for (const [, e] of this.cache)
|
|
784
814
|
this._disposeCacheEntry(e);
|
|
785
|
-
this.cache.clear(), this.textureRefCounts.clear(), this.trackedTextureSlots = /* @__PURE__ */ new WeakMap(), this.pendingTextureSlotRequests = /* @__PURE__ */ new WeakMap();
|
|
815
|
+
this.cache.clear(), this.textureRefCounts.clear(), this.trackedTextureSlots = /* @__PURE__ */ new WeakMap(), this.pendingTextureSlotRequests = /* @__PURE__ */ new WeakMap(), this.latestTextureSlotRequests = /* @__PURE__ */ new WeakMap(), this.textureSlotRequestId = 0;
|
|
786
816
|
}
|
|
787
817
|
}
|
|
788
818
|
/** Dispose a single cache entry's three.js resource(s) to free GPU memory. */
|
|
@@ -814,16 +844,16 @@ class h {
|
|
|
814
844
|
* The held value is the cache key string used in `previouslyLoaded`.
|
|
815
845
|
*/
|
|
816
846
|
static _resourceRegistry = new FinalizationRegistry((t) => {
|
|
817
|
-
const e =
|
|
818
|
-
(
|
|
819
|
-
${t}`), e instanceof WeakRef && (e.deref() || (
|
|
847
|
+
const e = p.cache.get(t);
|
|
848
|
+
(h || se) && console.debug(`[gltf-progressive] Memory: Resource GC'd
|
|
849
|
+
${t}`), e instanceof WeakRef && (e.deref() || (p.cache.delete(t), (h || se) && console.log("[gltf-progressive] ↪ Cache entry deleted (GC)")));
|
|
820
850
|
});
|
|
821
851
|
/**
|
|
822
852
|
* Track texture usage by incrementing reference count
|
|
823
853
|
*/
|
|
824
854
|
static trackTextureUsage(t) {
|
|
825
855
|
const e = t.uuid, s = this.textureRefCounts.get(e) || 0;
|
|
826
|
-
this.textureRefCounts.set(e, s + 1),
|
|
856
|
+
this.textureRefCounts.set(e, s + 1), h === "verbose" && console.log(`[gltf-progressive] Track texture ${e}, refCount: ${s} → ${s + 1}`);
|
|
827
857
|
}
|
|
828
858
|
/**
|
|
829
859
|
* Untrack texture usage by decrementing reference count.
|
|
@@ -833,147 +863,154 @@ ${t}`), e instanceof WeakRef && (e.deref() || (h.cache.delete(t), (f || se) && c
|
|
|
833
863
|
static untrackTextureUsage(t) {
|
|
834
864
|
const e = t.uuid, s = this.textureRefCounts.get(e);
|
|
835
865
|
if (!s)
|
|
836
|
-
return (
|
|
866
|
+
return (h === "verbose" || se) && n("[gltf-progressive] Memory: Untrack untracked texture (dispose immediately)", 0), t.dispose(), !0;
|
|
837
867
|
const r = s - 1;
|
|
838
868
|
if (r <= 0)
|
|
839
|
-
return this.textureRefCounts.delete(e), (
|
|
840
|
-
return this.textureRefCounts.set(e, r),
|
|
841
|
-
function n(o,
|
|
842
|
-
const
|
|
843
|
-
let
|
|
844
|
-
|
|
869
|
+
return this.textureRefCounts.delete(e), (h || se) && n("[gltf-progressive] Memory: Dispose texture", r), t.dispose(), !0;
|
|
870
|
+
return this.textureRefCounts.set(e, r), h === "verbose" && n("[gltf-progressive] Memory: Untrack texture", r), !1;
|
|
871
|
+
function n(o, a) {
|
|
872
|
+
const l = t.image?.width || t.source?.data?.width || 0, u = t.image?.height || t.source?.data?.height || 0, d = l && u ? `${l}x${u}` : "N/A";
|
|
873
|
+
let c = "N/A";
|
|
874
|
+
l && u && (c = `~${(lt(t) / (1024 * 1024)).toFixed(2)} MB`), console.log(`${o} — ${t.name} ${d} (${c}), refCount: ${s} → ${a}
|
|
845
875
|
${e}`);
|
|
846
876
|
}
|
|
847
877
|
}
|
|
848
878
|
static workers = [];
|
|
849
879
|
static _workersIndex = 0;
|
|
850
|
-
static async getOrLoadLOD(t, e) {
|
|
851
|
-
const
|
|
852
|
-
if (!
|
|
853
|
-
return
|
|
854
|
-
const
|
|
855
|
-
let
|
|
880
|
+
static async getOrLoadLOD(t, e, s) {
|
|
881
|
+
const r = h == "verbose", n = this.getAssignedLODInformation(t);
|
|
882
|
+
if (!n)
|
|
883
|
+
return h && console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`, t), null;
|
|
884
|
+
const o = n?.key;
|
|
885
|
+
let a;
|
|
856
886
|
if (t.isTexture === !0) {
|
|
857
|
-
const
|
|
858
|
-
|
|
887
|
+
const u = t;
|
|
888
|
+
u.source && u.source[fe] && (a = u.source[fe]);
|
|
859
889
|
}
|
|
860
|
-
if (
|
|
861
|
-
|
|
890
|
+
if (a || (a = p.lodInfos.get(o)), !a)
|
|
891
|
+
h && console.warn(`Can not load LOD ${e}: no LOD info found for "${o}" ${t.name}`, t.type, p.lodInfos);
|
|
862
892
|
else {
|
|
863
893
|
if (e > 0) {
|
|
864
894
|
let c = !1;
|
|
865
|
-
const
|
|
866
|
-
if (
|
|
867
|
-
const g = this.lowresCache.get(
|
|
895
|
+
const f = Array.isArray(a.lods);
|
|
896
|
+
if (f && e >= a.lods.length ? c = !0 : f || (c = !0), c) {
|
|
897
|
+
const g = this.lowresCache.get(o);
|
|
868
898
|
if (g) {
|
|
869
|
-
const
|
|
870
|
-
if (
|
|
871
|
-
this.lowresCache.delete(
|
|
899
|
+
const O = g.deref();
|
|
900
|
+
if (O) return O;
|
|
901
|
+
this.lowresCache.delete(o), h && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${o}`);
|
|
872
902
|
}
|
|
873
903
|
return null;
|
|
874
904
|
}
|
|
875
905
|
}
|
|
876
|
-
const
|
|
877
|
-
if (!
|
|
878
|
-
return
|
|
879
|
-
const
|
|
880
|
-
if (
|
|
881
|
-
if (!
|
|
882
|
-
return console.warn("missing pointer for glb/gltf texture",
|
|
883
|
-
const c =
|
|
884
|
-
if (
|
|
885
|
-
|
|
886
|
-
|
|
906
|
+
const u = Array.isArray(a.lods) ? a.lods[e]?.path : a.lods;
|
|
907
|
+
if (!u)
|
|
908
|
+
return h && !a["missing:uri"] && (a["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, a)), null;
|
|
909
|
+
const d = ot(n.url, u);
|
|
910
|
+
if (d.endsWith(".glb") || d.endsWith(".gltf")) {
|
|
911
|
+
if (!a.guid)
|
|
912
|
+
return console.warn("missing pointer for glb/gltf texture", a), null;
|
|
913
|
+
const c = d + "_" + a.guid, f = await this.tryResolveLODCacheEntry(this.cache.get(c), c, d, t, e, r);
|
|
914
|
+
if (f.found) return f.value;
|
|
915
|
+
if (s?.isCurrent?.() === !1)
|
|
916
|
+
return r && console.log(`Skipping stale LOD ${e} request before queue: ${d}`), null;
|
|
917
|
+
const g = await this.queue.slot(d);
|
|
918
|
+
if (s?.isCurrent?.() === !1)
|
|
919
|
+
return r && console.log(`Skipping stale LOD ${e} request after queue: ${d}`), null;
|
|
920
|
+
const O = await this.tryResolveLODCacheEntry(this.cache.get(c), c, d, t, e, r);
|
|
921
|
+
if (O.found) return O.value;
|
|
887
922
|
if (!g.use)
|
|
888
|
-
return
|
|
889
|
-
const
|
|
923
|
+
return h && console.log(`LOD ${e} was aborted: ${d}`), null;
|
|
924
|
+
const y = a, x = new Promise(async (L, V) => {
|
|
890
925
|
if (xt) {
|
|
891
|
-
const
|
|
892
|
-
if (
|
|
893
|
-
for (const
|
|
894
|
-
let
|
|
895
|
-
return
|
|
926
|
+
const m = await (await mt({})).load(d);
|
|
927
|
+
if (m.textures.length > 0)
|
|
928
|
+
for (const D of m.textures) {
|
|
929
|
+
let M = D.texture;
|
|
930
|
+
return p.assignLODInformation(n.url, M, o, e, void 0), t instanceof q && (M = this.copySettings(t, M)), M && (M.guid = y.guid), L(M);
|
|
896
931
|
}
|
|
897
|
-
if (
|
|
898
|
-
const
|
|
899
|
-
for (const
|
|
900
|
-
const
|
|
901
|
-
|
|
932
|
+
if (m.geometries.length > 0) {
|
|
933
|
+
const D = new Array();
|
|
934
|
+
for (const M of m.geometries) {
|
|
935
|
+
const G = M.geometry;
|
|
936
|
+
p.assignLODInformation(n.url, G, o, e, M.primitiveIndex), D.push(G);
|
|
902
937
|
}
|
|
903
|
-
return
|
|
938
|
+
return L(D);
|
|
904
939
|
}
|
|
905
|
-
return
|
|
940
|
+
return L(null);
|
|
906
941
|
}
|
|
907
|
-
const
|
|
908
|
-
Ae(
|
|
909
|
-
let
|
|
910
|
-
if (
|
|
911
|
-
const
|
|
912
|
-
|
|
942
|
+
const w = new Le();
|
|
943
|
+
Ae(w), h && (await new Promise((b) => setTimeout(b, 1e3)), r && console.warn("Start loading (delayed) " + d, y.guid));
|
|
944
|
+
let S = d;
|
|
945
|
+
if (y && Array.isArray(y.lods)) {
|
|
946
|
+
const b = y.lods[e];
|
|
947
|
+
b.hash && (S += "?v=" + b.hash);
|
|
913
948
|
}
|
|
914
|
-
const
|
|
915
|
-
`,
|
|
916
|
-
if (!
|
|
917
|
-
return
|
|
918
|
-
const
|
|
919
|
-
|
|
920
|
-
let
|
|
921
|
-
if (
|
|
922
|
-
let
|
|
923
|
-
for (const
|
|
924
|
-
if (
|
|
925
|
-
const
|
|
926
|
-
if (
|
|
927
|
-
|
|
949
|
+
const _ = await w.loadAsync(S).catch((b) => (console.error(`Error loading LOD ${e} from ${d}
|
|
950
|
+
`, b), L(null)));
|
|
951
|
+
if (!_)
|
|
952
|
+
return L(null);
|
|
953
|
+
const R = _.parser;
|
|
954
|
+
r && console.log("Loading finished " + d, y.guid);
|
|
955
|
+
let C = 0;
|
|
956
|
+
if (_.parser.json.textures) {
|
|
957
|
+
let b = !1;
|
|
958
|
+
for (const m of _.parser.json.textures) {
|
|
959
|
+
if (m?.extensions) {
|
|
960
|
+
const D = m?.extensions[U];
|
|
961
|
+
if (D?.guid && D.guid === y.guid) {
|
|
962
|
+
b = !0;
|
|
928
963
|
break;
|
|
929
964
|
}
|
|
930
965
|
}
|
|
931
|
-
|
|
966
|
+
C++;
|
|
932
967
|
}
|
|
933
|
-
if (
|
|
934
|
-
let
|
|
935
|
-
return
|
|
936
|
-
} else
|
|
968
|
+
if (b) {
|
|
969
|
+
let m = await R.getDependency("texture", C);
|
|
970
|
+
return m && p.assignLODInformation(n.url, m, o, e, void 0), r && console.log('change "' + t.name + '" → "' + m.name + '"', d, C, m, c), t instanceof q && (m = this.copySettings(t, m)), m && (m.guid = y.guid), L(m);
|
|
971
|
+
} else h && console.warn("Could not find texture with guid", y.guid, _.parser.json);
|
|
937
972
|
}
|
|
938
|
-
if (
|
|
939
|
-
let
|
|
940
|
-
for (const
|
|
941
|
-
if (
|
|
942
|
-
const
|
|
943
|
-
if (
|
|
944
|
-
|
|
973
|
+
if (C = 0, _.parser.json.meshes) {
|
|
974
|
+
let b = !1;
|
|
975
|
+
for (const m of _.parser.json.meshes) {
|
|
976
|
+
if (m?.extensions) {
|
|
977
|
+
const D = m?.extensions[U];
|
|
978
|
+
if (D?.guid && D.guid === y.guid) {
|
|
979
|
+
b = !0;
|
|
945
980
|
break;
|
|
946
981
|
}
|
|
947
982
|
}
|
|
948
|
-
|
|
983
|
+
C++;
|
|
949
984
|
}
|
|
950
|
-
if (
|
|
951
|
-
const
|
|
952
|
-
if (
|
|
953
|
-
const
|
|
954
|
-
return
|
|
985
|
+
if (b) {
|
|
986
|
+
const m = await R.getDependency("mesh", C);
|
|
987
|
+
if (r && console.log(`Loaded Mesh "${m.name}"`, d, C, m, c), m.isMesh === !0) {
|
|
988
|
+
const D = m.geometry;
|
|
989
|
+
return p.assignLODInformation(n.url, D, o, e, 0), L(D);
|
|
955
990
|
} else {
|
|
956
|
-
const
|
|
957
|
-
for (let
|
|
958
|
-
const
|
|
959
|
-
if (
|
|
960
|
-
const
|
|
961
|
-
|
|
991
|
+
const D = new Array();
|
|
992
|
+
for (let M = 0; M < m.children.length; M++) {
|
|
993
|
+
const G = m.children[M];
|
|
994
|
+
if (G.isMesh === !0) {
|
|
995
|
+
const ie = G.geometry;
|
|
996
|
+
p.assignLODInformation(n.url, ie, o, e, M), D.push(ie);
|
|
962
997
|
}
|
|
963
998
|
}
|
|
964
|
-
return
|
|
999
|
+
return L(D);
|
|
965
1000
|
}
|
|
966
|
-
} else
|
|
1001
|
+
} else h && console.warn("Could not find mesh with guid", y.guid, _.parser.json);
|
|
967
1002
|
}
|
|
968
|
-
return
|
|
1003
|
+
return L(null);
|
|
969
1004
|
});
|
|
970
|
-
this.cache.set(c,
|
|
971
|
-
const
|
|
972
|
-
return
|
|
973
|
-
} else if (t instanceof
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1005
|
+
this.cache.set(c, x), g.use(x);
|
|
1006
|
+
const v = await x;
|
|
1007
|
+
return v != null ? v instanceof q ? (this.cache.set(c, new WeakRef(v)), p._resourceRegistry.register(v, c)) : Array.isArray(v) ? this.cache.set(c, Promise.resolve(v)) : this.cache.set(c, Promise.resolve(v)) : this.cache.set(c, Promise.resolve(null)), v;
|
|
1008
|
+
} else if (t instanceof q) {
|
|
1009
|
+
if (s?.isCurrent?.() === !1)
|
|
1010
|
+
return r && console.log(`Skipping stale texture LOD ${e} request: ${d}`), null;
|
|
1011
|
+
r && console.log("Load texture from uri: " + d);
|
|
1012
|
+
const f = await new je().loadAsync(d);
|
|
1013
|
+
return s?.isCurrent?.() === !1 ? (f?.dispose(), null) : (f ? (f.guid = a.guid, f.flipY = !1, f.needsUpdate = !0, f.colorSpace = t.colorSpace, r && console.log(a, f)) : h && console.warn("failed loading", d), f);
|
|
977
1014
|
}
|
|
978
1015
|
}
|
|
979
1016
|
return null;
|
|
@@ -982,21 +1019,21 @@ ${e}`);
|
|
|
982
1019
|
if (t === void 0)
|
|
983
1020
|
return { found: !1 };
|
|
984
1021
|
if (o && console.log(`LOD ${n} was already loading/loaded: ${e}`), t instanceof WeakRef) {
|
|
985
|
-
const
|
|
986
|
-
if (
|
|
987
|
-
let
|
|
988
|
-
if (
|
|
989
|
-
return { found: !0, value:
|
|
1022
|
+
const u = t.deref();
|
|
1023
|
+
if (u) {
|
|
1024
|
+
let d = u, c = !1;
|
|
1025
|
+
if (d instanceof q && r instanceof q ? d.image?.data || d.source?.data ? d = this.copySettings(r, d) : c = !0 : d instanceof j && r instanceof j && (d.attributes.position?.array || (c = !0)), !c)
|
|
1026
|
+
return { found: !0, value: d };
|
|
990
1027
|
}
|
|
991
|
-
return this.cache.delete(e),
|
|
1028
|
+
return this.cache.delete(e), h && console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${e}`), { found: !1 };
|
|
992
1029
|
}
|
|
993
|
-
let
|
|
994
|
-
`,
|
|
995
|
-
return
|
|
1030
|
+
let a = await t.catch((u) => (console.error(`Error loading LOD ${n} from ${s}
|
|
1031
|
+
`, u), null)), l = !1;
|
|
1032
|
+
return a == null || (a instanceof q && r instanceof q ? a.image?.data || a.source?.data ? a = this.copySettings(r, a) : (l = !0, this.cache.delete(e)) : a instanceof j && r instanceof j && (a.attributes.position?.array || (l = !0, this.cache.delete(e)))), l ? { found: !1 } : { found: !0, value: a };
|
|
996
1033
|
}
|
|
997
1034
|
static _queue;
|
|
998
1035
|
static get queue() {
|
|
999
|
-
return this._queue ??= new at(
|
|
1036
|
+
return this._queue ??= new at(_e() ? 20 : 50, { debug: h != !1 });
|
|
1000
1037
|
}
|
|
1001
1038
|
static assignLODInformation(t, e, s, r, n) {
|
|
1002
1039
|
if (!e) return;
|
|
@@ -1009,7 +1046,7 @@ ${e}`);
|
|
|
1009
1046
|
}
|
|
1010
1047
|
// private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
|
|
1011
1048
|
static copySettings(t, e) {
|
|
1012
|
-
return e ? (
|
|
1049
|
+
return e ? (h === "verbose" && console.debug(`Copy texture settings
|
|
1013
1050
|
`, t.uuid, `
|
|
1014
1051
|
`, 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;
|
|
1015
1052
|
}
|
|
@@ -1074,7 +1111,7 @@ class oe {
|
|
|
1074
1111
|
_seen = /* @__PURE__ */ new WeakMap();
|
|
1075
1112
|
add(t, e, s) {
|
|
1076
1113
|
if (this._resolved) {
|
|
1077
|
-
|
|
1114
|
+
h && console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");
|
|
1078
1115
|
return;
|
|
1079
1116
|
}
|
|
1080
1117
|
if (!(this._frame_start !== void 0 && this._currentFrame > this._frame_start + this._frames_to_capture)) {
|
|
@@ -1082,7 +1119,7 @@ class oe {
|
|
|
1082
1119
|
if (this._seen.has(e)) {
|
|
1083
1120
|
const r = this._seen.get(e);
|
|
1084
1121
|
if (r >= this._maxPromisesPerObject) {
|
|
1085
|
-
|
|
1122
|
+
h && console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");
|
|
1086
1123
|
return;
|
|
1087
1124
|
}
|
|
1088
1125
|
this._seen.set(e, r + 1);
|
|
@@ -1101,7 +1138,7 @@ class oe {
|
|
|
1101
1138
|
});
|
|
1102
1139
|
}
|
|
1103
1140
|
}
|
|
1104
|
-
const A = N("debugprogressive"), Lt = A === "colors", vt = N("noprogressive"),
|
|
1141
|
+
const A = N("debugprogressive"), Lt = A === "colors", vt = N("noprogressive"), he = /* @__PURE__ */ Symbol("Needle:LODSManager"), ge = /* @__PURE__ */ Symbol("Needle:LODState"), F = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), T = { mesh_lod: -1, texture_lod: -1 }, _t = new ke(), Me = [
|
|
1105
1142
|
3526751,
|
|
1106
1143
|
11065402,
|
|
1107
1144
|
15978811,
|
|
@@ -1134,12 +1171,12 @@ const A = N("debugprogressive"), Lt = A === "colors", vt = N("noprogressive"), f
|
|
|
1134
1171
|
15817653,
|
|
1135
1172
|
5083278,
|
|
1136
1173
|
5592405
|
|
1137
|
-
],
|
|
1138
|
-
function
|
|
1174
|
+
], pe = new ue(), z = new ue(), Oe = new ue(), Dt = new P(), Mt = new P(), Ot = new Pe(), W = new P(), H = new P(), Q = new P(), J = new P();
|
|
1175
|
+
function St(i, t) {
|
|
1139
1176
|
const e = i.min, s = i.max, r = (e.x + s.x) * 0.5, n = (e.y + s.y) * 0.5;
|
|
1140
|
-
return
|
|
1177
|
+
return W.set(r, n, e.z).applyMatrix4(t).z < 0;
|
|
1141
1178
|
}
|
|
1142
|
-
function
|
|
1179
|
+
function bt(i) {
|
|
1143
1180
|
const {
|
|
1144
1181
|
geometry: t,
|
|
1145
1182
|
matrixWorld: e,
|
|
@@ -1147,59 +1184,59 @@ function Tt(i) {
|
|
|
1147
1184
|
projectionScreenMatrix: r,
|
|
1148
1185
|
desiredDensity: n,
|
|
1149
1186
|
canvasHeight: o = 0,
|
|
1150
|
-
currentLevel:
|
|
1151
|
-
xrEnabled:
|
|
1152
|
-
debugDrawLine:
|
|
1153
|
-
warnMissingPrimitiveDensities:
|
|
1154
|
-
} = i,
|
|
1155
|
-
level:
|
|
1156
|
-
primitiveIndex:
|
|
1187
|
+
currentLevel: a = -1,
|
|
1188
|
+
xrEnabled: l = !1,
|
|
1189
|
+
debugDrawLine: u,
|
|
1190
|
+
warnMissingPrimitiveDensities: d = !1
|
|
1191
|
+
} = i, c = p.getMeshLODExtension(t)?.lods, f = p.getPrimitiveIndex(t), g = i.target ?? {
|
|
1192
|
+
level: a,
|
|
1193
|
+
primitiveIndex: f,
|
|
1157
1194
|
screenCoverage: 0,
|
|
1158
|
-
screenspaceVolume: new
|
|
1195
|
+
screenspaceVolume: new P(),
|
|
1159
1196
|
centrality: 1
|
|
1160
1197
|
};
|
|
1161
|
-
if (
|
|
1162
|
-
let
|
|
1163
|
-
if (
|
|
1164
|
-
if (
|
|
1165
|
-
return
|
|
1166
|
-
if (z.copy(
|
|
1167
|
-
const
|
|
1168
|
-
let
|
|
1169
|
-
const
|
|
1170
|
-
|
|
1171
|
-
const
|
|
1172
|
-
|
|
1173
|
-
}
|
|
1174
|
-
const
|
|
1175
|
-
|
|
1176
|
-
const
|
|
1177
|
-
|
|
1178
|
-
const
|
|
1179
|
-
if (
|
|
1180
|
-
if (
|
|
1181
|
-
const
|
|
1182
|
-
|
|
1183
|
-
const
|
|
1184
|
-
|
|
1185
|
-
}
|
|
1186
|
-
for (let
|
|
1187
|
-
const
|
|
1188
|
-
if (
|
|
1189
|
-
|
|
1198
|
+
if (g.level = a, g.primitiveIndex = f, g.screenCoverage = 0, g.screenspaceVolume.set(0, 0, 0), g.centrality = 1, !c?.length) return g;
|
|
1199
|
+
let O = i.boundingBox ?? t.boundingBox;
|
|
1200
|
+
if (O || (t.computeBoundingBox(), O = t.boundingBox), !O) return g;
|
|
1201
|
+
if (pe.copy(O).applyMatrix4(e), s.isPerspectiveCamera && St(pe, r))
|
|
1202
|
+
return g.level = 0, g.screenCoverage = 1 / 0, g.screenspaceVolume.set(1 / 0, 1 / 0, 1 / 0), g;
|
|
1203
|
+
if (z.copy(pe).applyMatrix4(r), l && s.isPerspectiveCamera && s.fov > 70) {
|
|
1204
|
+
const w = z.min, S = z.max;
|
|
1205
|
+
let _ = w.x, R = w.y, C = S.x, b = S.y;
|
|
1206
|
+
const m = 2, D = 1.5, M = (w.x + S.x) * 0.5, G = (w.y + S.y) * 0.5;
|
|
1207
|
+
_ = (_ - M) * m + M, R = (R - G) * m + G, C = (C - M) * m + M, b = (b - G) * m + G;
|
|
1208
|
+
const ie = _ < 0 && C > 0 ? 0 : Math.min(Math.abs(w.x), Math.abs(S.x)), Fe = R < 0 && b > 0 ? 0 : Math.min(Math.abs(w.y), Math.abs(S.y)), ce = Math.max(ie, Fe);
|
|
1209
|
+
g.centrality = (D - ce) * (D - ce) * (D - ce);
|
|
1210
|
+
}
|
|
1211
|
+
const y = z.getSize(Dt);
|
|
1212
|
+
y.multiplyScalar(0.5), globalThis.screen?.availHeight > 0 && o > 0 && y.multiplyScalar(o / globalThis.screen.availHeight), s.isPerspectiveCamera && (y.x *= s.aspect), Oe.copy(O).applyMatrix4(e).applyMatrix4(s.matrixWorldInverse);
|
|
1213
|
+
const x = Oe.getSize(Mt), v = Math.max(y.x, y.y), L = Math.max(x.x, x.y);
|
|
1214
|
+
v !== 0 && L !== 0 && (y.z = x.z / L * v);
|
|
1215
|
+
const V = Math.max(y.x, y.y, y.z) * g.centrality;
|
|
1216
|
+
if (g.screenCoverage = V, g.screenspaceVolume.copy(y), V <= 0) return g;
|
|
1217
|
+
if (u) {
|
|
1218
|
+
const w = Ot.copy(r);
|
|
1219
|
+
w.invert(), W.copy(z.min), H.copy(z.max), H.x = W.x, Q.copy(z.max), Q.y = W.y, J.copy(z.max);
|
|
1220
|
+
const S = (W.z + J.z) * 0.5;
|
|
1221
|
+
W.z = H.z = Q.z = J.z = S, W.applyMatrix4(w), H.applyMatrix4(w), Q.applyMatrix4(w), J.applyMatrix4(w), u(W, H, 255), u(W, Q, 255), u(H, J, 255), u(Q, J, 255);
|
|
1222
|
+
}
|
|
1223
|
+
for (let w = 0; w < c.length; w++) {
|
|
1224
|
+
const S = c[w], _ = S.densities?.[f] || S.density || 1e-5;
|
|
1225
|
+
if (f > 0 && d && Be() && !S.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.")), _ / V < n) {
|
|
1226
|
+
g.level = w;
|
|
1190
1227
|
break;
|
|
1191
1228
|
}
|
|
1192
1229
|
}
|
|
1193
|
-
return
|
|
1230
|
+
return g;
|
|
1194
1231
|
}
|
|
1195
|
-
class
|
|
1232
|
+
class I {
|
|
1196
1233
|
/**
|
|
1197
1234
|
* 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.
|
|
1198
1235
|
*/
|
|
1199
1236
|
static debugDrawLine;
|
|
1200
1237
|
/** @internal */
|
|
1201
1238
|
static getObjectLODState(t) {
|
|
1202
|
-
return t[
|
|
1239
|
+
return t[ge];
|
|
1203
1240
|
}
|
|
1204
1241
|
static addPlugin(t) {
|
|
1205
1242
|
E.push(t);
|
|
@@ -1214,13 +1251,13 @@ class R {
|
|
|
1214
1251
|
* @returns The LODsManager instance.
|
|
1215
1252
|
*/
|
|
1216
1253
|
static get(t, e) {
|
|
1217
|
-
if (t[
|
|
1218
|
-
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[
|
|
1219
|
-
const s = new
|
|
1254
|
+
if (t[he])
|
|
1255
|
+
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[he];
|
|
1256
|
+
const s = new I(t, {
|
|
1220
1257
|
engine: "unknown",
|
|
1221
1258
|
...e
|
|
1222
1259
|
});
|
|
1223
|
-
return t[
|
|
1260
|
+
return t[he] = s, s;
|
|
1224
1261
|
}
|
|
1225
1262
|
renderer;
|
|
1226
1263
|
context;
|
|
@@ -1297,7 +1334,7 @@ class R {
|
|
|
1297
1334
|
const r = performance.now();
|
|
1298
1335
|
return s.ready.finally(() => {
|
|
1299
1336
|
const n = this._newPromiseGroups.indexOf(s);
|
|
1300
|
-
n >= 0 && (this._newPromiseGroups.splice(n, 1),
|
|
1337
|
+
n >= 0 && (this._newPromiseGroups.splice(n, 1), Be() && performance.measure("LODsManager:awaitLoading", {
|
|
1301
1338
|
start: r,
|
|
1302
1339
|
detail: { id: e, name: t?.name, awaited: s.awaitedCount, resolved: s.resolvedCount }
|
|
1303
1340
|
}));
|
|
@@ -1353,10 +1390,10 @@ class R {
|
|
|
1353
1390
|
this.renderer = t, this.context = { ...e };
|
|
1354
1391
|
}
|
|
1355
1392
|
#t;
|
|
1356
|
-
#
|
|
1393
|
+
#i = new Ke();
|
|
1357
1394
|
#r = 0;
|
|
1358
1395
|
#n = 0;
|
|
1359
|
-
#
|
|
1396
|
+
#o = 0;
|
|
1360
1397
|
#s = 0;
|
|
1361
1398
|
_fpsBuffer = [60, 60, 60, 60, 60];
|
|
1362
1399
|
/**
|
|
@@ -1368,9 +1405,9 @@ class R {
|
|
|
1368
1405
|
let t = 0;
|
|
1369
1406
|
this.#t = this.renderer.render;
|
|
1370
1407
|
const e = this;
|
|
1371
|
-
|
|
1408
|
+
ve(this.renderer), this.renderer.render = function(s, r) {
|
|
1372
1409
|
const n = e.renderer.getRenderTarget();
|
|
1373
|
-
(n == null || "isXRRenderTarget" in n && n.isXRRenderTarget) && (t = 0, e.#r += 1, e.#n = e.#
|
|
1410
|
+
(n == null || "isXRRenderTarget" in n && n.isXRRenderTarget) && (t = 0, e.#r += 1, e.#n = e.#i.getDelta(), e.#o += e.#n, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#n), e.#s = e._fpsBuffer.reduce((a, l) => a + l) / e._fpsBuffer.length, A && e.#r % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
|
|
1374
1411
|
const o = t++;
|
|
1375
1412
|
e.#t.call(this, s, r), e.onAfterRender(s, r, o);
|
|
1376
1413
|
};
|
|
@@ -1401,8 +1438,8 @@ class R {
|
|
|
1401
1438
|
const n = this.renderer.renderLists.get(t, 0).opaque;
|
|
1402
1439
|
let o = !0;
|
|
1403
1440
|
if (n.length === 1) {
|
|
1404
|
-
const
|
|
1405
|
-
(
|
|
1441
|
+
const a = n[0].material;
|
|
1442
|
+
(a.name === "EffectMaterial" || a.name === "CopyShader") && (o = !1);
|
|
1406
1443
|
}
|
|
1407
1444
|
if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (o = !1), o) {
|
|
1408
1445
|
if (vt || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1, A && console.warn("↓ Reducing LOD updates", this.#e, this.#s.toFixed(0))) : this.#s >= 60 && this.#e > 1 && (this.#e -= 1, A && console.warn("↑ Increasing LOD updates", this.#e, this.#s.toFixed(0))) : this.#e = this.updateInterval, this.#e > 0 && this.#r % this.#e != 0))
|
|
@@ -1417,12 +1454,12 @@ class R {
|
|
|
1417
1454
|
const s = this.renderer.renderLists.get(t, 0), r = s.opaque;
|
|
1418
1455
|
this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse);
|
|
1419
1456
|
const n = this.targetTriangleDensity;
|
|
1420
|
-
for (const
|
|
1421
|
-
if (
|
|
1422
|
-
A && (
|
|
1457
|
+
for (const l of r) {
|
|
1458
|
+
if (l.material && (l.geometry?.type === "BoxGeometry" || l.geometry?.type === "BufferGeometry") && (l.material.name === "SphericalGaussianBlur" || l.material.name == "BackgroundCubeMaterial" || l.material.name === "CubemapFromEquirect" || l.material.name === "EquirectangularToCubeUV")) {
|
|
1459
|
+
A && (l.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] || (l.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] = !0, console.warn("Ignoring skybox or BLIT object", l, l.material.name, l.material.type)));
|
|
1423
1460
|
continue;
|
|
1424
1461
|
}
|
|
1425
|
-
switch (
|
|
1462
|
+
switch (l.material.type) {
|
|
1426
1463
|
case "LineBasicMaterial":
|
|
1427
1464
|
case "LineDashedMaterial":
|
|
1428
1465
|
case "PointsMaterial":
|
|
@@ -1431,32 +1468,32 @@ class R {
|
|
|
1431
1468
|
case "MeshDepthMaterial":
|
|
1432
1469
|
continue;
|
|
1433
1470
|
}
|
|
1434
|
-
const
|
|
1435
|
-
(
|
|
1471
|
+
const u = l.object;
|
|
1472
|
+
(u instanceof K || u.isMesh) && this.updateLODs(t, e, u, n);
|
|
1436
1473
|
}
|
|
1437
1474
|
const o = s.transparent;
|
|
1438
|
-
for (const
|
|
1439
|
-
const
|
|
1440
|
-
(
|
|
1475
|
+
for (const l of o) {
|
|
1476
|
+
const u = l.object;
|
|
1477
|
+
(u instanceof K || u.isMesh) && this.updateLODs(t, e, u, n);
|
|
1441
1478
|
}
|
|
1442
|
-
const
|
|
1443
|
-
for (const
|
|
1444
|
-
const
|
|
1445
|
-
(
|
|
1479
|
+
const a = s.transmissive;
|
|
1480
|
+
for (const l of a) {
|
|
1481
|
+
const u = l.object;
|
|
1482
|
+
(u instanceof K || u.isMesh) && this.updateLODs(t, e, u, n);
|
|
1446
1483
|
}
|
|
1447
1484
|
}
|
|
1448
1485
|
/** Update the LOD levels for the renderer. */
|
|
1449
1486
|
updateLODs(t, e, s, r) {
|
|
1450
1487
|
s.userData || (s.userData = {});
|
|
1451
|
-
let n = s[
|
|
1452
|
-
if (n || (n = new
|
|
1488
|
+
let n = s[ge];
|
|
1489
|
+
if (n || (n = new Tt(), s[ge] = n), n.frames++ < 2)
|
|
1453
1490
|
return;
|
|
1454
|
-
for (const
|
|
1455
|
-
|
|
1491
|
+
for (const a of E)
|
|
1492
|
+
a.onBeforeUpdateLOD?.(this.renderer, t, e, s);
|
|
1456
1493
|
const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel : X;
|
|
1457
|
-
o >= 0 ? (T.mesh_lod = o, T.texture_lod = o) : (this.calculateLodLevel(e, s, n, r, T), T.mesh_lod = Math.round(T.mesh_lod), T.texture_lod = Math.round(T.texture_lod)), T.mesh_lod >= 0 && this.loadProgressiveMeshes(s, T.mesh_lod), s.material && T.texture_lod >= 0 && this.loadProgressiveTextures(s.material, T.texture_lod, o),
|
|
1458
|
-
for (const
|
|
1459
|
-
|
|
1494
|
+
o >= 0 ? (T.mesh_lod = o, T.texture_lod = o) : (this.calculateLodLevel(e, s, n, r, T), T.mesh_lod = Math.round(T.mesh_lod), T.texture_lod = Math.round(T.texture_lod)), T.mesh_lod >= 0 && this.loadProgressiveMeshes(s, T.mesh_lod), s.material && T.texture_lod >= 0 && this.loadProgressiveTextures(s.material, T.texture_lod, o), h && s.material && !s.isGizmo && Ge(s.material), Lt && s.material && !s.isGizmo && !s.isBatchedMesh && qe(s.material, T.mesh_lod);
|
|
1495
|
+
for (const a of E)
|
|
1496
|
+
a.onAfterUpdatedLOD?.(this.renderer, t, e, s, T);
|
|
1460
1497
|
n.lastLodLevel_Mesh = T.mesh_lod, n.lastLodLevel_Texture = T.texture_lod;
|
|
1461
1498
|
}
|
|
1462
1499
|
/** Load progressive textures for the given material
|
|
@@ -1472,14 +1509,14 @@ class R {
|
|
|
1472
1509
|
return;
|
|
1473
1510
|
}
|
|
1474
1511
|
let r = !1;
|
|
1475
|
-
(t[
|
|
1512
|
+
(t[F] === void 0 || e < t[F]) && (r = !0);
|
|
1476
1513
|
const n = s !== void 0 && s >= 0;
|
|
1477
|
-
if (n && (r = t[
|
|
1478
|
-
t[
|
|
1479
|
-
const o = n ? { force: !0 } : void 0,
|
|
1480
|
-
this._lodchangedlisteners.forEach((
|
|
1514
|
+
if (n && (r = t[F] != s, e = s), r) {
|
|
1515
|
+
t[F] = e;
|
|
1516
|
+
const o = n ? { force: !0 } : void 0, a = p.assignTextureLOD(t, e, o).then((l) => {
|
|
1517
|
+
this._lodchangedlisteners.forEach((u) => u({ type: "texture", level: e, object: t }));
|
|
1481
1518
|
});
|
|
1482
|
-
oe.addPromise("texture", t,
|
|
1519
|
+
oe.addPromise("texture", t, a, this._newPromiseGroups);
|
|
1483
1520
|
}
|
|
1484
1521
|
}
|
|
1485
1522
|
/** Load progressive meshes for the given mesh
|
|
@@ -1490,18 +1527,18 @@ class R {
|
|
|
1490
1527
|
*/
|
|
1491
1528
|
loadProgressiveMeshes(t, e) {
|
|
1492
1529
|
if (!t) return Promise.resolve(null);
|
|
1493
|
-
let s = t[
|
|
1530
|
+
let s = t[F] !== e;
|
|
1494
1531
|
const r = t["DEBUG:LOD"];
|
|
1495
|
-
if (r != null && (s = t[
|
|
1496
|
-
t[
|
|
1497
|
-
const n = t.geometry, o =
|
|
1532
|
+
if (r != null && (s = t[F] != r, e = r), s) {
|
|
1533
|
+
t[F] = e;
|
|
1534
|
+
const n = t.geometry, o = p.assignMeshLOD(t, e).then((a) => (a && t[F] == e && n != t.geometry && this._lodchangedlisteners.forEach((l) => l({ type: "mesh", level: e, object: t })), a));
|
|
1498
1535
|
return oe.addPromise("mesh", t, o, this._newPromiseGroups), o;
|
|
1499
1536
|
}
|
|
1500
1537
|
return Promise.resolve(null);
|
|
1501
1538
|
}
|
|
1502
1539
|
// private testIfLODLevelsAreAvailable() {
|
|
1503
|
-
_sphere = new
|
|
1504
|
-
_tempWorldPosition = new
|
|
1540
|
+
_sphere = new Ce();
|
|
1541
|
+
_tempWorldPosition = new P();
|
|
1505
1542
|
static skinnedMeshBoundsFrameOffsetCounter = 0;
|
|
1506
1543
|
static $skinnedMeshBoundsOffset = /* @__PURE__ */ Symbol("gltf-progressive-skinnedMeshBoundsOffset");
|
|
1507
1544
|
// #region calculateLodLevel
|
|
@@ -1514,86 +1551,86 @@ class R {
|
|
|
1514
1551
|
n.mesh_lod = -1, n.texture_lod = -1;
|
|
1515
1552
|
return;
|
|
1516
1553
|
}
|
|
1517
|
-
let
|
|
1554
|
+
let a = 10 + 1, l = !1;
|
|
1518
1555
|
if (A && e["DEBUG:LOD"] != null)
|
|
1519
1556
|
return e["DEBUG:LOD"];
|
|
1520
|
-
const
|
|
1521
|
-
if (!
|
|
1557
|
+
const u = p.getMeshLODExtension(e.geometry)?.lods, d = p.getPrimitiveIndex(e.geometry), c = u && u.length > 0, f = p.getMaterialMinMaxLODsCount(e.material), g = f.min_count !== 1 / 0 && f.min_count >= 0 && f.max_count >= 0;
|
|
1558
|
+
if (!c && !g) {
|
|
1522
1559
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1523
1560
|
return;
|
|
1524
1561
|
}
|
|
1525
|
-
|
|
1526
|
-
const
|
|
1527
|
-
let
|
|
1562
|
+
c || (l = !0, a = 0);
|
|
1563
|
+
const O = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
|
|
1564
|
+
let y = e.geometry.boundingBox;
|
|
1528
1565
|
if (e.type === "SkinnedMesh") {
|
|
1529
|
-
const
|
|
1530
|
-
if (!
|
|
1531
|
-
|
|
1566
|
+
const x = e;
|
|
1567
|
+
if (!x.boundingBox)
|
|
1568
|
+
x.computeBoundingBox();
|
|
1532
1569
|
else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
|
|
1533
|
-
if (!
|
|
1534
|
-
const
|
|
1535
|
-
|
|
1570
|
+
if (!x[I.$skinnedMeshBoundsOffset]) {
|
|
1571
|
+
const L = I.skinnedMeshBoundsFrameOffsetCounter++;
|
|
1572
|
+
x[I.$skinnedMeshBoundsOffset] = L;
|
|
1536
1573
|
}
|
|
1537
|
-
const
|
|
1538
|
-
if ((s.frames +
|
|
1539
|
-
const
|
|
1540
|
-
|
|
1574
|
+
const v = x[I.$skinnedMeshBoundsOffset];
|
|
1575
|
+
if ((s.frames + v) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
|
|
1576
|
+
const L = ne(x), V = x.geometry;
|
|
1577
|
+
L && (x.geometry = L), x.computeBoundingBox(), x.geometry = V;
|
|
1541
1578
|
}
|
|
1542
1579
|
}
|
|
1543
|
-
|
|
1580
|
+
y = x.boundingBox;
|
|
1544
1581
|
}
|
|
1545
|
-
if (
|
|
1582
|
+
if (y) {
|
|
1546
1583
|
if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
|
|
1547
1584
|
this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
|
|
1548
|
-
const
|
|
1549
|
-
if (this._sphere.containsPoint(
|
|
1585
|
+
const L = t.getWorldPosition(this._tempWorldPosition);
|
|
1586
|
+
if (this._sphere.containsPoint(L)) {
|
|
1550
1587
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1551
1588
|
return;
|
|
1552
1589
|
}
|
|
1553
1590
|
}
|
|
1554
|
-
const
|
|
1591
|
+
const x = bt({
|
|
1555
1592
|
geometry: e.geometry,
|
|
1556
1593
|
matrixWorld: e.matrixWorld,
|
|
1557
1594
|
camera: t,
|
|
1558
1595
|
projectionScreenMatrix: this.projectionScreenMatrix,
|
|
1559
1596
|
desiredDensity: r,
|
|
1560
|
-
canvasHeight:
|
|
1597
|
+
canvasHeight: O,
|
|
1561
1598
|
currentLevel: s.lastLodLevel_Mesh,
|
|
1562
|
-
boundingBox:
|
|
1599
|
+
boundingBox: y,
|
|
1563
1600
|
xrEnabled: this.renderer.xr.enabled,
|
|
1564
|
-
debugDrawLine: A ?
|
|
1601
|
+
debugDrawLine: A ? I.debugDrawLine : void 0,
|
|
1565
1602
|
warnMissingPrimitiveDensities: !0
|
|
1566
1603
|
});
|
|
1567
|
-
if (s.lastCentrality =
|
|
1604
|
+
if (s.lastCentrality = x.centrality, s.lastScreenCoverage = x.screenCoverage, s.lastScreenspaceVolume.copy(x.screenspaceVolume), x.screenCoverage === 1 / 0) {
|
|
1568
1605
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1569
1606
|
return;
|
|
1570
1607
|
}
|
|
1571
|
-
|
|
1608
|
+
x.level >= 0 && x.level < a && (a = x.level, l = !0);
|
|
1572
1609
|
}
|
|
1573
|
-
if (
|
|
1574
|
-
const
|
|
1575
|
-
|
|
1610
|
+
if (l ? n.mesh_lod = a : n.mesh_lod = s.lastLodLevel_Mesh, A && n.mesh_lod != s.lastLodLevel_Mesh) {
|
|
1611
|
+
const v = u?.[n.mesh_lod];
|
|
1612
|
+
v && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${v.densities?.[d].toFixed(0)}) | ${e.name}`);
|
|
1576
1613
|
}
|
|
1577
|
-
if (
|
|
1578
|
-
const
|
|
1614
|
+
if (g) {
|
|
1615
|
+
const x = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
|
|
1579
1616
|
if (s.lastLodLevel_Texture < 0) {
|
|
1580
|
-
if (n.texture_lod =
|
|
1581
|
-
const
|
|
1582
|
-
A && console.log(`First Texture LOD ${n.texture_lod} (${
|
|
1617
|
+
if (n.texture_lod = f.max_count - 1, A) {
|
|
1618
|
+
const v = f.lods[f.max_count - 1];
|
|
1619
|
+
A && console.log(`First Texture LOD ${n.texture_lod} (${v.max_height}px) - ${e.name}`);
|
|
1583
1620
|
}
|
|
1584
1621
|
} else {
|
|
1585
|
-
const
|
|
1586
|
-
let
|
|
1587
|
-
this.context?.engine === "model-viewer" && (
|
|
1588
|
-
const
|
|
1589
|
-
let
|
|
1590
|
-
for (let
|
|
1591
|
-
const
|
|
1592
|
-
if (!(
|
|
1593
|
-
if (
|
|
1594
|
-
const
|
|
1595
|
-
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${
|
|
1596
|
-
Screensize: ${
|
|
1622
|
+
const v = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
|
|
1623
|
+
let L = s.lastScreenCoverage * 4;
|
|
1624
|
+
this.context?.engine === "model-viewer" && (L *= 1.5);
|
|
1625
|
+
const w = O / window.devicePixelRatio * L;
|
|
1626
|
+
let S = !1;
|
|
1627
|
+
for (let _ = f.lods.length - 1; _ >= 0; _--) {
|
|
1628
|
+
const R = f.lods[_];
|
|
1629
|
+
if (!(x && R.max_height >= 2048) && !(_e() && R.max_height > 4096) && (R.max_height > w || !S && _ === 0)) {
|
|
1630
|
+
if (S = !0, n.texture_lod = _, A && n.texture_lod < s.lastLodLevel_Texture) {
|
|
1631
|
+
const C = R.max_height;
|
|
1632
|
+
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${C}px
|
|
1633
|
+
Screensize: ${w.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${v.toFixed(1)}
|
|
1597
1634
|
${e.name}`);
|
|
1598
1635
|
}
|
|
1599
1636
|
break;
|
|
@@ -1604,74 +1641,74 @@ ${e.name}`);
|
|
|
1604
1641
|
n.texture_lod = 0;
|
|
1605
1642
|
}
|
|
1606
1643
|
}
|
|
1607
|
-
class
|
|
1644
|
+
class Tt {
|
|
1608
1645
|
frames = 0;
|
|
1609
1646
|
lastLodLevel_Mesh = -1;
|
|
1610
1647
|
lastLodLevel_Texture = -1;
|
|
1611
1648
|
lastScreenCoverage = 0;
|
|
1612
|
-
lastScreenspaceVolume = new
|
|
1649
|
+
lastScreenspaceVolume = new P();
|
|
1613
1650
|
lastCentrality = 0;
|
|
1614
1651
|
}
|
|
1615
|
-
function
|
|
1652
|
+
function qe(i, t) {
|
|
1616
1653
|
if (!(t < 0)) {
|
|
1617
1654
|
if (Array.isArray(i)) {
|
|
1618
1655
|
for (const e of i)
|
|
1619
|
-
|
|
1656
|
+
qe(e, t);
|
|
1620
1657
|
return;
|
|
1621
1658
|
}
|
|
1622
|
-
"color" in i && i.color instanceof
|
|
1659
|
+
"color" in i && i.color instanceof ke && (i.color.copy(Ct(t, _t)), i.needsUpdate = !0);
|
|
1623
1660
|
}
|
|
1624
1661
|
}
|
|
1625
1662
|
function Ct(i, t) {
|
|
1626
1663
|
const e = Math.max(0, Math.min(Me.length - 1, Math.floor(i)));
|
|
1627
1664
|
return t.setHex(Me[e]);
|
|
1628
1665
|
}
|
|
1629
|
-
const
|
|
1630
|
-
let
|
|
1666
|
+
const Se = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), ae = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
|
|
1667
|
+
let me = null;
|
|
1631
1668
|
function We() {
|
|
1632
|
-
const i =
|
|
1669
|
+
const i = kt();
|
|
1633
1670
|
i && (i.mapURLs(function(t) {
|
|
1634
|
-
return
|
|
1635
|
-
}),
|
|
1671
|
+
return be(), t;
|
|
1672
|
+
}), be(), me?.disconnect(), me = new MutationObserver((t) => {
|
|
1636
1673
|
t.forEach((e) => {
|
|
1637
1674
|
e.addedNodes.forEach((s) => {
|
|
1638
1675
|
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Ue(s);
|
|
1639
1676
|
});
|
|
1640
1677
|
});
|
|
1641
|
-
}),
|
|
1678
|
+
}), me.observe(document, { childList: !0, subtree: !0 }));
|
|
1642
1679
|
}
|
|
1643
|
-
function
|
|
1680
|
+
function kt() {
|
|
1644
1681
|
if (typeof customElements > "u") return null;
|
|
1645
1682
|
const i = customElements.get("model-viewer");
|
|
1646
1683
|
return i || (customElements.whenDefined("model-viewer").then(() => {
|
|
1647
1684
|
console.debug("[gltf-progressive] model-viewer defined"), We();
|
|
1648
1685
|
}), null);
|
|
1649
1686
|
}
|
|
1650
|
-
function
|
|
1687
|
+
function be() {
|
|
1651
1688
|
if (typeof document > "u") return;
|
|
1652
1689
|
document.querySelectorAll("model-viewer").forEach((t) => {
|
|
1653
1690
|
Ue(t);
|
|
1654
1691
|
});
|
|
1655
1692
|
}
|
|
1656
1693
|
const Te = /* @__PURE__ */ new WeakSet();
|
|
1657
|
-
let
|
|
1694
|
+
let Pt = 0;
|
|
1658
1695
|
function Ue(i) {
|
|
1659
1696
|
if (!i || Te.has(i))
|
|
1660
1697
|
return null;
|
|
1661
|
-
Te.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++
|
|
1698
|
+
Te.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++Pt + `
|
|
1662
1699
|
`, i.getAttribute("src"));
|
|
1663
1700
|
let t = null, e = null, s = null;
|
|
1664
1701
|
for (let r = i; r != null; r = Object.getPrototypeOf(r)) {
|
|
1665
|
-
const n = Object.getOwnPropertySymbols(r), o = n.find((
|
|
1666
|
-
!t && o != null && (t = i[o].threeRenderer), !e &&
|
|
1702
|
+
const n = Object.getOwnPropertySymbols(r), o = n.find((u) => u.toString() == "Symbol(renderer)"), a = n.find((u) => u.toString() == "Symbol(scene)"), l = n.find((u) => u.toString() == "Symbol(needsRender)");
|
|
1703
|
+
!t && o != null && (t = i[o].threeRenderer), !e && a != null && (e = i[a]), !s && l != null && (s = i[l]);
|
|
1667
1704
|
}
|
|
1668
1705
|
if (t && e) {
|
|
1669
1706
|
let r = function() {
|
|
1670
1707
|
if (s) {
|
|
1671
1708
|
let o = 0;
|
|
1672
|
-
const
|
|
1709
|
+
const a = setInterval(() => {
|
|
1673
1710
|
if (o++ > 5) {
|
|
1674
|
-
clearInterval(
|
|
1711
|
+
clearInterval(a);
|
|
1675
1712
|
return;
|
|
1676
1713
|
}
|
|
1677
1714
|
s?.call(i);
|
|
@@ -1679,8 +1716,8 @@ function Ue(i) {
|
|
|
1679
1716
|
}
|
|
1680
1717
|
};
|
|
1681
1718
|
console.debug("[gltf-progressive] setup model-viewer");
|
|
1682
|
-
const n =
|
|
1683
|
-
return
|
|
1719
|
+
const n = I.get(t, { engine: "model-viewer" });
|
|
1720
|
+
return I.addPlugin(new Rt()), n.enable(), n.addEventListener("changed", () => {
|
|
1684
1721
|
s?.call(i);
|
|
1685
1722
|
}), i.addEventListener("model-visibility", (o) => {
|
|
1686
1723
|
o.detail.visible && s?.call(i);
|
|
@@ -1692,7 +1729,7 @@ function Ue(i) {
|
|
|
1692
1729
|
}
|
|
1693
1730
|
return null;
|
|
1694
1731
|
}
|
|
1695
|
-
class
|
|
1732
|
+
class Rt {
|
|
1696
1733
|
_didWarnAboutMissingUrl = !1;
|
|
1697
1734
|
onBeforeUpdateLOD(t, e, s, r) {
|
|
1698
1735
|
this.tryParseMeshLOD(e, r), this.tryParseTextureLOD(e, r);
|
|
@@ -1710,50 +1747,50 @@ class At {
|
|
|
1710
1747
|
return t.element;
|
|
1711
1748
|
}
|
|
1712
1749
|
tryParseTextureLOD(t, e) {
|
|
1713
|
-
if (e[
|
|
1714
|
-
e[
|
|
1750
|
+
if (e[ae] == !0) return;
|
|
1751
|
+
e[ae] = !0;
|
|
1715
1752
|
const s = this.tryGetCurrentGLTF(t), r = this.tryGetCurrentModelViewer(t), n = this.getUrl(r);
|
|
1716
1753
|
if (n && s && e.material) {
|
|
1717
|
-
let o = function(
|
|
1718
|
-
if (
|
|
1719
|
-
|
|
1720
|
-
const
|
|
1721
|
-
for (let
|
|
1722
|
-
const
|
|
1723
|
-
if (
|
|
1724
|
-
const
|
|
1725
|
-
if (
|
|
1726
|
-
const
|
|
1727
|
-
if (!
|
|
1728
|
-
console.warn("Texture data not found for texture index " +
|
|
1754
|
+
let o = function(l) {
|
|
1755
|
+
if (l[ae] == !0) return;
|
|
1756
|
+
l[ae] = !0, l.userData && (l.userData.LOD = -1);
|
|
1757
|
+
const u = Object.keys(l);
|
|
1758
|
+
for (let d = 0; d < u.length; d++) {
|
|
1759
|
+
const c = u[d], f = l[c];
|
|
1760
|
+
if (f?.isTexture === !0) {
|
|
1761
|
+
const g = f.userData?.associations?.textures;
|
|
1762
|
+
if (g == null) continue;
|
|
1763
|
+
const O = s.parser.json.textures[g];
|
|
1764
|
+
if (!O) {
|
|
1765
|
+
console.warn("Texture data not found for texture index " + g);
|
|
1729
1766
|
continue;
|
|
1730
1767
|
}
|
|
1731
|
-
if (
|
|
1732
|
-
const
|
|
1733
|
-
|
|
1768
|
+
if (O?.extensions?.[U]) {
|
|
1769
|
+
const y = O.extensions[U];
|
|
1770
|
+
y && n && p.registerTexture(n, f, y.lods.length, g, y);
|
|
1734
1771
|
}
|
|
1735
1772
|
}
|
|
1736
1773
|
}
|
|
1737
1774
|
};
|
|
1738
|
-
const
|
|
1739
|
-
if (Array.isArray(
|
|
1740
|
-
else o(
|
|
1775
|
+
const a = e.material;
|
|
1776
|
+
if (Array.isArray(a)) for (const l of a) o(l);
|
|
1777
|
+
else o(a);
|
|
1741
1778
|
}
|
|
1742
1779
|
}
|
|
1743
1780
|
tryParseMeshLOD(t, e) {
|
|
1744
|
-
if (e[
|
|
1745
|
-
e[
|
|
1781
|
+
if (e[Se] == !0) return;
|
|
1782
|
+
e[Se] = !0;
|
|
1746
1783
|
const s = this.tryGetCurrentModelViewer(t), r = this.getUrl(s);
|
|
1747
1784
|
if (!r)
|
|
1748
1785
|
return;
|
|
1749
|
-
const n = e.userData?.gltfExtensions?.[
|
|
1786
|
+
const n = e.userData?.gltfExtensions?.[U];
|
|
1750
1787
|
if (n && r) {
|
|
1751
1788
|
const o = e.uuid;
|
|
1752
|
-
|
|
1789
|
+
p.registerMesh(r, o, e, 0, n.lods.length, n);
|
|
1753
1790
|
}
|
|
1754
1791
|
}
|
|
1755
1792
|
}
|
|
1756
|
-
function
|
|
1793
|
+
function At(...i) {
|
|
1757
1794
|
let t, e, s, r;
|
|
1758
1795
|
switch (i.length) {
|
|
1759
1796
|
case 2:
|
|
@@ -1768,20 +1805,20 @@ function Rt(...i) {
|
|
|
1768
1805
|
default:
|
|
1769
1806
|
throw new Error("Invalid arguments");
|
|
1770
1807
|
}
|
|
1771
|
-
|
|
1808
|
+
ve(e), Ae(s), $e(s, {
|
|
1772
1809
|
progressive: !0,
|
|
1773
1810
|
...r?.hints
|
|
1774
|
-
}), s.register((o) => new
|
|
1775
|
-
const n =
|
|
1811
|
+
}), s.register((o) => new p(o));
|
|
1812
|
+
const n = I.get(e);
|
|
1776
1813
|
return r?.enableLODsManager !== !1 && n.enable(), n;
|
|
1777
1814
|
}
|
|
1778
1815
|
We();
|
|
1779
1816
|
if (!ct) {
|
|
1780
1817
|
const i = {
|
|
1781
1818
|
gltfProgressive: {
|
|
1782
|
-
useNeedleProgressive:
|
|
1783
|
-
LODsManager:
|
|
1784
|
-
configureLoader:
|
|
1819
|
+
useNeedleProgressive: At,
|
|
1820
|
+
LODsManager: I,
|
|
1821
|
+
configureLoader: $e,
|
|
1785
1822
|
getRaycastMesh: ne,
|
|
1786
1823
|
useRaycastMeshes: ft
|
|
1787
1824
|
}
|
|
@@ -1793,14 +1830,14 @@ if (!ct) {
|
|
|
1793
1830
|
globalThis.Needle[t] = i[t];
|
|
1794
1831
|
}
|
|
1795
1832
|
export {
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1833
|
+
U as EXTENSION_NAME,
|
|
1834
|
+
I as LODsManager,
|
|
1835
|
+
p as NEEDLE_progressive,
|
|
1799
1836
|
Je as VERSION,
|
|
1800
1837
|
Ae as addDracoAndKTX2Loaders,
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1838
|
+
bt as calculateMeshLODLevel,
|
|
1839
|
+
$e as configureLoader,
|
|
1840
|
+
ve as createLoaders,
|
|
1804
1841
|
Ct as getLODColor,
|
|
1805
1842
|
ne as getRaycastMesh,
|
|
1806
1843
|
Me as lodDebugColors,
|
|
@@ -1808,6 +1845,6 @@ export {
|
|
|
1808
1845
|
dt as registerRaycastMesh,
|
|
1809
1846
|
st as setDracoDecoderLocation,
|
|
1810
1847
|
rt as setKTX2TranscoderLocation,
|
|
1811
|
-
|
|
1848
|
+
At as useNeedleProgressive,
|
|
1812
1849
|
ft as useRaycastMeshes
|
|
1813
1850
|
};
|