@needle-tools/engine 5.1.12 → 5.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/SKILL.md +1 -1
- package/dist/gltf-progressive-BnLTsXZw.umd.cjs +10 -0
- package/dist/gltf-progressive-D6RT9IkB.min.js +10 -0
- package/dist/{gltf-progressive-B4DQEeBz.js → gltf-progressive-DaeP5KBr.js} +527 -514
- package/dist/{needle-engine.bundle-DdH96IqH.umd.cjs → needle-engine.bundle-B_ZctaDt.umd.cjs} +146 -146
- package/dist/{needle-engine.bundle-BmdWLmLa.min.js → needle-engine.bundle-DR967VjU.min.js} +145 -145
- package/dist/{needle-engine.bundle-9m-VdGg2.js → needle-engine.bundle-DTvJ1zCJ.js} +7302 -7153
- package/dist/needle-engine.d.ts +23 -15
- package/dist/needle-engine.js +517 -518
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/api.d.ts +4 -3
- package/lib/engine/api.js +3 -9
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/engine_addressables.d.ts +32 -1
- package/lib/engine/engine_addressables.js +71 -9
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_application.d.ts +2 -0
- package/lib/engine/engine_application.js +7 -3
- package/lib/engine/engine_application.js.map +1 -1
- package/lib/engine/engine_context.js +25 -1
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_init.js +2 -2
- package/lib/engine/engine_input.js +1 -1
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_license.d.ts +7 -7
- package/lib/engine/engine_license.js +121 -78
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_lifecycle_functions_internal.js +20 -2
- package/lib/engine/engine_lifecycle_functions_internal.js.map +1 -1
- package/lib/engine/engine_networking_blob.js +3 -3
- package/lib/engine/engine_networking_blob.js.map +1 -1
- package/lib/engine/engine_networking_streams.d.ts +3 -0
- package/lib/engine/engine_networking_streams.js +64 -17
- package/lib/engine/engine_networking_streams.js.map +1 -1
- package/lib/engine/engine_utils_qrcode.js +2 -2
- package/lib/engine/engine_utils_qrcode.js.map +1 -1
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +5 -0
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js.map +1 -1
- package/lib/engine/webcomponents/fonts.d.ts +1 -1
- package/lib/engine/webcomponents/fonts.js +16 -1
- package/lib/engine/webcomponents/fonts.js.map +1 -1
- package/lib/engine/webcomponents/icons.js +8 -1
- package/lib/engine/webcomponents/icons.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +2 -2
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +5 -0
- package/lib/engine/webcomponents/needle menu/needle-menu.js +34 -16
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +1 -0
- package/lib/engine/webcomponents/needle-engine.js +18 -6
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.loading.d.ts +2 -0
- package/lib/engine/webcomponents/needle-engine.loading.js +12 -2
- package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
- package/lib/engine/xr/TempXRContext.js +2 -2
- package/lib/engine/xr/TempXRContext.js.map +1 -1
- package/lib/engine-components/export/usdz/USDZExporter.js +4 -4
- package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
- package/package.json +2 -2
- package/plugins/common/license.js +4 -4
- package/plugins/vite/license.js +4 -4
- package/src/engine/api.ts +5 -3
- package/src/engine/engine_addressables.ts +75 -9
- package/src/engine/engine_application.ts +7 -2
- package/src/engine/engine_context.ts +25 -1
- package/src/engine/engine_init.ts +2 -2
- package/src/engine/engine_input.ts +2 -2
- package/src/engine/engine_license.ts +113 -75
- package/src/engine/engine_lifecycle_functions_internal.ts +21 -2
- package/src/engine/engine_networking_blob.ts +3 -3
- package/src/engine/engine_networking_streams.ts +61 -17
- package/src/engine/engine_utils_qrcode.ts +2 -2
- package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +8 -1
- package/src/engine/webcomponents/fonts.ts +16 -1
- package/src/engine/webcomponents/icons.ts +8 -1
- package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +2 -2
- package/src/engine/webcomponents/needle menu/needle-menu.ts +33 -15
- package/src/engine/webcomponents/needle-engine.loading.ts +19 -7
- package/src/engine/webcomponents/needle-engine.ts +16 -6
- package/src/engine/xr/TempXRContext.ts +2 -2
- package/src/engine-components/export/usdz/USDZExporter.ts +4 -4
- package/dist/gltf-progressive-CdjpU5eP.min.js +0 -10
- package/dist/gltf-progressive-DeZioRZe.umd.cjs +0 -10
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
import { RedFormat as je, RedIntegerFormat as He, RGFormat as Ke, RGIntegerFormat as Ye, RGBFormat as Qe, RGBAFormat as Je, RGBAIntegerFormat as Ze, BufferGeometry as
|
|
2
|
-
import { DRACOLoader as at, KTX2Loader as lt, MeshoptDecoder as ut, GLTFLoader as
|
|
1
|
+
import { RedFormat as je, RedIntegerFormat as He, RGFormat as Ke, RGIntegerFormat as Ye, RGBFormat as Qe, RGBAFormat as Je, RGBAIntegerFormat as Ze, BufferGeometry as K, Mesh as Y, Box3 as de, Vector3 as A, Sphere as $e, CompressedTexture as et, Texture as q, Matrix3 as tt, InterleavedBuffer as st, InterleavedBufferAttribute as rt, BufferAttribute as nt, TextureLoader as it, Matrix4 as Ge, THREE as ot, Color as Be } from "./three-core.js";
|
|
2
|
+
import { DRACOLoader as at, KTX2Loader as lt, MeshoptDecoder as ut, GLTFLoader as _e } from "./three-examples.js";
|
|
3
3
|
const ct = "";
|
|
4
4
|
globalThis.GLTF_PROGRESSIVE_VERSION = ct;
|
|
5
5
|
console.debug("[gltf-progressive] version -");
|
|
6
|
-
let
|
|
7
|
-
const ft =
|
|
8
|
-
|
|
9
|
-
fetch(
|
|
6
|
+
let G = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", Q = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
|
|
7
|
+
const ft = G, dt = Q, qe = new URL(G + "draco_decoder.js");
|
|
8
|
+
qe.searchParams.append("range", "true");
|
|
9
|
+
fetch(qe, {
|
|
10
10
|
method: "GET",
|
|
11
11
|
headers: {
|
|
12
12
|
Range: "bytes=0-1"
|
|
13
13
|
}
|
|
14
14
|
}).catch((i) => {
|
|
15
|
-
console.debug(`Failed to fetch remote Draco decoder from ${
|
|
15
|
+
console.debug(`Failed to fetch remote Draco decoder from ${G} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), G === ft && gt("./include/draco/"), Q === dt && pt("./include/ktx2/");
|
|
16
16
|
}).finally(() => {
|
|
17
|
-
|
|
17
|
+
Fe();
|
|
18
18
|
});
|
|
19
19
|
const ht = () => ({
|
|
20
|
-
dracoDecoderPath:
|
|
21
|
-
ktx2TranscoderPath:
|
|
20
|
+
dracoDecoderPath: G,
|
|
21
|
+
ktx2TranscoderPath: Q
|
|
22
22
|
});
|
|
23
23
|
function gt(i) {
|
|
24
|
-
|
|
24
|
+
G = i, P && P[Le] != G ? (console.debug("Updating Draco decoder path to " + i), P[Le] = G, P.setDecoderPath(G), P.preload()) : console.debug("Setting Draco decoder path to " + i);
|
|
25
25
|
}
|
|
26
26
|
function pt(i) {
|
|
27
|
-
|
|
27
|
+
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);
|
|
28
28
|
}
|
|
29
|
-
function
|
|
30
|
-
return
|
|
29
|
+
function be(i) {
|
|
30
|
+
return Fe(), i ? B.detectSupport(i) : i !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: P, ktx2Loader: B, meshoptDecoder: ce };
|
|
31
31
|
}
|
|
32
|
-
function
|
|
33
|
-
i.dracoLoader || i.setDRACOLoader(P), i.ktx2Loader || i.setKTX2Loader(
|
|
32
|
+
function We(i) {
|
|
33
|
+
i.dracoLoader || i.setDRACOLoader(P), i.ktx2Loader || i.setKTX2Loader(B), i.meshoptDecoder || i.setMeshoptDecoder(ce);
|
|
34
34
|
}
|
|
35
|
-
const
|
|
36
|
-
let P,
|
|
37
|
-
function
|
|
38
|
-
P || (P = new at(), P[
|
|
35
|
+
const Le = /* @__PURE__ */ Symbol("dracoDecoderPath");
|
|
36
|
+
let P, ce, B;
|
|
37
|
+
function Fe() {
|
|
38
|
+
P || (P = new at(), P[Le] = G, P.setDecoderPath(G), P.setDecoderConfig({ type: "js" }), P.preload()), B || (B = new lt(), B.setTranscoderPath(Q), B.init()), ce || (ce = ut);
|
|
39
39
|
}
|
|
40
|
-
const
|
|
41
|
-
function
|
|
42
|
-
let e =
|
|
43
|
-
e ? e = Object.assign(e, t) : e = t,
|
|
40
|
+
const we = /* @__PURE__ */ new WeakMap();
|
|
41
|
+
function Ue(i, t) {
|
|
42
|
+
let e = we.get(i);
|
|
43
|
+
e ? e = Object.assign(e, t) : e = t, we.set(i, e);
|
|
44
44
|
}
|
|
45
|
-
const mt =
|
|
45
|
+
const mt = _e.prototype.load;
|
|
46
46
|
function yt(...i) {
|
|
47
|
-
const t =
|
|
47
|
+
const t = we.get(this);
|
|
48
48
|
let e = i[0];
|
|
49
49
|
const s = xt(e);
|
|
50
50
|
if (s?.hostname.endsWith("needle.tools")) {
|
|
@@ -53,7 +53,7 @@ function yt(...i) {
|
|
|
53
53
|
}
|
|
54
54
|
return i[0] = e, mt?.call(this, ...i);
|
|
55
55
|
}
|
|
56
|
-
|
|
56
|
+
_e.prototype.load = yt;
|
|
57
57
|
function xt(i) {
|
|
58
58
|
try {
|
|
59
59
|
if (i instanceof URL)
|
|
@@ -64,10 +64,10 @@ function xt(i) {
|
|
|
64
64
|
return null;
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
function
|
|
67
|
+
function Se(i) {
|
|
68
68
|
return i != null && i.data != null;
|
|
69
69
|
}
|
|
70
|
-
function
|
|
70
|
+
function De(i) {
|
|
71
71
|
const t = i.source?.data;
|
|
72
72
|
return t != null && typeof t == "object" ? t : null;
|
|
73
73
|
}
|
|
@@ -75,15 +75,15 @@ function Lt(i) {
|
|
|
75
75
|
const t = i.image;
|
|
76
76
|
return t != null && typeof t == "object" ? t : null;
|
|
77
77
|
}
|
|
78
|
-
function
|
|
79
|
-
const t = Lt(i), e =
|
|
78
|
+
function ve(i) {
|
|
79
|
+
const t = Lt(i), e = De(i);
|
|
80
80
|
return {
|
|
81
81
|
width: t?.width || e?.width || 0,
|
|
82
82
|
height: t?.height || e?.height || 0
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
|
|
86
|
-
function
|
|
85
|
+
V("debugprogressive");
|
|
86
|
+
function V(i) {
|
|
87
87
|
const t = globalThis.location?.href;
|
|
88
88
|
if (!t) return !1;
|
|
89
89
|
const s = new URL(t).searchParams.get(i);
|
|
@@ -100,13 +100,13 @@ function wt(i, t) {
|
|
|
100
100
|
}
|
|
101
101
|
return t;
|
|
102
102
|
}
|
|
103
|
-
function
|
|
104
|
-
if (
|
|
103
|
+
function Oe() {
|
|
104
|
+
if (se !== void 0) return se;
|
|
105
105
|
const i = globalThis.navigator?.userAgent || "";
|
|
106
|
-
return
|
|
106
|
+
return se = /iPhone|iPad|iPod|Android|IEMobile/i.test(i), V("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", se), se;
|
|
107
107
|
}
|
|
108
|
-
let
|
|
109
|
-
function
|
|
108
|
+
let se;
|
|
109
|
+
function ze() {
|
|
110
110
|
const i = globalThis.location?.href;
|
|
111
111
|
if (!i) return !1;
|
|
112
112
|
const t = new URL(i), e = t.hostname === "localhost" || /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(t.hostname);
|
|
@@ -158,71 +158,71 @@ function Mt(i) {
|
|
|
158
158
|
const r = i.type;
|
|
159
159
|
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;
|
|
160
160
|
}
|
|
161
|
-
const _t = typeof window > "u" && typeof document > "u",
|
|
162
|
-
function
|
|
163
|
-
return i?.[
|
|
161
|
+
const _t = typeof window > "u" && typeof document > "u", Me = /* @__PURE__ */ Symbol("needle:raycast-mesh");
|
|
162
|
+
function ae(i) {
|
|
163
|
+
return i?.[Me] instanceof K ? i[Me] : null;
|
|
164
164
|
}
|
|
165
165
|
function bt(i, t) {
|
|
166
|
-
if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !
|
|
166
|
+
if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !ae(i)) {
|
|
167
167
|
const s = Tt(t);
|
|
168
|
-
s.userData = { isRaycastMesh: !0 }, i[
|
|
168
|
+
s.userData = { isRaycastMesh: !0 }, i[Me] = s;
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
function Ot(i = !0) {
|
|
172
172
|
if (i) {
|
|
173
|
-
if (
|
|
174
|
-
const t =
|
|
175
|
-
|
|
176
|
-
const r = this, n =
|
|
173
|
+
if (re) return;
|
|
174
|
+
const t = re = Y.prototype.raycast;
|
|
175
|
+
Y.prototype.raycast = function(e, s) {
|
|
176
|
+
const r = this, n = ae(r);
|
|
177
177
|
let o;
|
|
178
178
|
n && r.isMesh && (o = r.geometry, r.geometry = n), t.call(this, e, s), o && (r.geometry = o);
|
|
179
179
|
};
|
|
180
180
|
} else {
|
|
181
|
-
if (!
|
|
182
|
-
|
|
181
|
+
if (!re) return;
|
|
182
|
+
Y.prototype.raycast = re, re = null;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
let
|
|
185
|
+
let re = null;
|
|
186
186
|
function Tt(i) {
|
|
187
|
-
const t = new
|
|
187
|
+
const t = new K();
|
|
188
188
|
for (const e in i.attributes)
|
|
189
189
|
t.setAttribute(e, i.getAttribute(e));
|
|
190
190
|
return t.setIndex(i.getIndex()), t;
|
|
191
191
|
}
|
|
192
|
-
const
|
|
193
|
-
let
|
|
194
|
-
if (
|
|
192
|
+
const F = new Array(), g = V("debugprogressive");
|
|
193
|
+
let oe, j = -1;
|
|
194
|
+
if (g && typeof window < "u") {
|
|
195
195
|
let i = function() {
|
|
196
|
-
|
|
196
|
+
j += 1, j >= t && (j = -1), console.log(`Toggle LOD level [${j}]`);
|
|
197
197
|
};
|
|
198
198
|
const t = 6;
|
|
199
199
|
window.addEventListener("keyup", (e) => {
|
|
200
|
-
e.key === "p" && i(), e.key === "w" && (
|
|
200
|
+
e.key === "p" && i(), e.key === "w" && (oe = !oe, console.log(`Toggle wireframe [${oe}]`));
|
|
201
201
|
const s = parseInt(e.key);
|
|
202
|
-
!isNaN(s) && s >= 0 && (
|
|
202
|
+
!isNaN(s) && s >= 0 && (j = s, console.log(`Set LOD level to [${j}]`));
|
|
203
203
|
});
|
|
204
204
|
}
|
|
205
|
-
function
|
|
206
|
-
if (
|
|
205
|
+
function Ee(i) {
|
|
206
|
+
if (g && oe !== void 0)
|
|
207
207
|
if (Array.isArray(i))
|
|
208
208
|
for (const t of i)
|
|
209
|
-
|
|
210
|
-
else i && "wireframe" in i && (i.wireframe =
|
|
209
|
+
Ee(t);
|
|
210
|
+
else i && "wireframe" in i && (i.wireframe = oe === !0);
|
|
211
211
|
}
|
|
212
|
-
const
|
|
212
|
+
const ne = new Array();
|
|
213
213
|
let St = 0;
|
|
214
|
-
const Rt =
|
|
214
|
+
const Rt = Oe() ? 2 : 10;
|
|
215
215
|
function Pt(i) {
|
|
216
|
-
if (
|
|
217
|
-
const s =
|
|
218
|
-
|
|
219
|
-
const r =
|
|
220
|
-
return
|
|
221
|
-
}
|
|
222
|
-
const t = St++ %
|
|
223
|
-
return
|
|
216
|
+
if (ne.length < Rt) {
|
|
217
|
+
const s = ne.length;
|
|
218
|
+
g && console.warn(`[Worker] Creating new worker #${s}`);
|
|
219
|
+
const r = Te.createWorker(i || {});
|
|
220
|
+
return ne.push(r), r;
|
|
221
|
+
}
|
|
222
|
+
const t = St++ % ne.length;
|
|
223
|
+
return ne[t];
|
|
224
224
|
}
|
|
225
|
-
class
|
|
225
|
+
class Te {
|
|
226
226
|
constructor(t, e) {
|
|
227
227
|
this.worker = t, this._debug = e.debug ?? !1, t.onmessage = (s) => {
|
|
228
228
|
const r = s.data;
|
|
@@ -245,7 +245,7 @@ class Oe {
|
|
|
245
245
|
const e = /* new-worker */ new Worker(URL.createObjectURL(new Blob(["import '" + `${new URL('./gltf-progressive.worker-BqODMeeW.js', import.meta.url).toString()}` + "';"], { type: 'text/javascript' })), {
|
|
246
246
|
type: "module"
|
|
247
247
|
});
|
|
248
|
-
return new
|
|
248
|
+
return new Te(e, t);
|
|
249
249
|
}
|
|
250
250
|
_running = [];
|
|
251
251
|
_webglRenderer = null;
|
|
@@ -253,10 +253,10 @@ class Oe {
|
|
|
253
253
|
const s = ht();
|
|
254
254
|
let r = e?.renderer;
|
|
255
255
|
r || (this._webglRenderer ??= (async () => {
|
|
256
|
-
const { WebGLRenderer: u } = await import("./three-core.js").then((
|
|
256
|
+
const { WebGLRenderer: u } = await import("./three-core.js").then((d) => d.THREE);
|
|
257
257
|
return new u();
|
|
258
258
|
})(), r = await this._webglRenderer);
|
|
259
|
-
const
|
|
259
|
+
const l = be(r).ktx2Loader.workerConfig;
|
|
260
260
|
if (t instanceof URL)
|
|
261
261
|
t = t.toString();
|
|
262
262
|
else if (t.startsWith("file:"))
|
|
@@ -265,14 +265,14 @@ class Oe {
|
|
|
265
265
|
const u = globalThis.location?.href;
|
|
266
266
|
u && (t = new URL(t, u).toString());
|
|
267
267
|
}
|
|
268
|
-
const
|
|
268
|
+
const a = {
|
|
269
269
|
type: "load",
|
|
270
270
|
url: t,
|
|
271
271
|
dracoDecoderPath: s.dracoDecoderPath,
|
|
272
272
|
ktx2TranscoderPath: s.ktx2TranscoderPath,
|
|
273
|
-
ktx2LoaderConfig:
|
|
273
|
+
ktx2LoaderConfig: l
|
|
274
274
|
};
|
|
275
|
-
return this._debug && console.debug("[Worker] Sending load request",
|
|
275
|
+
return this._debug && console.debug("[Worker] Sending load request", a), this.worker.postMessage(a), new Promise((u) => {
|
|
276
276
|
this._running.push({
|
|
277
277
|
url: t.toString(),
|
|
278
278
|
resolve: u
|
|
@@ -283,30 +283,30 @@ class Oe {
|
|
|
283
283
|
}
|
|
284
284
|
function Ct(i) {
|
|
285
285
|
for (const t of i.geometries) {
|
|
286
|
-
const e = t.geometry, s = new
|
|
286
|
+
const e = t.geometry, s = new K();
|
|
287
287
|
if (s.name = e.name || "", e.index) {
|
|
288
288
|
const r = e.index;
|
|
289
|
-
s.setIndex(
|
|
289
|
+
s.setIndex(he(r));
|
|
290
290
|
}
|
|
291
291
|
for (const r in e.attributes) {
|
|
292
|
-
const n = e.attributes[r], o =
|
|
292
|
+
const n = e.attributes[r], o = he(n);
|
|
293
293
|
s.setAttribute(r, o);
|
|
294
294
|
}
|
|
295
295
|
if (e.morphAttributes)
|
|
296
296
|
for (const r in e.morphAttributes) {
|
|
297
|
-
const o = e.morphAttributes[r].map((
|
|
297
|
+
const o = e.morphAttributes[r].map((l) => he(l));
|
|
298
298
|
s.morphAttributes[r] = o;
|
|
299
299
|
}
|
|
300
|
-
if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new
|
|
300
|
+
if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new de(), s.boundingBox.min = new A(
|
|
301
301
|
e.boundingBox?.min.x,
|
|
302
302
|
e.boundingBox?.min.y,
|
|
303
303
|
e.boundingBox?.min.z
|
|
304
|
-
), s.boundingBox.max = new
|
|
304
|
+
), s.boundingBox.max = new A(
|
|
305
305
|
e.boundingBox?.max.x,
|
|
306
306
|
e.boundingBox?.max.y,
|
|
307
307
|
e.boundingBox?.max.z
|
|
308
|
-
), s.boundingSphere = new
|
|
309
|
-
new
|
|
308
|
+
), s.boundingSphere = new $e(
|
|
309
|
+
new A(
|
|
310
310
|
e.boundingSphere?.center.x,
|
|
311
311
|
e.boundingSphere?.center.y,
|
|
312
312
|
e.boundingSphere?.center.z
|
|
@@ -321,7 +321,7 @@ function Ct(i) {
|
|
|
321
321
|
const e = t.texture;
|
|
322
322
|
let s = null;
|
|
323
323
|
if (e.isCompressedTexture) {
|
|
324
|
-
const r = e.mipmaps, { width: n, height: o } =
|
|
324
|
+
const r = e.mipmaps, { width: n, height: o } = ve(e);
|
|
325
325
|
s = new et(
|
|
326
326
|
r,
|
|
327
327
|
n,
|
|
@@ -337,7 +337,7 @@ function Ct(i) {
|
|
|
337
337
|
e.colorSpace
|
|
338
338
|
);
|
|
339
339
|
} else
|
|
340
|
-
s = new
|
|
340
|
+
s = new q(
|
|
341
341
|
e.image,
|
|
342
342
|
e.mapping,
|
|
343
343
|
e.wrapS,
|
|
@@ -357,7 +357,7 @@ function Ct(i) {
|
|
|
357
357
|
}
|
|
358
358
|
return i;
|
|
359
359
|
}
|
|
360
|
-
function
|
|
360
|
+
function he(i) {
|
|
361
361
|
let t = i;
|
|
362
362
|
if ("isInterleavedBufferAttribute" in i && i.isInterleavedBufferAttribute) {
|
|
363
363
|
const e = i.data, s = e.array, r = new st(s, e.stride);
|
|
@@ -365,13 +365,13 @@ function de(i) {
|
|
|
365
365
|
} else "isBufferAttribute" in i && i.isBufferAttribute && (t = new nt(i.array, i.itemSize, i.normalized), t.usage = i.usage, t.gpuType = i.gpuType, t.updateRanges = i.updateRanges);
|
|
366
366
|
return t;
|
|
367
367
|
}
|
|
368
|
-
const kt =
|
|
369
|
-
|
|
370
|
-
const
|
|
371
|
-
class
|
|
368
|
+
const kt = V("gltf-progressive-worker");
|
|
369
|
+
V("gltf-progressive-reduce-mipmaps");
|
|
370
|
+
const ie = V("gltf-progressive-gc"), ge = /* @__PURE__ */ Symbol("needle-progressive-texture"), U = "NEEDLE_progressive";
|
|
371
|
+
class p {
|
|
372
372
|
/** The name of the extension */
|
|
373
373
|
get name() {
|
|
374
|
-
return
|
|
374
|
+
return U;
|
|
375
375
|
}
|
|
376
376
|
// #region PUBLIC API
|
|
377
377
|
/**
|
|
@@ -413,33 +413,33 @@ class g {
|
|
|
413
413
|
max_count: 0,
|
|
414
414
|
lods: []
|
|
415
415
|
}), Array.isArray(t)) {
|
|
416
|
-
for (const
|
|
417
|
-
this.getMaterialMinMaxLODsCount(
|
|
416
|
+
for (const l of t)
|
|
417
|
+
this.getMaterialMinMaxLODsCount(l, e);
|
|
418
418
|
return t[r] = e, e;
|
|
419
419
|
}
|
|
420
|
-
if (
|
|
421
|
-
const
|
|
422
|
-
for (const
|
|
423
|
-
const u =
|
|
420
|
+
if (g === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
|
|
421
|
+
const l = t;
|
|
422
|
+
for (const a of Object.keys(l.uniforms)) {
|
|
423
|
+
const u = l.uniforms[a].value;
|
|
424
424
|
u?.isTexture === !0 && o(u, e);
|
|
425
425
|
}
|
|
426
426
|
} else if (t.isMaterial)
|
|
427
|
-
for (const
|
|
428
|
-
const
|
|
429
|
-
|
|
427
|
+
for (const l of Object.keys(t)) {
|
|
428
|
+
const a = t[l];
|
|
429
|
+
a?.isTexture === !0 && o(a, e);
|
|
430
430
|
}
|
|
431
431
|
else
|
|
432
|
-
|
|
432
|
+
g && console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);
|
|
433
433
|
return t[r] = e, e;
|
|
434
|
-
function o(
|
|
435
|
-
const u = s.getAssignedLODInformation(
|
|
434
|
+
function o(l, a) {
|
|
435
|
+
const u = s.getAssignedLODInformation(l);
|
|
436
436
|
if (u) {
|
|
437
|
-
const
|
|
438
|
-
if (
|
|
439
|
-
|
|
440
|
-
for (let
|
|
441
|
-
const
|
|
442
|
-
|
|
437
|
+
const d = s.lodInfos.get(u.key);
|
|
438
|
+
if (d && d.lods) {
|
|
439
|
+
a.min_count = Math.min(a.min_count, d.lods.length), a.max_count = Math.max(a.max_count, d.lods.length);
|
|
440
|
+
for (let c = 0; c < d.lods.length; c++) {
|
|
441
|
+
const f = d.lods[c];
|
|
442
|
+
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));
|
|
443
443
|
}
|
|
444
444
|
}
|
|
445
445
|
}
|
|
@@ -493,25 +493,25 @@ class g {
|
|
|
493
493
|
*/
|
|
494
494
|
static assignMeshLOD(t, e, s) {
|
|
495
495
|
if (!t) return Promise.resolve(null);
|
|
496
|
-
if (t instanceof
|
|
496
|
+
if (t instanceof Y || t.isMesh === !0) {
|
|
497
497
|
const r = t.geometry, n = this.getAssignedLODInformation(r);
|
|
498
498
|
if (!n)
|
|
499
499
|
return Promise.resolve(null);
|
|
500
|
-
for (const
|
|
501
|
-
|
|
500
|
+
for (const l of F)
|
|
501
|
+
l.onBeforeGetLODMesh?.(t, e);
|
|
502
502
|
t["LOD:requested level"] = e;
|
|
503
503
|
const o = () => t["LOD:requested level"] === e || this.shouldApplyStaleMeshLOD(t, e);
|
|
504
|
-
return
|
|
504
|
+
return p.getOrLoadLOD(r, e, {
|
|
505
505
|
isCurrent: o
|
|
506
|
-
}).then((
|
|
507
|
-
if (Array.isArray(
|
|
506
|
+
}).then((l) => {
|
|
507
|
+
if (Array.isArray(l)) {
|
|
508
508
|
const u = n.index || 0;
|
|
509
|
-
|
|
509
|
+
l = l[u];
|
|
510
510
|
}
|
|
511
|
-
const
|
|
512
|
-
return (
|
|
513
|
-
}).catch((
|
|
514
|
-
} else
|
|
511
|
+
const a = t["LOD:requested level"] === e;
|
|
512
|
+
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;
|
|
513
|
+
}).catch((l) => (console.error("Error loading mesh LOD", t, l), null));
|
|
514
|
+
} else g && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
|
|
515
515
|
return Promise.resolve(null);
|
|
516
516
|
}
|
|
517
517
|
static assignTextureLOD(t, e = 0, s) {
|
|
@@ -521,48 +521,48 @@ class g {
|
|
|
521
521
|
const n = t;
|
|
522
522
|
if (Array.isArray(n.material)) {
|
|
523
523
|
const o = new Array();
|
|
524
|
-
for (const
|
|
525
|
-
const
|
|
526
|
-
o.push(
|
|
524
|
+
for (const l of n.material) {
|
|
525
|
+
const a = this.assignTextureLOD(l, e, s);
|
|
526
|
+
o.push(a);
|
|
527
527
|
}
|
|
528
|
-
return Promise.all(o).then((
|
|
529
|
-
const
|
|
530
|
-
for (const u of
|
|
531
|
-
Array.isArray(u) &&
|
|
532
|
-
return
|
|
528
|
+
return Promise.all(o).then((l) => {
|
|
529
|
+
const a = new Array();
|
|
530
|
+
for (const u of l)
|
|
531
|
+
Array.isArray(u) && a.push(...u);
|
|
532
|
+
return a;
|
|
533
533
|
});
|
|
534
534
|
} else
|
|
535
535
|
return this.assignTextureLOD(n.material, e, s);
|
|
536
536
|
}
|
|
537
537
|
if (t.isMaterial === !0) {
|
|
538
|
-
const n = t, o = [],
|
|
538
|
+
const n = t, o = [], l = new Array();
|
|
539
539
|
if (this.trackCurrentMaterialTextureSlots(n), n.uniforms && (n.isRawShaderMaterial || n.isShaderMaterial === !0)) {
|
|
540
|
-
const
|
|
541
|
-
for (const u of Object.keys(
|
|
542
|
-
const
|
|
543
|
-
if (
|
|
544
|
-
const
|
|
545
|
-
o.push(
|
|
540
|
+
const a = n;
|
|
541
|
+
for (const u of Object.keys(a.uniforms)) {
|
|
542
|
+
const d = a.uniforms[u].value;
|
|
543
|
+
if (d?.isTexture === !0) {
|
|
544
|
+
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));
|
|
545
|
+
o.push(c), l.push(u);
|
|
546
546
|
}
|
|
547
547
|
}
|
|
548
548
|
} else
|
|
549
|
-
for (const
|
|
550
|
-
const u = n[
|
|
549
|
+
for (const a of Object.keys(n)) {
|
|
550
|
+
const u = n[a];
|
|
551
551
|
if (u?.isTexture === !0) {
|
|
552
|
-
const
|
|
553
|
-
o.push(
|
|
552
|
+
const d = this.assignTextureLODForSlot(u, e, n, a, r);
|
|
553
|
+
o.push(d), l.push(a);
|
|
554
554
|
}
|
|
555
555
|
}
|
|
556
|
-
return Promise.all(o).then((
|
|
556
|
+
return Promise.all(o).then((a) => {
|
|
557
557
|
const u = new Array();
|
|
558
|
-
for (let
|
|
559
|
-
const
|
|
560
|
-
|
|
558
|
+
for (let d = 0; d < a.length; d++) {
|
|
559
|
+
const c = a[d], f = l[d];
|
|
560
|
+
c && c.isTexture === !0 ? u.push({ material: n, slot: f, texture: c, level: e }) : u.push({ material: n, slot: f, texture: null, level: e });
|
|
561
561
|
}
|
|
562
562
|
return u;
|
|
563
563
|
});
|
|
564
564
|
}
|
|
565
|
-
if (t instanceof
|
|
565
|
+
if (t instanceof q || t.isTexture === !0) {
|
|
566
566
|
const n = t;
|
|
567
567
|
return this.assignTextureLODForSlot(n, e, null, null, r);
|
|
568
568
|
}
|
|
@@ -573,10 +573,10 @@ class g {
|
|
|
573
573
|
* @default 50 on desktop, 20 on mobile devices
|
|
574
574
|
*/
|
|
575
575
|
static set maxConcurrentLoadingTasks(t) {
|
|
576
|
-
|
|
576
|
+
p.queue.maxConcurrent = t;
|
|
577
577
|
}
|
|
578
578
|
static get maxConcurrentLoadingTasks() {
|
|
579
|
-
return
|
|
579
|
+
return p.queue.maxConcurrent;
|
|
580
580
|
}
|
|
581
581
|
// #region INTERNAL
|
|
582
582
|
static assignTextureLODForSlot(t, e, s, r, n) {
|
|
@@ -588,31 +588,31 @@ class g {
|
|
|
588
588
|
if (o && (o.level === e || !n && o.level < e))
|
|
589
589
|
return Promise.resolve(t);
|
|
590
590
|
if (s && r) {
|
|
591
|
-
const
|
|
592
|
-
if (
|
|
593
|
-
return
|
|
591
|
+
const c = this.getPendingTextureSlotRequest(s, r);
|
|
592
|
+
if (c && c.level === e && c.force === n)
|
|
593
|
+
return c.promise;
|
|
594
594
|
}
|
|
595
|
-
const
|
|
595
|
+
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, {
|
|
596
596
|
isCurrent: u
|
|
597
|
-
}).then((
|
|
598
|
-
if (!
|
|
599
|
-
if (Array.isArray(
|
|
597
|
+
}).then((c) => {
|
|
598
|
+
if (!a() && !this.shouldApplyStaleTextureSlotLOD(s, r, e, n)) return null;
|
|
599
|
+
if (Array.isArray(c))
|
|
600
600
|
return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen..."), null;
|
|
601
|
-
if (
|
|
602
|
-
if (
|
|
603
|
-
const
|
|
604
|
-
if (
|
|
605
|
-
const
|
|
606
|
-
if (
|
|
607
|
-
return
|
|
601
|
+
if (c?.isTexture === !0) {
|
|
602
|
+
if (c != t && s && r) {
|
|
603
|
+
const f = this.getMaterialTextureSlot(s, r) ?? t;
|
|
604
|
+
if (f && !n) {
|
|
605
|
+
const h = this.getAssignedLODInformation(f);
|
|
606
|
+
if (h && h?.level < e)
|
|
607
|
+
return g === "verbose" && console.warn("Assigned texture level is already higher: ", h.level, e, s, f, c), null;
|
|
608
608
|
}
|
|
609
|
-
this.assignTrackedTextureSlot(s, r,
|
|
609
|
+
this.assignTrackedTextureSlot(s, r, c);
|
|
610
610
|
}
|
|
611
|
-
return
|
|
612
|
-
} else
|
|
611
|
+
return c;
|
|
612
|
+
} else g == "verbose" && console.warn("No LOD found for", t, e);
|
|
613
613
|
return null;
|
|
614
|
-
}).catch((
|
|
615
|
-
return s && r && this.setPendingTextureSlotRequest(s, r, e, n,
|
|
614
|
+
}).catch((c) => (console.error("Error loading LOD", t, c), null));
|
|
615
|
+
return s && r && this.setPendingTextureSlotRequest(s, r, e, n, l, d), d;
|
|
616
616
|
}
|
|
617
617
|
// Track material slots, not just texture objects. A shared fallback texture can be
|
|
618
618
|
// referenced by many slots and should only be disposed after every slot moved away.
|
|
@@ -648,8 +648,8 @@ class g {
|
|
|
648
648
|
}
|
|
649
649
|
static shouldApplyStaleTextureSlotLOD(t, e, s, r) {
|
|
650
650
|
if (!t || !e) return !1;
|
|
651
|
-
const n = this.getLatestTextureSlotRequest(t, e), o = this.getMaterialTextureSlot(t, e),
|
|
652
|
-
return s >=
|
|
651
|
+
const n = this.getLatestTextureSlotRequest(t, e), o = this.getMaterialTextureSlot(t, e), l = this.getAssignedLODInformation(o)?.level ?? 1 / 0;
|
|
652
|
+
return s >= l ? !1 : r ? n ? s >= n.level : !1 : !0;
|
|
653
653
|
}
|
|
654
654
|
static shouldApplyStaleMeshLOD(t, e) {
|
|
655
655
|
const s = t["LOD:requested level"];
|
|
@@ -658,11 +658,11 @@ class g {
|
|
|
658
658
|
return e < r && e >= s;
|
|
659
659
|
}
|
|
660
660
|
static setPendingTextureSlotRequest(t, e, s, r, n, o) {
|
|
661
|
-
let
|
|
662
|
-
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
|
|
661
|
+
let l = this.pendingTextureSlotRequests.get(t);
|
|
662
|
+
l || (l = /* @__PURE__ */ new Map(), this.pendingTextureSlotRequests.set(t, l));
|
|
663
|
+
const a = { level: s, force: r, id: n, promise: o };
|
|
664
|
+
l.set(e, a), o.finally(() => {
|
|
665
|
+
l.get(e)?.id === n && l.delete(e);
|
|
666
666
|
});
|
|
667
667
|
}
|
|
668
668
|
static getMaterialTextureSlot(t, e) {
|
|
@@ -695,7 +695,7 @@ class g {
|
|
|
695
695
|
}
|
|
696
696
|
static releaseTrackedTextureSlot(t, e, s) {
|
|
697
697
|
const r = this.trackedTextureSlots.get(t);
|
|
698
|
-
if (r?.get(e) === s && r.delete(e), this.untrackTextureUsage(s) && (
|
|
698
|
+
if (r?.get(e) === s && r.delete(e), this.untrackTextureUsage(s) && (g || ie)) {
|
|
699
699
|
const o = this.getAssignedLODInformation(s);
|
|
700
700
|
console.log(`[gltf-progressive] Disposed old texture LOD ${o?.level ?? "?"} for ${t.name || t.type}.${e}`, s.uuid);
|
|
701
701
|
}
|
|
@@ -704,13 +704,13 @@ class g {
|
|
|
704
704
|
url;
|
|
705
705
|
constructor(t) {
|
|
706
706
|
const e = t.options.path;
|
|
707
|
-
|
|
707
|
+
g && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
|
|
708
708
|
}
|
|
709
709
|
_isLoadingMesh;
|
|
710
710
|
loadMesh = (t) => {
|
|
711
711
|
if (this._isLoadingMesh) return null;
|
|
712
|
-
const e = this.parser.json.meshes[t]?.extensions?.[
|
|
713
|
-
return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s &&
|
|
712
|
+
const e = this.parser.json.meshes[t]?.extensions?.[U];
|
|
713
|
+
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;
|
|
714
714
|
};
|
|
715
715
|
// private _isLoadingTexture;
|
|
716
716
|
// loadTexture = (textureIndex: number) => {
|
|
@@ -727,30 +727,30 @@ class g {
|
|
|
727
727
|
// });
|
|
728
728
|
// }
|
|
729
729
|
afterRoot(t) {
|
|
730
|
-
return
|
|
730
|
+
return g && console.log("AFTER", this.url, t), this.parser.json.textures?.forEach((e, s) => {
|
|
731
731
|
if (e?.extensions) {
|
|
732
|
-
const r = e?.extensions[
|
|
732
|
+
const r = e?.extensions[U];
|
|
733
733
|
if (r) {
|
|
734
734
|
if (!r.lods) {
|
|
735
|
-
|
|
735
|
+
g && console.warn("Texture has no LODs", r);
|
|
736
736
|
return;
|
|
737
737
|
}
|
|
738
738
|
let n = !1;
|
|
739
739
|
for (const o of this.parser.associations.keys())
|
|
740
|
-
o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (n = !0,
|
|
740
|
+
o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (n = !0, p.registerTexture(this.url, o, r.lods?.length, s, r));
|
|
741
741
|
n || this.parser.getDependency("texture", s).then((o) => {
|
|
742
|
-
o &&
|
|
742
|
+
o && p.registerTexture(this.url, o, r.lods?.length, s, r);
|
|
743
743
|
});
|
|
744
744
|
}
|
|
745
745
|
}
|
|
746
746
|
}), this.parser.json.meshes?.forEach((e, s) => {
|
|
747
747
|
if (e?.extensions) {
|
|
748
|
-
const r = e?.extensions[
|
|
748
|
+
const r = e?.extensions[U];
|
|
749
749
|
if (r && r.lods) {
|
|
750
750
|
for (const n of this.parser.associations.keys())
|
|
751
751
|
if (n.isMesh) {
|
|
752
752
|
const o = this.parser.associations.get(n);
|
|
753
|
-
o?.meshes === s &&
|
|
753
|
+
o?.meshes === s && p.registerMesh(this.url, r.guid, n, r.lods.length, o.primitives, r);
|
|
754
754
|
}
|
|
755
755
|
}
|
|
756
756
|
}
|
|
@@ -769,16 +769,16 @@ class g {
|
|
|
769
769
|
*/
|
|
770
770
|
static registerTexture = (t, e, s, r, n) => {
|
|
771
771
|
if (!e) {
|
|
772
|
-
|
|
772
|
+
g && console.error("!! gltf-progressive: Called register texture without texture");
|
|
773
773
|
return;
|
|
774
774
|
}
|
|
775
|
-
if (
|
|
776
|
-
const { width:
|
|
777
|
-
console.log(`> gltf-progressive: register texture[${r}] "${e.name || e.uuid}", Current: ${
|
|
775
|
+
if (g) {
|
|
776
|
+
const { width: l, height: a } = ve(e);
|
|
777
|
+
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);
|
|
778
778
|
}
|
|
779
|
-
e.source && (e.source[
|
|
779
|
+
e.source && (e.source[ge] = n);
|
|
780
780
|
const o = n.guid;
|
|
781
|
-
|
|
781
|
+
p.assignLODInformation(t, e, o, s, r), p.lodInfos.set(o, n), p.lowresCache.set(o, new WeakRef(e));
|
|
782
782
|
};
|
|
783
783
|
/**
|
|
784
784
|
* Register a mesh with progressive LOD information. This associates the mesh geometry with its LOD extension data
|
|
@@ -794,16 +794,16 @@ class g {
|
|
|
794
794
|
* @param ext - The parsed progressive mesh extension data containing all available LOD levels with vertex/index counts and densities.
|
|
795
795
|
*/
|
|
796
796
|
static registerMesh = (t, e, s, r, n, o) => {
|
|
797
|
-
const
|
|
798
|
-
if (!
|
|
799
|
-
|
|
797
|
+
const l = s.geometry;
|
|
798
|
+
if (!l) {
|
|
799
|
+
g && console.warn("gltf-progressive: Register mesh without geometry");
|
|
800
800
|
return;
|
|
801
801
|
}
|
|
802
|
-
|
|
803
|
-
let u =
|
|
804
|
-
u ? u.push(s.geometry) : u = [s.geometry],
|
|
805
|
-
for (const
|
|
806
|
-
|
|
802
|
+
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);
|
|
803
|
+
let u = p.lowresCache.get(e)?.deref();
|
|
804
|
+
u ? u.push(s.geometry) : u = [s.geometry], p.lowresCache.set(e, new WeakRef(u)), r > 0 && !ae(s) && bt(s, l);
|
|
805
|
+
for (const d of F)
|
|
806
|
+
d.onRegisteredNewMesh?.(s, o);
|
|
807
807
|
};
|
|
808
808
|
/**
|
|
809
809
|
* Dispose cached resources to free memory.
|
|
@@ -830,7 +830,7 @@ class g {
|
|
|
830
830
|
for (const [s, r] of this.cache)
|
|
831
831
|
s.includes(t) && (this._disposeCacheEntry(r), this.cache.delete(s));
|
|
832
832
|
} else {
|
|
833
|
-
this.lodInfos.clear();
|
|
833
|
+
this.cacheGeneration++, this.lodInfos.clear();
|
|
834
834
|
for (const [, e] of this.lowresCache) {
|
|
835
835
|
const s = e.deref();
|
|
836
836
|
if (s) {
|
|
@@ -853,7 +853,7 @@ class g {
|
|
|
853
853
|
const e = t.deref();
|
|
854
854
|
e && (e.isTexture && this.textureRefCounts.delete(e.uuid), e.dispose());
|
|
855
855
|
} else
|
|
856
|
-
t.then((e) => {
|
|
856
|
+
this.disposedRequests.add(t), t.then((e) => {
|
|
857
857
|
if (e)
|
|
858
858
|
if (Array.isArray(e))
|
|
859
859
|
for (const s of e) s.dispose();
|
|
@@ -876,16 +876,16 @@ class g {
|
|
|
876
876
|
* The held value is the cache key string used in `previouslyLoaded`.
|
|
877
877
|
*/
|
|
878
878
|
static _resourceRegistry = new FinalizationRegistry((t) => {
|
|
879
|
-
const e =
|
|
880
|
-
(
|
|
881
|
-
${t}`), e instanceof WeakRef && (e.deref() || (
|
|
879
|
+
const e = p.cache.get(t);
|
|
880
|
+
(g || ie) && console.debug(`[gltf-progressive] Memory: Resource GC'd
|
|
881
|
+
${t}`), e instanceof WeakRef && (e.deref() || (p.cache.delete(t), (g || ie) && console.log("[gltf-progressive] ↪ Cache entry deleted (GC)")));
|
|
882
882
|
});
|
|
883
883
|
/**
|
|
884
884
|
* Track texture usage by incrementing reference count
|
|
885
885
|
*/
|
|
886
886
|
static trackTextureUsage(t) {
|
|
887
887
|
const e = t.uuid, s = this.textureRefCounts.get(e) || 0;
|
|
888
|
-
this.textureRefCounts.set(e, s + 1),
|
|
888
|
+
this.textureRefCounts.set(e, s + 1), g === "verbose" && console.log(`[gltf-progressive] Track texture ${e}, refCount: ${s} → ${s + 1}`);
|
|
889
889
|
}
|
|
890
890
|
/**
|
|
891
891
|
* Untrack texture usage by decrementing reference count.
|
|
@@ -895,155 +895,166 @@ ${t}`), e instanceof WeakRef && (e.deref() || (g.cache.delete(t), (h || se) && c
|
|
|
895
895
|
static untrackTextureUsage(t) {
|
|
896
896
|
const e = t.uuid, s = this.textureRefCounts.get(e);
|
|
897
897
|
if (!s)
|
|
898
|
-
return (
|
|
898
|
+
return (g === "verbose" || ie) && n("[gltf-progressive] Memory: Untrack untracked texture (dispose immediately)", 0), t.dispose(), !0;
|
|
899
899
|
const r = s - 1;
|
|
900
900
|
if (r <= 0)
|
|
901
|
-
return this.textureRefCounts.delete(e), (
|
|
902
|
-
return this.textureRefCounts.set(e, r),
|
|
903
|
-
function n(o,
|
|
904
|
-
let { width:
|
|
905
|
-
const
|
|
906
|
-
let
|
|
907
|
-
|
|
901
|
+
return this.textureRefCounts.delete(e), (g || ie) && n("[gltf-progressive] Memory: Dispose texture", r), t.dispose(), !0;
|
|
902
|
+
return this.textureRefCounts.set(e, r), g === "verbose" && n("[gltf-progressive] Memory: Untrack texture", r), !1;
|
|
903
|
+
function n(o, l) {
|
|
904
|
+
let { width: a, height: u } = ve(t);
|
|
905
|
+
const d = a && u ? `${a}x${u}` : "N/A";
|
|
906
|
+
let c = "N/A";
|
|
907
|
+
a && u && (c = `~${(vt(t) / (1024 * 1024)).toFixed(2)} MB`), console.log(`${o} — ${t.name} ${d} (${c}), refCount: ${s} → ${l}
|
|
908
908
|
${e}`);
|
|
909
909
|
}
|
|
910
910
|
}
|
|
911
911
|
static workers = [];
|
|
912
|
+
static cacheGeneration = 0;
|
|
913
|
+
static disposedRequests = /* @__PURE__ */ new WeakSet();
|
|
912
914
|
static _workersIndex = 0;
|
|
913
915
|
static async getOrLoadLOD(t, e, s) {
|
|
914
|
-
const r =
|
|
915
|
-
if (!
|
|
916
|
-
return
|
|
917
|
-
const
|
|
916
|
+
const r = this.cacheGeneration, n = g == "verbose", o = this.getAssignedLODInformation(t);
|
|
917
|
+
if (!o)
|
|
918
|
+
return g && console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`, t), null;
|
|
919
|
+
const l = o?.key;
|
|
918
920
|
let a;
|
|
919
921
|
if (t.isTexture === !0) {
|
|
920
|
-
const
|
|
921
|
-
|
|
922
|
+
const d = t;
|
|
923
|
+
d.source && d.source[ge] && (a = d.source[ge]);
|
|
922
924
|
}
|
|
923
|
-
if (a || (a =
|
|
924
|
-
|
|
925
|
+
if (a || (a = p.lodInfos.get(l)), !a)
|
|
926
|
+
g && console.warn(`Can not load LOD ${e}: no LOD info found for "${l}" ${t.name}`, t.type, p.lodInfos);
|
|
925
927
|
else {
|
|
926
928
|
if (e > 0) {
|
|
927
929
|
let f = !1;
|
|
928
|
-
const
|
|
929
|
-
if (
|
|
930
|
-
const
|
|
931
|
-
if (
|
|
932
|
-
const
|
|
933
|
-
if (
|
|
934
|
-
this.lowresCache.delete(
|
|
930
|
+
const h = Array.isArray(a.lods);
|
|
931
|
+
if (h && e >= a.lods.length ? f = !0 : h || (f = !0), f) {
|
|
932
|
+
const v = this.lowresCache.get(l);
|
|
933
|
+
if (v) {
|
|
934
|
+
const L = v.deref();
|
|
935
|
+
if (L) return L;
|
|
936
|
+
this.lowresCache.delete(l), g && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${l}`);
|
|
935
937
|
}
|
|
936
938
|
return null;
|
|
937
939
|
}
|
|
938
940
|
}
|
|
939
|
-
const
|
|
940
|
-
if (!
|
|
941
|
-
return
|
|
942
|
-
const c = wt(
|
|
941
|
+
const d = Array.isArray(a.lods) ? a.lods[e]?.path : a.lods;
|
|
942
|
+
if (!d)
|
|
943
|
+
return g && !a["missing:uri"] && (a["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, a)), null;
|
|
944
|
+
const c = wt(o.url, d);
|
|
943
945
|
if (c.endsWith(".glb") || c.endsWith(".gltf")) {
|
|
944
946
|
if (!a.guid)
|
|
945
947
|
return console.warn("missing pointer for glb/gltf texture", a), null;
|
|
946
|
-
const f = c + "_" + a.guid,
|
|
947
|
-
if (
|
|
948
|
+
const f = c + "_" + a.guid, h = await this.tryResolveLODCacheEntry(this.cache.get(f), f, c, t, e, n);
|
|
949
|
+
if (r !== this.cacheGeneration) return null;
|
|
950
|
+
if (h.found) return h.value;
|
|
948
951
|
if (s?.isCurrent?.() === !1)
|
|
949
|
-
return
|
|
950
|
-
const
|
|
952
|
+
return n && console.log(`Skipping stale LOD ${e} request before queue: ${c}`), null;
|
|
953
|
+
const v = await this.queue.slot(c);
|
|
954
|
+
if (r !== this.cacheGeneration) return null;
|
|
951
955
|
if (s?.isCurrent?.() === !1)
|
|
952
|
-
return
|
|
953
|
-
const
|
|
954
|
-
if (
|
|
955
|
-
if (
|
|
956
|
-
|
|
957
|
-
|
|
956
|
+
return n && console.log(`Skipping stale LOD ${e} request after queue: ${c}`), null;
|
|
957
|
+
const L = await this.tryResolveLODCacheEntry(this.cache.get(f), f, c, t, e, n);
|
|
958
|
+
if (r !== this.cacheGeneration) return null;
|
|
959
|
+
if (L.found) return L.value;
|
|
960
|
+
const x = this.cache.get(f);
|
|
961
|
+
if (x !== void 0) {
|
|
962
|
+
const y = await this.tryResolveLODCacheEntry(x, f, c, t, e, n);
|
|
963
|
+
if (r !== this.cacheGeneration) return null;
|
|
964
|
+
if (y.found) return y.value;
|
|
965
|
+
}
|
|
966
|
+
if (!v.use)
|
|
967
|
+
return g && console.log(`LOD ${e} was aborted: ${c}`), null;
|
|
968
|
+
const w = a, M = new Promise(async (y, T) => {
|
|
958
969
|
if (kt) {
|
|
959
970
|
const m = await (await Pt({})).load(c);
|
|
960
971
|
if (m.textures.length > 0)
|
|
961
|
-
for (const
|
|
962
|
-
let
|
|
963
|
-
return
|
|
972
|
+
for (const D of m.textures) {
|
|
973
|
+
let S = D.texture;
|
|
974
|
+
return p.assignLODInformation(o.url, S, l, e, void 0), t instanceof q && (S = this.copySettings(t, S)), S && (S.guid = w.guid), y(S);
|
|
964
975
|
}
|
|
965
976
|
if (m.geometries.length > 0) {
|
|
966
|
-
const
|
|
967
|
-
for (const
|
|
968
|
-
const
|
|
969
|
-
|
|
977
|
+
const D = new Array();
|
|
978
|
+
for (const S of m.geometries) {
|
|
979
|
+
const X = S.geometry;
|
|
980
|
+
p.assignLODInformation(o.url, X, l, e, S.primitiveIndex), D.push(X);
|
|
970
981
|
}
|
|
971
|
-
return
|
|
982
|
+
return y(D);
|
|
972
983
|
}
|
|
973
|
-
return
|
|
984
|
+
return y(null);
|
|
974
985
|
}
|
|
975
|
-
const
|
|
976
|
-
|
|
977
|
-
let
|
|
978
|
-
if (
|
|
979
|
-
const
|
|
980
|
-
|
|
986
|
+
const I = new _e();
|
|
987
|
+
We(I), g && (await new Promise((b) => setTimeout(b, 1e3)), n && console.warn("Start loading (delayed) " + c, w.guid));
|
|
988
|
+
let C = c;
|
|
989
|
+
if (w && Array.isArray(w.lods)) {
|
|
990
|
+
const b = w.lods[e];
|
|
991
|
+
b.hash && (C += "?v=" + b.hash);
|
|
981
992
|
}
|
|
982
|
-
const
|
|
983
|
-
`,
|
|
984
|
-
if (!
|
|
985
|
-
return
|
|
986
|
-
const
|
|
987
|
-
|
|
988
|
-
let
|
|
989
|
-
if (
|
|
990
|
-
let
|
|
991
|
-
for (const m of
|
|
993
|
+
const _ = await I.loadAsync(C).catch((b) => (console.error(`Error loading LOD ${e} from ${c}
|
|
994
|
+
`, b), y(null)));
|
|
995
|
+
if (!_)
|
|
996
|
+
return y(null);
|
|
997
|
+
const z = _.parser;
|
|
998
|
+
n && console.log("Loading finished " + c, w.guid);
|
|
999
|
+
let k = 0;
|
|
1000
|
+
if (_.parser.json.textures) {
|
|
1001
|
+
let b = !1;
|
|
1002
|
+
for (const m of _.parser.json.textures) {
|
|
992
1003
|
if (m?.extensions) {
|
|
993
|
-
const
|
|
994
|
-
if (
|
|
995
|
-
|
|
1004
|
+
const D = m?.extensions[U];
|
|
1005
|
+
if (D?.guid && D.guid === w.guid) {
|
|
1006
|
+
b = !0;
|
|
996
1007
|
break;
|
|
997
1008
|
}
|
|
998
1009
|
}
|
|
999
|
-
|
|
1010
|
+
k++;
|
|
1000
1011
|
}
|
|
1001
|
-
if (
|
|
1002
|
-
let m = await
|
|
1003
|
-
return m &&
|
|
1004
|
-
} else
|
|
1012
|
+
if (b) {
|
|
1013
|
+
let m = await z.getDependency("texture", k);
|
|
1014
|
+
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 q && (m = this.copySettings(t, m)), m && (m.guid = w.guid), y(m);
|
|
1015
|
+
} else g && console.warn("Could not find texture with guid", w.guid, _.parser.json);
|
|
1005
1016
|
}
|
|
1006
|
-
if (
|
|
1007
|
-
let
|
|
1008
|
-
for (const m of
|
|
1017
|
+
if (k = 0, _.parser.json.meshes) {
|
|
1018
|
+
let b = !1;
|
|
1019
|
+
for (const m of _.parser.json.meshes) {
|
|
1009
1020
|
if (m?.extensions) {
|
|
1010
|
-
const
|
|
1011
|
-
if (
|
|
1012
|
-
|
|
1021
|
+
const D = m?.extensions[U];
|
|
1022
|
+
if (D?.guid && D.guid === w.guid) {
|
|
1023
|
+
b = !0;
|
|
1013
1024
|
break;
|
|
1014
1025
|
}
|
|
1015
1026
|
}
|
|
1016
|
-
|
|
1027
|
+
k++;
|
|
1017
1028
|
}
|
|
1018
|
-
if (
|
|
1019
|
-
const m = await
|
|
1020
|
-
if (
|
|
1021
|
-
const
|
|
1022
|
-
return
|
|
1029
|
+
if (b) {
|
|
1030
|
+
const m = await z.getDependency("mesh", k);
|
|
1031
|
+
if (n && console.log(`Loaded Mesh "${m.name}"`, c, k, m, f), m.isMesh === !0) {
|
|
1032
|
+
const D = m.geometry;
|
|
1033
|
+
return p.assignLODInformation(o.url, D, l, e, 0), y(D);
|
|
1023
1034
|
} else {
|
|
1024
|
-
const
|
|
1025
|
-
for (let
|
|
1026
|
-
const
|
|
1027
|
-
if (
|
|
1028
|
-
const
|
|
1029
|
-
|
|
1035
|
+
const D = new Array();
|
|
1036
|
+
for (let S = 0; S < m.children.length; S++) {
|
|
1037
|
+
const X = m.children[S];
|
|
1038
|
+
if (X.isMesh === !0) {
|
|
1039
|
+
const J = X.geometry;
|
|
1040
|
+
p.assignLODInformation(o.url, J, l, e, S), D.push(J);
|
|
1030
1041
|
}
|
|
1031
1042
|
}
|
|
1032
|
-
return
|
|
1043
|
+
return y(D);
|
|
1033
1044
|
}
|
|
1034
|
-
} else
|
|
1045
|
+
} else g && console.warn("Could not find mesh with guid", w.guid, _.parser.json);
|
|
1035
1046
|
}
|
|
1036
|
-
return
|
|
1047
|
+
return y(null);
|
|
1037
1048
|
});
|
|
1038
|
-
this.cache.set(f,
|
|
1039
|
-
const
|
|
1040
|
-
return
|
|
1041
|
-
} else if (t instanceof
|
|
1049
|
+
this.cache.set(f, M), v.use(M);
|
|
1050
|
+
const O = await M;
|
|
1051
|
+
return r !== this.cacheGeneration || this.cache.get(f) !== M ? null : (O != null ? O instanceof q ? (this.cache.set(f, new WeakRef(O)), p._resourceRegistry.register(O, f)) : Array.isArray(O) ? this.cache.set(f, Promise.resolve(O)) : this.cache.set(f, Promise.resolve(O)) : this.cache.set(f, Promise.resolve(null)), O);
|
|
1052
|
+
} else if (t instanceof q) {
|
|
1042
1053
|
if (s?.isCurrent?.() === !1)
|
|
1043
|
-
return
|
|
1044
|
-
|
|
1045
|
-
const
|
|
1046
|
-
return s?.isCurrent?.() === !1 ? (
|
|
1054
|
+
return n && console.log(`Skipping stale texture LOD ${e} request: ${c}`), null;
|
|
1055
|
+
n && console.log("Load texture from uri: " + c);
|
|
1056
|
+
const h = await new it().loadAsync(c);
|
|
1057
|
+
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);
|
|
1047
1058
|
}
|
|
1048
1059
|
}
|
|
1049
1060
|
return null;
|
|
@@ -1054,19 +1065,21 @@ ${e}`);
|
|
|
1054
1065
|
if (o && console.log(`LOD ${n} was already loading/loaded: ${e}`), t instanceof WeakRef) {
|
|
1055
1066
|
const u = t.deref();
|
|
1056
1067
|
if (u) {
|
|
1057
|
-
let
|
|
1058
|
-
if (
|
|
1059
|
-
return { found: !0, value:
|
|
1068
|
+
let d = u, c = !1;
|
|
1069
|
+
if (d instanceof q && r instanceof q ? Se(d.image) || De(d) ? d = this.copySettings(r, d) : c = !0 : d instanceof K && r instanceof K && (d.attributes.position?.array || (c = !0)), !c)
|
|
1070
|
+
return { found: !0, value: d };
|
|
1060
1071
|
}
|
|
1061
|
-
return this.cache.delete(e),
|
|
1072
|
+
return this.cache.delete(e), g && console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${e}`), { found: !1 };
|
|
1062
1073
|
}
|
|
1063
|
-
let
|
|
1064
|
-
`, u), null))
|
|
1065
|
-
|
|
1074
|
+
let l = await t.catch((u) => (console.error(`Error loading LOD ${n} from ${s}
|
|
1075
|
+
`, u), null));
|
|
1076
|
+
if (this.disposedRequests.has(t)) return { found: !0, value: null };
|
|
1077
|
+
let a = !1;
|
|
1078
|
+
return l == null || (l instanceof q && r instanceof q ? Se(l.image) || De(l) ? l = this.copySettings(r, l) : (a = !0, this.cache.delete(e)) : l instanceof K && r instanceof K && (l.attributes.position?.array || (a = !0, this.cache.delete(e)))), a ? { found: !1 } : { found: !0, value: l };
|
|
1066
1079
|
}
|
|
1067
1080
|
static _queue;
|
|
1068
1081
|
static get queue() {
|
|
1069
|
-
return this._queue ??= new Dt(
|
|
1082
|
+
return this._queue ??= new Dt(Oe() ? 20 : 50, { debug: g != !1 });
|
|
1070
1083
|
}
|
|
1071
1084
|
static assignLODInformation(t, e, s, r, n) {
|
|
1072
1085
|
if (!e) return;
|
|
@@ -1079,7 +1092,7 @@ ${e}`);
|
|
|
1079
1092
|
}
|
|
1080
1093
|
// private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
|
|
1081
1094
|
static copySettings(t, e) {
|
|
1082
|
-
return e ? (
|
|
1095
|
+
return e ? (g === "verbose" && console.debug(`Copy texture settings
|
|
1083
1096
|
`, t.uuid, `
|
|
1084
1097
|
`, 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;
|
|
1085
1098
|
}
|
|
@@ -1095,7 +1108,7 @@ class At {
|
|
|
1095
1108
|
this.url = t, this.key = e, this.level = s, r != null && (this.index = r);
|
|
1096
1109
|
}
|
|
1097
1110
|
}
|
|
1098
|
-
class
|
|
1111
|
+
class le {
|
|
1099
1112
|
static addPromise = (t, e, s, r) => {
|
|
1100
1113
|
r.forEach((n) => {
|
|
1101
1114
|
n.add(t, e, s);
|
|
@@ -1144,7 +1157,7 @@ class oe {
|
|
|
1144
1157
|
_seen = /* @__PURE__ */ new WeakMap();
|
|
1145
1158
|
add(t, e, s) {
|
|
1146
1159
|
if (this._resolved) {
|
|
1147
|
-
|
|
1160
|
+
g && console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");
|
|
1148
1161
|
return;
|
|
1149
1162
|
}
|
|
1150
1163
|
if (!(this._frame_start !== void 0 && this._currentFrame > this._frame_start + this._frames_to_capture)) {
|
|
@@ -1152,7 +1165,7 @@ class oe {
|
|
|
1152
1165
|
if (this._seen.has(e)) {
|
|
1153
1166
|
const r = this._seen.get(e);
|
|
1154
1167
|
if (r >= this._maxPromisesPerObject) {
|
|
1155
|
-
|
|
1168
|
+
g && console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");
|
|
1156
1169
|
return;
|
|
1157
1170
|
}
|
|
1158
1171
|
this._seen.set(e, r + 1);
|
|
@@ -1171,7 +1184,7 @@ class oe {
|
|
|
1171
1184
|
});
|
|
1172
1185
|
}
|
|
1173
1186
|
}
|
|
1174
|
-
const
|
|
1187
|
+
const $ = V("debugprogressive"), It = $ === "colors", $t = V("noprogressive"), pe = /* @__PURE__ */ Symbol("Needle:LODSManager"), me = /* @__PURE__ */ Symbol("Needle:LODState"), E = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), Re = ot, R = { mesh_lod: -1, texture_lod: -1 }, Gt = new Be(), Pe = [
|
|
1175
1188
|
3526751,
|
|
1176
1189
|
11065402,
|
|
1177
1190
|
15978811,
|
|
@@ -1205,14 +1218,14 @@ const A = N("debugprogressive"), It = A === "colors", $t = N("noprogressive"), g
|
|
|
1205
1218
|
5083278,
|
|
1206
1219
|
5592405
|
|
1207
1220
|
];
|
|
1208
|
-
function
|
|
1209
|
-
const i =
|
|
1221
|
+
function Bt() {
|
|
1222
|
+
const i = Re.Timer || Re.Clock;
|
|
1210
1223
|
return new i();
|
|
1211
1224
|
}
|
|
1212
|
-
const
|
|
1225
|
+
const ye = new de(), N = new de(), Ce = new de(), qt = new A(), Wt = new A(), Ft = new Ge(), W = new A(), Z = new A(), ee = new A(), te = new A();
|
|
1213
1226
|
function Ut(i, t) {
|
|
1214
1227
|
const e = i.min, s = i.max, r = (e.x + s.x) * 0.5, n = (e.y + s.y) * 0.5;
|
|
1215
|
-
return
|
|
1228
|
+
return W.set(r, n, e.z).applyMatrix4(t).z < 0;
|
|
1216
1229
|
}
|
|
1217
1230
|
function zt(i) {
|
|
1218
1231
|
const {
|
|
@@ -1222,71 +1235,71 @@ function zt(i) {
|
|
|
1222
1235
|
projectionScreenMatrix: r,
|
|
1223
1236
|
desiredDensity: n,
|
|
1224
1237
|
canvasHeight: o = 0,
|
|
1225
|
-
currentLevel:
|
|
1226
|
-
xrEnabled:
|
|
1238
|
+
currentLevel: l = -1,
|
|
1239
|
+
xrEnabled: a = !1,
|
|
1227
1240
|
debugDrawLine: u,
|
|
1228
|
-
warnMissingPrimitiveDensities:
|
|
1229
|
-
} = i,
|
|
1230
|
-
level:
|
|
1231
|
-
primitiveIndex:
|
|
1241
|
+
warnMissingPrimitiveDensities: d = !1
|
|
1242
|
+
} = i, c = p.getMeshLODExtension(t)?.lods, f = p.getPrimitiveIndex(t), h = i.target ?? {
|
|
1243
|
+
level: l,
|
|
1244
|
+
primitiveIndex: f,
|
|
1232
1245
|
screenCoverage: 0,
|
|
1233
|
-
screenspaceVolume: new
|
|
1246
|
+
screenspaceVolume: new A(),
|
|
1234
1247
|
centrality: 1
|
|
1235
1248
|
};
|
|
1236
|
-
|
|
1237
|
-
let
|
|
1238
|
-
if (
|
|
1239
|
-
if (
|
|
1240
|
-
return
|
|
1241
|
-
if (
|
|
1242
|
-
const
|
|
1243
|
-
let
|
|
1244
|
-
const
|
|
1245
|
-
|
|
1246
|
-
const
|
|
1247
|
-
|
|
1248
|
-
}
|
|
1249
|
-
const
|
|
1250
|
-
|
|
1251
|
-
const x =
|
|
1252
|
-
w !== 0 &&
|
|
1253
|
-
const
|
|
1254
|
-
if (
|
|
1249
|
+
h.level = l, h.primitiveIndex = f, h.screenCoverage = 0, h.screenspaceVolume.set(0, 0, 0), h.centrality = 1;
|
|
1250
|
+
let v = i.boundingBox ?? t.boundingBox;
|
|
1251
|
+
if (v || (t.computeBoundingBox(), v = t.boundingBox), !v) return h;
|
|
1252
|
+
if (ye.copy(v).applyMatrix4(e), s.isPerspectiveCamera && Ut(ye, r))
|
|
1253
|
+
return h.level = 0, h.screenCoverage = 1 / 0, h.screenspaceVolume.set(1 / 0, 1 / 0, 1 / 0), h;
|
|
1254
|
+
if (N.copy(ye).applyMatrix4(r), a && s.isPerspectiveCamera && s.fov > 70) {
|
|
1255
|
+
const y = N.min, T = N.max;
|
|
1256
|
+
let I = y.x, C = y.y, _ = T.x, z = T.y;
|
|
1257
|
+
const k = 2, b = 1.5, m = (y.x + T.x) * 0.5, D = (y.y + T.y) * 0.5;
|
|
1258
|
+
I = (I - m) * k + m, C = (C - D) * k + D, _ = (_ - m) * k + m, z = (z - D) * k + D;
|
|
1259
|
+
const S = I < 0 && _ > 0 ? 0 : Math.min(Math.abs(y.x), Math.abs(T.x)), X = C < 0 && z > 0 ? 0 : Math.min(Math.abs(y.y), Math.abs(T.y)), J = Math.max(S, X);
|
|
1260
|
+
h.centrality = (b - J) * (b - J) * (b - J);
|
|
1261
|
+
}
|
|
1262
|
+
const L = N.getSize(qt);
|
|
1263
|
+
L.multiplyScalar(0.5), globalThis.screen?.availHeight > 0 && o > 0 && L.multiplyScalar(o / globalThis.screen.availHeight), s.isPerspectiveCamera && (L.x *= s.aspect), Ce.copy(v).applyMatrix4(e).applyMatrix4(s.matrixWorldInverse);
|
|
1264
|
+
const x = Ce.getSize(Wt), w = Math.max(L.x, L.y), M = Math.max(x.x, x.y);
|
|
1265
|
+
w !== 0 && M !== 0 && (L.z = x.z / M * w);
|
|
1266
|
+
const O = Math.max(L.x, L.y, L.z) * h.centrality;
|
|
1267
|
+
if (h.screenCoverage = O, h.screenspaceVolume.copy(L), O <= 0) return h;
|
|
1255
1268
|
if (u) {
|
|
1256
|
-
const
|
|
1257
|
-
|
|
1258
|
-
const
|
|
1259
|
-
|
|
1260
|
-
}
|
|
1261
|
-
if (
|
|
1262
|
-
for (let
|
|
1263
|
-
const
|
|
1264
|
-
if (
|
|
1265
|
-
|
|
1269
|
+
const y = Ft.copy(r);
|
|
1270
|
+
y.invert(), W.copy(N.min), Z.copy(N.max), Z.x = W.x, ee.copy(N.max), ee.y = W.y, te.copy(N.max);
|
|
1271
|
+
const T = (W.z + te.z) * 0.5;
|
|
1272
|
+
W.z = Z.z = ee.z = te.z = T, W.applyMatrix4(y), Z.applyMatrix4(y), ee.applyMatrix4(y), te.applyMatrix4(y), u(W, Z, 255), u(W, ee, 255), u(Z, te, 255), u(ee, te, 255);
|
|
1273
|
+
}
|
|
1274
|
+
if (c?.length)
|
|
1275
|
+
for (let y = 0; y < c.length; y++) {
|
|
1276
|
+
const T = c[y], I = T.densities?.[f] || T.density || 1e-5;
|
|
1277
|
+
if (f > 0 && d && ze() && !T.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 / O < n) {
|
|
1278
|
+
h.level = y;
|
|
1266
1279
|
break;
|
|
1267
1280
|
}
|
|
1268
1281
|
}
|
|
1269
|
-
return
|
|
1282
|
+
return h;
|
|
1270
1283
|
}
|
|
1271
|
-
let
|
|
1284
|
+
let fe = class H {
|
|
1272
1285
|
/**
|
|
1273
1286
|
* 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.
|
|
1274
1287
|
*/
|
|
1275
1288
|
static debugDrawLine;
|
|
1276
1289
|
/** @internal */
|
|
1277
1290
|
static getObjectLODState(t) {
|
|
1278
|
-
return t[
|
|
1291
|
+
return t[me];
|
|
1279
1292
|
}
|
|
1280
1293
|
static addPlugin(t) {
|
|
1281
|
-
|
|
1294
|
+
F.push(t);
|
|
1282
1295
|
}
|
|
1283
1296
|
static removePlugin(t) {
|
|
1284
|
-
const e =
|
|
1285
|
-
e >= 0 &&
|
|
1297
|
+
const e = F.indexOf(t);
|
|
1298
|
+
e >= 0 && F.splice(e, 1);
|
|
1286
1299
|
}
|
|
1287
1300
|
/** Read-only snapshot of the currently registered plugins, for inspection. Use {@link addPlugin} / {@link removePlugin} to modify the registry. */
|
|
1288
1301
|
static getPlugins() {
|
|
1289
|
-
return
|
|
1302
|
+
return F;
|
|
1290
1303
|
}
|
|
1291
1304
|
/**
|
|
1292
1305
|
* Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
|
|
@@ -1294,20 +1307,20 @@ let ue = class X {
|
|
|
1294
1307
|
* @returns The LODsManager instance.
|
|
1295
1308
|
*/
|
|
1296
1309
|
static get(t, e) {
|
|
1297
|
-
if (t[
|
|
1298
|
-
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[
|
|
1299
|
-
const s = new
|
|
1310
|
+
if (t[pe])
|
|
1311
|
+
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[pe];
|
|
1312
|
+
const s = new H(t, {
|
|
1300
1313
|
engine: "unknown",
|
|
1301
1314
|
...e
|
|
1302
1315
|
});
|
|
1303
|
-
return t[
|
|
1316
|
+
return t[pe] = s, s;
|
|
1304
1317
|
}
|
|
1305
1318
|
renderer;
|
|
1306
1319
|
context;
|
|
1307
|
-
projectionScreenMatrix = new
|
|
1320
|
+
projectionScreenMatrix = new Ge();
|
|
1308
1321
|
/** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
|
|
1309
1322
|
get plugins() {
|
|
1310
|
-
return
|
|
1323
|
+
return F;
|
|
1311
1324
|
}
|
|
1312
1325
|
/**
|
|
1313
1326
|
* Force override the LOD level for all objects (meshes + textures) rendered in the scene
|
|
@@ -1372,12 +1385,12 @@ let ue = class X {
|
|
|
1372
1385
|
* ```
|
|
1373
1386
|
*/
|
|
1374
1387
|
awaitLoading(t) {
|
|
1375
|
-
const e = this._promiseGroupIds++, s = new
|
|
1388
|
+
const e = this._promiseGroupIds++, s = new le(this.#r, { ...t });
|
|
1376
1389
|
this._newPromiseGroups.push(s);
|
|
1377
1390
|
const r = performance.now();
|
|
1378
1391
|
return s.ready.finally(() => {
|
|
1379
1392
|
const n = this._newPromiseGroups.indexOf(s);
|
|
1380
|
-
n >= 0 && (this._newPromiseGroups.splice(n, 1),
|
|
1393
|
+
n >= 0 && (this._newPromiseGroups.splice(n, 1), ze() && performance.measure("LODsManager:awaitLoading", {
|
|
1381
1394
|
start: r,
|
|
1382
1395
|
detail: { id: e, name: t?.name, awaited: s.awaitedCount, resolved: s.resolvedCount }
|
|
1383
1396
|
}));
|
|
@@ -1385,7 +1398,7 @@ let ue = class X {
|
|
|
1385
1398
|
}
|
|
1386
1399
|
/** Track LOD work started outside this manager so {@link awaitLoading} waits for it too. */
|
|
1387
1400
|
trackLoadingPromise(t, e, s) {
|
|
1388
|
-
return
|
|
1401
|
+
return le.addPromise(t, e, s, this._newPromiseGroups), s;
|
|
1389
1402
|
}
|
|
1390
1403
|
_postprocessPromiseGroups() {
|
|
1391
1404
|
if (this._newPromiseGroups.length !== 0)
|
|
@@ -1437,7 +1450,7 @@ let ue = class X {
|
|
|
1437
1450
|
#n = 0;
|
|
1438
1451
|
#o = 0;
|
|
1439
1452
|
#s = 0;
|
|
1440
|
-
#i =
|
|
1453
|
+
#i = Bt();
|
|
1441
1454
|
_fpsBuffer = [60, 60, 60, 60, 60];
|
|
1442
1455
|
/**
|
|
1443
1456
|
* Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
|
|
@@ -1448,9 +1461,9 @@ let ue = class X {
|
|
|
1448
1461
|
let t = 0;
|
|
1449
1462
|
this.#t = this.renderer.render;
|
|
1450
1463
|
const e = this;
|
|
1451
|
-
|
|
1464
|
+
be(this.renderer), this.renderer.render = function(s, r) {
|
|
1452
1465
|
const n = e.renderer.getRenderTarget();
|
|
1453
|
-
(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((
|
|
1466
|
+
(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));
|
|
1454
1467
|
const o = t++;
|
|
1455
1468
|
e.#t.call(this, s, r), e.onAfterRender(s, r, o);
|
|
1456
1469
|
};
|
|
@@ -1483,11 +1496,11 @@ let ue = class X {
|
|
|
1483
1496
|
const n = r.opaque;
|
|
1484
1497
|
let o = !0;
|
|
1485
1498
|
if (n.length === 1) {
|
|
1486
|
-
const
|
|
1487
|
-
(
|
|
1499
|
+
const l = n[0].material;
|
|
1500
|
+
(l.name === "EffectMaterial" || l.name === "CopyShader") && (o = !1);
|
|
1488
1501
|
}
|
|
1489
1502
|
if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (o = !1), o) {
|
|
1490
|
-
if ($t || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1,
|
|
1503
|
+
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))
|
|
1491
1504
|
return;
|
|
1492
1505
|
this.internalUpdate(t, e), this._postprocessPromiseGroups();
|
|
1493
1506
|
}
|
|
@@ -1501,12 +1514,12 @@ let ue = class X {
|
|
|
1501
1514
|
const r = s.opaque;
|
|
1502
1515
|
this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse);
|
|
1503
1516
|
const n = this.targetTriangleDensity;
|
|
1504
|
-
for (const
|
|
1505
|
-
if (
|
|
1506
|
-
|
|
1517
|
+
for (const a of r) {
|
|
1518
|
+
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")) {
|
|
1519
|
+
$ && (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)));
|
|
1507
1520
|
continue;
|
|
1508
1521
|
}
|
|
1509
|
-
switch (
|
|
1522
|
+
switch (a.material.type) {
|
|
1510
1523
|
case "LineBasicMaterial":
|
|
1511
1524
|
case "LineDashedMaterial":
|
|
1512
1525
|
case "PointsMaterial":
|
|
@@ -1515,18 +1528,18 @@ let ue = class X {
|
|
|
1515
1528
|
case "MeshDepthMaterial":
|
|
1516
1529
|
continue;
|
|
1517
1530
|
}
|
|
1518
|
-
const u =
|
|
1519
|
-
(u instanceof
|
|
1531
|
+
const u = a.object;
|
|
1532
|
+
(u instanceof Y || u.isMesh) && this.updateLODs(t, e, u, n);
|
|
1520
1533
|
}
|
|
1521
1534
|
const o = s.transparent;
|
|
1522
|
-
for (const
|
|
1523
|
-
const u =
|
|
1524
|
-
(u instanceof
|
|
1535
|
+
for (const a of o) {
|
|
1536
|
+
const u = a.object;
|
|
1537
|
+
(u instanceof Y || u.isMesh) && this.updateLODs(t, e, u, n);
|
|
1525
1538
|
}
|
|
1526
|
-
const
|
|
1527
|
-
for (const
|
|
1528
|
-
const u =
|
|
1529
|
-
(u instanceof
|
|
1539
|
+
const l = s.transmissive;
|
|
1540
|
+
for (const a of l) {
|
|
1541
|
+
const u = a.object;
|
|
1542
|
+
(u instanceof Y || u.isMesh) && this.updateLODs(t, e, u, n);
|
|
1530
1543
|
}
|
|
1531
1544
|
}
|
|
1532
1545
|
getRenderList(t, e, s) {
|
|
@@ -1551,15 +1564,15 @@ let ue = class X {
|
|
|
1551
1564
|
/** Update the LOD levels for the renderer. */
|
|
1552
1565
|
updateLODs(t, e, s, r) {
|
|
1553
1566
|
s.userData || (s.userData = {});
|
|
1554
|
-
let n = s[
|
|
1555
|
-
if (n || (n = new Et(), s[
|
|
1567
|
+
let n = s[me];
|
|
1568
|
+
if (n || (n = new Et(), s[me] = n), n.frames++ < 2)
|
|
1556
1569
|
return;
|
|
1557
|
-
for (const
|
|
1558
|
-
|
|
1559
|
-
const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel :
|
|
1560
|
-
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),
|
|
1561
|
-
for (const
|
|
1562
|
-
|
|
1570
|
+
for (const l of F)
|
|
1571
|
+
l.onBeforeUpdateLOD?.(this.renderer, t, e, s);
|
|
1572
|
+
const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel : j;
|
|
1573
|
+
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);
|
|
1574
|
+
for (const l of F)
|
|
1575
|
+
l.onAfterUpdatedLOD?.(this.renderer, t, e, s, R);
|
|
1563
1576
|
n.lastLodLevel_Mesh = R.mesh_lod, n.lastLodLevel_Texture = R.texture_lod;
|
|
1564
1577
|
}
|
|
1565
1578
|
/** Load progressive textures for the given material
|
|
@@ -1575,14 +1588,14 @@ let ue = class X {
|
|
|
1575
1588
|
return;
|
|
1576
1589
|
}
|
|
1577
1590
|
let r = !1;
|
|
1578
|
-
(t[
|
|
1591
|
+
(t[E] === void 0 || e < t[E]) && (r = !0);
|
|
1579
1592
|
const n = s !== void 0 && s >= 0;
|
|
1580
|
-
if (n && (r = t[
|
|
1581
|
-
t[
|
|
1582
|
-
const o = n ? { force: !0 } : void 0,
|
|
1593
|
+
if (n && (r = t[E] != s, e = s), r) {
|
|
1594
|
+
t[E] = e;
|
|
1595
|
+
const o = n ? { force: !0 } : void 0, l = p.assignTextureLOD(t, e, o).then((a) => {
|
|
1583
1596
|
this._lodchangedlisteners.forEach((u) => u({ type: "texture", level: e, object: t }));
|
|
1584
1597
|
});
|
|
1585
|
-
|
|
1598
|
+
le.addPromise("texture", t, l, this._newPromiseGroups);
|
|
1586
1599
|
}
|
|
1587
1600
|
}
|
|
1588
1601
|
/** Load progressive meshes for the given mesh
|
|
@@ -1593,18 +1606,18 @@ let ue = class X {
|
|
|
1593
1606
|
*/
|
|
1594
1607
|
loadProgressiveMeshes(t, e) {
|
|
1595
1608
|
if (!t) return Promise.resolve(null);
|
|
1596
|
-
let s = t[
|
|
1609
|
+
let s = t[E] !== e;
|
|
1597
1610
|
const r = t["DEBUG:LOD"];
|
|
1598
|
-
if (r != null && (s = t[
|
|
1599
|
-
t[
|
|
1600
|
-
const n = t.geometry, o =
|
|
1601
|
-
return
|
|
1611
|
+
if (r != null && (s = t[E] != r, e = r), s) {
|
|
1612
|
+
t[E] = e;
|
|
1613
|
+
const n = t.geometry, o = p.assignMeshLOD(t, e).then((l) => (l && t[E] == e && n != t.geometry && this._lodchangedlisteners.forEach((a) => a({ type: "mesh", level: e, object: t })), l));
|
|
1614
|
+
return le.addPromise("mesh", t, o, this._newPromiseGroups), o;
|
|
1602
1615
|
}
|
|
1603
1616
|
return Promise.resolve(null);
|
|
1604
1617
|
}
|
|
1605
1618
|
// private testIfLODLevelsAreAvailable() {
|
|
1606
|
-
_sphere = new
|
|
1607
|
-
_tempWorldPosition = new
|
|
1619
|
+
_sphere = new $e();
|
|
1620
|
+
_tempWorldPosition = new A();
|
|
1608
1621
|
static skinnedMeshBoundsFrameOffsetCounter = 0;
|
|
1609
1622
|
static $skinnedMeshBoundsOffset = /* @__PURE__ */ Symbol("gltf-progressive-skinnedMeshBoundsOffset");
|
|
1610
1623
|
// #region calculateLodLevel
|
|
@@ -1617,39 +1630,39 @@ let ue = class X {
|
|
|
1617
1630
|
n.mesh_lod = -1, n.texture_lod = -1;
|
|
1618
1631
|
return;
|
|
1619
1632
|
}
|
|
1620
|
-
let
|
|
1621
|
-
if (
|
|
1633
|
+
let l = 10 + 1, a = !1;
|
|
1634
|
+
if ($ && e["DEBUG:LOD"] != null)
|
|
1622
1635
|
return e["DEBUG:LOD"];
|
|
1623
|
-
const u =
|
|
1624
|
-
if (!
|
|
1636
|
+
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;
|
|
1637
|
+
if (!c && !h) {
|
|
1625
1638
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1626
1639
|
return;
|
|
1627
1640
|
}
|
|
1628
|
-
|
|
1629
|
-
const
|
|
1630
|
-
let
|
|
1641
|
+
c || (a = !0, l = 0);
|
|
1642
|
+
const v = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
|
|
1643
|
+
let L = e.geometry.boundingBox;
|
|
1631
1644
|
if (e.type === "SkinnedMesh") {
|
|
1632
1645
|
const x = e;
|
|
1633
1646
|
if (!x.boundingBox)
|
|
1634
1647
|
x.computeBoundingBox();
|
|
1635
1648
|
else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
|
|
1636
|
-
if (!x[
|
|
1637
|
-
const
|
|
1638
|
-
x[
|
|
1649
|
+
if (!x[H.$skinnedMeshBoundsOffset]) {
|
|
1650
|
+
const M = H.skinnedMeshBoundsFrameOffsetCounter++;
|
|
1651
|
+
x[H.$skinnedMeshBoundsOffset] = M;
|
|
1639
1652
|
}
|
|
1640
|
-
const w = x[
|
|
1653
|
+
const w = x[H.$skinnedMeshBoundsOffset];
|
|
1641
1654
|
if ((s.frames + w) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
|
|
1642
|
-
const
|
|
1643
|
-
|
|
1655
|
+
const M = ae(x), O = x.geometry;
|
|
1656
|
+
M && (x.geometry = M), x.computeBoundingBox(), x.geometry = O;
|
|
1644
1657
|
}
|
|
1645
1658
|
}
|
|
1646
|
-
|
|
1659
|
+
L = x.boundingBox;
|
|
1647
1660
|
}
|
|
1648
|
-
if (
|
|
1661
|
+
if (L) {
|
|
1649
1662
|
if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
|
|
1650
1663
|
this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
|
|
1651
|
-
const
|
|
1652
|
-
if (this._sphere.containsPoint(
|
|
1664
|
+
const M = t.getWorldPosition(this._tempWorldPosition);
|
|
1665
|
+
if (this._sphere.containsPoint(M)) {
|
|
1653
1666
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1654
1667
|
return;
|
|
1655
1668
|
}
|
|
@@ -1660,43 +1673,43 @@ let ue = class X {
|
|
|
1660
1673
|
camera: t,
|
|
1661
1674
|
projectionScreenMatrix: this.projectionScreenMatrix,
|
|
1662
1675
|
desiredDensity: r,
|
|
1663
|
-
canvasHeight:
|
|
1676
|
+
canvasHeight: v,
|
|
1664
1677
|
currentLevel: s.lastLodLevel_Mesh,
|
|
1665
|
-
boundingBox:
|
|
1678
|
+
boundingBox: L,
|
|
1666
1679
|
xrEnabled: this.renderer.xr.enabled,
|
|
1667
|
-
debugDrawLine:
|
|
1680
|
+
debugDrawLine: $ ? H.debugDrawLine : void 0,
|
|
1668
1681
|
warnMissingPrimitiveDensities: !0
|
|
1669
1682
|
});
|
|
1670
1683
|
if (s.lastCentrality = x.centrality, s.lastScreenCoverage = x.screenCoverage, s.lastScreenspaceVolume.copy(x.screenspaceVolume), x.screenCoverage === 1 / 0) {
|
|
1671
1684
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1672
1685
|
return;
|
|
1673
1686
|
}
|
|
1674
|
-
x.level >= 0 && x.level <
|
|
1687
|
+
x.level >= 0 && x.level < l && (l = x.level, a = !0);
|
|
1675
1688
|
}
|
|
1676
|
-
if (
|
|
1689
|
+
if (a ? n.mesh_lod = l : n.mesh_lod = s.lastLodLevel_Mesh, $ && n.mesh_lod != s.lastLodLevel_Mesh) {
|
|
1677
1690
|
const w = u?.[n.mesh_lod];
|
|
1678
|
-
w && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${w.densities?.[
|
|
1691
|
+
w && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${w.densities?.[d].toFixed(0)}) | ${e.name}`);
|
|
1679
1692
|
}
|
|
1680
|
-
if (
|
|
1693
|
+
if (h) {
|
|
1681
1694
|
const x = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
|
|
1682
1695
|
if (s.lastLodLevel_Texture < 0) {
|
|
1683
|
-
if (n.texture_lod =
|
|
1684
|
-
const w =
|
|
1685
|
-
|
|
1696
|
+
if (n.texture_lod = f.max_count - 1, $) {
|
|
1697
|
+
const w = f.lods[f.max_count - 1];
|
|
1698
|
+
$ && console.log(`First Texture LOD ${n.texture_lod} (${w.max_height}px) - ${e.name}`);
|
|
1686
1699
|
}
|
|
1687
1700
|
} else {
|
|
1688
1701
|
const w = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
|
|
1689
|
-
let
|
|
1690
|
-
this.context?.engine === "model-viewer" && (
|
|
1691
|
-
const
|
|
1692
|
-
let
|
|
1693
|
-
for (let C =
|
|
1694
|
-
const
|
|
1695
|
-
if (!(x &&
|
|
1696
|
-
if (
|
|
1697
|
-
const
|
|
1698
|
-
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${
|
|
1699
|
-
Screensize: ${
|
|
1702
|
+
let M = s.lastScreenCoverage * 4;
|
|
1703
|
+
this.context?.engine === "model-viewer" && (M *= 1.5);
|
|
1704
|
+
const O = this.renderer.getPixelRatio?.() || globalThis.devicePixelRatio || 1, T = v / O * M;
|
|
1705
|
+
let I = !1;
|
|
1706
|
+
for (let C = f.lods.length - 1; C >= 0; C--) {
|
|
1707
|
+
const _ = f.lods[C];
|
|
1708
|
+
if (!(x && _.max_height >= 2048) && !(Oe() && _.max_height > 4096) && (_.max_height > T || !I && C === 0)) {
|
|
1709
|
+
if (I = !0, n.texture_lod = C, $ && n.texture_lod < s.lastLodLevel_Texture) {
|
|
1710
|
+
const z = _.max_height;
|
|
1711
|
+
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${z}px
|
|
1712
|
+
Screensize: ${T.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${w.toFixed(1)}
|
|
1700
1713
|
${e.name}`);
|
|
1701
1714
|
}
|
|
1702
1715
|
break;
|
|
@@ -1712,69 +1725,69 @@ class Et {
|
|
|
1712
1725
|
lastLodLevel_Mesh = -1;
|
|
1713
1726
|
lastLodLevel_Texture = -1;
|
|
1714
1727
|
lastScreenCoverage = 0;
|
|
1715
|
-
lastScreenspaceVolume = new
|
|
1728
|
+
lastScreenspaceVolume = new A();
|
|
1716
1729
|
lastCentrality = 0;
|
|
1717
1730
|
}
|
|
1718
|
-
function
|
|
1731
|
+
function Ne(i, t) {
|
|
1719
1732
|
if (!(t < 0)) {
|
|
1720
1733
|
if (Array.isArray(i)) {
|
|
1721
1734
|
for (const e of i)
|
|
1722
|
-
|
|
1735
|
+
Ne(e, t);
|
|
1723
1736
|
return;
|
|
1724
1737
|
}
|
|
1725
|
-
"color" in i && i.color instanceof Be && (i.color.copy(Nt(t,
|
|
1738
|
+
"color" in i && i.color instanceof Be && (i.color.copy(Nt(t, Gt)), i.needsUpdate = !0);
|
|
1726
1739
|
}
|
|
1727
1740
|
}
|
|
1728
1741
|
function Nt(i, t) {
|
|
1729
|
-
const e = Math.max(0, Math.min(
|
|
1730
|
-
return t.setHex(
|
|
1742
|
+
const e = Math.max(0, Math.min(Pe.length - 1, Math.floor(i)));
|
|
1743
|
+
return t.setHex(Pe[e]);
|
|
1731
1744
|
}
|
|
1732
|
-
const
|
|
1733
|
-
let
|
|
1734
|
-
function
|
|
1745
|
+
const ke = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), ue = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
|
|
1746
|
+
let xe = null;
|
|
1747
|
+
function Ve() {
|
|
1735
1748
|
const i = Vt();
|
|
1736
1749
|
i && (i.mapURLs(function(t) {
|
|
1737
|
-
return
|
|
1738
|
-
}),
|
|
1750
|
+
return Ae(), t;
|
|
1751
|
+
}), Ae(), xe?.disconnect(), xe = new MutationObserver((t) => {
|
|
1739
1752
|
t.forEach((e) => {
|
|
1740
1753
|
e.addedNodes.forEach((s) => {
|
|
1741
|
-
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" &&
|
|
1754
|
+
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Xe(s);
|
|
1742
1755
|
});
|
|
1743
1756
|
});
|
|
1744
|
-
}),
|
|
1757
|
+
}), xe.observe(document, { childList: !0, subtree: !0 }));
|
|
1745
1758
|
}
|
|
1746
1759
|
function Vt() {
|
|
1747
1760
|
if (typeof customElements > "u") return null;
|
|
1748
1761
|
const i = customElements.get("model-viewer");
|
|
1749
1762
|
return i || (customElements.whenDefined("model-viewer").then(() => {
|
|
1750
|
-
console.debug("[gltf-progressive] model-viewer defined"),
|
|
1763
|
+
console.debug("[gltf-progressive] model-viewer defined"), Ve();
|
|
1751
1764
|
}), null);
|
|
1752
1765
|
}
|
|
1753
|
-
function
|
|
1766
|
+
function Ae() {
|
|
1754
1767
|
if (typeof document > "u") return;
|
|
1755
1768
|
document.querySelectorAll("model-viewer").forEach((t) => {
|
|
1756
|
-
|
|
1769
|
+
Xe(t);
|
|
1757
1770
|
});
|
|
1758
1771
|
}
|
|
1759
|
-
const
|
|
1772
|
+
const Ie = /* @__PURE__ */ new WeakSet();
|
|
1760
1773
|
let Xt = 0;
|
|
1761
|
-
function
|
|
1762
|
-
if (!i ||
|
|
1774
|
+
function Xe(i) {
|
|
1775
|
+
if (!i || Ie.has(i))
|
|
1763
1776
|
return null;
|
|
1764
|
-
|
|
1777
|
+
Ie.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++Xt + `
|
|
1765
1778
|
`, i.getAttribute("src"));
|
|
1766
1779
|
let t = null, e = null, s = null;
|
|
1767
1780
|
for (let r = i; r != null; r = Object.getPrototypeOf(r)) {
|
|
1768
|
-
const n = Object.getOwnPropertySymbols(r), o = n.find((u) => u.toString() == "Symbol(renderer)"),
|
|
1769
|
-
!t && o != null && (t = i[o].threeRenderer), !e &&
|
|
1781
|
+
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)");
|
|
1782
|
+
!t && o != null && (t = i[o].threeRenderer), !e && l != null && (e = i[l]), !s && a != null && (s = i[a]);
|
|
1770
1783
|
}
|
|
1771
1784
|
if (t && e) {
|
|
1772
1785
|
let r = function() {
|
|
1773
1786
|
if (s) {
|
|
1774
1787
|
let o = 0;
|
|
1775
|
-
const
|
|
1788
|
+
const l = setInterval(() => {
|
|
1776
1789
|
if (o++ > 5) {
|
|
1777
|
-
clearInterval(
|
|
1790
|
+
clearInterval(l);
|
|
1778
1791
|
return;
|
|
1779
1792
|
}
|
|
1780
1793
|
s?.call(i);
|
|
@@ -1782,8 +1795,8 @@ function Ve(i) {
|
|
|
1782
1795
|
}
|
|
1783
1796
|
};
|
|
1784
1797
|
console.debug("[gltf-progressive] setup model-viewer");
|
|
1785
|
-
const n =
|
|
1786
|
-
return
|
|
1798
|
+
const n = fe.get(t, { engine: "model-viewer" });
|
|
1799
|
+
return fe.addPlugin(new jt()), n.enable(), n.addEventListener("changed", () => {
|
|
1787
1800
|
s?.call(i);
|
|
1788
1801
|
}), i.addEventListener("model-visibility", (o) => {
|
|
1789
1802
|
o.detail.visible && s?.call(i);
|
|
@@ -1813,46 +1826,46 @@ class jt {
|
|
|
1813
1826
|
return t.element;
|
|
1814
1827
|
}
|
|
1815
1828
|
tryParseTextureLOD(t, e) {
|
|
1816
|
-
if (e[
|
|
1817
|
-
e[
|
|
1829
|
+
if (e[ue] == !0) return;
|
|
1830
|
+
e[ue] = !0;
|
|
1818
1831
|
const s = this.tryGetCurrentGLTF(t), r = this.tryGetCurrentModelViewer(t), n = this.getUrl(r);
|
|
1819
1832
|
if (n && s && e.material) {
|
|
1820
|
-
let o = function(
|
|
1821
|
-
if (
|
|
1822
|
-
|
|
1823
|
-
const u = Object.keys(
|
|
1824
|
-
for (let
|
|
1825
|
-
const
|
|
1826
|
-
if (
|
|
1827
|
-
const
|
|
1828
|
-
if (
|
|
1829
|
-
const
|
|
1830
|
-
if (!
|
|
1831
|
-
console.warn("Texture data not found for texture index " +
|
|
1833
|
+
let o = function(a) {
|
|
1834
|
+
if (a[ue] == !0) return;
|
|
1835
|
+
a[ue] = !0, a.userData && (a.userData.LOD = -1);
|
|
1836
|
+
const u = Object.keys(a);
|
|
1837
|
+
for (let d = 0; d < u.length; d++) {
|
|
1838
|
+
const c = u[d], f = a[c];
|
|
1839
|
+
if (f?.isTexture === !0) {
|
|
1840
|
+
const h = f.userData?.associations?.textures;
|
|
1841
|
+
if (h == null) continue;
|
|
1842
|
+
const v = s.parser.json.textures[h];
|
|
1843
|
+
if (!v) {
|
|
1844
|
+
console.warn("Texture data not found for texture index " + h);
|
|
1832
1845
|
continue;
|
|
1833
1846
|
}
|
|
1834
|
-
if (
|
|
1835
|
-
const
|
|
1836
|
-
|
|
1847
|
+
if (v?.extensions?.[U]) {
|
|
1848
|
+
const L = v.extensions[U];
|
|
1849
|
+
L && n && p.registerTexture(n, f, L.lods.length, h, L);
|
|
1837
1850
|
}
|
|
1838
1851
|
}
|
|
1839
1852
|
}
|
|
1840
1853
|
};
|
|
1841
|
-
const
|
|
1842
|
-
if (Array.isArray(
|
|
1843
|
-
else o(
|
|
1854
|
+
const l = e.material;
|
|
1855
|
+
if (Array.isArray(l)) for (const a of l) o(a);
|
|
1856
|
+
else o(l);
|
|
1844
1857
|
}
|
|
1845
1858
|
}
|
|
1846
1859
|
tryParseMeshLOD(t, e) {
|
|
1847
|
-
if (e[
|
|
1848
|
-
e[
|
|
1860
|
+
if (e[ke] == !0) return;
|
|
1861
|
+
e[ke] = !0;
|
|
1849
1862
|
const s = this.tryGetCurrentModelViewer(t), r = this.getUrl(s);
|
|
1850
1863
|
if (!r)
|
|
1851
1864
|
return;
|
|
1852
|
-
const n = e.userData?.gltfExtensions?.[
|
|
1865
|
+
const n = e.userData?.gltfExtensions?.[U];
|
|
1853
1866
|
if (n && r) {
|
|
1854
1867
|
const o = e.uuid;
|
|
1855
|
-
|
|
1868
|
+
p.registerMesh(r, o, e, 0, n.lods.length, n);
|
|
1856
1869
|
}
|
|
1857
1870
|
}
|
|
1858
1871
|
}
|
|
@@ -1871,21 +1884,21 @@ function Ht(...i) {
|
|
|
1871
1884
|
default:
|
|
1872
1885
|
throw new Error("Invalid arguments");
|
|
1873
1886
|
}
|
|
1874
|
-
|
|
1887
|
+
be(e), We(s), Ue(s, {
|
|
1875
1888
|
progressive: !0,
|
|
1876
1889
|
...r?.hints
|
|
1877
|
-
}), s.register((o) => new
|
|
1878
|
-
const n =
|
|
1890
|
+
}), s.register((o) => new p(o));
|
|
1891
|
+
const n = fe.get(e);
|
|
1879
1892
|
return r?.enableLODsManager !== !1 && n.enable(), n;
|
|
1880
1893
|
}
|
|
1881
|
-
|
|
1894
|
+
Ve();
|
|
1882
1895
|
if (!_t) {
|
|
1883
1896
|
const i = {
|
|
1884
1897
|
gltfProgressive: {
|
|
1885
1898
|
useNeedleProgressive: Ht,
|
|
1886
|
-
LODsManager:
|
|
1887
|
-
configureLoader:
|
|
1888
|
-
getRaycastMesh:
|
|
1899
|
+
LODsManager: fe,
|
|
1900
|
+
configureLoader: Ue,
|
|
1901
|
+
getRaycastMesh: ae,
|
|
1889
1902
|
useRaycastMeshes: Ot
|
|
1890
1903
|
}
|
|
1891
1904
|
};
|
|
@@ -1896,14 +1909,14 @@ if (!_t) {
|
|
|
1896
1909
|
globalThis.Needle[t] = i[t];
|
|
1897
1910
|
}
|
|
1898
1911
|
export {
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1912
|
+
fe as LODsManager,
|
|
1913
|
+
p as NEEDLE_progressive,
|
|
1914
|
+
We as addDracoAndKTX2Loaders,
|
|
1902
1915
|
zt as calculateMeshLODLevel,
|
|
1903
|
-
|
|
1904
|
-
|
|
1916
|
+
Ue as configureLoader,
|
|
1917
|
+
be as createLoaders,
|
|
1905
1918
|
Nt as getLODColor,
|
|
1906
|
-
|
|
1919
|
+
ae as getRaycastMesh,
|
|
1907
1920
|
gt as setDracoDecoderLocation,
|
|
1908
1921
|
pt as setKTX2TranscoderLocation
|
|
1909
1922
|
};
|