@needle-tools/gltf-progressive 1.2.2-alpha.3 → 1.2.3-alpha
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 -1
- package/README.md +3 -1
- package/examples/modelviewer-multiple.html +24 -12
- package/gltf-progressive.js +643 -604
- package/gltf-progressive.min.js +7 -6
- package/gltf-progressive.umd.cjs +8 -7
- package/lib/index.js +3 -3
- package/lib/lods_manager.d.ts +4 -4
- package/lib/lods_manager.js +56 -14
- package/lib/plugins/modelviewer.js +41 -6
- package/lib/version.js +1 -1
- package/package.json +1 -1
package/gltf-progressive.js
CHANGED
|
@@ -1,176 +1,184 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
var ze = Object.defineProperty;
|
|
2
|
+
var Ve = (a, t, e) => t in a ? ze(a, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[t] = e;
|
|
3
|
+
var d = (a, t, e) => (Ve(a, typeof t != "symbol" ? t + "" : t, e), e), Se = (a, t, e) => {
|
|
4
|
+
if (!t.has(a))
|
|
5
|
+
throw TypeError("Cannot " + e);
|
|
6
|
+
};
|
|
7
|
+
var m = (a, t, e) => (Se(a, t, "read from private field"), e ? e.call(a) : t.get(a)), q = (a, t, e) => {
|
|
8
|
+
if (t.has(a))
|
|
9
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
10
|
+
t instanceof WeakSet ? t.add(a) : t.set(a, e);
|
|
11
|
+
}, $ = (a, t, e, r) => (Se(a, t, "write to private field"), r ? r.call(a, e) : t.set(a, e), e);
|
|
12
|
+
import { BufferGeometry as de, Mesh as J, Material as Ne, Texture as ee, TextureLoader as Ue, Matrix4 as be, Frustum as We, Clock as Ke, MeshStandardMaterial as qe, Sphere as Xe, Box3 as Te, Vector3 as V } from "three";
|
|
13
|
+
import { GLTFLoader as Ye } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
14
|
+
import { MeshoptDecoder as He } from "three/examples/jsm/libs/meshopt_decoder.module.js";
|
|
15
|
+
import { DRACOLoader as Je } from "three/examples/jsm/loaders/DRACOLoader.js";
|
|
16
|
+
import { KTX2Loader as Qe } from "three/examples/jsm/loaders/KTX2Loader.js";
|
|
17
|
+
const Be = "";
|
|
18
|
+
globalThis.GLTF_PROGRESSIVE_VERSION = Be;
|
|
19
|
+
console.debug(`[gltf-progressive] version ${Be}`);
|
|
20
|
+
let he = "https://www.gstatic.com/draco/versioned/decoders/1.4.1/", _e = "https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";
|
|
21
|
+
fetch(he + "draco_decoder.js", { method: "head" }).catch((a) => {
|
|
22
|
+
he = "./include/draco/", _e = "./include/ktx2/";
|
|
15
23
|
});
|
|
16
|
-
function
|
|
17
|
-
|
|
24
|
+
function gt(a) {
|
|
25
|
+
he = a;
|
|
18
26
|
}
|
|
19
|
-
function
|
|
20
|
-
|
|
27
|
+
function pt(a) {
|
|
28
|
+
_e = a;
|
|
21
29
|
}
|
|
22
|
-
let
|
|
23
|
-
function
|
|
24
|
-
|
|
30
|
+
let ie, De, oe;
|
|
31
|
+
function ke(a) {
|
|
32
|
+
ie || (ie = new Je(), ie.setDecoderPath(he), ie.setDecoderConfig({ type: "js" })), oe || (oe = new Qe(), oe.setTranscoderPath(_e)), De || (De = He), a ? oe.detectSupport(a) : console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail");
|
|
25
33
|
}
|
|
26
|
-
function
|
|
27
|
-
|
|
34
|
+
function Ie(a) {
|
|
35
|
+
a.dracoLoader || a.setDRACOLoader(ie), a.ktx2Loader || a.setKTX2Loader(oe), a.meshoptDecoder || a.setMeshoptDecoder(De);
|
|
28
36
|
}
|
|
29
|
-
|
|
30
|
-
function
|
|
31
|
-
const
|
|
32
|
-
return
|
|
37
|
+
ae("debugprogressive");
|
|
38
|
+
function ae(a) {
|
|
39
|
+
const e = new URL(window.location.href).searchParams.get(a);
|
|
40
|
+
return e == null || e === "0" || e === "false" ? !1 : e === "" ? !0 : e;
|
|
33
41
|
}
|
|
34
|
-
function
|
|
35
|
-
if (
|
|
36
|
-
return
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
39
|
-
const r =
|
|
40
|
-
for (; r.endsWith("/") &&
|
|
41
|
-
|
|
42
|
-
return r +
|
|
43
|
-
}
|
|
44
|
-
return
|
|
42
|
+
function Ze(a, t) {
|
|
43
|
+
if (t === void 0 || t.startsWith("./") || t.startsWith("http") || a === void 0)
|
|
44
|
+
return t;
|
|
45
|
+
const e = a.lastIndexOf("/");
|
|
46
|
+
if (e >= 0) {
|
|
47
|
+
const r = a.substring(0, e + 1);
|
|
48
|
+
for (; r.endsWith("/") && t.startsWith("/"); )
|
|
49
|
+
t = t.substring(1);
|
|
50
|
+
return r + t;
|
|
51
|
+
}
|
|
52
|
+
return t;
|
|
45
53
|
}
|
|
46
|
-
let
|
|
47
|
-
function
|
|
48
|
-
return
|
|
54
|
+
let te;
|
|
55
|
+
function je() {
|
|
56
|
+
return te !== void 0 || (te = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), ae("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", te)), te;
|
|
49
57
|
}
|
|
50
|
-
const
|
|
51
|
-
function
|
|
52
|
-
return (
|
|
58
|
+
const we = Symbol("needle:raycast-mesh");
|
|
59
|
+
function Oe(a) {
|
|
60
|
+
return (a == null ? void 0 : a[we]) instanceof de ? a[we] : null;
|
|
53
61
|
}
|
|
54
|
-
function
|
|
55
|
-
if ((
|
|
56
|
-
const r =
|
|
57
|
-
r.userData = { isRaycastMesh: !0 },
|
|
62
|
+
function et(a, t) {
|
|
63
|
+
if ((a.type === "Mesh" || a.type === "SkinnedMesh") && !Oe(a)) {
|
|
64
|
+
const r = tt(t);
|
|
65
|
+
r.userData = { isRaycastMesh: !0 }, a[we] = r;
|
|
58
66
|
}
|
|
59
67
|
}
|
|
60
|
-
function
|
|
61
|
-
if (
|
|
62
|
-
if (
|
|
68
|
+
function yt(a = !0) {
|
|
69
|
+
if (a) {
|
|
70
|
+
if (re)
|
|
63
71
|
return;
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
const
|
|
72
|
+
const t = re = J.prototype.raycast;
|
|
73
|
+
J.prototype.raycast = function(e, r) {
|
|
74
|
+
const o = this, i = Oe(o);
|
|
67
75
|
let s;
|
|
68
|
-
|
|
76
|
+
i && o.isMesh && (s = o.geometry, o.geometry = i), t.call(this, e, r), s && (o.geometry = s);
|
|
69
77
|
};
|
|
70
78
|
} else {
|
|
71
|
-
if (!
|
|
79
|
+
if (!re)
|
|
72
80
|
return;
|
|
73
|
-
|
|
81
|
+
J.prototype.raycast = re, re = null;
|
|
74
82
|
}
|
|
75
83
|
}
|
|
76
|
-
let
|
|
77
|
-
function
|
|
78
|
-
const
|
|
79
|
-
for (const
|
|
80
|
-
|
|
81
|
-
return
|
|
84
|
+
let re = null;
|
|
85
|
+
function tt(a) {
|
|
86
|
+
const t = new de();
|
|
87
|
+
for (const e in a.attributes)
|
|
88
|
+
t.setAttribute(e, a.getAttribute(e));
|
|
89
|
+
return t.setIndex(a.getIndex()), t;
|
|
82
90
|
}
|
|
83
|
-
const
|
|
84
|
-
if (
|
|
85
|
-
let
|
|
86
|
-
|
|
87
|
-
for (const s of
|
|
88
|
-
const
|
|
89
|
-
if (
|
|
90
|
-
if (
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
} else if (
|
|
94
|
-
|
|
91
|
+
const X = new Array(), N = "NEEDLE_progressive", L = ae("debugprogressive"), xe = Symbol("needle-progressive-texture"), ne = /* @__PURE__ */ new Map(), ve = /* @__PURE__ */ new Set();
|
|
92
|
+
if (L) {
|
|
93
|
+
let a = function() {
|
|
94
|
+
t += 1, console.log("Toggle LOD level", t, ne), ne.forEach((o, i) => {
|
|
95
|
+
for (const s of o.keys) {
|
|
96
|
+
const n = i[s];
|
|
97
|
+
if (n != null) {
|
|
98
|
+
if (n.isBufferGeometry === !0) {
|
|
99
|
+
const l = S.getMeshLODInformation(n), u = l ? Math.min(t, l.lods.length) : 0;
|
|
100
|
+
i["DEBUG:LOD"] = t, S.assignMeshLOD(i, u), l && (e = Math.max(e, l.lods.length - 1));
|
|
101
|
+
} else if (i.isMaterial === !0) {
|
|
102
|
+
i["DEBUG:LOD"] = t, S.assignTextureLOD(i, t);
|
|
95
103
|
break;
|
|
96
104
|
}
|
|
97
105
|
}
|
|
98
106
|
}
|
|
99
|
-
}),
|
|
100
|
-
},
|
|
101
|
-
window.addEventListener("keyup", (
|
|
102
|
-
|
|
103
|
-
|
|
107
|
+
}), t >= e && (t = -1);
|
|
108
|
+
}, t = -1, e = 2, r = !1;
|
|
109
|
+
window.addEventListener("keyup", (o) => {
|
|
110
|
+
o.key === "p" && a(), o.key === "w" && (r = !r, ve && ve.forEach((i) => {
|
|
111
|
+
i.name != "BackgroundCubeMaterial" && i.glyphMap == null && "wireframe" in i && (i.wireframe = r);
|
|
104
112
|
}));
|
|
105
113
|
});
|
|
106
114
|
}
|
|
107
|
-
function
|
|
108
|
-
var
|
|
109
|
-
if (!
|
|
115
|
+
function Ae(a, t, e) {
|
|
116
|
+
var o;
|
|
117
|
+
if (!L)
|
|
110
118
|
return;
|
|
111
|
-
|
|
112
|
-
const r =
|
|
113
|
-
((
|
|
119
|
+
ne.has(a) || ne.set(a, { keys: [], sourceId: e });
|
|
120
|
+
const r = ne.get(a);
|
|
121
|
+
((o = r == null ? void 0 : r.keys) == null ? void 0 : o.includes(t)) == !1 && r.keys.push(t);
|
|
114
122
|
}
|
|
115
|
-
const
|
|
116
|
-
constructor(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
var r,
|
|
123
|
+
const O = class {
|
|
124
|
+
constructor(t, e) {
|
|
125
|
+
d(this, "parser");
|
|
126
|
+
d(this, "url");
|
|
127
|
+
d(this, "_isLoadingMesh");
|
|
128
|
+
d(this, "loadMesh", (t) => {
|
|
129
|
+
var r, o;
|
|
122
130
|
if (this._isLoadingMesh)
|
|
123
131
|
return null;
|
|
124
|
-
const
|
|
125
|
-
return
|
|
132
|
+
const e = (o = (r = this.parser.json.meshes[t]) == null ? void 0 : r.extensions) == null ? void 0 : o[N];
|
|
133
|
+
return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((i) => {
|
|
126
134
|
var s;
|
|
127
|
-
return this._isLoadingMesh = !1,
|
|
135
|
+
return this._isLoadingMesh = !1, i && O.registerMesh(this.url, e.guid, i, (s = e.lods) == null ? void 0 : s.length, void 0, e), i;
|
|
128
136
|
})) : null;
|
|
129
137
|
});
|
|
130
|
-
|
|
138
|
+
L && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
|
|
131
139
|
}
|
|
132
140
|
/** The name of the extension */
|
|
133
141
|
get name() {
|
|
134
|
-
return
|
|
142
|
+
return N;
|
|
135
143
|
}
|
|
136
|
-
static getMeshLODInformation(
|
|
137
|
-
const
|
|
138
|
-
return
|
|
144
|
+
static getMeshLODInformation(t) {
|
|
145
|
+
const e = this.getAssignedLODInformation(t);
|
|
146
|
+
return e != null && e.key ? this.lodInfos.get(e.key) : null;
|
|
139
147
|
}
|
|
140
|
-
static getMaterialMinMaxLODsCount(
|
|
141
|
-
const r = this,
|
|
142
|
-
if (
|
|
143
|
-
return
|
|
144
|
-
if (
|
|
148
|
+
static getMaterialMinMaxLODsCount(t, e) {
|
|
149
|
+
const r = this, o = "LODS:minmax", i = t[o];
|
|
150
|
+
if (i != null)
|
|
151
|
+
return i;
|
|
152
|
+
if (e || (e = {
|
|
145
153
|
min_count: 1 / 0,
|
|
146
154
|
max_count: 0,
|
|
147
155
|
lods: []
|
|
148
|
-
}), Array.isArray(
|
|
149
|
-
for (const
|
|
150
|
-
this.getMaterialMinMaxLODsCount(
|
|
151
|
-
return
|
|
156
|
+
}), Array.isArray(t)) {
|
|
157
|
+
for (const n of t)
|
|
158
|
+
this.getMaterialMinMaxLODsCount(n, e);
|
|
159
|
+
return t[o] = e, e;
|
|
152
160
|
}
|
|
153
|
-
if (
|
|
154
|
-
const
|
|
155
|
-
for (const
|
|
156
|
-
const
|
|
157
|
-
(
|
|
161
|
+
if (L === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
|
|
162
|
+
const n = t;
|
|
163
|
+
for (const l of Object.keys(n.uniforms)) {
|
|
164
|
+
const u = n.uniforms[l].value;
|
|
165
|
+
(u == null ? void 0 : u.isTexture) === !0 && s(u, e);
|
|
158
166
|
}
|
|
159
|
-
} else if (
|
|
160
|
-
for (const
|
|
161
|
-
const
|
|
162
|
-
(
|
|
167
|
+
} else if (t.isMaterial)
|
|
168
|
+
for (const n of Object.keys(t)) {
|
|
169
|
+
const l = t[n];
|
|
170
|
+
(l == null ? void 0 : l.isTexture) === !0 && s(l, e);
|
|
163
171
|
}
|
|
164
|
-
return
|
|
165
|
-
function s(
|
|
166
|
-
const
|
|
167
|
-
if (
|
|
168
|
-
const
|
|
169
|
-
if (
|
|
170
|
-
|
|
171
|
-
for (let
|
|
172
|
-
const
|
|
173
|
-
|
|
172
|
+
return t[o] = e, e;
|
|
173
|
+
function s(n, l) {
|
|
174
|
+
const u = r.getAssignedLODInformation(n);
|
|
175
|
+
if (u) {
|
|
176
|
+
const f = r.lodInfos.get(u.key);
|
|
177
|
+
if (f && f.lods) {
|
|
178
|
+
l.min_count = Math.min(l.min_count, f.lods.length), l.max_count = Math.max(l.max_count, f.lods.length);
|
|
179
|
+
for (let M = 0; M < f.lods.length; M++) {
|
|
180
|
+
const c = f.lods[M];
|
|
181
|
+
c.width && (l.lods[M] = l.lods[M] || { min_height: 1 / 0, max_height: 0 }, l.lods[M].min_height = Math.min(l.lods[M].min_height, c.height), l.lods[M].max_height = Math.max(l.lods[M].max_height, c.height));
|
|
174
182
|
}
|
|
175
183
|
}
|
|
176
184
|
}
|
|
@@ -181,33 +189,33 @@ const v = class {
|
|
|
181
189
|
* @param level the level of detail to check for (0 is the highest resolution). If undefined, the function checks if any LOD level is available
|
|
182
190
|
* @returns true if the LOD level is available (or if any LOD level is available if level is undefined)
|
|
183
191
|
*/
|
|
184
|
-
static hasLODLevelAvailable(
|
|
185
|
-
var
|
|
186
|
-
if (Array.isArray(
|
|
187
|
-
for (const s of
|
|
188
|
-
if (this.hasLODLevelAvailable(s,
|
|
192
|
+
static hasLODLevelAvailable(t, e) {
|
|
193
|
+
var i;
|
|
194
|
+
if (Array.isArray(t)) {
|
|
195
|
+
for (const s of t)
|
|
196
|
+
if (this.hasLODLevelAvailable(s, e))
|
|
189
197
|
return !0;
|
|
190
198
|
return !1;
|
|
191
199
|
}
|
|
192
|
-
if (
|
|
193
|
-
for (const s of Object.keys(
|
|
194
|
-
const
|
|
195
|
-
if (
|
|
200
|
+
if (t.isMaterial === !0) {
|
|
201
|
+
for (const s of Object.keys(t)) {
|
|
202
|
+
const n = t[s];
|
|
203
|
+
if (n && n.isTexture && this.hasLODLevelAvailable(n, e))
|
|
196
204
|
return !0;
|
|
197
205
|
}
|
|
198
206
|
return !1;
|
|
199
|
-
} else if (
|
|
200
|
-
for (const s of
|
|
201
|
-
if (s.isMesh === !0 && this.hasLODLevelAvailable(s,
|
|
207
|
+
} else if (t.isGroup === !0) {
|
|
208
|
+
for (const s of t.children)
|
|
209
|
+
if (s.isMesh === !0 && this.hasLODLevelAvailable(s, e))
|
|
202
210
|
return !0;
|
|
203
211
|
}
|
|
204
|
-
let r,
|
|
205
|
-
if (
|
|
212
|
+
let r, o;
|
|
213
|
+
if (t.isMesh ? r = t.geometry : (t.isBufferGeometry || t.isTexture) && (r = t), r && (i = r == null ? void 0 : r.userData) != null && i.LODS) {
|
|
206
214
|
const s = r.userData.LODS;
|
|
207
|
-
if (
|
|
208
|
-
return
|
|
209
|
-
if (
|
|
210
|
-
return Array.isArray(
|
|
215
|
+
if (o = this.lodInfos.get(s.key), e === void 0)
|
|
216
|
+
return o != null;
|
|
217
|
+
if (o)
|
|
218
|
+
return Array.isArray(o.lods) ? e < o.lods.length : e === 0;
|
|
211
219
|
}
|
|
212
220
|
return !1;
|
|
213
221
|
}
|
|
@@ -225,28 +233,28 @@ const v = class {
|
|
|
225
233
|
* });
|
|
226
234
|
* ```
|
|
227
235
|
*/
|
|
228
|
-
static assignMeshLOD(
|
|
236
|
+
static assignMeshLOD(t, e) {
|
|
229
237
|
var r;
|
|
230
|
-
if (!
|
|
238
|
+
if (!t)
|
|
231
239
|
return Promise.resolve(null);
|
|
232
|
-
if (
|
|
233
|
-
const
|
|
234
|
-
if (!
|
|
240
|
+
if (t instanceof J || t.isMesh === !0) {
|
|
241
|
+
const o = t.geometry, i = this.getAssignedLODInformation(o);
|
|
242
|
+
if (!i)
|
|
235
243
|
return Promise.resolve(null);
|
|
236
|
-
for (const s of
|
|
237
|
-
(r = s.onBeforeGetLODMesh) == null || r.call(s,
|
|
238
|
-
return
|
|
239
|
-
if (
|
|
240
|
-
if (delete
|
|
241
|
-
const
|
|
242
|
-
s = s[
|
|
244
|
+
for (const s of X)
|
|
245
|
+
(r = s.onBeforeGetLODMesh) == null || r.call(s, t, e);
|
|
246
|
+
return t["LOD:requested level"] = e, O.getOrLoadLOD(o, e).then((s) => {
|
|
247
|
+
if (t["LOD:requested level"] === e) {
|
|
248
|
+
if (delete t["LOD:requested level"], Array.isArray(s)) {
|
|
249
|
+
const n = i.index || 0;
|
|
250
|
+
s = s[n];
|
|
243
251
|
}
|
|
244
|
-
s &&
|
|
252
|
+
s && o != s && ((s == null ? void 0 : s.isBufferGeometry) ? (t.geometry = s, L && Ae(t, "geometry", i.url)) : L && console.error("Invalid LOD geometry", s));
|
|
245
253
|
}
|
|
246
254
|
return s;
|
|
247
|
-
}).catch((s) => (console.error("Error loading mesh LOD",
|
|
255
|
+
}).catch((s) => (console.error("Error loading mesh LOD", t, s), null));
|
|
248
256
|
} else
|
|
249
|
-
|
|
257
|
+
L && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
|
|
250
258
|
return Promise.resolve(null);
|
|
251
259
|
}
|
|
252
260
|
/** Load a different resolution of a texture (if available)
|
|
@@ -256,381 +264,389 @@ const v = class {
|
|
|
256
264
|
* @param level the level of detail to load (0 is the highest resolution) - currently only 0 is supported
|
|
257
265
|
* @returns a promise that resolves to the material or texture with the requested LOD level
|
|
258
266
|
*/
|
|
259
|
-
static assignTextureLOD(
|
|
260
|
-
if (!
|
|
267
|
+
static assignTextureLOD(t, e = 0) {
|
|
268
|
+
if (!t)
|
|
261
269
|
return Promise.resolve(null);
|
|
262
|
-
if (
|
|
263
|
-
const r =
|
|
264
|
-
if (
|
|
270
|
+
if (t instanceof Ne || t.isMaterial === !0) {
|
|
271
|
+
const r = t, o = [], i = new Array();
|
|
272
|
+
if (L && ve.add(r), r.uniforms && r.isRawShaderMaterial || r.isShaderMaterial === !0) {
|
|
265
273
|
const s = r;
|
|
266
|
-
for (const
|
|
267
|
-
const
|
|
268
|
-
if ((
|
|
269
|
-
const
|
|
270
|
-
|
|
274
|
+
for (const n of Object.keys(s.uniforms)) {
|
|
275
|
+
const l = s.uniforms[n].value;
|
|
276
|
+
if ((l == null ? void 0 : l.isTexture) === !0) {
|
|
277
|
+
const u = this.assignTextureLODForSlot(l, e, r, n);
|
|
278
|
+
o.push(u), i.push(n);
|
|
271
279
|
}
|
|
272
280
|
}
|
|
273
281
|
} else
|
|
274
282
|
for (const s of Object.keys(r)) {
|
|
275
|
-
const
|
|
276
|
-
if ((
|
|
277
|
-
const
|
|
278
|
-
|
|
283
|
+
const n = r[s];
|
|
284
|
+
if ((n == null ? void 0 : n.isTexture) === !0) {
|
|
285
|
+
const l = this.assignTextureLODForSlot(n, e, r, s);
|
|
286
|
+
o.push(l), i.push(s);
|
|
279
287
|
}
|
|
280
288
|
}
|
|
281
|
-
return Promise.all(
|
|
282
|
-
const
|
|
283
|
-
for (let
|
|
284
|
-
const
|
|
285
|
-
|
|
289
|
+
return Promise.all(o).then((s) => {
|
|
290
|
+
const n = new Array();
|
|
291
|
+
for (let l = 0; l < s.length; l++) {
|
|
292
|
+
const u = s[l], f = i[l];
|
|
293
|
+
u && u.isTexture === !0 ? n.push({ material: r, slot: f, texture: u, level: e }) : n.push({ material: r, slot: f, texture: null, level: e });
|
|
286
294
|
}
|
|
287
|
-
return
|
|
295
|
+
return n;
|
|
288
296
|
});
|
|
289
297
|
}
|
|
290
|
-
if (
|
|
291
|
-
const r =
|
|
292
|
-
return this.assignTextureLODForSlot(r,
|
|
298
|
+
if (t instanceof ee || t.isTexture === !0) {
|
|
299
|
+
const r = t;
|
|
300
|
+
return this.assignTextureLODForSlot(r, e, null, null);
|
|
293
301
|
}
|
|
294
302
|
return Promise.resolve(null);
|
|
295
303
|
}
|
|
296
|
-
static assignTextureLODForSlot(
|
|
297
|
-
return (
|
|
298
|
-
if (Array.isArray(
|
|
304
|
+
static assignTextureLODForSlot(t, e, r, o) {
|
|
305
|
+
return (t == null ? void 0 : t.isTexture) !== !0 ? Promise.resolve(null) : o === "glyphMap" ? Promise.resolve(t) : O.getOrLoadLOD(t, e).then((i) => {
|
|
306
|
+
if (Array.isArray(i))
|
|
299
307
|
return null;
|
|
300
|
-
if ((
|
|
301
|
-
if (
|
|
302
|
-
if (r &&
|
|
303
|
-
const s = r[
|
|
308
|
+
if ((i == null ? void 0 : i.isTexture) === !0) {
|
|
309
|
+
if (i != t) {
|
|
310
|
+
if (r && o) {
|
|
311
|
+
const s = r[o];
|
|
304
312
|
if (s) {
|
|
305
|
-
const
|
|
306
|
-
if (
|
|
307
|
-
return
|
|
313
|
+
const n = this.getAssignedLODInformation(s);
|
|
314
|
+
if (n && (n == null ? void 0 : n.level) < e)
|
|
315
|
+
return L === "verbose" && console.warn("Assigned texture level is already higher: ", n.level, e, r, s, i), null;
|
|
308
316
|
}
|
|
309
|
-
r[
|
|
317
|
+
r[o] = i;
|
|
310
318
|
}
|
|
311
|
-
if (
|
|
312
|
-
const s = this.getAssignedLODInformation(
|
|
313
|
-
s &&
|
|
319
|
+
if (L && o && r) {
|
|
320
|
+
const s = this.getAssignedLODInformation(t);
|
|
321
|
+
s && Ae(r, o, s.url);
|
|
314
322
|
}
|
|
315
323
|
}
|
|
316
|
-
return
|
|
324
|
+
return i;
|
|
317
325
|
} else
|
|
318
|
-
|
|
326
|
+
L == "verbose" && console.warn("No LOD found for", t, e);
|
|
319
327
|
return null;
|
|
320
|
-
}).catch((
|
|
328
|
+
}).catch((i) => (console.error("Error loading LOD", t, i), null));
|
|
321
329
|
}
|
|
322
|
-
afterRoot(
|
|
323
|
-
var
|
|
324
|
-
return
|
|
330
|
+
afterRoot(t) {
|
|
331
|
+
var e, r;
|
|
332
|
+
return L && console.log("AFTER", this.url, t), (e = this.parser.json.textures) == null || e.forEach((o, i) => {
|
|
325
333
|
var s;
|
|
326
|
-
if (
|
|
327
|
-
const
|
|
328
|
-
if (
|
|
329
|
-
if (!
|
|
330
|
-
|
|
334
|
+
if (o != null && o.extensions) {
|
|
335
|
+
const n = o == null ? void 0 : o.extensions[N];
|
|
336
|
+
if (n) {
|
|
337
|
+
if (!n.lods) {
|
|
338
|
+
L && console.warn("Texture has no LODs", n);
|
|
331
339
|
return;
|
|
332
340
|
}
|
|
333
|
-
let
|
|
334
|
-
for (const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
var
|
|
338
|
-
|
|
341
|
+
let l = !1;
|
|
342
|
+
for (const u of this.parser.associations.keys())
|
|
343
|
+
u.isTexture === !0 && this.parser.associations.get(u).textures === i && (l = !0, O.registerTexture(this.url, u, (s = n.lods) == null ? void 0 : s.length, i, n));
|
|
344
|
+
l || this.parser.getDependency("texture", i).then((u) => {
|
|
345
|
+
var f;
|
|
346
|
+
u && O.registerTexture(this.url, u, (f = n.lods) == null ? void 0 : f.length, i, n);
|
|
339
347
|
});
|
|
340
348
|
}
|
|
341
349
|
}
|
|
342
|
-
}), (r = this.parser.json.meshes) == null || r.forEach((
|
|
343
|
-
if (
|
|
344
|
-
const s =
|
|
350
|
+
}), (r = this.parser.json.meshes) == null || r.forEach((o, i) => {
|
|
351
|
+
if (o != null && o.extensions) {
|
|
352
|
+
const s = o == null ? void 0 : o.extensions[N];
|
|
345
353
|
if (s && s.lods) {
|
|
346
|
-
for (const
|
|
347
|
-
if (
|
|
348
|
-
const
|
|
349
|
-
|
|
354
|
+
for (const n of this.parser.associations.keys())
|
|
355
|
+
if (n.isMesh) {
|
|
356
|
+
const l = this.parser.associations.get(n);
|
|
357
|
+
l.meshes === i && O.registerMesh(this.url, s.guid, n, s.lods.length, l.primitives, s);
|
|
350
358
|
}
|
|
351
359
|
}
|
|
352
360
|
}
|
|
353
361
|
}), null;
|
|
354
362
|
}
|
|
355
|
-
static async getOrLoadLOD(
|
|
356
|
-
var
|
|
357
|
-
const r =
|
|
358
|
-
if (!
|
|
363
|
+
static async getOrLoadLOD(t, e) {
|
|
364
|
+
var n, l, u, f;
|
|
365
|
+
const r = L == "verbose", o = t.userData.LODS;
|
|
366
|
+
if (!o)
|
|
359
367
|
return null;
|
|
360
|
-
const
|
|
368
|
+
const i = o == null ? void 0 : o.key;
|
|
361
369
|
let s;
|
|
362
|
-
if (
|
|
363
|
-
const
|
|
364
|
-
|
|
370
|
+
if (t.isTexture === !0) {
|
|
371
|
+
const M = t;
|
|
372
|
+
M.source && M.source[xe] && (s = M.source[xe]);
|
|
365
373
|
}
|
|
366
|
-
if (s || (s =
|
|
367
|
-
if (
|
|
374
|
+
if (s || (s = O.lodInfos.get(i)), s) {
|
|
375
|
+
if (e > 0) {
|
|
368
376
|
let y = !1;
|
|
369
|
-
const
|
|
370
|
-
if (
|
|
371
|
-
return this.lowresCache.get(
|
|
377
|
+
const v = Array.isArray(s.lods);
|
|
378
|
+
if (v && e >= s.lods.length ? y = !0 : v || (y = !0), y)
|
|
379
|
+
return this.lowresCache.get(i);
|
|
372
380
|
}
|
|
373
|
-
const
|
|
374
|
-
if (!
|
|
375
|
-
return
|
|
376
|
-
const
|
|
377
|
-
if (
|
|
381
|
+
const M = Array.isArray(s.lods) ? (n = s.lods[e]) == null ? void 0 : n.path : s.lods;
|
|
382
|
+
if (!M)
|
|
383
|
+
return L && !s["missing:uri"] && (s["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, s)), null;
|
|
384
|
+
const c = Ze(o.url, M);
|
|
385
|
+
if (c.endsWith(".glb") || c.endsWith(".gltf")) {
|
|
378
386
|
if (!s.guid)
|
|
379
387
|
return console.warn("missing pointer for glb/gltf texture", s), null;
|
|
380
|
-
const y =
|
|
381
|
-
if (
|
|
382
|
-
r && console.log(`LOD ${
|
|
383
|
-
let p = await
|
|
384
|
-
`,
|
|
385
|
-
if (p == null || (p instanceof
|
|
388
|
+
const y = c + "_" + s.guid, v = this.previouslyLoaded.get(y);
|
|
389
|
+
if (v !== void 0) {
|
|
390
|
+
r && console.log(`LOD ${e} was already loading/loaded: ${y}`);
|
|
391
|
+
let p = await v.catch((Y) => (console.error(`Error loading LOD ${e} from ${c}
|
|
392
|
+
`, Y), null)), D = !1;
|
|
393
|
+
if (p == null || (p instanceof ee && t instanceof ee ? (l = p.image) != null && l.data || (u = p.source) != null && u.data ? p = this.copySettings(t, p) : (D = !0, this.previouslyLoaded.delete(y)) : p instanceof de && t instanceof de && ((f = p.attributes.position) != null && f.array || (D = !0, this.previouslyLoaded.delete(y)))), !D)
|
|
386
394
|
return p;
|
|
387
395
|
}
|
|
388
|
-
const
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
let
|
|
392
|
-
if (
|
|
393
|
-
const
|
|
394
|
-
|
|
396
|
+
const x = s, R = new Promise(async (p, D) => {
|
|
397
|
+
const Y = new Ye();
|
|
398
|
+
Ie(Y), L && (await new Promise((b) => setTimeout(b, 1e3)), r && console.warn("Start loading (delayed) " + c, x.guid));
|
|
399
|
+
let G = c;
|
|
400
|
+
if (x && Array.isArray(x.lods)) {
|
|
401
|
+
const b = x.lods[e];
|
|
402
|
+
b.hash && (G += "?v=" + b.hash);
|
|
395
403
|
}
|
|
396
|
-
const _ = await
|
|
397
|
-
`,
|
|
404
|
+
const _ = await Y.loadAsync(G).catch((b) => (console.error(`Error loading LOD ${e} from ${c}
|
|
405
|
+
`, b), null));
|
|
398
406
|
if (!_)
|
|
399
407
|
return null;
|
|
400
|
-
const
|
|
401
|
-
r && console.log("Loading finished " +
|
|
402
|
-
let
|
|
408
|
+
const K = _.parser;
|
|
409
|
+
r && console.log("Loading finished " + c, x.guid);
|
|
410
|
+
let F = 0;
|
|
403
411
|
if (_.parser.json.textures) {
|
|
404
|
-
let
|
|
412
|
+
let b = !1;
|
|
405
413
|
for (const g of _.parser.json.textures) {
|
|
406
414
|
if (g != null && g.extensions) {
|
|
407
|
-
const h = g == null ? void 0 : g.extensions[
|
|
408
|
-
if (h != null && h.guid && h.guid ===
|
|
409
|
-
|
|
415
|
+
const h = g == null ? void 0 : g.extensions[N];
|
|
416
|
+
if (h != null && h.guid && h.guid === x.guid) {
|
|
417
|
+
b = !0;
|
|
410
418
|
break;
|
|
411
419
|
}
|
|
412
420
|
}
|
|
413
|
-
|
|
421
|
+
F++;
|
|
414
422
|
}
|
|
415
|
-
if (
|
|
416
|
-
let g = await
|
|
417
|
-
return g &&
|
|
423
|
+
if (b) {
|
|
424
|
+
let g = await K.getDependency("texture", F);
|
|
425
|
+
return g && O.assignLODInformation(o.url, g, i, e, void 0, void 0), r && console.log('change "' + t.name + '" → "' + g.name + '"', c, F, g, y), t instanceof ee && (g = this.copySettings(t, g)), g && (g.guid = x.guid), p(g);
|
|
418
426
|
} else
|
|
419
|
-
|
|
427
|
+
L && console.warn("Could not find texture with guid", x.guid, _.parser.json);
|
|
420
428
|
}
|
|
421
|
-
if (
|
|
422
|
-
let
|
|
429
|
+
if (F = 0, _.parser.json.meshes) {
|
|
430
|
+
let b = !1;
|
|
423
431
|
for (const g of _.parser.json.meshes) {
|
|
424
432
|
if (g != null && g.extensions) {
|
|
425
|
-
const h = g == null ? void 0 : g.extensions[
|
|
426
|
-
if (h != null && h.guid && h.guid ===
|
|
427
|
-
|
|
433
|
+
const h = g == null ? void 0 : g.extensions[N];
|
|
434
|
+
if (h != null && h.guid && h.guid === x.guid) {
|
|
435
|
+
b = !0;
|
|
428
436
|
break;
|
|
429
437
|
}
|
|
430
438
|
}
|
|
431
|
-
|
|
439
|
+
F++;
|
|
432
440
|
}
|
|
433
|
-
if (
|
|
434
|
-
const g = await
|
|
435
|
-
if (r && console.log(`Loaded Mesh "${g.name}"`,
|
|
436
|
-
const
|
|
437
|
-
return
|
|
441
|
+
if (b) {
|
|
442
|
+
const g = await K.getDependency("mesh", F), h = x;
|
|
443
|
+
if (r && console.log(`Loaded Mesh "${g.name}"`, c, F, g, y), g.isMesh === !0) {
|
|
444
|
+
const w = g.geometry;
|
|
445
|
+
return O.assignLODInformation(o.url, w, i, e, void 0, h.density), p(w);
|
|
438
446
|
} else {
|
|
439
|
-
const
|
|
440
|
-
for (let
|
|
441
|
-
const
|
|
442
|
-
if (
|
|
443
|
-
const
|
|
444
|
-
|
|
447
|
+
const w = new Array();
|
|
448
|
+
for (let T = 0; T < g.children.length; T++) {
|
|
449
|
+
const A = g.children[T];
|
|
450
|
+
if (A.isMesh === !0) {
|
|
451
|
+
const P = A.geometry;
|
|
452
|
+
O.assignLODInformation(o.url, P, i, e, T, h.density), w.push(P);
|
|
445
453
|
}
|
|
446
454
|
}
|
|
447
|
-
return p(
|
|
455
|
+
return p(w);
|
|
448
456
|
}
|
|
449
457
|
} else
|
|
450
|
-
|
|
458
|
+
L && console.warn("Could not find mesh with guid", x.guid, _.parser.json);
|
|
451
459
|
}
|
|
452
460
|
return p(null);
|
|
453
461
|
});
|
|
454
|
-
return this.previouslyLoaded.set(y,
|
|
455
|
-
} else if (
|
|
456
|
-
r && console.log("Load texture from uri: " +
|
|
457
|
-
const
|
|
458
|
-
return
|
|
462
|
+
return this.previouslyLoaded.set(y, R), await R;
|
|
463
|
+
} else if (t instanceof ee) {
|
|
464
|
+
r && console.log("Load texture from uri: " + c);
|
|
465
|
+
const v = await new Ue().loadAsync(c);
|
|
466
|
+
return v ? (v.guid = s.guid, v.flipY = !1, v.needsUpdate = !0, v.colorSpace = t.colorSpace, r && console.log(s, v)) : L && console.warn("failed loading", c), v;
|
|
459
467
|
}
|
|
460
468
|
} else
|
|
461
|
-
|
|
469
|
+
L && console.warn(`Can not load LOD ${e}: no LOD info found for "${i}" ${t.name}`, t.type);
|
|
462
470
|
return null;
|
|
463
471
|
}
|
|
464
|
-
static assignLODInformation(
|
|
465
|
-
if (!
|
|
472
|
+
static assignLODInformation(t, e, r, o, i, s) {
|
|
473
|
+
if (!e)
|
|
466
474
|
return;
|
|
467
|
-
|
|
468
|
-
const
|
|
469
|
-
|
|
475
|
+
e.userData || (e.userData = {});
|
|
476
|
+
const n = new rt(t, r, o, i, s);
|
|
477
|
+
e.userData.LODS = n;
|
|
470
478
|
}
|
|
471
|
-
static getAssignedLODInformation(
|
|
472
|
-
var
|
|
473
|
-
return ((
|
|
479
|
+
static getAssignedLODInformation(t) {
|
|
480
|
+
var e;
|
|
481
|
+
return ((e = t == null ? void 0 : t.userData) == null ? void 0 : e.LODS) || null;
|
|
474
482
|
}
|
|
475
483
|
// private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
|
|
476
|
-
static copySettings(
|
|
477
|
-
return
|
|
478
|
-
`,
|
|
479
|
-
`,
|
|
484
|
+
static copySettings(t, e) {
|
|
485
|
+
return e = e.clone(), L && console.warn(`Copying texture settings
|
|
486
|
+
`, t.uuid, `
|
|
487
|
+
`, e.uuid), 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;
|
|
480
488
|
}
|
|
481
489
|
};
|
|
482
|
-
let
|
|
490
|
+
let S = O;
|
|
483
491
|
/**
|
|
484
492
|
* Register a texture with LOD information
|
|
485
493
|
*/
|
|
486
|
-
|
|
487
|
-
if (
|
|
488
|
-
|
|
494
|
+
d(S, "registerTexture", (t, e, r, o, i) => {
|
|
495
|
+
if (L && console.log("> Progressive: register texture", o, e.name, e.uuid, e, i), !e) {
|
|
496
|
+
L && console.error("gltf-progressive: Register texture without texture");
|
|
489
497
|
return;
|
|
490
498
|
}
|
|
491
|
-
|
|
492
|
-
const s =
|
|
493
|
-
|
|
499
|
+
e.source && (e.source[xe] = i);
|
|
500
|
+
const s = i.guid;
|
|
501
|
+
O.assignLODInformation(t, e, s, r, o, void 0), O.lodInfos.set(s, i), O.lowresCache.set(s, e);
|
|
494
502
|
}), /**
|
|
495
503
|
* Register a mesh with LOD information
|
|
496
504
|
*/
|
|
497
|
-
|
|
498
|
-
var
|
|
499
|
-
|
|
500
|
-
const
|
|
501
|
-
if (!
|
|
502
|
-
|
|
505
|
+
d(S, "registerMesh", (t, e, r, o, i, s) => {
|
|
506
|
+
var u;
|
|
507
|
+
L && console.log("> Progressive: register mesh", i, r.name, s, r.uuid, r);
|
|
508
|
+
const n = r.geometry;
|
|
509
|
+
if (!n) {
|
|
510
|
+
L && console.warn("gltf-progressive: Register mesh without geometry");
|
|
503
511
|
return;
|
|
504
512
|
}
|
|
505
|
-
|
|
506
|
-
let
|
|
507
|
-
|
|
508
|
-
for (const
|
|
509
|
-
(
|
|
513
|
+
n.userData || (n.userData = {}), O.assignLODInformation(t, n, e, o, i, s.density), O.lodInfos.set(e, s);
|
|
514
|
+
let l = O.lowresCache.get(e);
|
|
515
|
+
l ? l.push(r.geometry) : l = [r.geometry], O.lowresCache.set(e, l), o > 0 && !Oe(r) && et(r, n);
|
|
516
|
+
for (const f of X)
|
|
517
|
+
(u = f.onRegisteredNewMesh) == null || u.call(f, r, s);
|
|
510
518
|
}), /** A map of key = asset uuid and value = LOD information */
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
class
|
|
515
|
-
constructor(
|
|
516
|
-
|
|
519
|
+
d(S, "lodInfos", /* @__PURE__ */ new Map()), /** cache of already loaded mesh lods */
|
|
520
|
+
d(S, "previouslyLoaded", /* @__PURE__ */ new Map()), /** this contains the geometry/textures that were originally loaded */
|
|
521
|
+
d(S, "lowresCache", /* @__PURE__ */ new Map());
|
|
522
|
+
class rt {
|
|
523
|
+
constructor(t, e, r, o, i) {
|
|
524
|
+
d(this, "url");
|
|
517
525
|
/** the key to lookup the LOD information */
|
|
518
|
-
|
|
519
|
-
|
|
526
|
+
d(this, "key");
|
|
527
|
+
d(this, "level");
|
|
520
528
|
/** For multi objects (e.g. a group of meshes) this is the index of the object */
|
|
521
|
-
|
|
529
|
+
d(this, "index");
|
|
522
530
|
/** the mesh density */
|
|
523
|
-
|
|
524
|
-
this.url =
|
|
531
|
+
d(this, "density");
|
|
532
|
+
this.url = t, this.key = e, this.level = r, o != null && (this.index = o), i != null && (this.density = i);
|
|
525
533
|
}
|
|
526
534
|
}
|
|
527
|
-
const
|
|
535
|
+
const B = ae("debugprogressive"), st = ae("noprogressive"), Le = Symbol("Needle:LODSManager"), Me = Symbol("Needle:LODState"), H = Symbol("Needle:CurrentLOD"), k = { mesh_lod: -1, texture_lod: -1 };
|
|
536
|
+
var C, U, ge, Q, Z, pe, W;
|
|
537
|
+
const E = class {
|
|
528
538
|
// readonly plugins: NEEDLE_progressive_plugin[] = [];
|
|
529
|
-
constructor(
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
539
|
+
constructor(t, e) {
|
|
540
|
+
d(this, "context");
|
|
541
|
+
d(this, "renderer");
|
|
542
|
+
d(this, "projectionScreenMatrix", new be());
|
|
543
|
+
d(this, "cameraFrustrum", new We());
|
|
534
544
|
/**
|
|
535
545
|
* The target triangle density is the desired max amount of triangles on screen when the mesh is filling the screen.
|
|
536
546
|
* @default 200_000
|
|
537
547
|
*/
|
|
538
|
-
|
|
548
|
+
d(this, "targetTriangleDensity", 2e5);
|
|
539
549
|
/**
|
|
540
|
-
* The update interval in frames. If set to 0, the LODs will be updated every frame. If set to
|
|
550
|
+
* The update interval in frames. If set to 0, the LODs will be updated every frame. If set to 2, the LODs will be updated every second frame, etc.
|
|
541
551
|
*/
|
|
542
|
-
|
|
552
|
+
d(this, "updateInterval", "auto");
|
|
553
|
+
q(this, C, 1);
|
|
543
554
|
/**
|
|
544
555
|
* If set to true, the LODsManager will not update the LODs.
|
|
545
556
|
*/
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
557
|
+
d(this, "pause", !1);
|
|
558
|
+
d(this, "_lodchangedlisteners", []);
|
|
559
|
+
q(this, U, void 0);
|
|
560
|
+
q(this, ge, new Ke());
|
|
561
|
+
q(this, Q, 0);
|
|
562
|
+
q(this, Z, 0);
|
|
563
|
+
q(this, pe, 0);
|
|
564
|
+
q(this, W, 0);
|
|
565
|
+
d(this, "_fpsBuffer", [60, 60, 60, 60, 60]);
|
|
550
566
|
// private testIfLODLevelsAreAvailable() {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
this.renderer =
|
|
567
|
+
d(this, "_sphere", new Xe());
|
|
568
|
+
d(this, "_tempBox", new Te());
|
|
569
|
+
d(this, "_tempBox2", new Te());
|
|
570
|
+
d(this, "tempMatrix", new be());
|
|
571
|
+
d(this, "_tempWorldPosition", new V());
|
|
572
|
+
d(this, "_tempBoxSize", new V());
|
|
573
|
+
d(this, "_tempBox2Size", new V());
|
|
574
|
+
this.renderer = t, this.context = { ...e };
|
|
559
575
|
}
|
|
560
576
|
/** @internal */
|
|
561
|
-
static getObjectLODState(
|
|
562
|
-
return
|
|
577
|
+
static getObjectLODState(t) {
|
|
578
|
+
return t[Me];
|
|
563
579
|
}
|
|
564
|
-
static addPlugin(
|
|
565
|
-
|
|
580
|
+
static addPlugin(t) {
|
|
581
|
+
X.push(t);
|
|
566
582
|
}
|
|
567
|
-
static removePlugin(
|
|
568
|
-
const
|
|
569
|
-
|
|
583
|
+
static removePlugin(t) {
|
|
584
|
+
const e = X.indexOf(t);
|
|
585
|
+
e >= 0 && X.splice(e, 1);
|
|
570
586
|
}
|
|
571
587
|
/**
|
|
572
588
|
* Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
|
|
573
589
|
* @param renderer The renderer to get the LODsManager for.
|
|
574
590
|
* @returns The LODsManager instance.
|
|
575
591
|
*/
|
|
576
|
-
static get(
|
|
577
|
-
if (
|
|
578
|
-
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),
|
|
579
|
-
const r = new
|
|
592
|
+
static get(t, e) {
|
|
593
|
+
if (t[Le])
|
|
594
|
+
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[Le];
|
|
595
|
+
const r = new E(t, {
|
|
580
596
|
engine: "unknown",
|
|
581
|
-
...
|
|
597
|
+
...e
|
|
582
598
|
});
|
|
583
|
-
return
|
|
599
|
+
return t[Le] = r, r;
|
|
584
600
|
}
|
|
585
601
|
/** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
|
|
586
602
|
get plugins() {
|
|
587
|
-
return
|
|
603
|
+
return X;
|
|
588
604
|
}
|
|
589
|
-
addEventListener(
|
|
590
|
-
|
|
605
|
+
addEventListener(t, e) {
|
|
606
|
+
t === "changed" && this._lodchangedlisteners.push(e);
|
|
591
607
|
}
|
|
592
608
|
/**
|
|
593
609
|
* Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
|
|
594
610
|
*/
|
|
595
611
|
enable() {
|
|
596
|
-
if (this
|
|
612
|
+
if (m(this, U))
|
|
597
613
|
return;
|
|
598
614
|
console.debug("[gltf-progressive] Enabling LODsManager for renderer");
|
|
599
|
-
let
|
|
600
|
-
this
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
const s =
|
|
605
|
-
|
|
615
|
+
let t = 0;
|
|
616
|
+
$(this, U, this.renderer.render);
|
|
617
|
+
const e = this;
|
|
618
|
+
ke(this.renderer), this.renderer.render = function(r, o) {
|
|
619
|
+
e.renderer.getRenderTarget() == null && (t = 0, $(e, Q, m(e, Q) + 1), $(e, Z, m(e, ge).getDelta()), $(e, pe, m(e, pe) + m(e, Z)), e._fpsBuffer.shift(), e._fpsBuffer.push(1 / m(e, Z)), $(e, W, e._fpsBuffer.reduce((l, u) => l + u) / e._fpsBuffer.length), B && m(e, Q) % 30 === 0 && console.log("FPS", Math.round(m(e, W)), "Interval:", m(e, C)));
|
|
620
|
+
const s = m(e, Q), n = t++;
|
|
621
|
+
e.onBeforeRender(r, o, n, s), m(e, U).call(this, r, o), e.onAfterRender(r, o, n, s);
|
|
606
622
|
};
|
|
607
623
|
}
|
|
608
624
|
disable() {
|
|
609
|
-
this
|
|
625
|
+
m(this, U) && (this.renderer.render = m(this, U), $(this, U, void 0));
|
|
610
626
|
}
|
|
611
|
-
onBeforeRender(
|
|
627
|
+
onBeforeRender(t, e, r, o) {
|
|
612
628
|
}
|
|
613
|
-
onAfterRender(
|
|
614
|
-
var
|
|
629
|
+
onAfterRender(t, e, r, o) {
|
|
630
|
+
var l, u;
|
|
615
631
|
if (this.pause)
|
|
616
632
|
return;
|
|
617
|
-
const
|
|
618
|
-
let
|
|
633
|
+
const i = this.renderer.renderLists.get(t, 0), s = i.opaque;
|
|
634
|
+
let n = !0;
|
|
619
635
|
if (s.length === 1) {
|
|
620
|
-
const
|
|
621
|
-
(
|
|
636
|
+
const f = s[0].material;
|
|
637
|
+
(f.name === "EffectMaterial" || f.name === "CopyShader") && (n = !1);
|
|
622
638
|
}
|
|
623
|
-
if ((
|
|
624
|
-
if (
|
|
639
|
+
if ((e.parent && e.parent.type === "CubeCamera" || r >= 1 && e.type === "OrthographicCamera") && (n = !1), n) {
|
|
640
|
+
if (st || (this.updateInterval === "auto" ? m(this, W) < 40 && m(this, C) < 10 ? ($(this, C, m(this, C) + 1), B && console.warn("↓ Reducing LOD updates", m(this, C), m(this, W).toFixed(0))) : m(this, W) >= 80 && m(this, C) > 1 && ($(this, C, m(this, C) - 1), B && console.warn("↑ Increasing LOD updates", m(this, C), m(this, W).toFixed(0))) : $(this, C, this.updateInterval), m(this, C) > 0 && o % m(this, C) != 0))
|
|
625
641
|
return;
|
|
626
|
-
this.projectionScreenMatrix.multiplyMatrices(
|
|
627
|
-
const
|
|
628
|
-
for (const
|
|
629
|
-
if (
|
|
630
|
-
|
|
642
|
+
this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse), this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix, this.renderer.coordinateSystem);
|
|
643
|
+
const f = this.targetTriangleDensity;
|
|
644
|
+
for (const c of s) {
|
|
645
|
+
if (c.material && (((l = c.geometry) == null ? void 0 : l.type) === "BoxGeometry" || ((u = c.geometry) == null ? void 0 : u.type) === "BufferGeometry") && (c.material.name === "SphericalGaussianBlur" || c.material.name == "BackgroundCubeMaterial" || c.material.name === "CubemapFromEquirect" || c.material.name === "EquirectangularToCubeUV")) {
|
|
646
|
+
B && (c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] || (c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] = !0, console.warn("Ignoring skybox or BLIT object", c, c.material.name, c.material.type)));
|
|
631
647
|
continue;
|
|
632
648
|
}
|
|
633
|
-
switch (
|
|
649
|
+
switch (c.material.type) {
|
|
634
650
|
case "LineBasicMaterial":
|
|
635
651
|
case "LineDashedMaterial":
|
|
636
652
|
case "PointsMaterial":
|
|
@@ -639,51 +655,56 @@ const N = Z("debugprogressive"), Ue = Z("noprogressive"), le = Symbol("Needle:LO
|
|
|
639
655
|
case "MeshDepthMaterial":
|
|
640
656
|
continue;
|
|
641
657
|
}
|
|
642
|
-
|
|
643
|
-
|
|
658
|
+
if (B === "color" && c.material && !c.object.progressive_debug_color) {
|
|
659
|
+
c.object.progressive_debug_color = !0;
|
|
660
|
+
const v = Math.random() * 16777215, x = new qe({ color: v });
|
|
661
|
+
c.object.material = x;
|
|
662
|
+
}
|
|
663
|
+
const y = c.object;
|
|
664
|
+
(y instanceof J || y.isMesh) && this.updateLODs(t, e, y, f, o);
|
|
644
665
|
}
|
|
645
|
-
const
|
|
646
|
-
for (const
|
|
647
|
-
const y =
|
|
648
|
-
(y instanceof
|
|
666
|
+
const M = i.transparent;
|
|
667
|
+
for (const c of M) {
|
|
668
|
+
const y = c.object;
|
|
669
|
+
(y instanceof J || y.isMesh) && this.updateLODs(t, e, y, f, o);
|
|
649
670
|
}
|
|
650
671
|
}
|
|
651
672
|
}
|
|
652
673
|
/** Update the LOD levels for the renderer. */
|
|
653
|
-
updateLODs(
|
|
654
|
-
var
|
|
674
|
+
updateLODs(t, e, r, o, i) {
|
|
675
|
+
var l, u;
|
|
655
676
|
r.userData || (r.userData = {});
|
|
656
|
-
let s = r[
|
|
657
|
-
if (s || (s = new
|
|
677
|
+
let s = r[Me];
|
|
678
|
+
if (s || (s = new it(), r[Me] = s), s.frames++ < 2)
|
|
658
679
|
return;
|
|
659
|
-
for (const
|
|
660
|
-
(
|
|
661
|
-
this.calculateLodLevel(
|
|
662
|
-
let
|
|
663
|
-
if (r.material &&
|
|
664
|
-
const
|
|
665
|
-
|
|
680
|
+
for (const f of X)
|
|
681
|
+
(l = f.onBeforeUpdateLOD) == null || l.call(f, this.renderer, t, e, r);
|
|
682
|
+
this.calculateLodLevel(e, r, s, o, k), k.mesh_lod = Math.round(k.mesh_lod), k.texture_lod = Math.round(k.texture_lod), k.mesh_lod >= 0 && this.loadProgressiveMeshes(r, k.mesh_lod);
|
|
683
|
+
let n = k.texture_lod;
|
|
684
|
+
if (r.material && n >= 0) {
|
|
685
|
+
const f = r["DEBUG:LOD"];
|
|
686
|
+
f != null && (n = f), this.loadProgressiveTextures(r.material, n);
|
|
666
687
|
}
|
|
667
|
-
for (const
|
|
668
|
-
(
|
|
669
|
-
s.lastLodLevel_Mesh =
|
|
688
|
+
for (const f of X)
|
|
689
|
+
(u = f.onAfterUpdatedLOD) == null || u.call(f, this.renderer, t, e, r, k);
|
|
690
|
+
s.lastLodLevel_Mesh = k.mesh_lod, s.lastLodLevel_Texture = k.texture_lod;
|
|
670
691
|
}
|
|
671
692
|
/** Load progressive textures for the given material
|
|
672
693
|
* @param material the material to load the textures for
|
|
673
694
|
* @param level the LOD level to load. Level 0 is the best quality, higher levels are lower quality
|
|
674
695
|
* @returns Promise with true if the LOD was loaded, false if not
|
|
675
696
|
*/
|
|
676
|
-
loadProgressiveTextures(
|
|
677
|
-
if (!
|
|
697
|
+
loadProgressiveTextures(t, e) {
|
|
698
|
+
if (!t)
|
|
678
699
|
return;
|
|
679
|
-
if (Array.isArray(
|
|
680
|
-
for (const
|
|
681
|
-
this.loadProgressiveTextures(
|
|
700
|
+
if (Array.isArray(t)) {
|
|
701
|
+
for (const o of t)
|
|
702
|
+
this.loadProgressiveTextures(o, e);
|
|
682
703
|
return;
|
|
683
704
|
}
|
|
684
705
|
let r = !1;
|
|
685
|
-
(
|
|
686
|
-
this._lodchangedlisteners.forEach((
|
|
706
|
+
(t[H] === void 0 || e < t[H]) && (r = !0), r && (t[H] = e, S.assignTextureLOD(t, e).then((o) => {
|
|
707
|
+
this._lodchangedlisteners.forEach((i) => i({ type: "texture", level: e, object: t }));
|
|
687
708
|
}));
|
|
688
709
|
}
|
|
689
710
|
/** Load progressive meshes for the given mesh
|
|
@@ -692,275 +713,293 @@ const N = Z("debugprogressive"), Ue = Z("noprogressive"), le = Symbol("Needle:LO
|
|
|
692
713
|
* @param level the LOD level to load. Level 0 is the best quality, higher levels are lower quality
|
|
693
714
|
* @returns Promise with true if the LOD was loaded, false if not
|
|
694
715
|
*/
|
|
695
|
-
loadProgressiveMeshes(
|
|
696
|
-
if (!
|
|
716
|
+
loadProgressiveMeshes(t, e) {
|
|
717
|
+
if (!t)
|
|
697
718
|
return Promise.resolve(null);
|
|
698
|
-
if (
|
|
699
|
-
|
|
700
|
-
const r =
|
|
701
|
-
return
|
|
719
|
+
if (t[H] !== e) {
|
|
720
|
+
t[H] = e;
|
|
721
|
+
const r = t.geometry;
|
|
722
|
+
return S.assignMeshLOD(t, e).then((o) => (o && t[H] == e && r != t.geometry && this._lodchangedlisteners.forEach((i) => i({ type: "mesh", level: e, object: t })), o));
|
|
702
723
|
}
|
|
703
724
|
return Promise.resolve(null);
|
|
704
725
|
}
|
|
705
|
-
static isInside(
|
|
706
|
-
const r =
|
|
707
|
-
return this._tempPtInside.set(
|
|
726
|
+
static isInside(t, e) {
|
|
727
|
+
const r = t.min, o = t.max, i = (r.x + o.x) * 0.5, s = (r.y + o.y) * 0.5;
|
|
728
|
+
return this._tempPtInside.set(i, s, r.z).applyMatrix4(e).z < 0;
|
|
708
729
|
}
|
|
709
|
-
calculateLodLevel(
|
|
710
|
-
var
|
|
711
|
-
if (!t) {
|
|
712
|
-
n.mesh_lod = -1, n.texture_lod = -1;
|
|
713
|
-
return;
|
|
714
|
-
}
|
|
730
|
+
calculateLodLevel(t, e, r, o, i) {
|
|
731
|
+
var R, z;
|
|
715
732
|
if (!e) {
|
|
716
|
-
|
|
733
|
+
i.mesh_lod = -1, i.texture_lod = -1;
|
|
717
734
|
return;
|
|
718
735
|
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
return t["DEBUG:LOD"];
|
|
722
|
-
const d = O.getMeshLODInformation(t.geometry), c = d == null ? void 0 : d.lods, x = c && c.length > 0, u = O.getMaterialMinMaxLODsCount(t.material), y = (u == null ? void 0 : u.min_count) != 1 / 0 && u.min_count > 0 && u.max_count > 0;
|
|
723
|
-
if (!x && !y) {
|
|
724
|
-
n.mesh_lod = 0, n.texture_lod = 0;
|
|
736
|
+
if (!t) {
|
|
737
|
+
i.mesh_lod = -1, i.texture_lod = -1;
|
|
725
738
|
return;
|
|
726
739
|
}
|
|
727
|
-
|
|
728
|
-
|
|
740
|
+
let n = 10 + 1, l = !1;
|
|
741
|
+
if (B && e["DEBUG:LOD"] != null)
|
|
742
|
+
return e["DEBUG:LOD"];
|
|
743
|
+
const u = S.getMeshLODInformation(e.geometry), f = u == null ? void 0 : u.lods, M = f && f.length > 0, c = S.getMaterialMinMaxLODsCount(e.material), y = (c == null ? void 0 : c.min_count) != 1 / 0 && c.min_count > 0 && c.max_count > 0;
|
|
744
|
+
if (!M && !y) {
|
|
745
|
+
i.mesh_lod = 0, i.texture_lod = 0;
|
|
729
746
|
return;
|
|
730
747
|
}
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
const p = t;
|
|
735
|
-
p.boundingBox || p.computeBoundingBox(), L = p.boundingBox;
|
|
748
|
+
if (M || (l = !0, n = 0), !((R = this.cameraFrustrum) != null && R.intersectsObject(e))) {
|
|
749
|
+
i.mesh_lod = 99, i.texture_lod = 99;
|
|
750
|
+
return;
|
|
736
751
|
}
|
|
737
|
-
|
|
752
|
+
const v = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
|
|
753
|
+
let x = e.geometry.boundingBox;
|
|
754
|
+
if (e.type === "SkinnedMesh") {
|
|
738
755
|
const p = e;
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
756
|
+
p.boundingBox || p.computeBoundingBox(), x = p.boundingBox;
|
|
757
|
+
}
|
|
758
|
+
if (x && t.isPerspectiveCamera) {
|
|
759
|
+
const p = t;
|
|
760
|
+
if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
|
|
761
|
+
this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
|
|
762
|
+
const h = t.getWorldPosition(this._tempWorldPosition);
|
|
742
763
|
if (this._sphere.containsPoint(h)) {
|
|
743
|
-
|
|
764
|
+
i.mesh_lod = 0, i.texture_lod = 0;
|
|
744
765
|
return;
|
|
745
766
|
}
|
|
746
767
|
}
|
|
747
|
-
if (this._tempBox.copy(
|
|
748
|
-
|
|
768
|
+
if (this._tempBox.copy(x), this._tempBox.applyMatrix4(e.matrixWorld), E.isInside(this._tempBox, this.projectionScreenMatrix)) {
|
|
769
|
+
i.mesh_lod = 0, i.texture_lod = 0;
|
|
749
770
|
return;
|
|
750
771
|
}
|
|
751
772
|
if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && p.fov > 70) {
|
|
752
|
-
const h = this._tempBox.min,
|
|
753
|
-
let
|
|
754
|
-
const
|
|
755
|
-
|
|
756
|
-
const
|
|
757
|
-
r.lastCentrality = (
|
|
773
|
+
const h = this._tempBox.min, w = this._tempBox.max;
|
|
774
|
+
let T = h.x, A = h.y, P = w.x, j = w.y;
|
|
775
|
+
const le = 2, ye = 1.5, ce = (h.x + w.x) * 0.5, ue = (h.y + w.y) * 0.5;
|
|
776
|
+
T = (T - ce) * le + ce, A = (A - ue) * le + ue, P = (P - ce) * le + ce, j = (j - ue) * le + ue;
|
|
777
|
+
const Fe = T < 0 && P > 0 ? 0 : Math.min(Math.abs(h.x), Math.abs(w.x)), $e = A < 0 && j > 0 ? 0 : Math.min(Math.abs(h.y), Math.abs(w.y)), me = Math.max(Fe, $e);
|
|
778
|
+
r.lastCentrality = (ye - me) * (ye - me) * (ye - me);
|
|
758
779
|
} else
|
|
759
780
|
r.lastCentrality = 1;
|
|
760
|
-
const
|
|
761
|
-
|
|
762
|
-
const
|
|
763
|
-
|
|
764
|
-
const _ =
|
|
765
|
-
if (Math.max(
|
|
781
|
+
const D = this._tempBox.getSize(this._tempBoxSize);
|
|
782
|
+
D.multiplyScalar(0.5), screen.availHeight > 0 && v > 0 && D.multiplyScalar(v / screen.availHeight), D.x *= p.aspect;
|
|
783
|
+
const Y = t.matrixWorldInverse, G = this._tempBox2;
|
|
784
|
+
G.copy(x), G.applyMatrix4(e.matrixWorld), G.applyMatrix4(Y);
|
|
785
|
+
const _ = G.getSize(this._tempBox2Size), K = Math.max(_.x, _.y);
|
|
786
|
+
if (Math.max(D.x, D.y) != 0 && K != 0 && (D.z = _.z / Math.max(_.x, _.y) * Math.max(D.x, D.y)), r.lastScreenCoverage = Math.max(D.x, D.y, D.z), r.lastScreenspaceVolume.copy(D), r.lastScreenCoverage *= r.lastCentrality, B && E.debugDrawLine) {
|
|
766
787
|
const h = this.tempMatrix.copy(this.projectionScreenMatrix);
|
|
767
788
|
h.invert();
|
|
768
|
-
const
|
|
769
|
-
|
|
770
|
-
const
|
|
771
|
-
|
|
789
|
+
const w = E.corner0, T = E.corner1, A = E.corner2, P = E.corner3;
|
|
790
|
+
w.copy(this._tempBox.min), T.copy(this._tempBox.max), T.x = w.x, A.copy(this._tempBox.max), A.y = w.y, P.copy(this._tempBox.max);
|
|
791
|
+
const j = (w.z + P.z) * 0.5;
|
|
792
|
+
w.z = T.z = A.z = P.z = j, w.applyMatrix4(h), T.applyMatrix4(h), A.applyMatrix4(h), P.applyMatrix4(h), E.debugDrawLine(w, T, 255), E.debugDrawLine(w, A, 255), E.debugDrawLine(T, P, 255), E.debugDrawLine(A, P, 255);
|
|
772
793
|
}
|
|
773
|
-
let
|
|
774
|
-
if (
|
|
775
|
-
for (let h = 0; h <
|
|
776
|
-
if (
|
|
777
|
-
|
|
794
|
+
let b = 999;
|
|
795
|
+
if (f && r.lastScreenCoverage > 0) {
|
|
796
|
+
for (let h = 0; h < f.length; h++)
|
|
797
|
+
if (f[h].density / r.lastScreenCoverage < o) {
|
|
798
|
+
b = h;
|
|
778
799
|
break;
|
|
779
800
|
}
|
|
780
801
|
}
|
|
781
|
-
|
|
802
|
+
b < n && (n = b, l = !0);
|
|
782
803
|
}
|
|
783
|
-
if (
|
|
784
|
-
const
|
|
785
|
-
|
|
804
|
+
if (l ? i.mesh_lod = n : i.mesh_lod = r.lastLodLevel_Mesh, B && i.mesh_lod != r.lastLodLevel_Mesh) {
|
|
805
|
+
const D = f == null ? void 0 : f[i.mesh_lod];
|
|
806
|
+
D && console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${i.mesh_lod} (${D.density.toFixed(0)}) - ${e.name}`);
|
|
786
807
|
}
|
|
787
808
|
if (y)
|
|
788
809
|
if (r.lastLodLevel_Texture < 0) {
|
|
789
|
-
if (
|
|
790
|
-
const p =
|
|
791
|
-
|
|
810
|
+
if (i.texture_lod = c.max_count - 1, B) {
|
|
811
|
+
const p = c.lods[c.max_count - 1];
|
|
812
|
+
B && console.log(`First Texture LOD ${i.texture_lod} (${p.max_height}px) - ${e.name}`);
|
|
792
813
|
}
|
|
793
814
|
} else {
|
|
794
815
|
const p = r.lastScreenspaceVolume.x + r.lastScreenspaceVolume.y + r.lastScreenspaceVolume.z;
|
|
795
|
-
let
|
|
796
|
-
((
|
|
797
|
-
const
|
|
798
|
-
for (let _ =
|
|
799
|
-
let
|
|
800
|
-
if (!(
|
|
801
|
-
if (
|
|
802
|
-
const
|
|
803
|
-
|
|
804
|
-
Screensize: ${
|
|
805
|
-
${
|
|
816
|
+
let D = r.lastScreenCoverage * 2;
|
|
817
|
+
((z = this.context) == null ? void 0 : z.engine) === "model-viewer" && (D *= 2);
|
|
818
|
+
const G = v / window.devicePixelRatio * D;
|
|
819
|
+
for (let _ = c.lods.length - 1; _ >= 0; _--) {
|
|
820
|
+
let K = c.lods[_];
|
|
821
|
+
if (!(je() && K.max_height > 4096) && K.max_height > G) {
|
|
822
|
+
if (i.texture_lod = _, i.texture_lod < r.lastLodLevel_Texture) {
|
|
823
|
+
const F = K.max_height;
|
|
824
|
+
B && console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${i.texture_lod} = ${F}px
|
|
825
|
+
Screensize: ${G.toFixed(0)}px, Coverage: ${(100 * r.lastScreenCoverage).toFixed(2)}%, Volume ${p.toFixed(1)}
|
|
826
|
+
${e.name}`);
|
|
806
827
|
}
|
|
807
828
|
break;
|
|
808
829
|
}
|
|
809
830
|
}
|
|
810
831
|
}
|
|
811
832
|
else
|
|
812
|
-
|
|
833
|
+
i.texture_lod = 0;
|
|
813
834
|
}
|
|
814
835
|
};
|
|
815
|
-
let
|
|
816
|
-
/** 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.
|
|
836
|
+
let I = E;
|
|
837
|
+
C = new WeakMap(), U = new WeakMap(), ge = new WeakMap(), Q = new WeakMap(), Z = new WeakMap(), pe = new WeakMap(), W = new WeakMap(), /** 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.
|
|
817
838
|
*/
|
|
818
|
-
|
|
819
|
-
class
|
|
839
|
+
d(I, "debugDrawLine"), d(I, "corner0", new V()), d(I, "corner1", new V()), d(I, "corner2", new V()), d(I, "corner3", new V()), d(I, "_tempPtInside", new V());
|
|
840
|
+
class it {
|
|
820
841
|
constructor() {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
842
|
+
d(this, "frames", 0);
|
|
843
|
+
d(this, "lastLodLevel_Mesh", -1);
|
|
844
|
+
d(this, "lastLodLevel_Texture", -1);
|
|
845
|
+
d(this, "lastScreenCoverage", 0);
|
|
846
|
+
d(this, "lastScreenspaceVolume", new V());
|
|
847
|
+
d(this, "lastCentrality", 0);
|
|
827
848
|
}
|
|
828
849
|
}
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
|
|
850
|
+
const Pe = Symbol("NEEDLE_mesh_lod"), fe = Symbol("NEEDLE_texture_lod");
|
|
851
|
+
let se = null;
|
|
852
|
+
function Re() {
|
|
853
|
+
const a = ot();
|
|
854
|
+
a && (a.mapURLs(function(t) {
|
|
855
|
+
return Ee(), t;
|
|
856
|
+
}), Ee(), se == null || se.disconnect(), se = new MutationObserver((t) => {
|
|
857
|
+
t.forEach((e) => {
|
|
858
|
+
e.addedNodes.forEach((r) => {
|
|
859
|
+
r instanceof HTMLElement && r.tagName.toLowerCase() === "model-viewer" && Ge(r);
|
|
860
|
+
});
|
|
861
|
+
});
|
|
862
|
+
}), se.observe(document, { childList: !0, subtree: !0 }));
|
|
863
|
+
}
|
|
864
|
+
function ot() {
|
|
865
|
+
const a = customElements.get("model-viewer");
|
|
866
|
+
return a || (customElements.whenDefined("model-viewer").then(() => {
|
|
867
|
+
console.debug("[gltf-progressive] model-viewer defined"), Re();
|
|
868
|
+
}), null);
|
|
832
869
|
}
|
|
833
|
-
function
|
|
834
|
-
document.querySelectorAll("model-viewer").forEach((
|
|
835
|
-
|
|
870
|
+
function Ee() {
|
|
871
|
+
document.querySelectorAll("model-viewer").forEach((t) => {
|
|
872
|
+
Ge(t);
|
|
836
873
|
});
|
|
837
874
|
}
|
|
838
|
-
const
|
|
839
|
-
|
|
840
|
-
|
|
875
|
+
const Ce = /* @__PURE__ */ new WeakSet();
|
|
876
|
+
let nt = 0;
|
|
877
|
+
function Ge(a) {
|
|
878
|
+
if (!a || Ce.has(a))
|
|
841
879
|
return null;
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
880
|
+
Ce.add(a), console.debug("[gltf-progressive] found new model-viewer..." + ++nt + `
|
|
881
|
+
`, a.getAttribute("src"));
|
|
882
|
+
let t = null, e = null, r = null;
|
|
883
|
+
for (let o = a; o != null; o = Object.getPrototypeOf(o)) {
|
|
884
|
+
const i = Object.getOwnPropertySymbols(o), s = i.find((u) => u.toString() == "Symbol(renderer)"), n = i.find((u) => u.toString() == "Symbol(scene)"), l = i.find((u) => u.toString() == "Symbol(needsRender)");
|
|
885
|
+
!t && s != null && (t = a[s].threeRenderer), !e && n != null && (e = a[n]), !r && l != null && (r = a[l]);
|
|
886
|
+
}
|
|
887
|
+
if (t && e) {
|
|
888
|
+
let o = function() {
|
|
889
|
+
if (r) {
|
|
890
|
+
let s = 0, n = setInterval(() => {
|
|
891
|
+
if (s++ > 5) {
|
|
892
|
+
clearInterval(n);
|
|
854
893
|
return;
|
|
855
894
|
}
|
|
856
|
-
|
|
895
|
+
r == null || r.call(a);
|
|
857
896
|
}, 300);
|
|
858
897
|
}
|
|
859
898
|
};
|
|
860
899
|
console.debug("[gltf-progressive] setup model-viewer");
|
|
861
|
-
const
|
|
862
|
-
return
|
|
863
|
-
|
|
864
|
-
}),
|
|
865
|
-
|
|
866
|
-
}),
|
|
867
|
-
|
|
900
|
+
const i = I.get(t, { engine: "model-viewer" });
|
|
901
|
+
return I.addPlugin(new at()), i.enable(), i.addEventListener("changed", () => {
|
|
902
|
+
r == null || r.call(a);
|
|
903
|
+
}), a.addEventListener("model-visibility", (s) => {
|
|
904
|
+
s.detail.visible && (r == null || r.call(a));
|
|
905
|
+
}), a.addEventListener("load", () => {
|
|
906
|
+
o();
|
|
868
907
|
}), () => {
|
|
869
|
-
|
|
908
|
+
i.disable();
|
|
870
909
|
};
|
|
871
910
|
}
|
|
872
911
|
return null;
|
|
873
912
|
}
|
|
874
|
-
class
|
|
913
|
+
class at {
|
|
875
914
|
constructor() {
|
|
876
|
-
|
|
915
|
+
d(this, "_didWarnAboutMissingUrl", !1);
|
|
877
916
|
}
|
|
878
|
-
onBeforeUpdateLOD(
|
|
879
|
-
this.tryParseMeshLOD(
|
|
917
|
+
onBeforeUpdateLOD(t, e, r, o) {
|
|
918
|
+
this.tryParseMeshLOD(e, o), this.tryParseTextureLOD(e, o);
|
|
880
919
|
}
|
|
881
|
-
getUrl(
|
|
882
|
-
if (!
|
|
920
|
+
getUrl(t) {
|
|
921
|
+
if (!t)
|
|
883
922
|
return null;
|
|
884
|
-
let
|
|
885
|
-
return
|
|
923
|
+
let e = t.getAttribute("src");
|
|
924
|
+
return e || (e = t.src), e || (this._didWarnAboutMissingUrl || console.warn("No url found in modelviewer", t), this._didWarnAboutMissingUrl = !0), e;
|
|
886
925
|
}
|
|
887
|
-
tryGetCurrentGLTF(
|
|
888
|
-
return
|
|
926
|
+
tryGetCurrentGLTF(t) {
|
|
927
|
+
return t._currentGLTF;
|
|
889
928
|
}
|
|
890
|
-
tryGetCurrentModelViewer(
|
|
891
|
-
return
|
|
929
|
+
tryGetCurrentModelViewer(t) {
|
|
930
|
+
return t.element;
|
|
892
931
|
}
|
|
893
|
-
tryParseTextureLOD(
|
|
894
|
-
if (
|
|
932
|
+
tryParseTextureLOD(t, e) {
|
|
933
|
+
if (e[fe] == !0)
|
|
895
934
|
return;
|
|
896
|
-
|
|
897
|
-
const r = this.tryGetCurrentGLTF(
|
|
898
|
-
if (
|
|
899
|
-
let s = function(
|
|
900
|
-
var
|
|
901
|
-
if (
|
|
935
|
+
e[fe] = !0;
|
|
936
|
+
const r = this.tryGetCurrentGLTF(t), o = this.tryGetCurrentModelViewer(t), i = this.getUrl(o);
|
|
937
|
+
if (i && r && e.material) {
|
|
938
|
+
let s = function(l) {
|
|
939
|
+
var f, M, c;
|
|
940
|
+
if (l[fe] == !0)
|
|
902
941
|
return;
|
|
903
|
-
|
|
904
|
-
const
|
|
905
|
-
for (let y = 0; y <
|
|
906
|
-
const
|
|
907
|
-
if ((
|
|
908
|
-
const
|
|
909
|
-
if (
|
|
942
|
+
l[fe] = !0, l.userData && (l.userData.LOD = -1);
|
|
943
|
+
const u = Object.keys(l);
|
|
944
|
+
for (let y = 0; y < u.length; y++) {
|
|
945
|
+
const v = u[y], x = l[v];
|
|
946
|
+
if ((x == null ? void 0 : x.isTexture) === !0) {
|
|
947
|
+
const R = (M = (f = x.userData) == null ? void 0 : f.associations) == null ? void 0 : M.textures;
|
|
948
|
+
if (R == null)
|
|
910
949
|
continue;
|
|
911
|
-
const
|
|
912
|
-
if (!
|
|
913
|
-
console.warn("Texture data not found for texture index " +
|
|
950
|
+
const z = r.parser.json.textures[R];
|
|
951
|
+
if (!z) {
|
|
952
|
+
console.warn("Texture data not found for texture index " + R);
|
|
914
953
|
continue;
|
|
915
954
|
}
|
|
916
|
-
if ((
|
|
917
|
-
const p =
|
|
918
|
-
p &&
|
|
955
|
+
if ((c = z == null ? void 0 : z.extensions) != null && c[N]) {
|
|
956
|
+
const p = z.extensions[N];
|
|
957
|
+
p && i && S.registerTexture(i, x, p.lods.length, R, p);
|
|
919
958
|
}
|
|
920
959
|
}
|
|
921
960
|
}
|
|
922
961
|
};
|
|
923
|
-
const
|
|
924
|
-
if (Array.isArray(
|
|
925
|
-
for (const
|
|
926
|
-
s(
|
|
962
|
+
const n = e.material;
|
|
963
|
+
if (Array.isArray(n))
|
|
964
|
+
for (const l of n)
|
|
965
|
+
s(l);
|
|
927
966
|
else
|
|
928
|
-
s(
|
|
967
|
+
s(n);
|
|
929
968
|
}
|
|
930
969
|
}
|
|
931
|
-
tryParseMeshLOD(
|
|
932
|
-
var s,
|
|
933
|
-
if (
|
|
970
|
+
tryParseMeshLOD(t, e) {
|
|
971
|
+
var s, n;
|
|
972
|
+
if (e[Pe] == !0)
|
|
934
973
|
return;
|
|
935
|
-
|
|
936
|
-
const r = this.tryGetCurrentModelViewer(
|
|
937
|
-
if (!
|
|
974
|
+
e[Pe] = !0;
|
|
975
|
+
const r = this.tryGetCurrentModelViewer(t), o = this.getUrl(r);
|
|
976
|
+
if (!o)
|
|
938
977
|
return;
|
|
939
|
-
const
|
|
940
|
-
if (
|
|
941
|
-
const
|
|
942
|
-
|
|
978
|
+
const i = (n = (s = e.userData) == null ? void 0 : s.gltfExtensions) == null ? void 0 : n[N];
|
|
979
|
+
if (i && o) {
|
|
980
|
+
const l = e.uuid;
|
|
981
|
+
S.registerMesh(o, l, e, 0, i.lods.length, i);
|
|
943
982
|
}
|
|
944
983
|
}
|
|
945
984
|
}
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
return (r == null ? void 0 : r.enableLODsManager) !== !1 && i.enable(), i;
|
|
985
|
+
function mt(a, t, e, r) {
|
|
986
|
+
ke(t), Ie(e), e.register((i) => new S(i, a));
|
|
987
|
+
const o = I.get(t);
|
|
988
|
+
return (r == null ? void 0 : r.enableLODsManager) !== !1 && o.enable(), o;
|
|
951
989
|
}
|
|
990
|
+
Re();
|
|
952
991
|
export {
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
992
|
+
N as EXTENSION_NAME,
|
|
993
|
+
I as LODsManager,
|
|
994
|
+
S as NEEDLE_progressive,
|
|
995
|
+
Be as VERSION,
|
|
996
|
+
Ie as addDracoAndKTX2Loaders,
|
|
997
|
+
ke as createLoaders,
|
|
998
|
+
Oe as getRaycastMesh,
|
|
999
|
+
Re as patchModelViewer,
|
|
1000
|
+
gt as setDracoDecoderLocation,
|
|
1001
|
+
pt as setKTX2TranscoderLocation,
|
|
1002
|
+
et as setRaycastMesh,
|
|
1003
|
+
mt as useNeedleProgressive,
|
|
1004
|
+
yt as useRaycastMeshes
|
|
966
1005
|
};
|