@needle-tools/gltf-progressive 3.6.0-alpha.1 → 3.6.0-alpha.2
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 +5 -0
- package/gltf-progressive.js +493 -464
- package/gltf-progressive.min.js +9 -9
- package/gltf-progressive.umd.cjs +9 -9
- package/lib/extension.d.ts +4 -1
- package/lib/extension.js +10 -5
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/lods.manager.d.ts +25 -12
- package/lib/lods.manager.js +149 -134
- package/lib/version.js +1 -1
- package/package.json +1 -1
package/gltf-progressive.js
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
import { BufferGeometry as
|
|
2
|
-
import { GLTFLoader as
|
|
3
|
-
import { MeshoptDecoder as
|
|
4
|
-
import { DRACOLoader as
|
|
5
|
-
import { KTX2Loader as
|
|
6
|
-
const
|
|
7
|
-
globalThis.GLTF_PROGRESSIVE_VERSION =
|
|
1
|
+
import { BufferGeometry as j, Mesh as K, Box3 as le, Vector3 as k, Sphere as Se, CompressedTexture as ze, Texture as G, Matrix3 as Ee, InterleavedBuffer as Ne, InterleavedBufferAttribute as Ve, BufferAttribute as Xe, TextureLoader as je, Color as Ce, Matrix4 as Pe, Clock as Ke } from "three";
|
|
2
|
+
import { GLTFLoader as we } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
3
|
+
import { MeshoptDecoder as Ye } from "three/examples/jsm/libs/meshopt_decoder.module.js";
|
|
4
|
+
import { DRACOLoader as He } from "three/examples/jsm/loaders/DRACOLoader.js";
|
|
5
|
+
import { KTX2Loader as Qe } from "three/examples/jsm/loaders/KTX2Loader.js";
|
|
6
|
+
const Je = "";
|
|
7
|
+
globalThis.GLTF_PROGRESSIVE_VERSION = Je;
|
|
8
8
|
console.debug("[gltf-progressive] version -");
|
|
9
|
-
let I = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/",
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
fetch(
|
|
9
|
+
let I = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", Y = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
|
|
10
|
+
const Ze = I, et = Y, ke = new URL(I + "draco_decoder.js");
|
|
11
|
+
ke.searchParams.append("range", "true");
|
|
12
|
+
fetch(ke, {
|
|
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 ${I} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), I ===
|
|
18
|
+
console.debug(`Failed to fetch remote Draco decoder from ${I} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), I === Ze && st("./include/draco/"), Y === et && rt("./include/ktx2/");
|
|
19
19
|
}).finally(() => {
|
|
20
|
-
|
|
20
|
+
Re();
|
|
21
21
|
});
|
|
22
|
-
const
|
|
22
|
+
const tt = () => ({
|
|
23
23
|
dracoDecoderPath: I,
|
|
24
|
-
ktx2TranscoderPath:
|
|
24
|
+
ktx2TranscoderPath: Y
|
|
25
25
|
});
|
|
26
|
-
function
|
|
27
|
-
I = i,
|
|
26
|
+
function st(i) {
|
|
27
|
+
I = i, P && P[me] != I ? (console.debug("Updating Draco decoder path to " + i), P[me] = I, P.setDecoderPath(I), P.preload()) : console.debug("Setting Draco decoder path to " + i);
|
|
28
28
|
}
|
|
29
|
-
function
|
|
30
|
-
|
|
29
|
+
function rt(i) {
|
|
30
|
+
Y = i, $ && $.transcoderPath != Y ? (console.debug("Updating KTX2 transcoder path to " + i), $.setTranscoderPath(Y), $.init()) : console.debug("Setting KTX2 transcoder path to " + i);
|
|
31
31
|
}
|
|
32
|
-
function
|
|
33
|
-
return
|
|
32
|
+
function Le(i) {
|
|
33
|
+
return Re(), i ? $.detectSupport(i) : i !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: P, ktx2Loader: $, meshoptDecoder: ae };
|
|
34
34
|
}
|
|
35
|
-
function
|
|
36
|
-
i.dracoLoader || i.setDRACOLoader(
|
|
35
|
+
function Ae(i) {
|
|
36
|
+
i.dracoLoader || i.setDRACOLoader(P), i.ktx2Loader || i.setKTX2Loader($), i.meshoptDecoder || i.setMeshoptDecoder(ae);
|
|
37
37
|
}
|
|
38
|
-
const
|
|
39
|
-
let
|
|
40
|
-
function
|
|
41
|
-
|
|
38
|
+
const me = /* @__PURE__ */ Symbol("dracoDecoderPath");
|
|
39
|
+
let P, ae, $;
|
|
40
|
+
function Re() {
|
|
41
|
+
P || (P = new He(), P[me] = I, P.setDecoderPath(I), P.setDecoderConfig({ type: "js" }), P.preload()), $ || ($ = new Qe(), $.setTranscoderPath(Y), $.init()), ae || (ae = Ye);
|
|
42
42
|
}
|
|
43
|
-
const
|
|
44
|
-
function
|
|
45
|
-
let e =
|
|
46
|
-
e ? e = Object.assign(e, t) : e = t,
|
|
43
|
+
const ye = /* @__PURE__ */ new WeakMap();
|
|
44
|
+
function Ie(i, t) {
|
|
45
|
+
let e = ye.get(i);
|
|
46
|
+
e ? e = Object.assign(e, t) : e = t, ye.set(i, e);
|
|
47
47
|
}
|
|
48
|
-
const
|
|
49
|
-
function
|
|
50
|
-
const t =
|
|
48
|
+
const nt = we.prototype.load;
|
|
49
|
+
function ot(...i) {
|
|
50
|
+
const t = ye.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")) {
|
|
54
54
|
const n = t?.progressive !== void 0 ? t.progressive : !0, o = t?.usecase ? t.usecase : "default";
|
|
55
55
|
n ? this.requestHeader.Accept = `*/*;progressive=allowed;usecase=${o}` : this.requestHeader.Accept = `*/*;usecase=${o}`, e = s.toString();
|
|
56
56
|
}
|
|
57
|
-
return i[0] = e,
|
|
57
|
+
return i[0] = e, nt?.call(this, ...i);
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
we.prototype.load = ot;
|
|
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 it(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,16 +74,16 @@ function nt(i, t) {
|
|
|
74
74
|
}
|
|
75
75
|
return t;
|
|
76
76
|
}
|
|
77
|
-
function
|
|
78
|
-
return
|
|
77
|
+
function ve() {
|
|
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
|
-
let
|
|
81
|
-
function
|
|
80
|
+
let Z;
|
|
81
|
+
function $e() {
|
|
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;
|
|
85
85
|
}
|
|
86
|
-
class
|
|
86
|
+
class at {
|
|
87
87
|
constructor(t, e = {}) {
|
|
88
88
|
this.maxConcurrent = t, this.debug = e.debug ?? !1, typeof window < "u" && window.requestAnimationFrame(this.tick);
|
|
89
89
|
}
|
|
@@ -117,11 +117,11 @@ class ot {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
function
|
|
121
|
-
const t = i.image?.width ?? 0, e = i.image?.height ?? 0, s = i.image?.depth ?? 1, r = Math.floor(Math.log2(Math.max(t, e, s))) + 1, n =
|
|
120
|
+
function lt(i) {
|
|
121
|
+
const t = i.image?.width ?? 0, e = i.image?.height ?? 0, s = i.image?.depth ?? 1, r = Math.floor(Math.log2(Math.max(t, e, s))) + 1, n = ut(i);
|
|
122
122
|
return t * e * s * n * (1 - Math.pow(0.25, r)) / (1 - 0.25);
|
|
123
123
|
}
|
|
124
|
-
function
|
|
124
|
+
function ut(i) {
|
|
125
125
|
let t = 4;
|
|
126
126
|
const e = i.format;
|
|
127
127
|
e === 1024 || e === 1025 ? t = 1 : e === 1026 || e === 1027 ? t = 2 : e === 1022 || e === 1029 ? t = 3 : (e === 1023 || e === 1033) && (t = 4);
|
|
@@ -129,69 +129,69 @@ function at(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
|
|
133
|
-
function
|
|
134
|
-
return i?.[
|
|
132
|
+
const ct = typeof window > "u" && typeof document > "u", xe = /* @__PURE__ */ Symbol("needle:raycast-mesh");
|
|
133
|
+
function ne(i) {
|
|
134
|
+
return i?.[xe] instanceof j ? i[xe] : null;
|
|
135
135
|
}
|
|
136
|
-
function
|
|
137
|
-
if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !
|
|
138
|
-
const s =
|
|
139
|
-
s.userData = { isRaycastMesh: !0 }, i[
|
|
136
|
+
function dt(i, t) {
|
|
137
|
+
if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !ne(i)) {
|
|
138
|
+
const s = ht(t);
|
|
139
|
+
s.userData = { isRaycastMesh: !0 }, i[xe] = s;
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
-
function
|
|
142
|
+
function ft(i = !0) {
|
|
143
143
|
if (i) {
|
|
144
|
-
if (
|
|
145
|
-
const t =
|
|
146
|
-
|
|
147
|
-
const r = this, n =
|
|
144
|
+
if (ee) return;
|
|
145
|
+
const t = ee = K.prototype.raycast;
|
|
146
|
+
K.prototype.raycast = function(e, s) {
|
|
147
|
+
const r = this, n = ne(r);
|
|
148
148
|
let o;
|
|
149
149
|
n && r.isMesh && (o = r.geometry, r.geometry = n), t.call(this, e, s), o && (r.geometry = o);
|
|
150
150
|
};
|
|
151
151
|
} else {
|
|
152
|
-
if (!
|
|
153
|
-
|
|
152
|
+
if (!ee) return;
|
|
153
|
+
K.prototype.raycast = ee, ee = null;
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
|
-
let
|
|
157
|
-
function
|
|
158
|
-
const t = new
|
|
156
|
+
let ee = null;
|
|
157
|
+
function ht(i) {
|
|
158
|
+
const t = new j();
|
|
159
159
|
for (const e in i.attributes)
|
|
160
160
|
t.setAttribute(e, i.getAttribute(e));
|
|
161
161
|
return t.setIndex(i.getIndex()), t;
|
|
162
162
|
}
|
|
163
|
-
const
|
|
164
|
-
let
|
|
165
|
-
if (
|
|
163
|
+
const E = new Array(), f = N("debugprogressive");
|
|
164
|
+
let re, X = -1;
|
|
165
|
+
if (f) {
|
|
166
166
|
let i = function() {
|
|
167
|
-
|
|
167
|
+
X += 1, X >= t && (X = -1), console.log(`Toggle LOD level [${X}]`);
|
|
168
168
|
};
|
|
169
169
|
const t = 6;
|
|
170
170
|
window.addEventListener("keyup", (e) => {
|
|
171
|
-
e.key === "p" && i(), e.key === "w" && (
|
|
171
|
+
e.key === "p" && i(), e.key === "w" && (re = !re, console.log(`Toggle wireframe [${re}]`));
|
|
172
172
|
const s = parseInt(e.key);
|
|
173
|
-
!isNaN(s) && s >= 0 && (
|
|
173
|
+
!isNaN(s) && s >= 0 && (X = s, console.log(`Set LOD level to [${X}]`));
|
|
174
174
|
});
|
|
175
175
|
}
|
|
176
|
-
function
|
|
177
|
-
if (
|
|
176
|
+
function Be(i) {
|
|
177
|
+
if (f && re !== void 0)
|
|
178
178
|
if (Array.isArray(i))
|
|
179
179
|
for (const t of i)
|
|
180
|
-
|
|
181
|
-
else i && "wireframe" in i && (i.wireframe =
|
|
180
|
+
Be(t);
|
|
181
|
+
else i && "wireframe" in i && (i.wireframe = re === !0);
|
|
182
182
|
}
|
|
183
|
-
const
|
|
184
|
-
let
|
|
185
|
-
const
|
|
186
|
-
function
|
|
187
|
-
if (
|
|
188
|
-
const s =
|
|
189
|
-
|
|
183
|
+
const te = new Array();
|
|
184
|
+
let gt = 0;
|
|
185
|
+
const pt = ve() ? 2 : 10;
|
|
186
|
+
function mt(i) {
|
|
187
|
+
if (te.length < pt) {
|
|
188
|
+
const s = te.length;
|
|
189
|
+
f && console.warn(`[Worker] Creating new worker #${s}`);
|
|
190
190
|
const r = _e.createWorker(i || {});
|
|
191
|
-
return
|
|
191
|
+
return te.push(r), r;
|
|
192
192
|
}
|
|
193
|
-
const t =
|
|
194
|
-
return
|
|
193
|
+
const t = gt++ % te.length;
|
|
194
|
+
return te[t];
|
|
195
195
|
}
|
|
196
196
|
class _e {
|
|
197
197
|
constructor(t, e) {
|
|
@@ -201,7 +201,7 @@ class _e {
|
|
|
201
201
|
case "loaded-gltf":
|
|
202
202
|
for (const n of this._running)
|
|
203
203
|
if (n.url === r.result.url) {
|
|
204
|
-
|
|
204
|
+
yt(r.result), n.resolve(r.result);
|
|
205
205
|
const o = n.url;
|
|
206
206
|
o.startsWith("blob:") && URL.revokeObjectURL(o);
|
|
207
207
|
}
|
|
@@ -225,13 +225,13 @@ class _e {
|
|
|
225
225
|
_running = [];
|
|
226
226
|
_webglRenderer = null;
|
|
227
227
|
async load(t, e) {
|
|
228
|
-
const s =
|
|
228
|
+
const s = tt();
|
|
229
229
|
let r = e?.renderer;
|
|
230
230
|
r || (this._webglRenderer ??= (async () => {
|
|
231
231
|
const { WebGLRenderer: l } = await import("three");
|
|
232
232
|
return new l();
|
|
233
233
|
})(), r = await this._webglRenderer);
|
|
234
|
-
const u =
|
|
234
|
+
const u = Le(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
236
|
const a = {
|
|
237
237
|
type: "load",
|
|
@@ -249,32 +249,32 @@ class _e {
|
|
|
249
249
|
}
|
|
250
250
|
_debug = !1;
|
|
251
251
|
}
|
|
252
|
-
function
|
|
252
|
+
function yt(i) {
|
|
253
253
|
for (const t of i.geometries) {
|
|
254
|
-
const e = t.geometry, s = new
|
|
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(ce(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 = ce(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((u) =>
|
|
265
|
+
const o = e.morphAttributes[r].map((u) => ce(u));
|
|
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 le(), s.boundingBox.min = new k(
|
|
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 k(
|
|
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 Se(
|
|
277
|
+
new k(
|
|
278
278
|
e.boundingSphere?.center.x,
|
|
279
279
|
e.boundingSphere?.center.y,
|
|
280
280
|
e.boundingSphere?.center.z
|
|
@@ -290,7 +290,7 @@ function pt(i) {
|
|
|
290
290
|
let s = null;
|
|
291
291
|
if (e.isCompressedTexture) {
|
|
292
292
|
const r = e.mipmaps, n = e.image?.width || e.source?.data?.width || -1, o = e.image?.height || e.source?.data?.height || -1;
|
|
293
|
-
s = new
|
|
293
|
+
s = new ze(
|
|
294
294
|
r,
|
|
295
295
|
n,
|
|
296
296
|
o,
|
|
@@ -305,7 +305,7 @@ function pt(i) {
|
|
|
305
305
|
e.colorSpace
|
|
306
306
|
);
|
|
307
307
|
} else
|
|
308
|
-
s = new
|
|
308
|
+
s = new G(
|
|
309
309
|
e.image,
|
|
310
310
|
e.mapping,
|
|
311
311
|
e.wrapS,
|
|
@@ -316,7 +316,7 @@ function pt(i) {
|
|
|
316
316
|
e.type,
|
|
317
317
|
e.anisotropy,
|
|
318
318
|
e.colorSpace
|
|
319
|
-
), s.mipmaps = e.mipmaps, s.channel = e.channel, s.source.data = e.source.data, s.flipY = e.flipY, s.premultiplyAlpha = e.premultiplyAlpha, s.unpackAlignment = e.unpackAlignment, s.matrix = new
|
|
319
|
+
), s.mipmaps = e.mipmaps, s.channel = e.channel, s.source.data = e.source.data, s.flipY = e.flipY, s.premultiplyAlpha = e.premultiplyAlpha, s.unpackAlignment = e.unpackAlignment, s.matrix = new Ee(...e.matrix.elements);
|
|
320
320
|
if (!s) {
|
|
321
321
|
console.error("[Worker] Failed to create new texture from received data. Texture is not a CompressedTexture or Texture.");
|
|
322
322
|
continue;
|
|
@@ -325,21 +325,21 @@ function pt(i) {
|
|
|
325
325
|
}
|
|
326
326
|
return i;
|
|
327
327
|
}
|
|
328
|
-
function
|
|
328
|
+
function ce(i) {
|
|
329
329
|
let t = i;
|
|
330
330
|
if ("isInterleavedBufferAttribute" in i && i.isInterleavedBufferAttribute) {
|
|
331
|
-
const e = i.data, s = e.array, r = new
|
|
332
|
-
t = new
|
|
333
|
-
} else "isBufferAttribute" in i && i.isBufferAttribute && (t = new
|
|
331
|
+
const e = i.data, s = e.array, r = new Ne(s, e.stride);
|
|
332
|
+
t = new Ve(r, i.itemSize, s.byteOffset, i.normalized), t.offset = i.offset;
|
|
333
|
+
} else "isBufferAttribute" in i && i.isBufferAttribute && (t = new Xe(i.array, i.itemSize, i.normalized), t.usage = i.usage, t.gpuType = i.gpuType, t.updateRanges = i.updateRanges);
|
|
334
334
|
return t;
|
|
335
335
|
}
|
|
336
|
-
const
|
|
336
|
+
const xt = N("gltf-progressive-worker");
|
|
337
337
|
N("gltf-progressive-reduce-mipmaps");
|
|
338
|
-
const
|
|
339
|
-
class
|
|
338
|
+
const se = N("gltf-progressive-gc"), de = /* @__PURE__ */ Symbol("needle-progressive-texture"), F = "NEEDLE_progressive";
|
|
339
|
+
class h {
|
|
340
340
|
/** The name of the extension */
|
|
341
341
|
get name() {
|
|
342
|
-
return
|
|
342
|
+
return F;
|
|
343
343
|
}
|
|
344
344
|
// #region PUBLIC API
|
|
345
345
|
/**
|
|
@@ -385,7 +385,7 @@ class p {
|
|
|
385
385
|
this.getMaterialMinMaxLODsCount(u, e);
|
|
386
386
|
return t[r] = e, e;
|
|
387
387
|
}
|
|
388
|
-
if (
|
|
388
|
+
if (f === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
|
|
389
389
|
const u = t;
|
|
390
390
|
for (const a of Object.keys(u.uniforms)) {
|
|
391
391
|
const l = u.uniforms[a].value;
|
|
@@ -397,7 +397,7 @@ class p {
|
|
|
397
397
|
a?.isTexture === !0 && o(a, e);
|
|
398
398
|
}
|
|
399
399
|
else
|
|
400
|
-
|
|
400
|
+
f && console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);
|
|
401
401
|
return t[r] = e, e;
|
|
402
402
|
function o(u, a) {
|
|
403
403
|
const l = s.getAssignedLODInformation(u);
|
|
@@ -405,9 +405,9 @@ class p {
|
|
|
405
405
|
const c = s.lodInfos.get(l.key);
|
|
406
406
|
if (c && c.lods) {
|
|
407
407
|
a.min_count = Math.min(a.min_count, c.lods.length), a.max_count = Math.max(a.max_count, c.lods.length);
|
|
408
|
-
for (let
|
|
409
|
-
const
|
|
410
|
-
|
|
408
|
+
for (let d = 0; d < c.lods.length; d++) {
|
|
409
|
+
const g = c.lods[d];
|
|
410
|
+
g.width && (a.lods[d] = a.lods[d] || { min_height: 1 / 0, max_height: 0 }, a.lods[d].min_height = Math.min(a.lods[d].min_height, g.height), a.lods[d].max_height = Math.max(a.lods[d].max_height, g.height));
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
413
|
}
|
|
@@ -459,22 +459,22 @@ class p {
|
|
|
459
459
|
* });
|
|
460
460
|
* ```
|
|
461
461
|
*/
|
|
462
|
-
static assignMeshLOD(t, e) {
|
|
462
|
+
static assignMeshLOD(t, e, s) {
|
|
463
463
|
if (!t) return Promise.resolve(null);
|
|
464
|
-
if (t instanceof
|
|
465
|
-
const
|
|
466
|
-
if (!
|
|
464
|
+
if (t instanceof K || t.isMesh === !0) {
|
|
465
|
+
const r = t.geometry, n = this.getAssignedLODInformation(r);
|
|
466
|
+
if (!n)
|
|
467
467
|
return Promise.resolve(null);
|
|
468
|
-
for (const
|
|
469
|
-
|
|
470
|
-
return t["LOD:requested level"] = e,
|
|
471
|
-
if (Array.isArray(
|
|
472
|
-
const
|
|
473
|
-
|
|
468
|
+
for (const o of E)
|
|
469
|
+
o.onBeforeGetLODMesh?.(t, e);
|
|
470
|
+
return t["LOD:requested level"] = e, h.getOrLoadLOD(r, e).then((o) => {
|
|
471
|
+
if (Array.isArray(o)) {
|
|
472
|
+
const u = n.index || 0;
|
|
473
|
+
o = o[u];
|
|
474
474
|
}
|
|
475
|
-
return t["LOD:requested level"] === e && (delete t["LOD:requested level"],
|
|
476
|
-
}).catch((
|
|
477
|
-
} else
|
|
475
|
+
return t["LOD:requested level"] === e && (delete t["LOD:requested level"], o && r != o && (o?.isBufferGeometry ? typeof s?.apply == "function" ? s.apply(o, e, t) : s?.apply !== !1 && (t.geometry = o) : f && console.error("Invalid LOD geometry", o))), o;
|
|
476
|
+
}).catch((o) => (console.error("Error loading mesh LOD", t, o), null));
|
|
477
|
+
} else f && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
|
|
478
478
|
return Promise.resolve(null);
|
|
479
479
|
}
|
|
480
480
|
static assignTextureLOD(t, e = 0, s) {
|
|
@@ -504,8 +504,8 @@ class p {
|
|
|
504
504
|
for (const l of Object.keys(a.uniforms)) {
|
|
505
505
|
const c = a.uniforms[l].value;
|
|
506
506
|
if (c?.isTexture === !0) {
|
|
507
|
-
const
|
|
508
|
-
o.push(
|
|
507
|
+
const d = this.assignTextureLODForSlot(c, e, n, l, r).then((g) => (g && a.uniforms[l].value != g && (a.uniforms[l].value = g, a.uniformsNeedUpdate = !0), g));
|
|
508
|
+
o.push(d), u.push(l);
|
|
509
509
|
}
|
|
510
510
|
}
|
|
511
511
|
} else
|
|
@@ -519,13 +519,13 @@ class p {
|
|
|
519
519
|
return Promise.all(o).then((a) => {
|
|
520
520
|
const l = new Array();
|
|
521
521
|
for (let c = 0; c < a.length; c++) {
|
|
522
|
-
const
|
|
523
|
-
|
|
522
|
+
const d = a[c], g = u[c];
|
|
523
|
+
d && d.isTexture === !0 ? l.push({ material: n, slot: g, texture: d, level: e }) : l.push({ material: n, slot: g, texture: null, level: e });
|
|
524
524
|
}
|
|
525
525
|
return l;
|
|
526
526
|
});
|
|
527
527
|
}
|
|
528
|
-
if (t instanceof
|
|
528
|
+
if (t instanceof G || t.isTexture === !0) {
|
|
529
529
|
const n = t;
|
|
530
530
|
return this.assignTextureLODForSlot(n, e, null, null, r);
|
|
531
531
|
}
|
|
@@ -536,10 +536,10 @@ class p {
|
|
|
536
536
|
* @default 50 on desktop, 20 on mobile devices
|
|
537
537
|
*/
|
|
538
538
|
static set maxConcurrentLoadingTasks(t) {
|
|
539
|
-
|
|
539
|
+
h.queue.maxConcurrent = t;
|
|
540
540
|
}
|
|
541
541
|
static get maxConcurrentLoadingTasks() {
|
|
542
|
-
return
|
|
542
|
+
return h.queue.maxConcurrent;
|
|
543
543
|
}
|
|
544
544
|
// #region INTERNAL
|
|
545
545
|
static assignTextureLODForSlot(t, e, s, r, n) {
|
|
@@ -555,7 +555,7 @@ class p {
|
|
|
555
555
|
if (a && a.level === e && a.force === n)
|
|
556
556
|
return a.promise;
|
|
557
557
|
}
|
|
558
|
-
const u =
|
|
558
|
+
const u = h.getOrLoadLOD(t, e).then((a) => {
|
|
559
559
|
if (Array.isArray(a))
|
|
560
560
|
return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen..."), null;
|
|
561
561
|
if (a?.isTexture === !0) {
|
|
@@ -564,12 +564,12 @@ class p {
|
|
|
564
564
|
if (l && !n) {
|
|
565
565
|
const c = this.getAssignedLODInformation(l);
|
|
566
566
|
if (c && c?.level < e)
|
|
567
|
-
return
|
|
567
|
+
return f === "verbose" && console.warn("Assigned texture level is already higher: ", c.level, e, s, l, a), null;
|
|
568
568
|
}
|
|
569
569
|
this.assignTrackedTextureSlot(s, r, a);
|
|
570
570
|
}
|
|
571
571
|
return a;
|
|
572
|
-
} else
|
|
572
|
+
} else f == "verbose" && console.warn("No LOD found for", t, e);
|
|
573
573
|
return null;
|
|
574
574
|
}).catch((a) => (console.error("Error loading LOD", t, a), null));
|
|
575
575
|
return s && r && this.setPendingTextureSlotRequest(s, r, e, n, u), u;
|
|
@@ -633,7 +633,7 @@ class p {
|
|
|
633
633
|
}
|
|
634
634
|
static releaseTrackedTextureSlot(t, e, s) {
|
|
635
635
|
const r = this.trackedTextureSlots.get(t);
|
|
636
|
-
if (r?.get(e) === s && r.delete(e), this.untrackTextureUsage(s) && (
|
|
636
|
+
if (r?.get(e) === s && r.delete(e), this.untrackTextureUsage(s) && (f || se)) {
|
|
637
637
|
const o = this.getAssignedLODInformation(s);
|
|
638
638
|
console.log(`[gltf-progressive] Disposed old texture LOD ${o?.level ?? "?"} for ${t.name || t.type}.${e}`, s.uuid);
|
|
639
639
|
}
|
|
@@ -642,13 +642,13 @@ class p {
|
|
|
642
642
|
url;
|
|
643
643
|
constructor(t) {
|
|
644
644
|
const e = t.options.path;
|
|
645
|
-
|
|
645
|
+
f && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
|
|
646
646
|
}
|
|
647
647
|
_isLoadingMesh;
|
|
648
648
|
loadMesh = (t) => {
|
|
649
649
|
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 &&
|
|
650
|
+
const e = this.parser.json.meshes[t]?.extensions?.[F];
|
|
651
|
+
return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s && h.registerMesh(this.url, e.guid, s, e.lods?.length, 0, e), s))) : null;
|
|
652
652
|
};
|
|
653
653
|
// private _isLoadingTexture;
|
|
654
654
|
// loadTexture = (textureIndex: number) => {
|
|
@@ -665,30 +665,30 @@ class p {
|
|
|
665
665
|
// });
|
|
666
666
|
// }
|
|
667
667
|
afterRoot(t) {
|
|
668
|
-
return
|
|
668
|
+
return f && console.log("AFTER", this.url, t), this.parser.json.textures?.forEach((e, s) => {
|
|
669
669
|
if (e?.extensions) {
|
|
670
|
-
const r = e?.extensions[
|
|
670
|
+
const r = e?.extensions[F];
|
|
671
671
|
if (r) {
|
|
672
672
|
if (!r.lods) {
|
|
673
|
-
|
|
673
|
+
f && console.warn("Texture has no LODs", r);
|
|
674
674
|
return;
|
|
675
675
|
}
|
|
676
676
|
let n = !1;
|
|
677
677
|
for (const o of this.parser.associations.keys())
|
|
678
|
-
o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (n = !0,
|
|
678
|
+
o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (n = !0, h.registerTexture(this.url, o, r.lods?.length, s, r));
|
|
679
679
|
n || this.parser.getDependency("texture", s).then((o) => {
|
|
680
|
-
o &&
|
|
680
|
+
o && h.registerTexture(this.url, o, r.lods?.length, s, r);
|
|
681
681
|
});
|
|
682
682
|
}
|
|
683
683
|
}
|
|
684
684
|
}), this.parser.json.meshes?.forEach((e, s) => {
|
|
685
685
|
if (e?.extensions) {
|
|
686
|
-
const r = e?.extensions[
|
|
686
|
+
const r = e?.extensions[F];
|
|
687
687
|
if (r && r.lods) {
|
|
688
688
|
for (const n of this.parser.associations.keys())
|
|
689
689
|
if (n.isMesh) {
|
|
690
690
|
const o = this.parser.associations.get(n);
|
|
691
|
-
o?.meshes === s &&
|
|
691
|
+
o?.meshes === s && h.registerMesh(this.url, r.guid, n, r.lods.length, o.primitives, r);
|
|
692
692
|
}
|
|
693
693
|
}
|
|
694
694
|
}
|
|
@@ -707,16 +707,16 @@ class p {
|
|
|
707
707
|
*/
|
|
708
708
|
static registerTexture = (t, e, s, r, n) => {
|
|
709
709
|
if (!e) {
|
|
710
|
-
|
|
710
|
+
f && console.error("!! gltf-progressive: Called register texture without texture");
|
|
711
711
|
return;
|
|
712
712
|
}
|
|
713
|
-
if (
|
|
713
|
+
if (f) {
|
|
714
714
|
const u = e.image?.width || e.source?.data?.width || 0, a = e.image?.height || e.source?.data?.height || 0;
|
|
715
715
|
console.log(`> gltf-progressive: register texture[${r}] "${e.name || e.uuid}", Current: ${u}x${a}, Max: ${n.lods[0]?.width}x${n.lods[0]?.height}, uuid: ${e.uuid}`, n, e);
|
|
716
716
|
}
|
|
717
|
-
e.source && (e.source[
|
|
717
|
+
e.source && (e.source[de] = n);
|
|
718
718
|
const o = n.guid;
|
|
719
|
-
|
|
719
|
+
h.assignLODInformation(t, e, o, s, r), h.lodInfos.set(o, n), h.lowresCache.set(o, new WeakRef(e));
|
|
720
720
|
};
|
|
721
721
|
/**
|
|
722
722
|
* Register a mesh with progressive LOD information. This associates the mesh geometry with its LOD extension data
|
|
@@ -734,13 +734,13 @@ class p {
|
|
|
734
734
|
static registerMesh = (t, e, s, r, n, o) => {
|
|
735
735
|
const u = s.geometry;
|
|
736
736
|
if (!u) {
|
|
737
|
-
|
|
737
|
+
f && console.warn("gltf-progressive: Register mesh without geometry");
|
|
738
738
|
return;
|
|
739
739
|
}
|
|
740
|
-
u.userData || (u.userData = {}),
|
|
741
|
-
let l =
|
|
742
|
-
l ? l.push(s.geometry) : l = [s.geometry],
|
|
743
|
-
for (const c of
|
|
740
|
+
u.userData || (u.userData = {}), f && console.log("> Progressive: register mesh " + s.name, { index: n, uuid: s.uuid }, o, s), h.assignLODInformation(t, u, e, r, n), h.lodInfos.set(e, o);
|
|
741
|
+
let l = h.lowresCache.get(e)?.deref();
|
|
742
|
+
l ? l.push(s.geometry) : l = [s.geometry], h.lowresCache.set(e, new WeakRef(l)), r > 0 && !ne(s) && dt(s, u);
|
|
743
|
+
for (const c of E)
|
|
744
744
|
c.onRegisteredNewMesh?.(s, o);
|
|
745
745
|
};
|
|
746
746
|
/**
|
|
@@ -814,16 +814,16 @@ class p {
|
|
|
814
814
|
* The held value is the cache key string used in `previouslyLoaded`.
|
|
815
815
|
*/
|
|
816
816
|
static _resourceRegistry = new FinalizationRegistry((t) => {
|
|
817
|
-
const e =
|
|
818
|
-
(
|
|
819
|
-
${t}`), e instanceof WeakRef && (e.deref() || (
|
|
817
|
+
const e = h.cache.get(t);
|
|
818
|
+
(f || se) && console.debug(`[gltf-progressive] Memory: Resource GC'd
|
|
819
|
+
${t}`), e instanceof WeakRef && (e.deref() || (h.cache.delete(t), (f || se) && console.log("[gltf-progressive] ↪ Cache entry deleted (GC)")));
|
|
820
820
|
});
|
|
821
821
|
/**
|
|
822
822
|
* Track texture usage by incrementing reference count
|
|
823
823
|
*/
|
|
824
824
|
static trackTextureUsage(t) {
|
|
825
825
|
const e = t.uuid, s = this.textureRefCounts.get(e) || 0;
|
|
826
|
-
this.textureRefCounts.set(e, s + 1),
|
|
826
|
+
this.textureRefCounts.set(e, s + 1), f === "verbose" && console.log(`[gltf-progressive] Track texture ${e}, refCount: ${s} → ${s + 1}`);
|
|
827
827
|
}
|
|
828
828
|
/**
|
|
829
829
|
* Untrack texture usage by decrementing reference count.
|
|
@@ -833,147 +833,147 @@ ${t}`), e instanceof WeakRef && (e.deref() || (p.cache.delete(t), (h || J) && co
|
|
|
833
833
|
static untrackTextureUsage(t) {
|
|
834
834
|
const e = t.uuid, s = this.textureRefCounts.get(e);
|
|
835
835
|
if (!s)
|
|
836
|
-
return (
|
|
836
|
+
return (f === "verbose" || se) && n("[gltf-progressive] Memory: Untrack untracked texture (dispose immediately)", 0), t.dispose(), !0;
|
|
837
837
|
const r = s - 1;
|
|
838
838
|
if (r <= 0)
|
|
839
|
-
return this.textureRefCounts.delete(e), (
|
|
840
|
-
return this.textureRefCounts.set(e, r),
|
|
839
|
+
return this.textureRefCounts.delete(e), (f || se) && n("[gltf-progressive] Memory: Dispose texture", r), t.dispose(), !0;
|
|
840
|
+
return this.textureRefCounts.set(e, r), f === "verbose" && n("[gltf-progressive] Memory: Untrack texture", r), !1;
|
|
841
841
|
function n(o, u) {
|
|
842
842
|
const a = t.image?.width || t.source?.data?.width || 0, l = t.image?.height || t.source?.data?.height || 0, c = a && l ? `${a}x${l}` : "N/A";
|
|
843
|
-
let
|
|
844
|
-
a && l && (
|
|
843
|
+
let d = "N/A";
|
|
844
|
+
a && l && (d = `~${(lt(t) / (1024 * 1024)).toFixed(2)} MB`), console.log(`${o} — ${t.name} ${c} (${d}), refCount: ${s} → ${u}
|
|
845
845
|
${e}`);
|
|
846
846
|
}
|
|
847
847
|
}
|
|
848
848
|
static workers = [];
|
|
849
849
|
static _workersIndex = 0;
|
|
850
850
|
static async getOrLoadLOD(t, e) {
|
|
851
|
-
const s =
|
|
851
|
+
const s = f == "verbose", r = this.getAssignedLODInformation(t);
|
|
852
852
|
if (!r)
|
|
853
|
-
return
|
|
853
|
+
return f && console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`, t), null;
|
|
854
854
|
const n = r?.key;
|
|
855
855
|
let o;
|
|
856
856
|
if (t.isTexture === !0) {
|
|
857
857
|
const a = t;
|
|
858
|
-
a.source && a.source[
|
|
858
|
+
a.source && a.source[de] && (o = a.source[de]);
|
|
859
859
|
}
|
|
860
|
-
if (o || (o =
|
|
861
|
-
|
|
860
|
+
if (o || (o = h.lodInfos.get(n)), !o)
|
|
861
|
+
f && console.warn(`Can not load LOD ${e}: no LOD info found for "${n}" ${t.name}`, t.type, h.lodInfos);
|
|
862
862
|
else {
|
|
863
863
|
if (e > 0) {
|
|
864
864
|
let c = !1;
|
|
865
|
-
const
|
|
866
|
-
if (
|
|
867
|
-
const
|
|
868
|
-
if (
|
|
869
|
-
const
|
|
870
|
-
if (
|
|
871
|
-
this.lowresCache.delete(n),
|
|
865
|
+
const d = Array.isArray(o.lods);
|
|
866
|
+
if (d && e >= o.lods.length ? c = !0 : d || (c = !0), c) {
|
|
867
|
+
const g = this.lowresCache.get(n);
|
|
868
|
+
if (g) {
|
|
869
|
+
const m = g.deref();
|
|
870
|
+
if (m) return m;
|
|
871
|
+
this.lowresCache.delete(n), f && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${n}`);
|
|
872
872
|
}
|
|
873
873
|
return null;
|
|
874
874
|
}
|
|
875
875
|
}
|
|
876
876
|
const a = Array.isArray(o.lods) ? o.lods[e]?.path : o.lods;
|
|
877
877
|
if (!a)
|
|
878
|
-
return
|
|
879
|
-
const l =
|
|
878
|
+
return f && !o["missing:uri"] && (o["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, o)), null;
|
|
879
|
+
const l = it(r.url, a);
|
|
880
880
|
if (l.endsWith(".glb") || l.endsWith(".gltf")) {
|
|
881
881
|
if (!o.guid)
|
|
882
882
|
return console.warn("missing pointer for glb/gltf texture", o), null;
|
|
883
|
-
const c = l + "_" + o.guid,
|
|
884
|
-
if (
|
|
885
|
-
const
|
|
886
|
-
if (
|
|
887
|
-
if (!
|
|
888
|
-
return
|
|
889
|
-
const
|
|
890
|
-
if (
|
|
891
|
-
const
|
|
892
|
-
if (
|
|
893
|
-
for (const
|
|
894
|
-
let
|
|
895
|
-
return
|
|
883
|
+
const c = l + "_" + o.guid, d = await this.tryResolveLODCacheEntry(this.cache.get(c), c, l, t, e, s);
|
|
884
|
+
if (d.found) return d.value;
|
|
885
|
+
const g = await this.queue.slot(l), m = await this.tryResolveLODCacheEntry(this.cache.get(c), c, l, t, e, s);
|
|
886
|
+
if (m.found) return m.value;
|
|
887
|
+
if (!g.use)
|
|
888
|
+
return f && console.log(`LOD ${e} was aborted: ${l}`), null;
|
|
889
|
+
const x = o, v = new Promise(async (_, C) => {
|
|
890
|
+
if (xt) {
|
|
891
|
+
const y = await (await mt({})).load(l);
|
|
892
|
+
if (y.textures.length > 0)
|
|
893
|
+
for (const M of y.textures) {
|
|
894
|
+
let b = M.texture;
|
|
895
|
+
return h.assignLODInformation(r.url, b, n, e, void 0), t instanceof G && (b = this.copySettings(t, b)), b && (b.guid = x.guid), _(b);
|
|
896
896
|
}
|
|
897
|
-
if (
|
|
898
|
-
const
|
|
899
|
-
for (const
|
|
900
|
-
const
|
|
901
|
-
|
|
897
|
+
if (y.geometries.length > 0) {
|
|
898
|
+
const M = new Array();
|
|
899
|
+
for (const b of y.geometries) {
|
|
900
|
+
const B = b.geometry;
|
|
901
|
+
h.assignLODInformation(r.url, B, n, e, b.primitiveIndex), M.push(B);
|
|
902
902
|
}
|
|
903
|
-
return
|
|
903
|
+
return _(M);
|
|
904
904
|
}
|
|
905
|
-
return
|
|
905
|
+
return _(null);
|
|
906
906
|
}
|
|
907
|
-
const
|
|
908
|
-
|
|
909
|
-
let
|
|
910
|
-
if (
|
|
911
|
-
const
|
|
912
|
-
|
|
907
|
+
const W = new we();
|
|
908
|
+
Ae(W), f && (await new Promise((D) => setTimeout(D, 1e3)), s && console.warn("Start loading (delayed) " + l, x.guid));
|
|
909
|
+
let L = l;
|
|
910
|
+
if (x && Array.isArray(x.lods)) {
|
|
911
|
+
const D = x.lods[e];
|
|
912
|
+
D.hash && (L += "?v=" + D.hash);
|
|
913
913
|
}
|
|
914
|
-
const
|
|
915
|
-
`,
|
|
916
|
-
if (!
|
|
917
|
-
return
|
|
918
|
-
const
|
|
919
|
-
s && console.log("Loading finished " + l,
|
|
920
|
-
let
|
|
921
|
-
if (
|
|
922
|
-
let
|
|
923
|
-
for (const
|
|
924
|
-
if (
|
|
925
|
-
const
|
|
926
|
-
if (
|
|
927
|
-
|
|
914
|
+
const w = await W.loadAsync(L).catch((D) => (console.error(`Error loading LOD ${e} from ${l}
|
|
915
|
+
`, D), _(null)));
|
|
916
|
+
if (!w)
|
|
917
|
+
return _(null);
|
|
918
|
+
const S = w.parser;
|
|
919
|
+
s && console.log("Loading finished " + l, x.guid);
|
|
920
|
+
let O = 0;
|
|
921
|
+
if (w.parser.json.textures) {
|
|
922
|
+
let D = !1;
|
|
923
|
+
for (const y of w.parser.json.textures) {
|
|
924
|
+
if (y?.extensions) {
|
|
925
|
+
const M = y?.extensions[F];
|
|
926
|
+
if (M?.guid && M.guid === x.guid) {
|
|
927
|
+
D = !0;
|
|
928
928
|
break;
|
|
929
929
|
}
|
|
930
930
|
}
|
|
931
|
-
|
|
931
|
+
O++;
|
|
932
932
|
}
|
|
933
|
-
if (
|
|
934
|
-
let
|
|
935
|
-
return
|
|
936
|
-
} else
|
|
933
|
+
if (D) {
|
|
934
|
+
let y = await S.getDependency("texture", O);
|
|
935
|
+
return y && h.assignLODInformation(r.url, y, n, e, void 0), s && console.log('change "' + t.name + '" → "' + y.name + '"', l, O, y, c), t instanceof G && (y = this.copySettings(t, y)), y && (y.guid = x.guid), _(y);
|
|
936
|
+
} else f && console.warn("Could not find texture with guid", x.guid, w.parser.json);
|
|
937
937
|
}
|
|
938
|
-
if (
|
|
939
|
-
let
|
|
940
|
-
for (const
|
|
941
|
-
if (
|
|
942
|
-
const
|
|
943
|
-
if (
|
|
944
|
-
|
|
938
|
+
if (O = 0, w.parser.json.meshes) {
|
|
939
|
+
let D = !1;
|
|
940
|
+
for (const y of w.parser.json.meshes) {
|
|
941
|
+
if (y?.extensions) {
|
|
942
|
+
const M = y?.extensions[F];
|
|
943
|
+
if (M?.guid && M.guid === x.guid) {
|
|
944
|
+
D = !0;
|
|
945
945
|
break;
|
|
946
946
|
}
|
|
947
947
|
}
|
|
948
|
-
|
|
948
|
+
O++;
|
|
949
949
|
}
|
|
950
|
-
if (
|
|
951
|
-
const
|
|
952
|
-
if (s && console.log(`Loaded Mesh "${
|
|
953
|
-
const
|
|
954
|
-
return
|
|
950
|
+
if (D) {
|
|
951
|
+
const y = await S.getDependency("mesh", O);
|
|
952
|
+
if (s && console.log(`Loaded Mesh "${y.name}"`, l, O, y, c), y.isMesh === !0) {
|
|
953
|
+
const M = y.geometry;
|
|
954
|
+
return h.assignLODInformation(r.url, M, n, e, 0), _(M);
|
|
955
955
|
} else {
|
|
956
|
-
const
|
|
957
|
-
for (let
|
|
958
|
-
const
|
|
959
|
-
if (
|
|
960
|
-
const
|
|
961
|
-
|
|
956
|
+
const M = new Array();
|
|
957
|
+
for (let b = 0; b < y.children.length; b++) {
|
|
958
|
+
const B = y.children[b];
|
|
959
|
+
if (B.isMesh === !0) {
|
|
960
|
+
const V = B.geometry;
|
|
961
|
+
h.assignLODInformation(r.url, V, n, e, b), M.push(V);
|
|
962
962
|
}
|
|
963
963
|
}
|
|
964
|
-
return
|
|
964
|
+
return _(M);
|
|
965
965
|
}
|
|
966
|
-
} else
|
|
966
|
+
} else f && console.warn("Could not find mesh with guid", x.guid, w.parser.json);
|
|
967
967
|
}
|
|
968
|
-
return
|
|
968
|
+
return _(null);
|
|
969
969
|
});
|
|
970
|
-
this.cache.set(c,
|
|
971
|
-
const
|
|
972
|
-
return
|
|
973
|
-
} else if (t instanceof
|
|
970
|
+
this.cache.set(c, v), g.use(v);
|
|
971
|
+
const p = await v;
|
|
972
|
+
return p != null ? p instanceof G ? (this.cache.set(c, new WeakRef(p)), h._resourceRegistry.register(p, c)) : Array.isArray(p) ? this.cache.set(c, Promise.resolve(p)) : this.cache.set(c, Promise.resolve(p)) : this.cache.set(c, Promise.resolve(null)), p;
|
|
973
|
+
} else if (t instanceof G) {
|
|
974
974
|
s && console.log("Load texture from uri: " + l);
|
|
975
|
-
const
|
|
976
|
-
return
|
|
975
|
+
const d = await new je().loadAsync(l);
|
|
976
|
+
return d ? (d.guid = o.guid, d.flipY = !1, d.needsUpdate = !0, d.colorSpace = t.colorSpace, s && console.log(o, d)) : f && console.warn("failed loading", l), d;
|
|
977
977
|
}
|
|
978
978
|
}
|
|
979
979
|
return null;
|
|
@@ -984,24 +984,24 @@ ${e}`);
|
|
|
984
984
|
if (o && console.log(`LOD ${n} was already loading/loaded: ${e}`), t instanceof WeakRef) {
|
|
985
985
|
const l = t.deref();
|
|
986
986
|
if (l) {
|
|
987
|
-
let c = l,
|
|
988
|
-
if (c instanceof
|
|
987
|
+
let c = l, d = !1;
|
|
988
|
+
if (c instanceof G && r instanceof G ? c.image?.data || c.source?.data ? c = this.copySettings(r, c) : d = !0 : c instanceof j && r instanceof j && (c.attributes.position?.array || (d = !0)), !d)
|
|
989
989
|
return { found: !0, value: c };
|
|
990
990
|
}
|
|
991
|
-
return this.cache.delete(e),
|
|
991
|
+
return this.cache.delete(e), f && console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${e}`), { found: !1 };
|
|
992
992
|
}
|
|
993
993
|
let u = await t.catch((l) => (console.error(`Error loading LOD ${n} from ${s}
|
|
994
994
|
`, l), null)), a = !1;
|
|
995
|
-
return u == null || (u instanceof
|
|
995
|
+
return u == null || (u instanceof G && r instanceof G ? u.image?.data || u.source?.data ? u = this.copySettings(r, u) : (a = !0, this.cache.delete(e)) : u instanceof j && r instanceof j && (u.attributes.position?.array || (a = !0, this.cache.delete(e)))), a ? { found: !1 } : { found: !0, value: u };
|
|
996
996
|
}
|
|
997
997
|
static _queue;
|
|
998
998
|
static get queue() {
|
|
999
|
-
return this._queue ??= new
|
|
999
|
+
return this._queue ??= new at(ve() ? 20 : 50, { debug: f != !1 });
|
|
1000
1000
|
}
|
|
1001
1001
|
static assignLODInformation(t, e, s, r, n) {
|
|
1002
1002
|
if (!e) return;
|
|
1003
1003
|
e.userData || (e.userData = {});
|
|
1004
|
-
const o = new
|
|
1004
|
+
const o = new wt(t, s, r, n);
|
|
1005
1005
|
e.userData.LODS = o, "source" in e && typeof e.source == "object" && (e.source.LODS = o);
|
|
1006
1006
|
}
|
|
1007
1007
|
static getAssignedLODInformation(t) {
|
|
@@ -1009,12 +1009,12 @@ ${e}`);
|
|
|
1009
1009
|
}
|
|
1010
1010
|
// private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
|
|
1011
1011
|
static copySettings(t, e) {
|
|
1012
|
-
return e ? (
|
|
1012
|
+
return e ? (f === "verbose" && console.debug(`Copy texture settings
|
|
1013
1013
|
`, t.uuid, `
|
|
1014
1014
|
`, 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
1015
|
}
|
|
1016
1016
|
}
|
|
1017
|
-
class
|
|
1017
|
+
class wt {
|
|
1018
1018
|
url;
|
|
1019
1019
|
/** the key to lookup the LOD information */
|
|
1020
1020
|
key;
|
|
@@ -1025,7 +1025,7 @@ class yt {
|
|
|
1025
1025
|
this.url = t, this.key = e, this.level = s, r != null && (this.index = r);
|
|
1026
1026
|
}
|
|
1027
1027
|
}
|
|
1028
|
-
class
|
|
1028
|
+
class oe {
|
|
1029
1029
|
static addPromise = (t, e, s, r) => {
|
|
1030
1030
|
r.forEach((n) => {
|
|
1031
1031
|
n.add(t, e, s);
|
|
@@ -1074,7 +1074,7 @@ class ce {
|
|
|
1074
1074
|
_seen = /* @__PURE__ */ new WeakMap();
|
|
1075
1075
|
add(t, e, s) {
|
|
1076
1076
|
if (this._resolved) {
|
|
1077
|
-
|
|
1077
|
+
f && console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");
|
|
1078
1078
|
return;
|
|
1079
1079
|
}
|
|
1080
1080
|
if (!(this._frame_start !== void 0 && this._currentFrame > this._frame_start + this._frames_to_capture)) {
|
|
@@ -1082,7 +1082,7 @@ class ce {
|
|
|
1082
1082
|
if (this._seen.has(e)) {
|
|
1083
1083
|
const r = this._seen.get(e);
|
|
1084
1084
|
if (r >= this._maxPromisesPerObject) {
|
|
1085
|
-
|
|
1085
|
+
f && console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");
|
|
1086
1086
|
return;
|
|
1087
1087
|
}
|
|
1088
1088
|
this._seen.set(e, r + 1);
|
|
@@ -1101,7 +1101,7 @@ class ce {
|
|
|
1101
1101
|
});
|
|
1102
1102
|
}
|
|
1103
1103
|
}
|
|
1104
|
-
const
|
|
1104
|
+
const A = N("debugprogressive"), Lt = A === "colors", vt = N("noprogressive"), fe = /* @__PURE__ */ Symbol("Needle:LODSManager"), he = /* @__PURE__ */ Symbol("Needle:LODState"), q = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), T = { mesh_lod: -1, texture_lod: -1 }, _t = new Ce(), Me = [
|
|
1105
1105
|
3526751,
|
|
1106
1106
|
11065402,
|
|
1107
1107
|
15978811,
|
|
@@ -1134,22 +1134,79 @@ const R = N("debugprogressive"), xt = R === "colors", wt = N("noprogressive"), d
|
|
|
1134
1134
|
15817653,
|
|
1135
1135
|
5083278,
|
|
1136
1136
|
5592405
|
|
1137
|
-
];
|
|
1138
|
-
|
|
1137
|
+
], ge = new le(), z = new le(), De = new le(), Mt = new k(), Dt = new k(), bt = new Pe(), U = new k(), H = new k(), Q = new k(), J = new k();
|
|
1138
|
+
function Ot(i, t) {
|
|
1139
|
+
const e = i.min, s = i.max, r = (e.x + s.x) * 0.5, n = (e.y + s.y) * 0.5;
|
|
1140
|
+
return U.set(r, n, e.z).applyMatrix4(t).z < 0;
|
|
1141
|
+
}
|
|
1142
|
+
function Tt(i) {
|
|
1143
|
+
const {
|
|
1144
|
+
geometry: t,
|
|
1145
|
+
matrixWorld: e,
|
|
1146
|
+
camera: s,
|
|
1147
|
+
projectionScreenMatrix: r,
|
|
1148
|
+
desiredDensity: n,
|
|
1149
|
+
canvasHeight: o = 0,
|
|
1150
|
+
currentLevel: u = -1,
|
|
1151
|
+
xrEnabled: a = !1,
|
|
1152
|
+
debugDrawLine: l,
|
|
1153
|
+
warnMissingPrimitiveDensities: c = !1
|
|
1154
|
+
} = i, d = h.getMeshLODExtension(t)?.lods, g = h.getPrimitiveIndex(t), m = i.target ?? {
|
|
1155
|
+
level: u,
|
|
1156
|
+
primitiveIndex: g,
|
|
1157
|
+
screenCoverage: 0,
|
|
1158
|
+
screenspaceVolume: new k(),
|
|
1159
|
+
centrality: 1
|
|
1160
|
+
};
|
|
1161
|
+
if (m.level = u, m.primitiveIndex = g, m.screenCoverage = 0, m.screenspaceVolume.set(0, 0, 0), m.centrality = 1, !d?.length) return m;
|
|
1162
|
+
let x = i.boundingBox ?? t.boundingBox;
|
|
1163
|
+
if (x || (t.computeBoundingBox(), x = t.boundingBox), !x) return m;
|
|
1164
|
+
if (ge.copy(x).applyMatrix4(e), s.isPerspectiveCamera && Ot(ge, r))
|
|
1165
|
+
return m.level = 0, m.screenCoverage = 1 / 0, m.screenspaceVolume.set(1 / 0, 1 / 0, 1 / 0), m;
|
|
1166
|
+
if (z.copy(ge).applyMatrix4(r), a && s.isPerspectiveCamera && s.fov > 70) {
|
|
1167
|
+
const L = z.min, w = z.max;
|
|
1168
|
+
let S = L.x, O = L.y, D = w.x, y = w.y;
|
|
1169
|
+
const M = 2, b = 1.5, B = (L.x + w.x) * 0.5, V = (L.y + w.y) * 0.5;
|
|
1170
|
+
S = (S - B) * M + B, O = (O - V) * M + V, D = (D - B) * M + B, y = (y - V) * M + V;
|
|
1171
|
+
const Fe = S < 0 && D > 0 ? 0 : Math.min(Math.abs(L.x), Math.abs(w.x)), qe = O < 0 && y > 0 ? 0 : Math.min(Math.abs(L.y), Math.abs(w.y)), ue = Math.max(Fe, qe);
|
|
1172
|
+
m.centrality = (b - ue) * (b - ue) * (b - ue);
|
|
1173
|
+
}
|
|
1174
|
+
const v = z.getSize(Mt);
|
|
1175
|
+
v.multiplyScalar(0.5), globalThis.screen?.availHeight > 0 && o > 0 && v.multiplyScalar(o / globalThis.screen.availHeight), s.isPerspectiveCamera && (v.x *= s.aspect), De.copy(x).applyMatrix4(e).applyMatrix4(s.matrixWorldInverse);
|
|
1176
|
+
const p = De.getSize(Dt), _ = Math.max(v.x, v.y), C = Math.max(p.x, p.y);
|
|
1177
|
+
_ !== 0 && C !== 0 && (v.z = p.z / C * _);
|
|
1178
|
+
const W = Math.max(v.x, v.y, v.z) * m.centrality;
|
|
1179
|
+
if (m.screenCoverage = W, m.screenspaceVolume.copy(v), W <= 0) return m;
|
|
1180
|
+
if (l) {
|
|
1181
|
+
const L = bt.copy(r);
|
|
1182
|
+
L.invert(), U.copy(z.min), H.copy(z.max), H.x = U.x, Q.copy(z.max), Q.y = U.y, J.copy(z.max);
|
|
1183
|
+
const w = (U.z + J.z) * 0.5;
|
|
1184
|
+
U.z = H.z = Q.z = J.z = w, U.applyMatrix4(L), H.applyMatrix4(L), Q.applyMatrix4(L), J.applyMatrix4(L), l(U, H, 255), l(U, Q, 255), l(H, J, 255), l(Q, J, 255);
|
|
1185
|
+
}
|
|
1186
|
+
for (let L = 0; L < d.length; L++) {
|
|
1187
|
+
const w = d[L], S = w.densities?.[g] || w.density || 1e-5;
|
|
1188
|
+
if (g > 0 && c && $e() && !w.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.")), S / W < n) {
|
|
1189
|
+
m.level = L;
|
|
1190
|
+
break;
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
return m;
|
|
1194
|
+
}
|
|
1195
|
+
class R {
|
|
1139
1196
|
/**
|
|
1140
1197
|
* 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.
|
|
1141
1198
|
*/
|
|
1142
1199
|
static debugDrawLine;
|
|
1143
1200
|
/** @internal */
|
|
1144
1201
|
static getObjectLODState(t) {
|
|
1145
|
-
return t[
|
|
1202
|
+
return t[he];
|
|
1146
1203
|
}
|
|
1147
1204
|
static addPlugin(t) {
|
|
1148
|
-
|
|
1205
|
+
E.push(t);
|
|
1149
1206
|
}
|
|
1150
1207
|
static removePlugin(t) {
|
|
1151
|
-
const e =
|
|
1152
|
-
e >= 0 &&
|
|
1208
|
+
const e = E.indexOf(t);
|
|
1209
|
+
e >= 0 && E.splice(e, 1);
|
|
1153
1210
|
}
|
|
1154
1211
|
/**
|
|
1155
1212
|
* Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
|
|
@@ -1157,20 +1214,20 @@ class L {
|
|
|
1157
1214
|
* @returns The LODsManager instance.
|
|
1158
1215
|
*/
|
|
1159
1216
|
static get(t, e) {
|
|
1160
|
-
if (t[
|
|
1161
|
-
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[
|
|
1162
|
-
const s = new
|
|
1217
|
+
if (t[fe])
|
|
1218
|
+
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[fe];
|
|
1219
|
+
const s = new R(t, {
|
|
1163
1220
|
engine: "unknown",
|
|
1164
1221
|
...e
|
|
1165
1222
|
});
|
|
1166
|
-
return t[
|
|
1223
|
+
return t[fe] = s, s;
|
|
1167
1224
|
}
|
|
1168
1225
|
renderer;
|
|
1169
1226
|
context;
|
|
1170
|
-
projectionScreenMatrix = new
|
|
1227
|
+
projectionScreenMatrix = new Pe();
|
|
1171
1228
|
/** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
|
|
1172
1229
|
get plugins() {
|
|
1173
|
-
return
|
|
1230
|
+
return E;
|
|
1174
1231
|
}
|
|
1175
1232
|
/**
|
|
1176
1233
|
* Force override the LOD level for all objects (meshes + textures) rendered in the scene
|
|
@@ -1235,17 +1292,21 @@ class L {
|
|
|
1235
1292
|
* ```
|
|
1236
1293
|
*/
|
|
1237
1294
|
awaitLoading(t) {
|
|
1238
|
-
const e = this._promiseGroupIds++, s = new
|
|
1295
|
+
const e = this._promiseGroupIds++, s = new oe(this.#r, { ...t });
|
|
1239
1296
|
this._newPromiseGroups.push(s);
|
|
1240
1297
|
const r = performance.now();
|
|
1241
1298
|
return s.ready.finally(() => {
|
|
1242
1299
|
const n = this._newPromiseGroups.indexOf(s);
|
|
1243
|
-
n >= 0 && (this._newPromiseGroups.splice(n, 1),
|
|
1300
|
+
n >= 0 && (this._newPromiseGroups.splice(n, 1), $e() && performance.measure("LODsManager:awaitLoading", {
|
|
1244
1301
|
start: r,
|
|
1245
1302
|
detail: { id: e, name: t?.name, awaited: s.awaitedCount, resolved: s.resolvedCount }
|
|
1246
1303
|
}));
|
|
1247
1304
|
}), s.ready;
|
|
1248
1305
|
}
|
|
1306
|
+
/** Track LOD work started outside this manager so {@link awaitLoading} waits for it too. */
|
|
1307
|
+
trackLoadingPromise(t, e, s) {
|
|
1308
|
+
return oe.addPromise(t, e, s, this._newPromiseGroups), s;
|
|
1309
|
+
}
|
|
1249
1310
|
_postprocessPromiseGroups() {
|
|
1250
1311
|
if (this._newPromiseGroups.length !== 0)
|
|
1251
1312
|
for (let t = this._newPromiseGroups.length - 1; t >= 0; t--)
|
|
@@ -1292,7 +1353,7 @@ class L {
|
|
|
1292
1353
|
this.renderer = t, this.context = { ...e };
|
|
1293
1354
|
}
|
|
1294
1355
|
#t;
|
|
1295
|
-
#o = new
|
|
1356
|
+
#o = new Ke();
|
|
1296
1357
|
#r = 0;
|
|
1297
1358
|
#n = 0;
|
|
1298
1359
|
#i = 0;
|
|
@@ -1307,9 +1368,9 @@ class L {
|
|
|
1307
1368
|
let t = 0;
|
|
1308
1369
|
this.#t = this.renderer.render;
|
|
1309
1370
|
const e = this;
|
|
1310
|
-
|
|
1371
|
+
Le(this.renderer), this.renderer.render = function(s, r) {
|
|
1311
1372
|
const n = e.renderer.getRenderTarget();
|
|
1312
|
-
(n == null || "isXRRenderTarget" in n && n.isXRRenderTarget) && (t = 0, e.#r += 1, e.#n = e.#o.getDelta(), e.#i += e.#n, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#n), e.#s = e._fpsBuffer.reduce((u, a) => u + a) / e._fpsBuffer.length,
|
|
1373
|
+
(n == null || "isXRRenderTarget" in n && n.isXRRenderTarget) && (t = 0, e.#r += 1, e.#n = e.#o.getDelta(), e.#i += e.#n, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#n), e.#s = e._fpsBuffer.reduce((u, a) => u + a) / e._fpsBuffer.length, A && e.#r % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
|
|
1313
1374
|
const o = t++;
|
|
1314
1375
|
e.#t.call(this, s, r), e.onAfterRender(s, r, o);
|
|
1315
1376
|
};
|
|
@@ -1344,7 +1405,7 @@ class L {
|
|
|
1344
1405
|
(u.name === "EffectMaterial" || u.name === "CopyShader") && (o = !1);
|
|
1345
1406
|
}
|
|
1346
1407
|
if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (o = !1), o) {
|
|
1347
|
-
if (
|
|
1408
|
+
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))
|
|
1348
1409
|
return;
|
|
1349
1410
|
this.internalUpdate(t, e), this._postprocessPromiseGroups();
|
|
1350
1411
|
}
|
|
@@ -1358,7 +1419,7 @@ class L {
|
|
|
1358
1419
|
const n = this.targetTriangleDensity;
|
|
1359
1420
|
for (const a of r) {
|
|
1360
1421
|
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")) {
|
|
1361
|
-
|
|
1422
|
+
A && (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)));
|
|
1362
1423
|
continue;
|
|
1363
1424
|
}
|
|
1364
1425
|
switch (a.material.type) {
|
|
@@ -1371,32 +1432,32 @@ class L {
|
|
|
1371
1432
|
continue;
|
|
1372
1433
|
}
|
|
1373
1434
|
const l = a.object;
|
|
1374
|
-
(l instanceof
|
|
1435
|
+
(l instanceof K || l.isMesh) && this.updateLODs(t, e, l, n);
|
|
1375
1436
|
}
|
|
1376
1437
|
const o = s.transparent;
|
|
1377
1438
|
for (const a of o) {
|
|
1378
1439
|
const l = a.object;
|
|
1379
|
-
(l instanceof
|
|
1440
|
+
(l instanceof K || l.isMesh) && this.updateLODs(t, e, l, n);
|
|
1380
1441
|
}
|
|
1381
1442
|
const u = s.transmissive;
|
|
1382
1443
|
for (const a of u) {
|
|
1383
1444
|
const l = a.object;
|
|
1384
|
-
(l instanceof
|
|
1445
|
+
(l instanceof K || l.isMesh) && this.updateLODs(t, e, l, n);
|
|
1385
1446
|
}
|
|
1386
1447
|
}
|
|
1387
1448
|
/** Update the LOD levels for the renderer. */
|
|
1388
1449
|
updateLODs(t, e, s, r) {
|
|
1389
1450
|
s.userData || (s.userData = {});
|
|
1390
|
-
let n = s[
|
|
1391
|
-
if (n || (n = new
|
|
1451
|
+
let n = s[he];
|
|
1452
|
+
if (n || (n = new St(), s[he] = n), n.frames++ < 2)
|
|
1392
1453
|
return;
|
|
1393
|
-
for (const u of
|
|
1454
|
+
for (const u of E)
|
|
1394
1455
|
u.onBeforeUpdateLOD?.(this.renderer, t, e, s);
|
|
1395
|
-
const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel :
|
|
1396
|
-
o >= 0 ? (
|
|
1397
|
-
for (const u of
|
|
1398
|
-
u.onAfterUpdatedLOD?.(this.renderer, t, e, s,
|
|
1399
|
-
n.lastLodLevel_Mesh =
|
|
1456
|
+
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), f && s.material && !s.isGizmo && Be(s.material), Lt && s.material && !s.isGizmo && !s.isBatchedMesh && Ge(s.material, T.mesh_lod);
|
|
1458
|
+
for (const u of E)
|
|
1459
|
+
u.onAfterUpdatedLOD?.(this.renderer, t, e, s, T);
|
|
1460
|
+
n.lastLodLevel_Mesh = T.mesh_lod, n.lastLodLevel_Texture = T.texture_lod;
|
|
1400
1461
|
}
|
|
1401
1462
|
/** Load progressive textures for the given material
|
|
1402
1463
|
* @param material the material to load the textures for
|
|
@@ -1411,14 +1472,14 @@ class L {
|
|
|
1411
1472
|
return;
|
|
1412
1473
|
}
|
|
1413
1474
|
let r = !1;
|
|
1414
|
-
(t[
|
|
1475
|
+
(t[q] === void 0 || e < t[q]) && (r = !0);
|
|
1415
1476
|
const n = s !== void 0 && s >= 0;
|
|
1416
|
-
if (n && (r = t[
|
|
1417
|
-
t[
|
|
1418
|
-
const o = n ? { force: !0 } : void 0, u =
|
|
1477
|
+
if (n && (r = t[q] != s, e = s), r) {
|
|
1478
|
+
t[q] = e;
|
|
1479
|
+
const o = n ? { force: !0 } : void 0, u = h.assignTextureLOD(t, e, o).then((a) => {
|
|
1419
1480
|
this._lodchangedlisteners.forEach((l) => l({ type: "texture", level: e, object: t }));
|
|
1420
1481
|
});
|
|
1421
|
-
|
|
1482
|
+
oe.addPromise("texture", t, u, this._newPromiseGroups);
|
|
1422
1483
|
}
|
|
1423
1484
|
}
|
|
1424
1485
|
/** Load progressive meshes for the given mesh
|
|
@@ -1429,32 +1490,18 @@ class L {
|
|
|
1429
1490
|
*/
|
|
1430
1491
|
loadProgressiveMeshes(t, e) {
|
|
1431
1492
|
if (!t) return Promise.resolve(null);
|
|
1432
|
-
let s = t[
|
|
1493
|
+
let s = t[q] !== e;
|
|
1433
1494
|
const r = t["DEBUG:LOD"];
|
|
1434
|
-
if (r != null && (s = t[
|
|
1435
|
-
t[
|
|
1436
|
-
const n = t.geometry, o =
|
|
1437
|
-
return
|
|
1495
|
+
if (r != null && (s = t[q] != r, e = r), s) {
|
|
1496
|
+
t[q] = e;
|
|
1497
|
+
const n = t.geometry, o = h.assignMeshLOD(t, e).then((u) => (u && t[q] == e && n != t.geometry && this._lodchangedlisteners.forEach((a) => a({ type: "mesh", level: e, object: t })), u));
|
|
1498
|
+
return oe.addPromise("mesh", t, o, this._newPromiseGroups), o;
|
|
1438
1499
|
}
|
|
1439
1500
|
return Promise.resolve(null);
|
|
1440
1501
|
}
|
|
1441
1502
|
// private testIfLODLevelsAreAvailable() {
|
|
1442
|
-
_sphere = new
|
|
1443
|
-
|
|
1444
|
-
_tempBox2 = new ge();
|
|
1445
|
-
tempMatrix = new ve();
|
|
1446
|
-
_tempWorldPosition = new P();
|
|
1447
|
-
_tempBoxSize = new P();
|
|
1448
|
-
_tempBox2Size = new P();
|
|
1449
|
-
static corner0 = new P();
|
|
1450
|
-
static corner1 = new P();
|
|
1451
|
-
static corner2 = new P();
|
|
1452
|
-
static corner3 = new P();
|
|
1453
|
-
static _tempPtInside = new P();
|
|
1454
|
-
static isInside(t, e) {
|
|
1455
|
-
const s = t.min, r = t.max, n = (s.x + r.x) * 0.5, o = (s.y + r.y) * 0.5;
|
|
1456
|
-
return this._tempPtInside.set(n, o, s.z).applyMatrix4(e).z < 0;
|
|
1457
|
-
}
|
|
1503
|
+
_sphere = new Se();
|
|
1504
|
+
_tempWorldPosition = new k();
|
|
1458
1505
|
static skinnedMeshBoundsFrameOffsetCounter = 0;
|
|
1459
1506
|
static $skinnedMeshBoundsOffset = /* @__PURE__ */ Symbol("gltf-progressive-skinnedMeshBoundsOffset");
|
|
1460
1507
|
// #region calculateLodLevel
|
|
@@ -1468,104 +1515,85 @@ class L {
|
|
|
1468
1515
|
return;
|
|
1469
1516
|
}
|
|
1470
1517
|
let u = 10 + 1, a = !1;
|
|
1471
|
-
if (
|
|
1518
|
+
if (A && e["DEBUG:LOD"] != null)
|
|
1472
1519
|
return e["DEBUG:LOD"];
|
|
1473
|
-
const l =
|
|
1474
|
-
if (!
|
|
1520
|
+
const l = h.getMeshLODExtension(e.geometry)?.lods, c = h.getPrimitiveIndex(e.geometry), d = l && l.length > 0, g = h.getMaterialMinMaxLODsCount(e.material), m = g.min_count !== 1 / 0 && g.min_count >= 0 && g.max_count >= 0;
|
|
1521
|
+
if (!d && !m) {
|
|
1475
1522
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1476
1523
|
return;
|
|
1477
1524
|
}
|
|
1478
|
-
|
|
1479
|
-
const
|
|
1480
|
-
let
|
|
1525
|
+
d || (a = !0, u = 0);
|
|
1526
|
+
const x = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
|
|
1527
|
+
let v = e.geometry.boundingBox;
|
|
1481
1528
|
if (e.type === "SkinnedMesh") {
|
|
1482
|
-
const
|
|
1483
|
-
if (!
|
|
1484
|
-
|
|
1529
|
+
const p = e;
|
|
1530
|
+
if (!p.boundingBox)
|
|
1531
|
+
p.computeBoundingBox();
|
|
1485
1532
|
else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
|
|
1486
|
-
if (!
|
|
1487
|
-
const
|
|
1488
|
-
|
|
1533
|
+
if (!p[R.$skinnedMeshBoundsOffset]) {
|
|
1534
|
+
const C = R.skinnedMeshBoundsFrameOffsetCounter++;
|
|
1535
|
+
p[R.$skinnedMeshBoundsOffset] = C;
|
|
1489
1536
|
}
|
|
1490
|
-
const
|
|
1491
|
-
if ((s.frames +
|
|
1492
|
-
const
|
|
1493
|
-
|
|
1537
|
+
const _ = p[R.$skinnedMeshBoundsOffset];
|
|
1538
|
+
if ((s.frames + _) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
|
|
1539
|
+
const C = ne(p), W = p.geometry;
|
|
1540
|
+
C && (p.geometry = C), p.computeBoundingBox(), p.geometry = W;
|
|
1494
1541
|
}
|
|
1495
1542
|
}
|
|
1496
|
-
|
|
1543
|
+
v = p.boundingBox;
|
|
1497
1544
|
}
|
|
1498
|
-
if (
|
|
1499
|
-
const x = t;
|
|
1545
|
+
if (v) {
|
|
1500
1546
|
if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
|
|
1501
1547
|
this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
|
|
1502
|
-
const
|
|
1503
|
-
if (this._sphere.containsPoint(
|
|
1548
|
+
const C = t.getWorldPosition(this._tempWorldPosition);
|
|
1549
|
+
if (this._sphere.containsPoint(C)) {
|
|
1504
1550
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1505
1551
|
return;
|
|
1506
1552
|
}
|
|
1507
1553
|
}
|
|
1508
|
-
|
|
1554
|
+
const p = Tt({
|
|
1555
|
+
geometry: e.geometry,
|
|
1556
|
+
matrixWorld: e.matrixWorld,
|
|
1557
|
+
camera: t,
|
|
1558
|
+
projectionScreenMatrix: this.projectionScreenMatrix,
|
|
1559
|
+
desiredDensity: r,
|
|
1560
|
+
canvasHeight: x,
|
|
1561
|
+
currentLevel: s.lastLodLevel_Mesh,
|
|
1562
|
+
boundingBox: v,
|
|
1563
|
+
xrEnabled: this.renderer.xr.enabled,
|
|
1564
|
+
debugDrawLine: A ? R.debugDrawLine : void 0,
|
|
1565
|
+
warnMissingPrimitiveDensities: !0
|
|
1566
|
+
});
|
|
1567
|
+
if (s.lastCentrality = p.centrality, s.lastScreenCoverage = p.screenCoverage, s.lastScreenspaceVolume.copy(p.screenspaceVolume), p.screenCoverage === 1 / 0) {
|
|
1509
1568
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1510
1569
|
return;
|
|
1511
1570
|
}
|
|
1512
|
-
|
|
1513
|
-
const d = this._tempBox.min, g = this._tempBox.max;
|
|
1514
|
-
let w = d.x, v = d.y, O = g.x, Y = g.y;
|
|
1515
|
-
const te = 2, ie = 1.5, se = (d.x + g.x) * 0.5, re = (d.y + g.y) * 0.5;
|
|
1516
|
-
w = (w - se) * te + se, v = (v - re) * te + re, O = (O - se) * te + se, Y = (Y - re) * te + re;
|
|
1517
|
-
const We = w < 0 && O > 0 ? 0 : Math.min(Math.abs(d.x), Math.abs(g.x)), Fe = v < 0 && Y > 0 ? 0 : Math.min(Math.abs(d.y), Math.abs(g.y)), ae = Math.max(We, Fe);
|
|
1518
|
-
s.lastCentrality = (ie - ae) * (ie - ae) * (ie - ae);
|
|
1519
|
-
} else
|
|
1520
|
-
s.lastCentrality = 1;
|
|
1521
|
-
const m = this._tempBox.getSize(this._tempBoxSize);
|
|
1522
|
-
m.multiplyScalar(0.5), screen.availHeight > 0 && _ > 0 && m.multiplyScalar(_ / screen.availHeight), t.isPerspectiveCamera ? m.x *= t.aspect : t.isOrthographicCamera;
|
|
1523
|
-
const B = t.matrixWorldInverse, G = this._tempBox2;
|
|
1524
|
-
G.copy(C), G.applyMatrix4(e.matrixWorld), G.applyMatrix4(B);
|
|
1525
|
-
const A = G.getSize(this._tempBox2Size), S = Math.max(A.x, A.y);
|
|
1526
|
-
if (Math.max(m.x, m.y) != 0 && S != 0 && (m.z = A.z / Math.max(A.x, A.y) * Math.max(m.x, m.y)), s.lastScreenCoverage = Math.max(m.x, m.y, m.z), s.lastScreenspaceVolume.copy(m), s.lastScreenCoverage *= s.lastCentrality, R && L.debugDrawLine) {
|
|
1527
|
-
const d = this.tempMatrix.copy(this.projectionScreenMatrix);
|
|
1528
|
-
d.invert();
|
|
1529
|
-
const g = L.corner0, w = L.corner1, v = L.corner2, O = L.corner3;
|
|
1530
|
-
g.copy(this._tempBox.min), w.copy(this._tempBox.max), w.x = g.x, v.copy(this._tempBox.max), v.y = g.y, O.copy(this._tempBox.max);
|
|
1531
|
-
const Y = (g.z + O.z) * 0.5;
|
|
1532
|
-
g.z = w.z = v.z = O.z = Y, g.applyMatrix4(d), w.applyMatrix4(d), v.applyMatrix4(d), O.applyMatrix4(d), L.debugDrawLine(g, w, 255), L.debugDrawLine(g, v, 255), L.debugDrawLine(w, O, 255), L.debugDrawLine(v, O, 255);
|
|
1533
|
-
}
|
|
1534
|
-
let M = 999;
|
|
1535
|
-
if (l && s.lastScreenCoverage > 0)
|
|
1536
|
-
for (let d = 0; d < l.length; d++) {
|
|
1537
|
-
const g = l[d], v = (g.densities?.[c] || g.density || 1e-5) / s.lastScreenCoverage;
|
|
1538
|
-
if (c > 0 && Me() && !g.densities && !globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] && (window["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 < r) {
|
|
1539
|
-
M = d;
|
|
1540
|
-
break;
|
|
1541
|
-
}
|
|
1542
|
-
}
|
|
1543
|
-
M < u && (u = M, a = !0);
|
|
1571
|
+
p.level >= 0 && p.level < u && (u = p.level, a = !0);
|
|
1544
1572
|
}
|
|
1545
|
-
if (a ? n.mesh_lod = u : n.mesh_lod = s.lastLodLevel_Mesh,
|
|
1546
|
-
const
|
|
1547
|
-
|
|
1573
|
+
if (a ? n.mesh_lod = u : n.mesh_lod = s.lastLodLevel_Mesh, A && n.mesh_lod != s.lastLodLevel_Mesh) {
|
|
1574
|
+
const _ = l?.[n.mesh_lod];
|
|
1575
|
+
_ && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${_.densities?.[c].toFixed(0)}) | ${e.name}`);
|
|
1548
1576
|
}
|
|
1549
|
-
if (
|
|
1550
|
-
const
|
|
1577
|
+
if (m) {
|
|
1578
|
+
const p = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
|
|
1551
1579
|
if (s.lastLodLevel_Texture < 0) {
|
|
1552
|
-
if (n.texture_lod =
|
|
1553
|
-
const
|
|
1554
|
-
|
|
1580
|
+
if (n.texture_lod = g.max_count - 1, A) {
|
|
1581
|
+
const _ = g.lods[g.max_count - 1];
|
|
1582
|
+
A && console.log(`First Texture LOD ${n.texture_lod} (${_.max_height}px) - ${e.name}`);
|
|
1555
1583
|
}
|
|
1556
1584
|
} else {
|
|
1557
|
-
const
|
|
1558
|
-
let
|
|
1559
|
-
this.context?.engine === "model-viewer" && (
|
|
1560
|
-
const
|
|
1561
|
-
let
|
|
1562
|
-
for (let
|
|
1563
|
-
const
|
|
1564
|
-
if (!(
|
|
1565
|
-
if (
|
|
1566
|
-
const
|
|
1567
|
-
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${
|
|
1568
|
-
Screensize: ${
|
|
1585
|
+
const _ = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
|
|
1586
|
+
let C = s.lastScreenCoverage * 4;
|
|
1587
|
+
this.context?.engine === "model-viewer" && (C *= 1.5);
|
|
1588
|
+
const L = x / window.devicePixelRatio * C;
|
|
1589
|
+
let w = !1;
|
|
1590
|
+
for (let S = g.lods.length - 1; S >= 0; S--) {
|
|
1591
|
+
const O = g.lods[S];
|
|
1592
|
+
if (!(p && O.max_height >= 2048) && !(ve() && O.max_height > 4096) && (O.max_height > L || !w && S === 0)) {
|
|
1593
|
+
if (w = !0, n.texture_lod = S, A && n.texture_lod < s.lastLodLevel_Texture) {
|
|
1594
|
+
const D = O.max_height;
|
|
1595
|
+
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${D}px
|
|
1596
|
+
Screensize: ${L.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${_.toFixed(1)}
|
|
1569
1597
|
${e.name}`);
|
|
1570
1598
|
}
|
|
1571
1599
|
break;
|
|
@@ -1576,61 +1604,61 @@ ${e.name}`);
|
|
|
1576
1604
|
n.texture_lod = 0;
|
|
1577
1605
|
}
|
|
1578
1606
|
}
|
|
1579
|
-
class
|
|
1607
|
+
class St {
|
|
1580
1608
|
frames = 0;
|
|
1581
1609
|
lastLodLevel_Mesh = -1;
|
|
1582
1610
|
lastLodLevel_Texture = -1;
|
|
1583
1611
|
lastScreenCoverage = 0;
|
|
1584
|
-
lastScreenspaceVolume = new
|
|
1612
|
+
lastScreenspaceVolume = new k();
|
|
1585
1613
|
lastCentrality = 0;
|
|
1586
1614
|
}
|
|
1587
|
-
function
|
|
1615
|
+
function Ge(i, t) {
|
|
1588
1616
|
if (!(t < 0)) {
|
|
1589
1617
|
if (Array.isArray(i)) {
|
|
1590
1618
|
for (const e of i)
|
|
1591
|
-
|
|
1619
|
+
Ge(e, t);
|
|
1592
1620
|
return;
|
|
1593
1621
|
}
|
|
1594
|
-
"color" in i && i.color instanceof
|
|
1622
|
+
"color" in i && i.color instanceof Ce && (i.color.copy(Ct(t, _t)), i.needsUpdate = !0);
|
|
1595
1623
|
}
|
|
1596
1624
|
}
|
|
1597
|
-
function
|
|
1598
|
-
const e = Math.max(0, Math.min(
|
|
1599
|
-
return t.setHex(
|
|
1625
|
+
function Ct(i, t) {
|
|
1626
|
+
const e = Math.max(0, Math.min(Me.length - 1, Math.floor(i)));
|
|
1627
|
+
return t.setHex(Me[e]);
|
|
1600
1628
|
}
|
|
1601
|
-
const
|
|
1602
|
-
let
|
|
1603
|
-
function
|
|
1604
|
-
const i =
|
|
1629
|
+
const be = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), ie = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
|
|
1630
|
+
let pe = null;
|
|
1631
|
+
function We() {
|
|
1632
|
+
const i = Pt();
|
|
1605
1633
|
i && (i.mapURLs(function(t) {
|
|
1606
|
-
return
|
|
1607
|
-
}),
|
|
1634
|
+
return Oe(), t;
|
|
1635
|
+
}), Oe(), pe?.disconnect(), pe = new MutationObserver((t) => {
|
|
1608
1636
|
t.forEach((e) => {
|
|
1609
1637
|
e.addedNodes.forEach((s) => {
|
|
1610
|
-
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" &&
|
|
1638
|
+
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Ue(s);
|
|
1611
1639
|
});
|
|
1612
1640
|
});
|
|
1613
|
-
}),
|
|
1641
|
+
}), pe.observe(document, { childList: !0, subtree: !0 }));
|
|
1614
1642
|
}
|
|
1615
|
-
function
|
|
1643
|
+
function Pt() {
|
|
1616
1644
|
if (typeof customElements > "u") return null;
|
|
1617
1645
|
const i = customElements.get("model-viewer");
|
|
1618
1646
|
return i || (customElements.whenDefined("model-viewer").then(() => {
|
|
1619
|
-
console.debug("[gltf-progressive] model-viewer defined"),
|
|
1647
|
+
console.debug("[gltf-progressive] model-viewer defined"), We();
|
|
1620
1648
|
}), null);
|
|
1621
1649
|
}
|
|
1622
|
-
function
|
|
1650
|
+
function Oe() {
|
|
1623
1651
|
if (typeof document > "u") return;
|
|
1624
1652
|
document.querySelectorAll("model-viewer").forEach((t) => {
|
|
1625
|
-
|
|
1653
|
+
Ue(t);
|
|
1626
1654
|
});
|
|
1627
1655
|
}
|
|
1628
|
-
const
|
|
1629
|
-
let
|
|
1630
|
-
function
|
|
1631
|
-
if (!i ||
|
|
1656
|
+
const Te = /* @__PURE__ */ new WeakSet();
|
|
1657
|
+
let kt = 0;
|
|
1658
|
+
function Ue(i) {
|
|
1659
|
+
if (!i || Te.has(i))
|
|
1632
1660
|
return null;
|
|
1633
|
-
|
|
1661
|
+
Te.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++kt + `
|
|
1634
1662
|
`, i.getAttribute("src"));
|
|
1635
1663
|
let t = null, e = null, s = null;
|
|
1636
1664
|
for (let r = i; r != null; r = Object.getPrototypeOf(r)) {
|
|
@@ -1651,8 +1679,8 @@ function Ge(i) {
|
|
|
1651
1679
|
}
|
|
1652
1680
|
};
|
|
1653
1681
|
console.debug("[gltf-progressive] setup model-viewer");
|
|
1654
|
-
const n =
|
|
1655
|
-
return
|
|
1682
|
+
const n = R.get(t, { engine: "model-viewer" });
|
|
1683
|
+
return R.addPlugin(new At()), n.enable(), n.addEventListener("changed", () => {
|
|
1656
1684
|
s?.call(i);
|
|
1657
1685
|
}), i.addEventListener("model-visibility", (o) => {
|
|
1658
1686
|
o.detail.visible && s?.call(i);
|
|
@@ -1664,7 +1692,7 @@ function Ge(i) {
|
|
|
1664
1692
|
}
|
|
1665
1693
|
return null;
|
|
1666
1694
|
}
|
|
1667
|
-
class
|
|
1695
|
+
class At {
|
|
1668
1696
|
_didWarnAboutMissingUrl = !1;
|
|
1669
1697
|
onBeforeUpdateLOD(t, e, s, r) {
|
|
1670
1698
|
this.tryParseMeshLOD(e, r), this.tryParseTextureLOD(e, r);
|
|
@@ -1682,27 +1710,27 @@ class Dt {
|
|
|
1682
1710
|
return t.element;
|
|
1683
1711
|
}
|
|
1684
1712
|
tryParseTextureLOD(t, e) {
|
|
1685
|
-
if (e[
|
|
1686
|
-
e[
|
|
1713
|
+
if (e[ie] == !0) return;
|
|
1714
|
+
e[ie] = !0;
|
|
1687
1715
|
const s = this.tryGetCurrentGLTF(t), r = this.tryGetCurrentModelViewer(t), n = this.getUrl(r);
|
|
1688
1716
|
if (n && s && e.material) {
|
|
1689
1717
|
let o = function(a) {
|
|
1690
|
-
if (a[
|
|
1691
|
-
a[
|
|
1718
|
+
if (a[ie] == !0) return;
|
|
1719
|
+
a[ie] = !0, a.userData && (a.userData.LOD = -1);
|
|
1692
1720
|
const l = Object.keys(a);
|
|
1693
1721
|
for (let c = 0; c < l.length; c++) {
|
|
1694
|
-
const
|
|
1695
|
-
if (
|
|
1696
|
-
const
|
|
1697
|
-
if (
|
|
1698
|
-
const
|
|
1699
|
-
if (!
|
|
1700
|
-
console.warn("Texture data not found for texture index " +
|
|
1722
|
+
const d = l[c], g = a[d];
|
|
1723
|
+
if (g?.isTexture === !0) {
|
|
1724
|
+
const m = g.userData?.associations?.textures;
|
|
1725
|
+
if (m == null) continue;
|
|
1726
|
+
const x = s.parser.json.textures[m];
|
|
1727
|
+
if (!x) {
|
|
1728
|
+
console.warn("Texture data not found for texture index " + m);
|
|
1701
1729
|
continue;
|
|
1702
1730
|
}
|
|
1703
|
-
if (
|
|
1704
|
-
const
|
|
1705
|
-
|
|
1731
|
+
if (x?.extensions?.[F]) {
|
|
1732
|
+
const v = x.extensions[F];
|
|
1733
|
+
v && n && h.registerTexture(n, g, v.lods.length, m, v);
|
|
1706
1734
|
}
|
|
1707
1735
|
}
|
|
1708
1736
|
}
|
|
@@ -1713,19 +1741,19 @@ class Dt {
|
|
|
1713
1741
|
}
|
|
1714
1742
|
}
|
|
1715
1743
|
tryParseMeshLOD(t, e) {
|
|
1716
|
-
if (e[
|
|
1717
|
-
e[
|
|
1744
|
+
if (e[be] == !0) return;
|
|
1745
|
+
e[be] = !0;
|
|
1718
1746
|
const s = this.tryGetCurrentModelViewer(t), r = this.getUrl(s);
|
|
1719
1747
|
if (!r)
|
|
1720
1748
|
return;
|
|
1721
|
-
const n = e.userData?.gltfExtensions?.[
|
|
1749
|
+
const n = e.userData?.gltfExtensions?.[F];
|
|
1722
1750
|
if (n && r) {
|
|
1723
1751
|
const o = e.uuid;
|
|
1724
|
-
|
|
1752
|
+
h.registerMesh(r, o, e, 0, n.lods.length, n);
|
|
1725
1753
|
}
|
|
1726
1754
|
}
|
|
1727
1755
|
}
|
|
1728
|
-
function
|
|
1756
|
+
function Rt(...i) {
|
|
1729
1757
|
let t, e, s, r;
|
|
1730
1758
|
switch (i.length) {
|
|
1731
1759
|
case 2:
|
|
@@ -1740,22 +1768,22 @@ function Tt(...i) {
|
|
|
1740
1768
|
default:
|
|
1741
1769
|
throw new Error("Invalid arguments");
|
|
1742
1770
|
}
|
|
1743
|
-
|
|
1771
|
+
Le(e), Ae(s), Ie(s, {
|
|
1744
1772
|
progressive: !0,
|
|
1745
1773
|
...r?.hints
|
|
1746
|
-
}), s.register((o) => new
|
|
1747
|
-
const n =
|
|
1774
|
+
}), s.register((o) => new h(o));
|
|
1775
|
+
const n = R.get(e);
|
|
1748
1776
|
return r?.enableLODsManager !== !1 && n.enable(), n;
|
|
1749
1777
|
}
|
|
1750
|
-
|
|
1751
|
-
if (!
|
|
1778
|
+
We();
|
|
1779
|
+
if (!ct) {
|
|
1752
1780
|
const i = {
|
|
1753
1781
|
gltfProgressive: {
|
|
1754
|
-
useNeedleProgressive:
|
|
1755
|
-
LODsManager:
|
|
1756
|
-
configureLoader:
|
|
1757
|
-
getRaycastMesh:
|
|
1758
|
-
useRaycastMeshes:
|
|
1782
|
+
useNeedleProgressive: Rt,
|
|
1783
|
+
LODsManager: R,
|
|
1784
|
+
configureLoader: Ie,
|
|
1785
|
+
getRaycastMesh: ne,
|
|
1786
|
+
useRaycastMeshes: ft
|
|
1759
1787
|
}
|
|
1760
1788
|
};
|
|
1761
1789
|
if (!globalThis.Needle)
|
|
@@ -1765,20 +1793,21 @@ if (!lt) {
|
|
|
1765
1793
|
globalThis.Needle[t] = i[t];
|
|
1766
1794
|
}
|
|
1767
1795
|
export {
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1796
|
+
F as EXTENSION_NAME,
|
|
1797
|
+
R as LODsManager,
|
|
1798
|
+
h as NEEDLE_progressive,
|
|
1799
|
+
Je as VERSION,
|
|
1800
|
+
Ae as addDracoAndKTX2Loaders,
|
|
1801
|
+
Tt as calculateMeshLODLevel,
|
|
1802
|
+
Ie as configureLoader,
|
|
1803
|
+
Le as createLoaders,
|
|
1804
|
+
Ct as getLODColor,
|
|
1805
|
+
ne as getRaycastMesh,
|
|
1806
|
+
Me as lodDebugColors,
|
|
1807
|
+
We as patchModelViewer,
|
|
1808
|
+
dt as registerRaycastMesh,
|
|
1809
|
+
st as setDracoDecoderLocation,
|
|
1810
|
+
rt as setKTX2TranscoderLocation,
|
|
1811
|
+
Rt as useNeedleProgressive,
|
|
1812
|
+
ft as useRaycastMeshes
|
|
1784
1813
|
};
|