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