@needle-tools/gltf-progressive 3.6.0-canary.5401de9 → 3.6.0
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/README.md +16 -14
- package/examples/modelviewer-multiple.html +4 -4
- package/examples/modelviewer.html +4 -4
- package/examples/offscreen/main.js +39 -7
- package/examples/react-three-fiber/package-lock.json +482 -484
- package/examples/react-three-fiber/package.json +4 -4
- package/examples/react-three-fiber/src/App.tsx +28 -14
- package/examples/shared/example-utils.js +75 -3
- package/examples/shared/example.css +17 -0
- package/examples/shared/runtime.js +2 -1
- package/examples/threejs/index.html +4 -4
- package/examples/webgpu/main.js +42 -7
- package/examples/worker-rendering/main.js +19 -1
- package/examples/worker-rendering/worker.js +108 -19
- package/gltf-progressive.js +100 -99
- package/gltf-progressive.min.js +7 -7
- package/gltf-progressive.umd.cjs +2 -2
- package/lib/loaders.d.ts +8 -1
- package/lib/lods.manager.js +16 -12
- package/lib/utils.d.ts +1 -1
- package/lib/utils.internal.js +8 -2
- package/lib/version.js +1 -1
- package/package.json +3 -3
package/gltf-progressive.js
CHANGED
|
@@ -71,7 +71,7 @@ function yt(i) {
|
|
|
71
71
|
function Te(i) {
|
|
72
72
|
return i != null && i.data != null;
|
|
73
73
|
}
|
|
74
|
-
function
|
|
74
|
+
function Le(i) {
|
|
75
75
|
const t = i.source?.data;
|
|
76
76
|
return t != null && typeof t == "object" ? t : null;
|
|
77
77
|
}
|
|
@@ -79,8 +79,8 @@ function xt(i) {
|
|
|
79
79
|
const t = i.image;
|
|
80
80
|
return t != null && typeof t == "object" ? t : null;
|
|
81
81
|
}
|
|
82
|
-
function
|
|
83
|
-
const t = xt(i), e =
|
|
82
|
+
function we(i) {
|
|
83
|
+
const t = xt(i), e = Le(i);
|
|
84
84
|
return {
|
|
85
85
|
width: t?.width || e?.width || 0,
|
|
86
86
|
height: t?.height || e?.height || 0
|
|
@@ -93,7 +93,7 @@ function V(i) {
|
|
|
93
93
|
const s = new URL(t).searchParams.get(i);
|
|
94
94
|
return s == null || s === "0" || s === "false" ? !1 : s === "" ? !0 : s;
|
|
95
95
|
}
|
|
96
|
-
function
|
|
96
|
+
function Lt(i, t) {
|
|
97
97
|
if (t === void 0 || i === void 0 || t.startsWith("./") || t.startsWith("http") || t.startsWith("data:") || t.startsWith("blob:"))
|
|
98
98
|
return t;
|
|
99
99
|
const e = i.lastIndexOf("/");
|
|
@@ -116,9 +116,9 @@ function Fe() {
|
|
|
116
116
|
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
117
|
return t.hostname === "127.0.0.1" || e;
|
|
118
118
|
}
|
|
119
|
-
class
|
|
119
|
+
class wt {
|
|
120
120
|
constructor(t, e = {}) {
|
|
121
|
-
this.maxConcurrent = t, this.debug = e.debug ?? !1, typeof
|
|
121
|
+
this.maxConcurrent = t, this.debug = e.debug ?? !1, typeof globalThis.requestAnimationFrame == "function" ? globalThis.requestAnimationFrame(this.tick) : setTimeout(this.tick, 0);
|
|
122
122
|
}
|
|
123
123
|
_running = /* @__PURE__ */ new Map();
|
|
124
124
|
_queue = [];
|
|
@@ -329,7 +329,7 @@ function Ct(i) {
|
|
|
329
329
|
const e = t.texture;
|
|
330
330
|
let s = null;
|
|
331
331
|
if (e.isCompressedTexture) {
|
|
332
|
-
const r = e.mipmaps, { width: n, height: o } =
|
|
332
|
+
const r = e.mipmaps, { width: n, height: o } = we(e);
|
|
333
333
|
s = new et(
|
|
334
334
|
r,
|
|
335
335
|
n,
|
|
@@ -376,7 +376,7 @@ function fe(i) {
|
|
|
376
376
|
const Pt = V("gltf-progressive-worker");
|
|
377
377
|
V("gltf-progressive-reduce-mipmaps");
|
|
378
378
|
const se = V("gltf-progressive-gc"), de = /* @__PURE__ */ Symbol("needle-progressive-texture"), U = "NEEDLE_progressive";
|
|
379
|
-
class
|
|
379
|
+
class g {
|
|
380
380
|
/** The name of the extension */
|
|
381
381
|
get name() {
|
|
382
382
|
return U;
|
|
@@ -509,7 +509,7 @@ class p {
|
|
|
509
509
|
a.onBeforeGetLODMesh?.(t, e);
|
|
510
510
|
t["LOD:requested level"] = e;
|
|
511
511
|
const o = () => t["LOD:requested level"] === e || this.shouldApplyStaleMeshLOD(t, e);
|
|
512
|
-
return
|
|
512
|
+
return g.getOrLoadLOD(r, e, {
|
|
513
513
|
isCurrent: o
|
|
514
514
|
}).then((a) => {
|
|
515
515
|
if (Array.isArray(a)) {
|
|
@@ -581,10 +581,10 @@ class p {
|
|
|
581
581
|
* @default 50 on desktop, 20 on mobile devices
|
|
582
582
|
*/
|
|
583
583
|
static set maxConcurrentLoadingTasks(t) {
|
|
584
|
-
|
|
584
|
+
g.queue.maxConcurrent = t;
|
|
585
585
|
}
|
|
586
586
|
static get maxConcurrentLoadingTasks() {
|
|
587
|
-
return
|
|
587
|
+
return g.queue.maxConcurrent;
|
|
588
588
|
}
|
|
589
589
|
// #region INTERNAL
|
|
590
590
|
static assignTextureLODForSlot(t, e, s, r, n) {
|
|
@@ -600,7 +600,7 @@ class p {
|
|
|
600
600
|
if (c && c.level === e && c.force === n)
|
|
601
601
|
return c.promise;
|
|
602
602
|
}
|
|
603
|
-
const a = s && r ? this.nextTextureSlotRequestId(s, r, e, n) : 0, l = () => !s || !r || this.getLatestTextureSlotRequest(s, r)?.id === a, u = () => l() || this.shouldApplyStaleTextureSlotLOD(s, r, e, n), f =
|
|
603
|
+
const a = s && r ? this.nextTextureSlotRequestId(s, r, e, n) : 0, l = () => !s || !r || this.getLatestTextureSlotRequest(s, r)?.id === a, u = () => l() || this.shouldApplyStaleTextureSlotLOD(s, r, e, n), f = g.getOrLoadLOD(t, e, {
|
|
604
604
|
isCurrent: u
|
|
605
605
|
}).then((c) => {
|
|
606
606
|
if (!l() && !this.shouldApplyStaleTextureSlotLOD(s, r, e, n)) return null;
|
|
@@ -610,9 +610,9 @@ class p {
|
|
|
610
610
|
if (c != t && s && r) {
|
|
611
611
|
const d = this.getMaterialTextureSlot(s, r) ?? t;
|
|
612
612
|
if (d && !n) {
|
|
613
|
-
const
|
|
614
|
-
if (
|
|
615
|
-
return h === "verbose" && console.warn("Assigned texture level is already higher: ",
|
|
613
|
+
const p = this.getAssignedLODInformation(d);
|
|
614
|
+
if (p && p?.level < e)
|
|
615
|
+
return h === "verbose" && console.warn("Assigned texture level is already higher: ", p.level, e, s, d, c), null;
|
|
616
616
|
}
|
|
617
617
|
this.assignTrackedTextureSlot(s, r, c);
|
|
618
618
|
}
|
|
@@ -718,7 +718,7 @@ class p {
|
|
|
718
718
|
loadMesh = (t) => {
|
|
719
719
|
if (this._isLoadingMesh) return null;
|
|
720
720
|
const e = this.parser.json.meshes[t]?.extensions?.[U];
|
|
721
|
-
return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s &&
|
|
721
|
+
return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s && g.registerMesh(this.url, e.guid, s, e.lods?.length, 0, e), s))) : null;
|
|
722
722
|
};
|
|
723
723
|
// private _isLoadingTexture;
|
|
724
724
|
// loadTexture = (textureIndex: number) => {
|
|
@@ -745,9 +745,9 @@ class p {
|
|
|
745
745
|
}
|
|
746
746
|
let n = !1;
|
|
747
747
|
for (const o of this.parser.associations.keys())
|
|
748
|
-
o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (n = !0,
|
|
748
|
+
o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (n = !0, g.registerTexture(this.url, o, r.lods?.length, s, r));
|
|
749
749
|
n || this.parser.getDependency("texture", s).then((o) => {
|
|
750
|
-
o &&
|
|
750
|
+
o && g.registerTexture(this.url, o, r.lods?.length, s, r);
|
|
751
751
|
});
|
|
752
752
|
}
|
|
753
753
|
}
|
|
@@ -758,7 +758,7 @@ class p {
|
|
|
758
758
|
for (const n of this.parser.associations.keys())
|
|
759
759
|
if (n.isMesh) {
|
|
760
760
|
const o = this.parser.associations.get(n);
|
|
761
|
-
o?.meshes === s &&
|
|
761
|
+
o?.meshes === s && g.registerMesh(this.url, r.guid, n, r.lods.length, o.primitives, r);
|
|
762
762
|
}
|
|
763
763
|
}
|
|
764
764
|
}
|
|
@@ -781,12 +781,12 @@ class p {
|
|
|
781
781
|
return;
|
|
782
782
|
}
|
|
783
783
|
if (h) {
|
|
784
|
-
const { width: a, height: l } =
|
|
784
|
+
const { width: a, height: l } = we(e);
|
|
785
785
|
console.log(`> gltf-progressive: register texture[${r}] "${e.name || e.uuid}", Current: ${a}x${l}, Max: ${n.lods[0]?.width}x${n.lods[0]?.height}, uuid: ${e.uuid}`, n, e);
|
|
786
786
|
}
|
|
787
787
|
e.source && (e.source[de] = n);
|
|
788
788
|
const o = n.guid;
|
|
789
|
-
|
|
789
|
+
g.assignLODInformation(t, e, o, s, r), g.lodInfos.set(o, n), g.lowresCache.set(o, new WeakRef(e));
|
|
790
790
|
};
|
|
791
791
|
/**
|
|
792
792
|
* Register a mesh with progressive LOD information. This associates the mesh geometry with its LOD extension data
|
|
@@ -807,9 +807,9 @@ class p {
|
|
|
807
807
|
h && console.warn("gltf-progressive: Register mesh without geometry");
|
|
808
808
|
return;
|
|
809
809
|
}
|
|
810
|
-
a.userData || (a.userData = {}), h && console.log("> Progressive: register mesh " + s.name, { index: n, uuid: s.uuid }, o, s),
|
|
811
|
-
let u =
|
|
812
|
-
u ? u.push(s.geometry) : u = [s.geometry],
|
|
810
|
+
a.userData || (a.userData = {}), h && console.log("> Progressive: register mesh " + s.name, { index: n, uuid: s.uuid }, o, s), g.assignLODInformation(t, a, e, r, n), g.lodInfos.set(e, o);
|
|
811
|
+
let u = g.lowresCache.get(e)?.deref();
|
|
812
|
+
u ? u.push(s.geometry) : u = [s.geometry], g.lowresCache.set(e, new WeakRef(u)), r > 0 && !ne(s) && Mt(s, a);
|
|
813
813
|
for (const f of F)
|
|
814
814
|
f.onRegisteredNewMesh?.(s, o);
|
|
815
815
|
};
|
|
@@ -884,9 +884,9 @@ class p {
|
|
|
884
884
|
* The held value is the cache key string used in `previouslyLoaded`.
|
|
885
885
|
*/
|
|
886
886
|
static _resourceRegistry = new FinalizationRegistry((t) => {
|
|
887
|
-
const e =
|
|
887
|
+
const e = g.cache.get(t);
|
|
888
888
|
(h || se) && console.debug(`[gltf-progressive] Memory: Resource GC'd
|
|
889
|
-
${t}`), e instanceof WeakRef && (e.deref() || (
|
|
889
|
+
${t}`), e instanceof WeakRef && (e.deref() || (g.cache.delete(t), (h || se) && console.log("[gltf-progressive] ↪ Cache entry deleted (GC)")));
|
|
890
890
|
});
|
|
891
891
|
/**
|
|
892
892
|
* Track texture usage by incrementing reference count
|
|
@@ -909,7 +909,7 @@ ${t}`), e instanceof WeakRef && (e.deref() || (p.cache.delete(t), (h || se) && c
|
|
|
909
909
|
return this.textureRefCounts.delete(e), (h || se) && n("[gltf-progressive] Memory: Dispose texture", r), t.dispose(), !0;
|
|
910
910
|
return this.textureRefCounts.set(e, r), h === "verbose" && n("[gltf-progressive] Memory: Untrack texture", r), !1;
|
|
911
911
|
function n(o, a) {
|
|
912
|
-
let { width: l, height: u } =
|
|
912
|
+
let { width: l, height: u } = we(t);
|
|
913
913
|
const f = l && u ? `${l}x${u}` : "N/A";
|
|
914
914
|
let c = "N/A";
|
|
915
915
|
l && u && (c = `~${(vt(t) / (1024 * 1024)).toFixed(2)} MB`), console.log(`${o} — ${t.name} ${f} (${c}), refCount: ${s} → ${a}
|
|
@@ -928,16 +928,16 @@ ${e}`);
|
|
|
928
928
|
const u = t;
|
|
929
929
|
u.source && u.source[de] && (a = u.source[de]);
|
|
930
930
|
}
|
|
931
|
-
if (a || (a =
|
|
932
|
-
h && console.warn(`Can not load LOD ${e}: no LOD info found for "${o}" ${t.name}`, t.type,
|
|
931
|
+
if (a || (a = g.lodInfos.get(o)), !a)
|
|
932
|
+
h && console.warn(`Can not load LOD ${e}: no LOD info found for "${o}" ${t.name}`, t.type, g.lodInfos);
|
|
933
933
|
else {
|
|
934
934
|
if (e > 0) {
|
|
935
935
|
let c = !1;
|
|
936
936
|
const d = Array.isArray(a.lods);
|
|
937
937
|
if (d && e >= a.lods.length ? c = !0 : d || (c = !0), c) {
|
|
938
|
-
const
|
|
939
|
-
if (
|
|
940
|
-
const b =
|
|
938
|
+
const p = this.lowresCache.get(o);
|
|
939
|
+
if (p) {
|
|
940
|
+
const b = p.deref();
|
|
941
941
|
if (b) return b;
|
|
942
942
|
this.lowresCache.delete(o), h && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${o}`);
|
|
943
943
|
}
|
|
@@ -947,7 +947,7 @@ ${e}`);
|
|
|
947
947
|
const u = Array.isArray(a.lods) ? a.lods[e]?.path : a.lods;
|
|
948
948
|
if (!u)
|
|
949
949
|
return h && !a["missing:uri"] && (a["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, a)), null;
|
|
950
|
-
const f =
|
|
950
|
+
const f = Lt(n.url, u);
|
|
951
951
|
if (f.endsWith(".glb") || f.endsWith(".gltf")) {
|
|
952
952
|
if (!a.guid)
|
|
953
953
|
return console.warn("missing pointer for glb/gltf texture", a), null;
|
|
@@ -955,30 +955,30 @@ ${e}`);
|
|
|
955
955
|
if (d.found) return d.value;
|
|
956
956
|
if (s?.isCurrent?.() === !1)
|
|
957
957
|
return r && console.log(`Skipping stale LOD ${e} request before queue: ${f}`), null;
|
|
958
|
-
const
|
|
958
|
+
const p = await this.queue.slot(f);
|
|
959
959
|
if (s?.isCurrent?.() === !1)
|
|
960
960
|
return r && console.log(`Skipping stale LOD ${e} request after queue: ${f}`), null;
|
|
961
961
|
const b = await this.tryResolveLODCacheEntry(this.cache.get(c), c, f, t, e, r);
|
|
962
962
|
if (b.found) return b.value;
|
|
963
|
-
if (!
|
|
963
|
+
if (!p.use)
|
|
964
964
|
return h && console.log(`LOD ${e} was aborted: ${f}`), null;
|
|
965
|
-
const y = a, x = new Promise(async (
|
|
965
|
+
const y = a, x = new Promise(async (L, z) => {
|
|
966
966
|
if (Pt) {
|
|
967
967
|
const m = await (await Rt({})).load(f);
|
|
968
968
|
if (m.textures.length > 0)
|
|
969
969
|
for (const D of m.textures) {
|
|
970
970
|
let M = D.texture;
|
|
971
|
-
return
|
|
971
|
+
return g.assignLODInformation(n.url, M, o, e, void 0), t instanceof q && (M = this.copySettings(t, M)), M && (M.guid = y.guid), L(M);
|
|
972
972
|
}
|
|
973
973
|
if (m.geometries.length > 0) {
|
|
974
974
|
const D = new Array();
|
|
975
975
|
for (const M of m.geometries) {
|
|
976
976
|
const G = M.geometry;
|
|
977
|
-
|
|
977
|
+
g.assignLODInformation(n.url, G, o, e, M.primitiveIndex), D.push(G);
|
|
978
978
|
}
|
|
979
|
-
return
|
|
979
|
+
return L(D);
|
|
980
980
|
}
|
|
981
|
-
return
|
|
981
|
+
return L(null);
|
|
982
982
|
}
|
|
983
983
|
const v = new De();
|
|
984
984
|
Ge(v), h && (await new Promise((_) => setTimeout(_, 1e3)), r && console.warn("Start loading (delayed) " + f, y.guid));
|
|
@@ -988,9 +988,9 @@ ${e}`);
|
|
|
988
988
|
_.hash && (T += "?v=" + _.hash);
|
|
989
989
|
}
|
|
990
990
|
const O = await v.loadAsync(T).catch((_) => (console.error(`Error loading LOD ${e} from ${f}
|
|
991
|
-
`, _),
|
|
991
|
+
`, _), L(null)));
|
|
992
992
|
if (!O)
|
|
993
|
-
return
|
|
993
|
+
return L(null);
|
|
994
994
|
const P = O.parser;
|
|
995
995
|
r && console.log("Loading finished " + f, y.guid);
|
|
996
996
|
let S = 0;
|
|
@@ -1008,7 +1008,7 @@ ${e}`);
|
|
|
1008
1008
|
}
|
|
1009
1009
|
if (_) {
|
|
1010
1010
|
let m = await P.getDependency("texture", S);
|
|
1011
|
-
return m &&
|
|
1011
|
+
return m && g.assignLODInformation(n.url, m, o, e, void 0), r && console.log('change "' + t.name + '" → "' + m.name + '"', f, S, m, c), t instanceof q && (m = this.copySettings(t, m)), m && (m.guid = y.guid), L(m);
|
|
1012
1012
|
} else h && console.warn("Could not find texture with guid", y.guid, O.parser.json);
|
|
1013
1013
|
}
|
|
1014
1014
|
if (S = 0, O.parser.json.meshes) {
|
|
@@ -1027,25 +1027,25 @@ ${e}`);
|
|
|
1027
1027
|
const m = await P.getDependency("mesh", S);
|
|
1028
1028
|
if (r && console.log(`Loaded Mesh "${m.name}"`, f, S, m, c), m.isMesh === !0) {
|
|
1029
1029
|
const D = m.geometry;
|
|
1030
|
-
return
|
|
1030
|
+
return g.assignLODInformation(n.url, D, o, e, 0), L(D);
|
|
1031
1031
|
} else {
|
|
1032
1032
|
const D = new Array();
|
|
1033
1033
|
for (let M = 0; M < m.children.length; M++) {
|
|
1034
1034
|
const G = m.children[M];
|
|
1035
1035
|
if (G.isMesh === !0) {
|
|
1036
1036
|
const ie = G.geometry;
|
|
1037
|
-
|
|
1037
|
+
g.assignLODInformation(n.url, ie, o, e, M), D.push(ie);
|
|
1038
1038
|
}
|
|
1039
1039
|
}
|
|
1040
|
-
return
|
|
1040
|
+
return L(D);
|
|
1041
1041
|
}
|
|
1042
1042
|
} else h && console.warn("Could not find mesh with guid", y.guid, O.parser.json);
|
|
1043
1043
|
}
|
|
1044
|
-
return
|
|
1044
|
+
return L(null);
|
|
1045
1045
|
});
|
|
1046
|
-
this.cache.set(c, x),
|
|
1047
|
-
const
|
|
1048
|
-
return
|
|
1046
|
+
this.cache.set(c, x), p.use(x);
|
|
1047
|
+
const w = await x;
|
|
1048
|
+
return w != null ? w instanceof q ? (this.cache.set(c, new WeakRef(w)), g._resourceRegistry.register(w, c)) : Array.isArray(w) ? this.cache.set(c, Promise.resolve(w)) : this.cache.set(c, Promise.resolve(w)) : this.cache.set(c, Promise.resolve(null)), w;
|
|
1049
1049
|
} else if (t instanceof q) {
|
|
1050
1050
|
if (s?.isCurrent?.() === !1)
|
|
1051
1051
|
return r && console.log(`Skipping stale texture LOD ${e} request: ${f}`), null;
|
|
@@ -1063,18 +1063,18 @@ ${e}`);
|
|
|
1063
1063
|
const u = t.deref();
|
|
1064
1064
|
if (u) {
|
|
1065
1065
|
let f = u, c = !1;
|
|
1066
|
-
if (f instanceof q && r instanceof q ? Te(f.image) ||
|
|
1066
|
+
if (f instanceof q && r instanceof q ? Te(f.image) || Le(f) ? f = this.copySettings(r, f) : c = !0 : f instanceof j && r instanceof j && (f.attributes.position?.array || (c = !0)), !c)
|
|
1067
1067
|
return { found: !0, value: f };
|
|
1068
1068
|
}
|
|
1069
1069
|
return this.cache.delete(e), h && console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${e}`), { found: !1 };
|
|
1070
1070
|
}
|
|
1071
1071
|
let a = await t.catch((u) => (console.error(`Error loading LOD ${n} from ${s}
|
|
1072
1072
|
`, u), null)), l = !1;
|
|
1073
|
-
return a == null || (a instanceof q && r instanceof q ? Te(a.image) ||
|
|
1073
|
+
return a == null || (a instanceof q && r instanceof q ? Te(a.image) || Le(a) ? a = this.copySettings(r, a) : (l = !0, this.cache.delete(e)) : a instanceof j && r instanceof j && (a.attributes.position?.array || (l = !0, this.cache.delete(e)))), l ? { found: !1 } : { found: !0, value: a };
|
|
1074
1074
|
}
|
|
1075
1075
|
static _queue;
|
|
1076
1076
|
static get queue() {
|
|
1077
|
-
return this._queue ??= new
|
|
1077
|
+
return this._queue ??= new wt(Me() ? 20 : 50, { debug: h != !1 });
|
|
1078
1078
|
}
|
|
1079
1079
|
static assignLODInformation(t, e, s, r, n) {
|
|
1080
1080
|
if (!e) return;
|
|
@@ -1234,46 +1234,47 @@ function Ut(i) {
|
|
|
1234
1234
|
xrEnabled: l = !1,
|
|
1235
1235
|
debugDrawLine: u,
|
|
1236
1236
|
warnMissingPrimitiveDensities: f = !1
|
|
1237
|
-
} = i, c =
|
|
1237
|
+
} = i, c = g.getMeshLODExtension(t)?.lods, d = g.getPrimitiveIndex(t), p = i.target ?? {
|
|
1238
1238
|
level: a,
|
|
1239
1239
|
primitiveIndex: d,
|
|
1240
1240
|
screenCoverage: 0,
|
|
1241
1241
|
screenspaceVolume: new k(),
|
|
1242
1242
|
centrality: 1
|
|
1243
1243
|
};
|
|
1244
|
-
|
|
1244
|
+
p.level = a, p.primitiveIndex = d, p.screenCoverage = 0, p.screenspaceVolume.set(0, 0, 0), p.centrality = 1;
|
|
1245
1245
|
let b = i.boundingBox ?? t.boundingBox;
|
|
1246
|
-
if (b || (t.computeBoundingBox(), b = t.boundingBox), !b) return
|
|
1246
|
+
if (b || (t.computeBoundingBox(), b = t.boundingBox), !b) return p;
|
|
1247
1247
|
if (pe.copy(b).applyMatrix4(e), s.isPerspectiveCamera && Ft(pe, r))
|
|
1248
|
-
return
|
|
1248
|
+
return p.level = 0, p.screenCoverage = 1 / 0, p.screenspaceVolume.set(1 / 0, 1 / 0, 1 / 0), p;
|
|
1249
1249
|
if (N.copy(pe).applyMatrix4(r), l && s.isPerspectiveCamera && s.fov > 70) {
|
|
1250
1250
|
const v = N.min, T = N.max;
|
|
1251
1251
|
let O = v.x, P = v.y, S = T.x, _ = T.y;
|
|
1252
1252
|
const m = 2, D = 1.5, M = (v.x + T.x) * 0.5, G = (v.y + T.y) * 0.5;
|
|
1253
1253
|
O = (O - M) * m + M, P = (P - G) * m + G, S = (S - M) * m + M, _ = (_ - G) * m + G;
|
|
1254
1254
|
const ie = O < 0 && S > 0 ? 0 : Math.min(Math.abs(v.x), Math.abs(T.x)), Ve = P < 0 && _ > 0 ? 0 : Math.min(Math.abs(v.y), Math.abs(T.y)), ce = Math.max(ie, Ve);
|
|
1255
|
-
|
|
1255
|
+
p.centrality = (D - ce) * (D - ce) * (D - ce);
|
|
1256
1256
|
}
|
|
1257
1257
|
const y = N.getSize(Gt);
|
|
1258
1258
|
y.multiplyScalar(0.5), globalThis.screen?.availHeight > 0 && o > 0 && y.multiplyScalar(o / globalThis.screen.availHeight), s.isPerspectiveCamera && (y.x *= s.aspect), Re.copy(b).applyMatrix4(e).applyMatrix4(s.matrixWorldInverse);
|
|
1259
|
-
const x = Re.getSize(qt),
|
|
1260
|
-
|
|
1261
|
-
const z = Math.max(y.x, y.y, y.z) *
|
|
1262
|
-
if (
|
|
1259
|
+
const x = Re.getSize(qt), w = Math.max(y.x, y.y), L = Math.max(x.x, x.y);
|
|
1260
|
+
w !== 0 && L !== 0 && (y.z = x.z / L * w);
|
|
1261
|
+
const z = Math.max(y.x, y.y, y.z) * p.centrality;
|
|
1262
|
+
if (p.screenCoverage = z, p.screenspaceVolume.copy(y), z <= 0) return p;
|
|
1263
1263
|
if (u) {
|
|
1264
1264
|
const v = Wt.copy(r);
|
|
1265
1265
|
v.invert(), W.copy(N.min), H.copy(N.max), H.x = W.x, Q.copy(N.max), Q.y = W.y, J.copy(N.max);
|
|
1266
1266
|
const T = (W.z + J.z) * 0.5;
|
|
1267
1267
|
W.z = H.z = Q.z = J.z = T, W.applyMatrix4(v), H.applyMatrix4(v), Q.applyMatrix4(v), J.applyMatrix4(v), u(W, H, 255), u(W, Q, 255), u(H, J, 255), u(Q, J, 255);
|
|
1268
1268
|
}
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1269
|
+
if (c?.length)
|
|
1270
|
+
for (let v = 0; v < c.length; v++) {
|
|
1271
|
+
const T = c[v], O = T.densities?.[d] || T.density || 1e-5;
|
|
1272
|
+
if (d > 0 && f && Fe() && !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.")), O / z < n) {
|
|
1273
|
+
p.level = v;
|
|
1274
|
+
break;
|
|
1275
|
+
}
|
|
1274
1276
|
}
|
|
1275
|
-
|
|
1276
|
-
return g;
|
|
1277
|
+
return p;
|
|
1277
1278
|
}
|
|
1278
1279
|
class I {
|
|
1279
1280
|
/**
|
|
@@ -1586,7 +1587,7 @@ class I {
|
|
|
1586
1587
|
const n = s !== void 0 && s >= 0;
|
|
1587
1588
|
if (n && (r = t[E] != s, e = s), r) {
|
|
1588
1589
|
t[E] = e;
|
|
1589
|
-
const o = n ? { force: !0 } : void 0, a =
|
|
1590
|
+
const o = n ? { force: !0 } : void 0, a = g.assignTextureLOD(t, e, o).then((l) => {
|
|
1590
1591
|
this._lodchangedlisteners.forEach((u) => u({ type: "texture", level: e, object: t }));
|
|
1591
1592
|
});
|
|
1592
1593
|
oe.addPromise("texture", t, a, this._newPromiseGroups);
|
|
@@ -1604,7 +1605,7 @@ class I {
|
|
|
1604
1605
|
const r = t["DEBUG:LOD"];
|
|
1605
1606
|
if (r != null && (s = t[E] != r, e = r), s) {
|
|
1606
1607
|
t[E] = e;
|
|
1607
|
-
const n = t.geometry, o =
|
|
1608
|
+
const n = t.geometry, o = g.assignMeshLOD(t, e).then((a) => (a && t[E] == e && n != t.geometry && this._lodchangedlisteners.forEach((l) => l({ type: "mesh", level: e, object: t })), a));
|
|
1608
1609
|
return oe.addPromise("mesh", t, o, this._newPromiseGroups), o;
|
|
1609
1610
|
}
|
|
1610
1611
|
return Promise.resolve(null);
|
|
@@ -1627,8 +1628,8 @@ class I {
|
|
|
1627
1628
|
let a = 10 + 1, l = !1;
|
|
1628
1629
|
if (A && e["DEBUG:LOD"] != null)
|
|
1629
1630
|
return e["DEBUG:LOD"];
|
|
1630
|
-
const u =
|
|
1631
|
-
if (!c && !
|
|
1631
|
+
const u = g.getMeshLODExtension(e.geometry)?.lods, f = g.getPrimitiveIndex(e.geometry), c = u && u.length > 0, d = g.getMaterialMinMaxLODsCount(e.material), p = d.min_count !== 1 / 0 && d.min_count >= 0 && d.max_count >= 0;
|
|
1632
|
+
if (!c && !p) {
|
|
1632
1633
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1633
1634
|
return;
|
|
1634
1635
|
}
|
|
@@ -1641,13 +1642,13 @@ class I {
|
|
|
1641
1642
|
x.computeBoundingBox();
|
|
1642
1643
|
else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
|
|
1643
1644
|
if (!x[I.$skinnedMeshBoundsOffset]) {
|
|
1644
|
-
const
|
|
1645
|
-
x[I.$skinnedMeshBoundsOffset] =
|
|
1645
|
+
const L = I.skinnedMeshBoundsFrameOffsetCounter++;
|
|
1646
|
+
x[I.$skinnedMeshBoundsOffset] = L;
|
|
1646
1647
|
}
|
|
1647
|
-
const
|
|
1648
|
-
if ((s.frames +
|
|
1649
|
-
const
|
|
1650
|
-
|
|
1648
|
+
const w = x[I.$skinnedMeshBoundsOffset];
|
|
1649
|
+
if ((s.frames + w) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
|
|
1650
|
+
const L = ne(x), z = x.geometry;
|
|
1651
|
+
L && (x.geometry = L), x.computeBoundingBox(), x.geometry = z;
|
|
1651
1652
|
}
|
|
1652
1653
|
}
|
|
1653
1654
|
y = x.boundingBox;
|
|
@@ -1655,8 +1656,8 @@ class I {
|
|
|
1655
1656
|
if (y) {
|
|
1656
1657
|
if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
|
|
1657
1658
|
this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
|
|
1658
|
-
const
|
|
1659
|
-
if (this._sphere.containsPoint(
|
|
1659
|
+
const L = t.getWorldPosition(this._tempWorldPosition);
|
|
1660
|
+
if (this._sphere.containsPoint(L)) {
|
|
1660
1661
|
n.mesh_lod = 0, n.texture_lod = 0;
|
|
1661
1662
|
return;
|
|
1662
1663
|
}
|
|
@@ -1681,21 +1682,21 @@ class I {
|
|
|
1681
1682
|
x.level >= 0 && x.level < a && (a = x.level, l = !0);
|
|
1682
1683
|
}
|
|
1683
1684
|
if (l ? n.mesh_lod = a : n.mesh_lod = s.lastLodLevel_Mesh, A && n.mesh_lod != s.lastLodLevel_Mesh) {
|
|
1684
|
-
const
|
|
1685
|
-
|
|
1685
|
+
const w = u?.[n.mesh_lod];
|
|
1686
|
+
w && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${n.mesh_lod} (density: ${w.densities?.[f].toFixed(0)}) | ${e.name}`);
|
|
1686
1687
|
}
|
|
1687
|
-
if (
|
|
1688
|
+
if (p) {
|
|
1688
1689
|
const x = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
|
|
1689
1690
|
if (s.lastLodLevel_Texture < 0) {
|
|
1690
1691
|
if (n.texture_lod = d.max_count - 1, A) {
|
|
1691
|
-
const
|
|
1692
|
-
A && console.log(`First Texture LOD ${n.texture_lod} (${
|
|
1692
|
+
const w = d.lods[d.max_count - 1];
|
|
1693
|
+
A && console.log(`First Texture LOD ${n.texture_lod} (${w.max_height}px) - ${e.name}`);
|
|
1693
1694
|
}
|
|
1694
1695
|
} else {
|
|
1695
|
-
const
|
|
1696
|
-
let
|
|
1697
|
-
this.context?.engine === "model-viewer" && (
|
|
1698
|
-
const z = this.renderer.getPixelRatio?.() || globalThis.devicePixelRatio || 1, T = b / z *
|
|
1696
|
+
const w = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
|
|
1697
|
+
let L = s.lastScreenCoverage * 4;
|
|
1698
|
+
this.context?.engine === "model-viewer" && (L *= 1.5);
|
|
1699
|
+
const z = this.renderer.getPixelRatio?.() || globalThis.devicePixelRatio || 1, T = b / z * L;
|
|
1699
1700
|
let O = !1;
|
|
1700
1701
|
for (let P = d.lods.length - 1; P >= 0; P--) {
|
|
1701
1702
|
const S = d.lods[P];
|
|
@@ -1703,7 +1704,7 @@ class I {
|
|
|
1703
1704
|
if (O = !0, n.texture_lod = P, A && n.texture_lod < s.lastLodLevel_Texture) {
|
|
1704
1705
|
const _ = S.max_height;
|
|
1705
1706
|
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${n.texture_lod} = ${_}px
|
|
1706
|
-
Screensize: ${T.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${
|
|
1707
|
+
Screensize: ${T.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${w.toFixed(1)}
|
|
1707
1708
|
${e.name}`);
|
|
1708
1709
|
}
|
|
1709
1710
|
break;
|
|
@@ -1831,16 +1832,16 @@ class Xt {
|
|
|
1831
1832
|
for (let f = 0; f < u.length; f++) {
|
|
1832
1833
|
const c = u[f], d = l[c];
|
|
1833
1834
|
if (d?.isTexture === !0) {
|
|
1834
|
-
const
|
|
1835
|
-
if (
|
|
1836
|
-
const b = s.parser.json.textures[
|
|
1835
|
+
const p = d.userData?.associations?.textures;
|
|
1836
|
+
if (p == null) continue;
|
|
1837
|
+
const b = s.parser.json.textures[p];
|
|
1837
1838
|
if (!b) {
|
|
1838
|
-
console.warn("Texture data not found for texture index " +
|
|
1839
|
+
console.warn("Texture data not found for texture index " + p);
|
|
1839
1840
|
continue;
|
|
1840
1841
|
}
|
|
1841
1842
|
if (b?.extensions?.[U]) {
|
|
1842
1843
|
const y = b.extensions[U];
|
|
1843
|
-
y && n &&
|
|
1844
|
+
y && n && g.registerTexture(n, d, y.lods.length, p, y);
|
|
1844
1845
|
}
|
|
1845
1846
|
}
|
|
1846
1847
|
}
|
|
@@ -1859,7 +1860,7 @@ class Xt {
|
|
|
1859
1860
|
const n = e.userData?.gltfExtensions?.[U];
|
|
1860
1861
|
if (n && r) {
|
|
1861
1862
|
const o = e.uuid;
|
|
1862
|
-
|
|
1863
|
+
g.registerMesh(r, o, e, 0, n.lods.length, n);
|
|
1863
1864
|
}
|
|
1864
1865
|
}
|
|
1865
1866
|
}
|
|
@@ -1881,7 +1882,7 @@ function jt(...i) {
|
|
|
1881
1882
|
_e(e), Ge(s), We(s, {
|
|
1882
1883
|
progressive: !0,
|
|
1883
1884
|
...r?.hints
|
|
1884
|
-
}), s.register((o) => new
|
|
1885
|
+
}), s.register((o) => new g(o));
|
|
1885
1886
|
const n = I.get(e);
|
|
1886
1887
|
return r?.enableLODsManager !== !1 && n.enable(), n;
|
|
1887
1888
|
}
|
|
@@ -1905,7 +1906,7 @@ if (!_t) {
|
|
|
1905
1906
|
export {
|
|
1906
1907
|
U as EXTENSION_NAME,
|
|
1907
1908
|
I as LODsManager,
|
|
1908
|
-
|
|
1909
|
+
g as NEEDLE_progressive,
|
|
1909
1910
|
ut as VERSION,
|
|
1910
1911
|
Ge as addDracoAndKTX2Loaders,
|
|
1911
1912
|
Ut as calculateMeshLODLevel,
|