@needle-tools/gltf-progressive 4.0.0-alpha.3 → 4.0.0-alpha.5
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 +6 -0
- package/gltf-progressive.js +126 -124
- package/gltf-progressive.min.js +8 -8
- package/gltf-progressive.umd.cjs +7 -7
- package/lib/loaders.js +24 -34
- package/lib/utils.internal.js +3 -8
- package/lib/version.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to this package will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [4.0.0-alpha.5] - 2026-10-06
|
|
8
|
+
- Fix: Progressive LOD loading starts during an immersive WebXR session when the window animation frame callback is paused.
|
|
9
|
+
|
|
10
|
+
## [4.0.0-alpha.4] - 2026-10-02
|
|
11
|
+
- Fix: Server-side rendering no longer checks browser-only decoder URLs during import.
|
|
12
|
+
|
|
7
13
|
## [4.0.0-alpha.3] - 2026-09-09
|
|
8
14
|
- Fix: LOD loads completing after disposal no longer restore cleared caches or apply disposed resources to meshes and textures.
|
|
9
15
|
- Fix: concurrent mesh LOD requests share the same download and geometry instead of starting duplicate loads.
|
package/gltf-progressive.js
CHANGED
|
@@ -1,64 +1,66 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { RedFormat as
|
|
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
3
|
import { GLTFLoader as Me } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
4
|
-
import { MeshoptDecoder as
|
|
5
|
-
import { DRACOLoader as
|
|
6
|
-
import { KTX2Loader as
|
|
7
|
-
const
|
|
8
|
-
globalThis.GLTF_PROGRESSIVE_VERSION =
|
|
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
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
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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 = () => ({
|
|
24
26
|
dracoDecoderPath: B,
|
|
25
27
|
ktx2TranscoderPath: Q
|
|
26
28
|
});
|
|
27
|
-
function
|
|
29
|
+
function dt(i) {
|
|
28
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
|
|
32
|
+
function ht(i) {
|
|
31
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
|
|
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
|
|
38
|
+
function Be(i) {
|
|
37
39
|
i.dracoLoader || i.setDRACOLoader(k), i.ktx2Loader || i.setKTX2Loader(q), i.meshoptDecoder || i.setMeshoptDecoder(ce);
|
|
38
40
|
}
|
|
39
41
|
const xe = /* @__PURE__ */ Symbol("dracoDecoderPath");
|
|
40
42
|
let k, ce, q;
|
|
41
|
-
function
|
|
42
|
-
k || (k = new
|
|
43
|
+
function qe() {
|
|
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
46
|
const we = /* @__PURE__ */ new WeakMap();
|
|
45
|
-
function
|
|
47
|
+
function We(i, t) {
|
|
46
48
|
let e = we.get(i);
|
|
47
49
|
e ? e = Object.assign(e, t) : e = t, we.set(i, e);
|
|
48
50
|
}
|
|
49
|
-
const
|
|
50
|
-
function
|
|
51
|
+
const gt = Me.prototype.load;
|
|
52
|
+
function pt(...i) {
|
|
51
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
|
-
Me.prototype.load =
|
|
61
|
-
function
|
|
62
|
+
Me.prototype.load = pt;
|
|
63
|
+
function mt(i) {
|
|
62
64
|
try {
|
|
63
65
|
if (i instanceof URL)
|
|
64
66
|
return i;
|
|
@@ -75,12 +77,12 @@ 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
84
|
function ve(i) {
|
|
83
|
-
const t =
|
|
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
|
|
@@ -93,7 +95,7 @@ function X(i) {
|
|
|
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("/");
|
|
@@ -110,15 +112,15 @@ function be() {
|
|
|
110
112
|
return se = /iPhone|iPad|iPod|Android|IEMobile/i.test(i), X("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", se), se;
|
|
111
113
|
}
|
|
112
114
|
let se;
|
|
113
|
-
function
|
|
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
|
-
this.maxConcurrent = t, this.debug = e.debug ?? !1,
|
|
123
|
+
this.maxConcurrent = t, this.debug = e.debug ?? !1, setTimeout(this.tick, 0);
|
|
122
124
|
}
|
|
123
125
|
_running = /* @__PURE__ */ new Map();
|
|
124
126
|
_queue = [];
|
|
@@ -150,29 +152,29 @@ 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
|
|
167
|
+
const Dt = typeof window > "u" && typeof document > "u", De = /* @__PURE__ */ Symbol("needle:raycast-mesh");
|
|
166
168
|
function ae(i) {
|
|
167
169
|
return i?.[De] instanceof H ? i[De] : null;
|
|
168
170
|
}
|
|
169
|
-
function
|
|
171
|
+
function Mt(i, t) {
|
|
170
172
|
if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !ae(i)) {
|
|
171
|
-
const s =
|
|
173
|
+
const s = bt(t);
|
|
172
174
|
s.userData = { isRaycastMesh: !0 }, i[De] = s;
|
|
173
175
|
}
|
|
174
176
|
}
|
|
175
|
-
function
|
|
177
|
+
function _t(i = !0) {
|
|
176
178
|
if (i) {
|
|
177
179
|
if (re) return;
|
|
178
180
|
const t = re = Y.prototype.raycast;
|
|
@@ -187,7 +189,7 @@ function bt(i = !0) {
|
|
|
187
189
|
}
|
|
188
190
|
}
|
|
189
191
|
let re = null;
|
|
190
|
-
function
|
|
192
|
+
function bt(i) {
|
|
191
193
|
const t = new H();
|
|
192
194
|
for (const e in i.attributes)
|
|
193
195
|
t.setAttribute(e, i.getAttribute(e));
|
|
@@ -206,24 +208,24 @@ if (g && typeof window < "u") {
|
|
|
206
208
|
!isNaN(s) && s >= 0 && (K = s, console.log(`Set LOD level to [${K}]`));
|
|
207
209
|
});
|
|
208
210
|
}
|
|
209
|
-
function
|
|
211
|
+
function Ue(i) {
|
|
210
212
|
if (g && oe !== void 0)
|
|
211
213
|
if (Array.isArray(i))
|
|
212
214
|
for (const t of i)
|
|
213
|
-
|
|
215
|
+
Ue(t);
|
|
214
216
|
else i && "wireframe" in i && (i.wireframe = oe === !0);
|
|
215
217
|
}
|
|
216
218
|
const ne = new Array();
|
|
217
|
-
let
|
|
218
|
-
const
|
|
219
|
-
function
|
|
220
|
-
if (ne.length <
|
|
219
|
+
let Tt = 0;
|
|
220
|
+
const Ot = be() ? 2 : 10;
|
|
221
|
+
function St(i) {
|
|
222
|
+
if (ne.length < Ot) {
|
|
221
223
|
const s = ne.length;
|
|
222
224
|
g && console.warn(`[Worker] Creating new worker #${s}`);
|
|
223
225
|
const r = Te.createWorker(i || {});
|
|
224
226
|
return ne.push(r), r;
|
|
225
227
|
}
|
|
226
|
-
const t =
|
|
228
|
+
const t = Tt++ % ne.length;
|
|
227
229
|
return ne[t];
|
|
228
230
|
}
|
|
229
231
|
class Te {
|
|
@@ -234,7 +236,7 @@ class Te {
|
|
|
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
|
}
|
|
@@ -258,7 +260,7 @@ class Te {
|
|
|
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");
|
|
@@ -289,7 +291,7 @@ class Te {
|
|
|
289
291
|
}
|
|
290
292
|
_debug = !1;
|
|
291
293
|
}
|
|
292
|
-
function
|
|
294
|
+
function Rt(i) {
|
|
293
295
|
for (const t of i.geometries) {
|
|
294
296
|
const e = t.geometry, s = new H();
|
|
295
297
|
if (s.name = e.name || "", e.index) {
|
|
@@ -330,7 +332,7 @@ function Pt(i) {
|
|
|
330
332
|
let s = null;
|
|
331
333
|
if (e.isCompressedTexture) {
|
|
332
334
|
const r = e.mipmaps, { width: n, height: o } = ve(e);
|
|
333
|
-
s = new
|
|
335
|
+
s = new Ze(
|
|
334
336
|
r,
|
|
335
337
|
n,
|
|
336
338
|
o,
|
|
@@ -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;
|
|
@@ -368,12 +370,12 @@ function Pt(i) {
|
|
|
368
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
|
|
378
|
+
const Pt = X("gltf-progressive-worker");
|
|
377
379
|
X("gltf-progressive-reduce-mipmaps");
|
|
378
380
|
const ie = X("gltf-progressive-gc"), he = /* @__PURE__ */ Symbol("needle-progressive-texture"), z = "NEEDLE_progressive";
|
|
379
381
|
class p {
|
|
@@ -809,7 +811,7 @@ class p {
|
|
|
809
811
|
}
|
|
810
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);
|
|
811
813
|
let u = p.lowresCache.get(e)?.deref();
|
|
812
|
-
u ? u.push(s.geometry) : u = [s.geometry], p.lowresCache.set(e, new WeakRef(u)), r > 0 && !ae(s) &&
|
|
814
|
+
u ? u.push(s.geometry) : u = [s.geometry], p.lowresCache.set(e, new WeakRef(u)), r > 0 && !ae(s) && Mt(s, l);
|
|
813
815
|
for (const d of U)
|
|
814
816
|
d.onRegisteredNewMesh?.(s, o);
|
|
815
817
|
};
|
|
@@ -912,7 +914,7 @@ ${t}`), e instanceof WeakRef && (e.deref() || (p.cache.delete(t), (g || ie) && c
|
|
|
912
914
|
let { width: a, height: u } = ve(t);
|
|
913
915
|
const d = a && u ? `${a}x${u}` : "N/A";
|
|
914
916
|
let c = "N/A";
|
|
915
|
-
a && u && (c = `~${(
|
|
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
|
}
|
|
@@ -949,7 +951,7 @@ ${e}`);
|
|
|
949
951
|
const d = Array.isArray(a.lods) ? a.lods[e]?.path : a.lods;
|
|
950
952
|
if (!d)
|
|
951
953
|
return g && !a["missing:uri"] && (a["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, a)), null;
|
|
952
|
-
const c =
|
|
954
|
+
const c = xt(o.url, d);
|
|
953
955
|
if (c.endsWith(".glb") || c.endsWith(".gltf")) {
|
|
954
956
|
if (!a.guid)
|
|
955
957
|
return console.warn("missing pointer for glb/gltf texture", a), null;
|
|
@@ -974,8 +976,8 @@ ${e}`);
|
|
|
974
976
|
if (!D.use)
|
|
975
977
|
return g && console.log(`LOD ${e} was aborted: ${c}`), null;
|
|
976
978
|
const L = a, M = new Promise(async (y, O) => {
|
|
977
|
-
if (
|
|
978
|
-
const m = await (await
|
|
979
|
+
if (Pt) {
|
|
980
|
+
const m = await (await St({})).load(c);
|
|
979
981
|
if (m.textures.length > 0)
|
|
980
982
|
for (const v of m.textures) {
|
|
981
983
|
let S = v.texture;
|
|
@@ -992,7 +994,7 @@ ${e}`);
|
|
|
992
994
|
return y(null);
|
|
993
995
|
}
|
|
994
996
|
const I = new Me();
|
|
995
|
-
|
|
997
|
+
Be(I), g && (await new Promise((b) => setTimeout(b, 1e3)), n && console.warn("Start loading (delayed) " + c, L.guid));
|
|
996
998
|
let P = c;
|
|
997
999
|
if (L && Array.isArray(L.lods)) {
|
|
998
1000
|
const b = L.lods[e];
|
|
@@ -1061,7 +1063,7 @@ ${e}`);
|
|
|
1061
1063
|
if (s?.isCurrent?.() === !1)
|
|
1062
1064
|
return n && console.log(`Skipping stale texture LOD ${e} request: ${c}`), null;
|
|
1063
1065
|
n && console.log("Load texture from uri: " + c);
|
|
1064
|
-
const h = await new
|
|
1066
|
+
const h = await new nt().loadAsync(c);
|
|
1065
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);
|
|
1066
1068
|
}
|
|
1067
1069
|
}
|
|
@@ -1087,12 +1089,12 @@ ${e}`);
|
|
|
1087
1089
|
}
|
|
1088
1090
|
static _queue;
|
|
1089
1091
|
static get queue() {
|
|
1090
|
-
return this._queue ??= new
|
|
1092
|
+
return this._queue ??= new wt(be() ? 20 : 50, { debug: g != !1 });
|
|
1091
1093
|
}
|
|
1092
1094
|
static assignLODInformation(t, e, s, r, n) {
|
|
1093
1095
|
if (!e) return;
|
|
1094
1096
|
e.userData || (e.userData = {});
|
|
1095
|
-
const o = new
|
|
1097
|
+
const o = new Ct(t, s, r, n);
|
|
1096
1098
|
e.userData.LODS = o, "source" in e && typeof e.source == "object" && (e.source.LODS = o);
|
|
1097
1099
|
}
|
|
1098
1100
|
static getAssignedLODInformation(t) {
|
|
@@ -1105,7 +1107,7 @@ ${e}`);
|
|
|
1105
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;
|
|
1106
1108
|
}
|
|
1107
1109
|
}
|
|
1108
|
-
class
|
|
1110
|
+
class Ct {
|
|
1109
1111
|
url;
|
|
1110
1112
|
/** the key to lookup the LOD information */
|
|
1111
1113
|
key;
|
|
@@ -1192,7 +1194,7 @@ class le {
|
|
|
1192
1194
|
});
|
|
1193
1195
|
}
|
|
1194
1196
|
}
|
|
1195
|
-
const $ = X("debugprogressive"),
|
|
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 = [
|
|
1196
1198
|
3526751,
|
|
1197
1199
|
11065402,
|
|
1198
1200
|
15978811,
|
|
@@ -1226,16 +1228,16 @@ const $ = X("debugprogressive"), At = $ === "colors", It = X("noprogressive"), g
|
|
|
1226
1228
|
5083278,
|
|
1227
1229
|
5592405
|
|
1228
1230
|
];
|
|
1229
|
-
function
|
|
1231
|
+
function $t() {
|
|
1230
1232
|
const i = Se.Timer || Se.Clock;
|
|
1231
1233
|
return new i();
|
|
1232
1234
|
}
|
|
1233
|
-
const me = new fe(), V = new fe(), Pe = new fe(),
|
|
1234
|
-
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) {
|
|
1235
1237
|
const e = i.min, s = i.max, r = (e.x + s.x) * 0.5, n = (e.y + s.y) * 0.5;
|
|
1236
1238
|
return F.set(r, n, e.z).applyMatrix4(t).z < 0;
|
|
1237
1239
|
}
|
|
1238
|
-
function
|
|
1240
|
+
function Ft(i) {
|
|
1239
1241
|
const {
|
|
1240
1242
|
geometry: t,
|
|
1241
1243
|
matrixWorld: e,
|
|
@@ -1257,7 +1259,7 @@ function Ut(i) {
|
|
|
1257
1259
|
h.level = l, h.primitiveIndex = f, h.screenCoverage = 0, h.screenspaceVolume.set(0, 0, 0), h.centrality = 1;
|
|
1258
1260
|
let D = i.boundingBox ?? t.boundingBox;
|
|
1259
1261
|
if (D || (t.computeBoundingBox(), D = t.boundingBox), !D) return h;
|
|
1260
|
-
if (me.copy(D).applyMatrix4(e), s.isPerspectiveCamera &&
|
|
1262
|
+
if (me.copy(D).applyMatrix4(e), s.isPerspectiveCamera && Wt(me, r))
|
|
1261
1263
|
return h.level = 0, h.screenCoverage = 1 / 0, h.screenspaceVolume.set(1 / 0, 1 / 0, 1 / 0), h;
|
|
1262
1264
|
if (V.copy(me).applyMatrix4(r), a && s.isPerspectiveCamera && s.fov > 70) {
|
|
1263
1265
|
const y = V.min, O = V.max;
|
|
@@ -1267,14 +1269,14 @@ function Ut(i) {
|
|
|
1267
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);
|
|
1268
1270
|
h.centrality = (b - J) * (b - J) * (b - J);
|
|
1269
1271
|
}
|
|
1270
|
-
const w = V.getSize(
|
|
1272
|
+
const w = V.getSize(Gt);
|
|
1271
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);
|
|
1272
|
-
const x = Pe.getSize(
|
|
1274
|
+
const x = Pe.getSize(Bt), L = Math.max(w.x, w.y), M = Math.max(x.x, x.y);
|
|
1273
1275
|
L !== 0 && M !== 0 && (w.z = x.z / M * L);
|
|
1274
1276
|
const T = Math.max(w.x, w.y, w.z) * h.centrality;
|
|
1275
1277
|
if (h.screenCoverage = T, h.screenspaceVolume.copy(w), T <= 0) return h;
|
|
1276
1278
|
if (u) {
|
|
1277
|
-
const y =
|
|
1279
|
+
const y = qt.copy(r);
|
|
1278
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);
|
|
1279
1281
|
const O = (F.z + te.z) * 0.5;
|
|
1280
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);
|
|
@@ -1282,7 +1284,7 @@ function Ut(i) {
|
|
|
1282
1284
|
if (c?.length)
|
|
1283
1285
|
for (let y = 0; y < c.length; y++) {
|
|
1284
1286
|
const O = c[y], I = O.densities?.[f] || O.density || 1e-5;
|
|
1285
|
-
if (f > 0 && d &&
|
|
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) {
|
|
1286
1288
|
h.level = y;
|
|
1287
1289
|
break;
|
|
1288
1290
|
}
|
|
@@ -1398,7 +1400,7 @@ class G {
|
|
|
1398
1400
|
const r = performance.now();
|
|
1399
1401
|
return s.ready.finally(() => {
|
|
1400
1402
|
const n = this._newPromiseGroups.indexOf(s);
|
|
1401
|
-
n >= 0 && (this._newPromiseGroups.splice(n, 1),
|
|
1403
|
+
n >= 0 && (this._newPromiseGroups.splice(n, 1), Fe() && performance.measure("LODsManager:awaitLoading", {
|
|
1402
1404
|
start: r,
|
|
1403
1405
|
detail: { id: e, name: t?.name, awaited: s.awaitedCount, resolved: s.resolvedCount }
|
|
1404
1406
|
}));
|
|
@@ -1458,7 +1460,7 @@ class G {
|
|
|
1458
1460
|
#n = 0;
|
|
1459
1461
|
#o = 0;
|
|
1460
1462
|
#s = 0;
|
|
1461
|
-
#i =
|
|
1463
|
+
#i = $t();
|
|
1462
1464
|
_fpsBuffer = [60, 60, 60, 60, 60];
|
|
1463
1465
|
/**
|
|
1464
1466
|
* Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
|
|
@@ -1508,7 +1510,7 @@ class G {
|
|
|
1508
1510
|
(l.name === "EffectMaterial" || l.name === "CopyShader") && (o = !1);
|
|
1509
1511
|
}
|
|
1510
1512
|
if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (o = !1), o) {
|
|
1511
|
-
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))
|
|
1512
1514
|
return;
|
|
1513
1515
|
this.internalUpdate(t, e), this._postprocessPromiseGroups();
|
|
1514
1516
|
}
|
|
@@ -1573,12 +1575,12 @@ class G {
|
|
|
1573
1575
|
updateLODs(t, e, s, r) {
|
|
1574
1576
|
s.userData || (s.userData = {});
|
|
1575
1577
|
let n = s[pe];
|
|
1576
|
-
if (n || (n = new
|
|
1578
|
+
if (n || (n = new Ut(), s[pe] = n), n.frames++ < 2)
|
|
1577
1579
|
return;
|
|
1578
1580
|
for (const l of U)
|
|
1579
1581
|
l.onBeforeUpdateLOD?.(this.renderer, t, e, s);
|
|
1580
1582
|
const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel : K;
|
|
1581
|
-
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 &&
|
|
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);
|
|
1582
1584
|
for (const l of U)
|
|
1583
1585
|
l.onAfterUpdatedLOD?.(this.renderer, t, e, s, R);
|
|
1584
1586
|
n.lastLodLevel_Mesh = R.mesh_lod, n.lastLodLevel_Texture = R.texture_lod;
|
|
@@ -1675,7 +1677,7 @@ class G {
|
|
|
1675
1677
|
return;
|
|
1676
1678
|
}
|
|
1677
1679
|
}
|
|
1678
|
-
const x =
|
|
1680
|
+
const x = Ft({
|
|
1679
1681
|
geometry: e.geometry,
|
|
1680
1682
|
matrixWorld: e.matrixWorld,
|
|
1681
1683
|
camera: t,
|
|
@@ -1728,7 +1730,7 @@ ${e.name}`);
|
|
|
1728
1730
|
n.texture_lod = 0;
|
|
1729
1731
|
}
|
|
1730
1732
|
}
|
|
1731
|
-
class
|
|
1733
|
+
class Ut {
|
|
1732
1734
|
frames = 0;
|
|
1733
1735
|
lastLodLevel_Mesh = -1;
|
|
1734
1736
|
lastLodLevel_Texture = -1;
|
|
@@ -1736,53 +1738,53 @@ class zt {
|
|
|
1736
1738
|
lastScreenspaceVolume = new A();
|
|
1737
1739
|
lastCentrality = 0;
|
|
1738
1740
|
}
|
|
1739
|
-
function
|
|
1741
|
+
function ze(i, t) {
|
|
1740
1742
|
if (!(t < 0)) {
|
|
1741
1743
|
if (Array.isArray(i)) {
|
|
1742
1744
|
for (const e of i)
|
|
1743
|
-
|
|
1745
|
+
ze(e, t);
|
|
1744
1746
|
return;
|
|
1745
1747
|
}
|
|
1746
|
-
"color" in i && i.color instanceof $e && (i.color.copy(
|
|
1748
|
+
"color" in i && i.color instanceof $e && (i.color.copy(zt(t, It)), i.needsUpdate = !0);
|
|
1747
1749
|
}
|
|
1748
1750
|
}
|
|
1749
|
-
function
|
|
1751
|
+
function zt(i, t) {
|
|
1750
1752
|
const e = Math.max(0, Math.min(Re.length - 1, Math.floor(i)));
|
|
1751
1753
|
return t.setHex(Re[e]);
|
|
1752
1754
|
}
|
|
1753
1755
|
const Ce = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), ue = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
|
|
1754
1756
|
let ye = null;
|
|
1755
|
-
function
|
|
1756
|
-
const i =
|
|
1757
|
+
function Ee() {
|
|
1758
|
+
const i = Et();
|
|
1757
1759
|
i && (i.mapURLs(function(t) {
|
|
1758
1760
|
return ke(), t;
|
|
1759
1761
|
}), ke(), ye?.disconnect(), ye = new MutationObserver((t) => {
|
|
1760
1762
|
t.forEach((e) => {
|
|
1761
1763
|
e.addedNodes.forEach((s) => {
|
|
1762
|
-
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" &&
|
|
1764
|
+
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Ne(s);
|
|
1763
1765
|
});
|
|
1764
1766
|
});
|
|
1765
1767
|
}), ye.observe(document, { childList: !0, subtree: !0 }));
|
|
1766
1768
|
}
|
|
1767
|
-
function
|
|
1769
|
+
function Et() {
|
|
1768
1770
|
if (typeof customElements > "u") return null;
|
|
1769
1771
|
const i = customElements.get("model-viewer");
|
|
1770
1772
|
return i || (customElements.whenDefined("model-viewer").then(() => {
|
|
1771
|
-
console.debug("[gltf-progressive] model-viewer defined"),
|
|
1773
|
+
console.debug("[gltf-progressive] model-viewer defined"), Ee();
|
|
1772
1774
|
}), null);
|
|
1773
1775
|
}
|
|
1774
1776
|
function ke() {
|
|
1775
1777
|
if (typeof document > "u") return;
|
|
1776
1778
|
document.querySelectorAll("model-viewer").forEach((t) => {
|
|
1777
|
-
|
|
1779
|
+
Ne(t);
|
|
1778
1780
|
});
|
|
1779
1781
|
}
|
|
1780
1782
|
const Ae = /* @__PURE__ */ new WeakSet();
|
|
1781
|
-
let
|
|
1782
|
-
function
|
|
1783
|
+
let Nt = 0;
|
|
1784
|
+
function Ne(i) {
|
|
1783
1785
|
if (!i || Ae.has(i))
|
|
1784
1786
|
return null;
|
|
1785
|
-
Ae.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++
|
|
1787
|
+
Ae.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++Nt + `
|
|
1786
1788
|
`, i.getAttribute("src"));
|
|
1787
1789
|
let t = null, e = null, s = null;
|
|
1788
1790
|
for (let r = i; r != null; r = Object.getPrototypeOf(r)) {
|
|
@@ -1804,7 +1806,7 @@ function Ve(i) {
|
|
|
1804
1806
|
};
|
|
1805
1807
|
console.debug("[gltf-progressive] setup model-viewer");
|
|
1806
1808
|
const n = G.get(t, { engine: "model-viewer" });
|
|
1807
|
-
return G.addPlugin(new
|
|
1809
|
+
return G.addPlugin(new Vt()), n.enable(), n.addEventListener("changed", () => {
|
|
1808
1810
|
s?.call(i);
|
|
1809
1811
|
}), i.addEventListener("model-visibility", (o) => {
|
|
1810
1812
|
o.detail.visible && s?.call(i);
|
|
@@ -1816,7 +1818,7 @@ function Ve(i) {
|
|
|
1816
1818
|
}
|
|
1817
1819
|
return null;
|
|
1818
1820
|
}
|
|
1819
|
-
class
|
|
1821
|
+
class Vt {
|
|
1820
1822
|
_didWarnAboutMissingUrl = !1;
|
|
1821
1823
|
onBeforeUpdateLOD(t, e, s, r) {
|
|
1822
1824
|
this.tryParseMeshLOD(e, r), this.tryParseTextureLOD(e, r);
|
|
@@ -1877,7 +1879,7 @@ class Xt {
|
|
|
1877
1879
|
}
|
|
1878
1880
|
}
|
|
1879
1881
|
}
|
|
1880
|
-
function
|
|
1882
|
+
function Xt(...i) {
|
|
1881
1883
|
let t, e, s, r;
|
|
1882
1884
|
switch (i.length) {
|
|
1883
1885
|
case 2:
|
|
@@ -1892,22 +1894,22 @@ function jt(...i) {
|
|
|
1892
1894
|
default:
|
|
1893
1895
|
throw new Error("Invalid arguments");
|
|
1894
1896
|
}
|
|
1895
|
-
_e(e),
|
|
1897
|
+
_e(e), Be(s), We(s, {
|
|
1896
1898
|
progressive: !0,
|
|
1897
1899
|
...r?.hints
|
|
1898
1900
|
}), s.register((o) => new p(o));
|
|
1899
1901
|
const n = G.get(e);
|
|
1900
1902
|
return r?.enableLODsManager !== !1 && n.enable(), n;
|
|
1901
1903
|
}
|
|
1902
|
-
|
|
1903
|
-
if (!
|
|
1904
|
+
Ee();
|
|
1905
|
+
if (!Dt) {
|
|
1904
1906
|
const i = {
|
|
1905
1907
|
gltfProgressive: {
|
|
1906
|
-
useNeedleProgressive:
|
|
1908
|
+
useNeedleProgressive: Xt,
|
|
1907
1909
|
LODsManager: G,
|
|
1908
|
-
configureLoader:
|
|
1910
|
+
configureLoader: We,
|
|
1909
1911
|
getRaycastMesh: ae,
|
|
1910
|
-
useRaycastMeshes:
|
|
1912
|
+
useRaycastMeshes: _t
|
|
1911
1913
|
}
|
|
1912
1914
|
};
|
|
1913
1915
|
if (!globalThis.Needle)
|
|
@@ -1920,18 +1922,18 @@ export {
|
|
|
1920
1922
|
z as EXTENSION_NAME,
|
|
1921
1923
|
G as LODsManager,
|
|
1922
1924
|
p as NEEDLE_progressive,
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1925
|
+
lt as VERSION,
|
|
1926
|
+
Be as addDracoAndKTX2Loaders,
|
|
1927
|
+
Ft as calculateMeshLODLevel,
|
|
1928
|
+
We as configureLoader,
|
|
1927
1929
|
_e as createLoaders,
|
|
1928
|
-
|
|
1930
|
+
zt as getLODColor,
|
|
1929
1931
|
ae as getRaycastMesh,
|
|
1930
1932
|
Re as lodDebugColors,
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1933
|
+
Ee as patchModelViewer,
|
|
1934
|
+
Mt as registerRaycastMesh,
|
|
1935
|
+
dt as setDracoDecoderLocation,
|
|
1936
|
+
ht as setKTX2TranscoderLocation,
|
|
1937
|
+
Xt as useNeedleProgressive,
|
|
1938
|
+
_t as useRaycastMeshes
|
|
1937
1939
|
};
|