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