@needle-tools/gltf-progressive 1.0.0-alpha.13 → 1.0.0-alpha.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +6 -0
- package/examples/modelviewer.html +4 -4
- package/examples/threejs/index.html +1 -1
- package/examples/threejs/main.js +8 -8
- package/gltf-progressive.js +182 -154
- package/gltf-progressive.min.js +3 -3
- package/gltf-progressive.umd.cjs +3 -3
- package/lib/extension.js +4 -1
- package/lib/index.d.ts +4 -4
- package/lib/index.js +5 -4
- package/lib/lods_manager.d.ts +37 -2
- package/lib/lods_manager.js +54 -4
- package/lib/plugins/index.d.ts +1 -1
- package/lib/plugins/index.js +0 -1
- package/lib/plugins/modelviewer.js +7 -3
- package/lib/plugins/plugin.d.ts +0 -4
- package/lib/plugins/plugin.js +0 -6
- package/lib/utils.d.ts +13 -0
- package/lib/utils.js +24 -0
- package/package.json +1 -1
package/gltf-progressive.js
CHANGED
|
@@ -1,57 +1,60 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var c = (
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
let
|
|
10
|
-
fetch(
|
|
11
|
-
|
|
1
|
+
var ue = Object.defineProperty;
|
|
2
|
+
var ce = (a, e, t) => e in a ? ue(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
|
|
3
|
+
var c = (a, e, t) => (ce(a, typeof e != "symbol" ? e + "" : e, t), t);
|
|
4
|
+
import { MeshoptDecoder as fe } from "three/examples/jsm/libs/meshopt_decoder.module.js";
|
|
5
|
+
import { DRACOLoader as de } from "three/examples/jsm/loaders/DRACOLoader.js";
|
|
6
|
+
import { KTX2Loader as ge } from "three/examples/jsm/loaders/KTX2Loader.js";
|
|
7
|
+
import { BufferGeometry as K, Mesh as X, Material as he, Texture as U, TextureLoader as pe, Matrix4 as te, Frustum as ye, Sphere as me, Box3 as re, Vector3 as C } from "three";
|
|
8
|
+
import { GLTFLoader as Le } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
9
|
+
let Y = "https://www.gstatic.com/draco/versioned/decoders/1.4.1/", j = "https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";
|
|
10
|
+
fetch(Y + "draco_decoder.js", { method: "head" }).catch((a) => {
|
|
11
|
+
Y = "./include/draco/", j = "./include/ktx2/";
|
|
12
12
|
});
|
|
13
|
-
function
|
|
14
|
-
|
|
13
|
+
function Re(a) {
|
|
14
|
+
Y = a;
|
|
15
15
|
}
|
|
16
|
-
function
|
|
17
|
-
j =
|
|
16
|
+
function Ce(a) {
|
|
17
|
+
j = a;
|
|
18
18
|
}
|
|
19
|
-
let
|
|
20
|
-
function
|
|
21
|
-
|
|
19
|
+
let W, Q, z;
|
|
20
|
+
function oe(a) {
|
|
21
|
+
W || (W = new de(), W.setDecoderPath(Y), W.setDecoderConfig({ type: "js" })), z || (z = new ge(), z.setTranscoderPath(j)), Q || (Q = fe), a ? z.detectSupport(a) : console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail");
|
|
22
22
|
}
|
|
23
|
-
function
|
|
24
|
-
|
|
23
|
+
function ae(a) {
|
|
24
|
+
a.dracoLoader || a.setDRACOLoader(W), a.ktx2Loader || a.setKTX2Loader(z), a.meshoptDecoder || a.setMeshoptDecoder(Q);
|
|
25
25
|
}
|
|
26
|
-
function ee(
|
|
27
|
-
const t = new URL(window.location.href).searchParams.get(
|
|
26
|
+
function ee(a) {
|
|
27
|
+
const t = new URL(window.location.href).searchParams.get(a);
|
|
28
28
|
return t == null || t === "0" || t === "false" ? !1 : t === "" ? !0 : t;
|
|
29
29
|
}
|
|
30
|
-
function
|
|
31
|
-
if (e === void 0 || e.startsWith("./") || e.startsWith("http") ||
|
|
30
|
+
function De(a, e) {
|
|
31
|
+
if (e === void 0 || e.startsWith("./") || e.startsWith("http") || a === void 0)
|
|
32
32
|
return e;
|
|
33
|
-
const t =
|
|
33
|
+
const t = a.lastIndexOf("/");
|
|
34
34
|
if (t >= 0) {
|
|
35
|
-
const r =
|
|
35
|
+
const r = a.substring(0, t + 1);
|
|
36
36
|
for (; r.endsWith("/") && e.startsWith("/"); )
|
|
37
37
|
e = e.substring(1);
|
|
38
38
|
return r + e;
|
|
39
39
|
}
|
|
40
40
|
return e;
|
|
41
41
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
function xe(a) {
|
|
43
|
+
var e;
|
|
44
|
+
return ((e = a.userData) == null ? void 0 : e["needle:raycast-mesh"]) instanceof K ? a.userData["needle:raycast-mesh"] : null;
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
function we(a, e) {
|
|
47
|
+
(a.type === "Mesh" || a.type === "SkinnedMesh") && (a.userData || (a.userData = {}), a.userData["needle:raycast-mesh"] = e);
|
|
48
|
+
}
|
|
49
|
+
const F = new Array(), E = "NEEDLE_progressive", S = ee("debugprogressive"), H = Symbol("needle-progressive-texture"), N = /* @__PURE__ */ new Map(), Z = /* @__PURE__ */ new Set();
|
|
47
50
|
if (S) {
|
|
48
|
-
let
|
|
49
|
-
e += 1, console.log("Toggle LOD level", e,
|
|
51
|
+
let a = function() {
|
|
52
|
+
e += 1, console.log("Toggle LOD level", e, N), N.forEach((i, n) => {
|
|
50
53
|
for (const s of i.keys) {
|
|
51
54
|
const o = n[s];
|
|
52
55
|
if (o.isBufferGeometry === !0) {
|
|
53
|
-
const
|
|
54
|
-
n["DEBUG:LOD"] = e, v.assignMeshLOD(n, g),
|
|
56
|
+
const l = v.getMeshLODInformation(o), g = l ? Math.min(e, l.lods.length) : 0;
|
|
57
|
+
n["DEBUG:LOD"] = e, v.assignMeshLOD(n, g), l && (t = Math.max(t, l.lods.length - 1));
|
|
55
58
|
} else if (n.isMaterial === !0) {
|
|
56
59
|
n["DEBUG:LOD"] = e, v.assignTextureLOD(n, e);
|
|
57
60
|
break;
|
|
@@ -60,17 +63,17 @@ if (S) {
|
|
|
60
63
|
}), e >= t && (e = -1);
|
|
61
64
|
}, e = -1, t = 2, r = !1;
|
|
62
65
|
window.addEventListener("keyup", (i) => {
|
|
63
|
-
i.key === "p" &&
|
|
66
|
+
i.key === "p" && a(), i.key === "w" && (r = !r, Z && Z.forEach((n) => {
|
|
64
67
|
n.name != "BackgroundCubeMaterial" && "wireframe" in n && (n.wireframe = r);
|
|
65
68
|
}));
|
|
66
69
|
});
|
|
67
70
|
}
|
|
68
|
-
function se(
|
|
71
|
+
function se(a, e, t) {
|
|
69
72
|
var i;
|
|
70
73
|
if (!S)
|
|
71
74
|
return;
|
|
72
|
-
|
|
73
|
-
const r =
|
|
75
|
+
N.has(a) || N.set(a, { keys: [], sourceId: t });
|
|
76
|
+
const r = N.get(a);
|
|
74
77
|
((i = r == null ? void 0 : r.keys) == null ? void 0 : i.includes(e)) == !1 && r.keys.push(e);
|
|
75
78
|
}
|
|
76
79
|
const M = class {
|
|
@@ -81,7 +84,7 @@ const M = class {
|
|
|
81
84
|
}
|
|
82
85
|
/** The name of the extension */
|
|
83
86
|
get name() {
|
|
84
|
-
return
|
|
87
|
+
return E;
|
|
85
88
|
}
|
|
86
89
|
static getMeshLODInformation(e) {
|
|
87
90
|
const t = this.getAssignedLODInformation(e);
|
|
@@ -134,11 +137,11 @@ const M = class {
|
|
|
134
137
|
var r;
|
|
135
138
|
if (!e)
|
|
136
139
|
return Promise.resolve(null);
|
|
137
|
-
if (e instanceof
|
|
140
|
+
if (e instanceof X || e.isMesh === !0) {
|
|
138
141
|
const i = e.geometry, n = this.getAssignedLODInformation(i);
|
|
139
142
|
if (!n)
|
|
140
143
|
return Promise.resolve(null);
|
|
141
|
-
for (const s of
|
|
144
|
+
for (const s of F)
|
|
142
145
|
(r = s.onBeforeGetLODMesh) == null || r.call(s, e, t);
|
|
143
146
|
return e["LOD:requested level"] = t, M.getOrLoadLOD(i, t).then((s) => {
|
|
144
147
|
if (e["LOD:requested level"] === t) {
|
|
@@ -146,7 +149,7 @@ const M = class {
|
|
|
146
149
|
const o = n.index || 0;
|
|
147
150
|
s = s[o];
|
|
148
151
|
}
|
|
149
|
-
s && i != s && s instanceof
|
|
152
|
+
s && i != s && s instanceof K && (e.geometry = s, S && se(e, "geometry", n.url));
|
|
150
153
|
}
|
|
151
154
|
return s;
|
|
152
155
|
}).catch((s) => (console.error("Error loading mesh LOD", e, s), null));
|
|
@@ -164,14 +167,14 @@ const M = class {
|
|
|
164
167
|
static assignTextureLOD(e, t = 0) {
|
|
165
168
|
if (!e)
|
|
166
169
|
return Promise.resolve(null);
|
|
167
|
-
if (e instanceof
|
|
170
|
+
if (e instanceof he || e.isMaterial === !0) {
|
|
168
171
|
const r = e, i = [], n = new Array();
|
|
169
172
|
if (S && Z.add(r), r.uniforms && r.isRawShaderMaterial || r.isShaderMaterial === !0) {
|
|
170
173
|
const s = r;
|
|
171
174
|
for (const o of Object.keys(s.uniforms)) {
|
|
172
|
-
const
|
|
173
|
-
if ((
|
|
174
|
-
const g = this.assignTextureLODForSlot(
|
|
175
|
+
const l = s.uniforms[o].value;
|
|
176
|
+
if ((l == null ? void 0 : l.isTexture) === !0) {
|
|
177
|
+
const g = this.assignTextureLODForSlot(l, t, r, o);
|
|
175
178
|
i.push(g), n.push(o);
|
|
176
179
|
}
|
|
177
180
|
}
|
|
@@ -179,20 +182,20 @@ const M = class {
|
|
|
179
182
|
for (const s of Object.keys(r)) {
|
|
180
183
|
const o = r[s];
|
|
181
184
|
if ((o == null ? void 0 : o.isTexture) === !0) {
|
|
182
|
-
const
|
|
183
|
-
i.push(
|
|
185
|
+
const l = this.assignTextureLODForSlot(o, t, r, s);
|
|
186
|
+
i.push(l), n.push(s);
|
|
184
187
|
}
|
|
185
188
|
}
|
|
186
189
|
return Promise.all(i).then((s) => {
|
|
187
190
|
const o = new Array();
|
|
188
|
-
for (let
|
|
189
|
-
const g = s[
|
|
191
|
+
for (let l = 0; l < s.length; l++) {
|
|
192
|
+
const g = s[l], f = n[l];
|
|
190
193
|
g && g.isTexture === !0 ? o.push({ material: r, slot: f, texture: g, level: t }) : o.push({ material: r, slot: f, texture: null, level: t });
|
|
191
194
|
}
|
|
192
195
|
return o;
|
|
193
196
|
});
|
|
194
197
|
}
|
|
195
|
-
if (e instanceof
|
|
198
|
+
if (e instanceof U || e.isTexture === !0) {
|
|
196
199
|
const r = e;
|
|
197
200
|
return this.assignTextureLODForSlot(r, t, null, null);
|
|
198
201
|
}
|
|
@@ -217,31 +220,31 @@ const M = class {
|
|
|
217
220
|
var t, r;
|
|
218
221
|
return S && console.log("AFTER", this.url, e), (t = this.parser.json.textures) == null || t.forEach((i, n) => {
|
|
219
222
|
if (i != null && i.extensions) {
|
|
220
|
-
const s = i == null ? void 0 : i.extensions[
|
|
223
|
+
const s = i == null ? void 0 : i.extensions[E];
|
|
221
224
|
if (s) {
|
|
222
225
|
let o = !1;
|
|
223
|
-
for (const
|
|
224
|
-
|
|
225
|
-
o || this.parser.getDependency("texture", n).then((
|
|
226
|
-
|
|
226
|
+
for (const l of this.parser.associations.keys())
|
|
227
|
+
l.isTexture === !0 && this.parser.associations.get(l).textures === n && (o = !0, M.registerTexture(this.url, l, n, s));
|
|
228
|
+
o || this.parser.getDependency("texture", n).then((l) => {
|
|
229
|
+
l && M.registerTexture(this.url, l, n, s);
|
|
227
230
|
});
|
|
228
231
|
}
|
|
229
232
|
}
|
|
230
233
|
}), (r = this.parser.json.meshes) == null || r.forEach((i, n) => {
|
|
231
234
|
if (i != null && i.extensions) {
|
|
232
|
-
const s = i == null ? void 0 : i.extensions[
|
|
235
|
+
const s = i == null ? void 0 : i.extensions[E];
|
|
233
236
|
if (s && s.lods) {
|
|
234
237
|
for (const o of this.parser.associations.keys())
|
|
235
238
|
if (o.isMesh) {
|
|
236
|
-
const
|
|
237
|
-
|
|
239
|
+
const l = this.parser.associations.get(o);
|
|
240
|
+
l.meshes === n && M.registerMesh(this.url, s.guid, o, s.lods.length, l.primitives, s);
|
|
238
241
|
}
|
|
239
242
|
}
|
|
240
243
|
}
|
|
241
244
|
}), null;
|
|
242
245
|
}
|
|
243
246
|
static async getOrLoadLOD(e, t) {
|
|
244
|
-
var o,
|
|
247
|
+
var o, l, g;
|
|
245
248
|
const r = S == "verbose", i = e.userData.LODS;
|
|
246
249
|
if (!i)
|
|
247
250
|
return null;
|
|
@@ -249,7 +252,7 @@ const M = class {
|
|
|
249
252
|
let s;
|
|
250
253
|
if (e.isTexture === !0) {
|
|
251
254
|
const f = e;
|
|
252
|
-
f.source && f.source[
|
|
255
|
+
f.source && f.source[H] && (s = f.source[H]);
|
|
253
256
|
}
|
|
254
257
|
if (s || (s = M.lodInfos.get(n)), s) {
|
|
255
258
|
if (t > 0) {
|
|
@@ -261,27 +264,27 @@ const M = class {
|
|
|
261
264
|
const f = Array.isArray(s.lods) ? s.lods[t].path : s.lods;
|
|
262
265
|
if (!f)
|
|
263
266
|
return S && !s["missing:uri"] && (s["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + t, s)), null;
|
|
264
|
-
const p =
|
|
267
|
+
const p = De(i.url, f);
|
|
265
268
|
if (p.endsWith(".glb") || p.endsWith(".gltf")) {
|
|
266
269
|
if (!s.guid)
|
|
267
270
|
return console.warn("missing pointer for glb/gltf texture", s), null;
|
|
268
271
|
const u = p + "_" + s.guid, h = this.previouslyLoaded.get(u);
|
|
269
272
|
if (h !== void 0) {
|
|
270
273
|
r && console.log(`LOD ${t} was already loading/loaded: ${u}`);
|
|
271
|
-
let x = await h.catch((
|
|
272
|
-
`,
|
|
273
|
-
if (x == null || (x instanceof
|
|
274
|
+
let x = await h.catch((I) => (console.error(`Error loading LOD ${t} from ${p}
|
|
275
|
+
`, I), null)), R = !1;
|
|
276
|
+
if (x == null || (x instanceof U && e instanceof U ? (o = x.image) != null && o.data || (l = x.source) != null && l.data ? x = this.copySettings(e, x) : (R = !0, this.previouslyLoaded.delete(u)) : x instanceof K && e instanceof K && ((g = x.attributes.position) != null && g.array || (R = !0, this.previouslyLoaded.delete(u)))), !R)
|
|
274
277
|
return x;
|
|
275
278
|
}
|
|
276
|
-
const D = s, A = new Promise(async (x,
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
+
const D = s, A = new Promise(async (x, R) => {
|
|
280
|
+
const I = new Le();
|
|
281
|
+
ae(I), S && (await new Promise((m) => setTimeout(m, 1e3)), r && console.warn("Start loading (delayed) " + p, D.guid));
|
|
279
282
|
let L = p;
|
|
280
283
|
if (D && Array.isArray(D.lods)) {
|
|
281
284
|
const m = D.lods[t];
|
|
282
285
|
m.hash && (L += "?v=" + m.hash);
|
|
283
286
|
}
|
|
284
|
-
const y = await
|
|
287
|
+
const y = await I.loadAsync(L).catch((m) => (console.error(`Error loading LOD ${t} from ${p}
|
|
285
288
|
`, m), null));
|
|
286
289
|
if (!y)
|
|
287
290
|
return null;
|
|
@@ -292,7 +295,7 @@ const M = class {
|
|
|
292
295
|
let m = !1;
|
|
293
296
|
for (const d of y.parser.json.textures) {
|
|
294
297
|
if (d != null && d.extensions) {
|
|
295
|
-
const O = d == null ? void 0 : d.extensions[
|
|
298
|
+
const O = d == null ? void 0 : d.extensions[E];
|
|
296
299
|
if (O != null && O.guid && O.guid === D.guid) {
|
|
297
300
|
m = !0;
|
|
298
301
|
break;
|
|
@@ -302,14 +305,14 @@ const M = class {
|
|
|
302
305
|
}
|
|
303
306
|
if (m) {
|
|
304
307
|
let d = await T.getDependency("texture", w);
|
|
305
|
-
return r && console.log('change "' + e.name + '" → "' + d.name + '"', p, w, d, u), e instanceof
|
|
308
|
+
return r && console.log('change "' + e.name + '" → "' + d.name + '"', p, w, d, u), e instanceof U && (d = this.copySettings(e, d)), d && (d.guid = D.guid), x(d);
|
|
306
309
|
}
|
|
307
310
|
}
|
|
308
311
|
if (w = 0, y.parser.json.meshes) {
|
|
309
312
|
let m = !1;
|
|
310
313
|
for (const d of y.parser.json.meshes) {
|
|
311
314
|
if (d != null && d.extensions) {
|
|
312
|
-
const O = d == null ? void 0 : d.extensions[
|
|
315
|
+
const O = d == null ? void 0 : d.extensions[E];
|
|
313
316
|
if (O != null && O.guid && O.guid === D.guid) {
|
|
314
317
|
m = !0;
|
|
315
318
|
break;
|
|
@@ -320,27 +323,27 @@ const M = class {
|
|
|
320
323
|
if (m) {
|
|
321
324
|
const d = await T.getDependency("mesh", w), O = D;
|
|
322
325
|
if (r && console.log(`Loaded Mesh "${d.name}"`, p, w, d, u), d.isMesh === !0) {
|
|
323
|
-
const
|
|
324
|
-
return M.assignLODInformation(i.url,
|
|
326
|
+
const _ = d.geometry;
|
|
327
|
+
return M.assignLODInformation(i.url, _, n, t, void 0, O.density), x(_);
|
|
325
328
|
} else {
|
|
326
|
-
const
|
|
327
|
-
for (let
|
|
328
|
-
const
|
|
329
|
-
if (
|
|
330
|
-
const
|
|
331
|
-
M.assignLODInformation(i.url,
|
|
329
|
+
const _ = new Array();
|
|
330
|
+
for (let k = 0; k < d.children.length; k++) {
|
|
331
|
+
const G = d.children[k];
|
|
332
|
+
if (G instanceof X) {
|
|
333
|
+
const $ = G.geometry;
|
|
334
|
+
M.assignLODInformation(i.url, $, n, t, k, O.density), _.push($);
|
|
332
335
|
}
|
|
333
336
|
}
|
|
334
|
-
return x(
|
|
337
|
+
return x(_);
|
|
335
338
|
}
|
|
336
339
|
}
|
|
337
340
|
}
|
|
338
341
|
return x(null);
|
|
339
342
|
});
|
|
340
343
|
return this.previouslyLoaded.set(u, A), await A;
|
|
341
|
-
} else if (e instanceof
|
|
344
|
+
} else if (e instanceof U) {
|
|
342
345
|
r && console.log("Load texture from uri: " + p);
|
|
343
|
-
const h = await new
|
|
346
|
+
const h = await new pe().loadAsync(p);
|
|
344
347
|
return h ? (h.guid = s.guid, h.flipY = !1, h.needsUpdate = !0, h.colorSpace = e.colorSpace, r && console.log(s, h)) : S && console.warn("failed loading", p), h;
|
|
345
348
|
}
|
|
346
349
|
} else
|
|
@@ -351,7 +354,7 @@ const M = class {
|
|
|
351
354
|
if (!t)
|
|
352
355
|
return;
|
|
353
356
|
t.userData || (t.userData = {});
|
|
354
|
-
const o = new
|
|
357
|
+
const o = new Oe(e, r, i, n, s);
|
|
355
358
|
t.userData.LODS = o, t.userData.LOD = i;
|
|
356
359
|
}
|
|
357
360
|
static getAssignedLODInformation(e) {
|
|
@@ -368,7 +371,7 @@ let v = M;
|
|
|
368
371
|
* Register a texture with LOD information
|
|
369
372
|
*/
|
|
370
373
|
c(v, "registerTexture", (e, t, r, i) => {
|
|
371
|
-
S && console.log("> Progressive: register texture", r, t.name, t.uuid, t, i), t.source && (t.source[
|
|
374
|
+
S && console.log("> Progressive: register texture", r, t.name, t.uuid, t, i), t.source && (t.source[H] = i);
|
|
372
375
|
const n = i.guid;
|
|
373
376
|
M.assignLODInformation(e, t, n, 0, 0, void 0), M.lodInfos.set(n, i), M.lowresCache.set(n, t);
|
|
374
377
|
}), /**
|
|
@@ -379,15 +382,15 @@ c(v, "registerMesh", (e, t, r, i, n, s) => {
|
|
|
379
382
|
S && console.log("> Progressive: register mesh", n, r.name, s, r.uuid, r);
|
|
380
383
|
const o = r.geometry;
|
|
381
384
|
o.userData || (o.userData = {}), M.assignLODInformation(e, o, t, i, n, s.density), M.lodInfos.set(t, s);
|
|
382
|
-
let
|
|
383
|
-
|
|
384
|
-
for (const f of
|
|
385
|
+
let l = M.lowresCache.get(t);
|
|
386
|
+
l ? l.push(r.geometry) : l = [r.geometry], M.lowresCache.set(t, l), i > 0 && !xe(r) && we(r, o);
|
|
387
|
+
for (const f of F)
|
|
385
388
|
(g = f.onRegisteredNewMesh) == null || g.call(f, r, s);
|
|
386
389
|
}), /** A map of key = asset uuid and value = LOD information */
|
|
387
390
|
c(v, "lodInfos", /* @__PURE__ */ new Map()), /** cache of already loaded mesh lods */
|
|
388
391
|
c(v, "previouslyLoaded", /* @__PURE__ */ new Map()), /** this contains the geometry/textures that were originally loaded */
|
|
389
392
|
c(v, "lowresCache", /* @__PURE__ */ new Map()), c(v, "_copiedTextures", /* @__PURE__ */ new Map());
|
|
390
|
-
class
|
|
393
|
+
class Oe {
|
|
391
394
|
constructor(e, t, r, i, n) {
|
|
392
395
|
c(this, "url");
|
|
393
396
|
/** the key to lookup the LOD information */
|
|
@@ -400,11 +403,17 @@ class De {
|
|
|
400
403
|
this.url = e, this.key = t, this.level = r, i != null && (this.index = i), n != null && (this.density = n);
|
|
401
404
|
}
|
|
402
405
|
}
|
|
403
|
-
const
|
|
406
|
+
const J = ee("debugprogressive"), Me = ee("noprogressive"), ie = Symbol("Needle:LODSManager"), b = class {
|
|
407
|
+
// readonly plugins: NEEDLE_progressive_plugin[] = [];
|
|
404
408
|
constructor(e) {
|
|
405
409
|
c(this, "renderer");
|
|
406
410
|
c(this, "projectionScreenMatrix", new te());
|
|
407
|
-
c(this, "cameraFrustrum", new
|
|
411
|
+
c(this, "cameraFrustrum", new ye());
|
|
412
|
+
/**
|
|
413
|
+
* The target triangle density is the desired max amount of triangles on screen when the mesh is filling the screen.
|
|
414
|
+
* @default 200_000
|
|
415
|
+
*/
|
|
416
|
+
c(this, "targetTriangleDensity", 2e5);
|
|
408
417
|
/**
|
|
409
418
|
* The update interval in frames. If set to 0, the LODs will be updated every frame. If set to 1, the LODs will be updated every second frame, etc.
|
|
410
419
|
*/
|
|
@@ -413,11 +422,10 @@ const H = ee("debugprogressive"), xe = ee("noprogressive"), b = class {
|
|
|
413
422
|
* If set to true, the LODsManager will not update the LODs.
|
|
414
423
|
*/
|
|
415
424
|
c(this, "pause", !1);
|
|
416
|
-
c(this, "plugins", []);
|
|
417
425
|
c(this, "_frame", 0);
|
|
418
426
|
c(this, "_originalRender");
|
|
419
427
|
// private testIfLODLevelsAreAvailable() {
|
|
420
|
-
c(this, "_sphere", new
|
|
428
|
+
c(this, "_sphere", new me());
|
|
421
429
|
c(this, "_tempBox", new re());
|
|
422
430
|
c(this, "tempMatrix", new te());
|
|
423
431
|
c(this, "_tempWorldPosition", new C());
|
|
@@ -430,6 +438,21 @@ const H = ee("debugprogressive"), xe = ee("noprogressive"), b = class {
|
|
|
430
438
|
var t;
|
|
431
439
|
return (t = e.userData) == null ? void 0 : t.LOD_state;
|
|
432
440
|
}
|
|
441
|
+
static addPlugin(e) {
|
|
442
|
+
F.push(e);
|
|
443
|
+
}
|
|
444
|
+
static removePlugin(e) {
|
|
445
|
+
const t = F.indexOf(e);
|
|
446
|
+
t >= 0 && F.splice(t, 1);
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
|
|
450
|
+
* @param renderer The renderer to get the LODsManager for.
|
|
451
|
+
* @returns The LODsManager instance.
|
|
452
|
+
*/
|
|
453
|
+
static get(e) {
|
|
454
|
+
return e[ie] ? e[ie] : new b(e);
|
|
455
|
+
}
|
|
433
456
|
/**
|
|
434
457
|
* Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
|
|
435
458
|
*/
|
|
@@ -439,7 +462,7 @@ const H = ee("debugprogressive"), xe = ee("noprogressive"), b = class {
|
|
|
439
462
|
let e = 0;
|
|
440
463
|
this._originalRender = this.renderer.render;
|
|
441
464
|
const t = this;
|
|
442
|
-
|
|
465
|
+
oe(this.renderer), this.renderer.render = function(r, i) {
|
|
443
466
|
t.renderer.getRenderTarget() == null && (e = 0, t._frame += 1);
|
|
444
467
|
const s = t._frame, o = e++;
|
|
445
468
|
t.onBeforeRender(r, i, o, s), t._originalRender.call(this, r, i), t.onAfterRender(r, i, o, s);
|
|
@@ -451,7 +474,7 @@ const H = ee("debugprogressive"), xe = ee("noprogressive"), b = class {
|
|
|
451
474
|
onBeforeRender(e, t, r, i) {
|
|
452
475
|
}
|
|
453
476
|
onAfterRender(e, t, r, i) {
|
|
454
|
-
var
|
|
477
|
+
var l, g;
|
|
455
478
|
if (this.pause)
|
|
456
479
|
return;
|
|
457
480
|
const n = this.renderer.renderLists.get(e, 0), s = n.opaque;
|
|
@@ -461,32 +484,32 @@ const H = ee("debugprogressive"), xe = ee("noprogressive"), b = class {
|
|
|
461
484
|
(f.name === "EffectMaterial" || f.name === "CopyShader") && (o = !1);
|
|
462
485
|
}
|
|
463
486
|
if (o) {
|
|
464
|
-
if (
|
|
487
|
+
if (Me || this.updateInterval > 0 && i % this.updateInterval != 0)
|
|
465
488
|
return;
|
|
466
489
|
this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix, t.matrixWorldInverse), this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix, this.renderer.coordinateSystem);
|
|
467
|
-
const f =
|
|
490
|
+
const f = this.targetTriangleDensity;
|
|
468
491
|
for (const u of s) {
|
|
469
|
-
if (u.material && (((
|
|
470
|
-
|
|
492
|
+
if (u.material && (((l = u.geometry) == null ? void 0 : l.type) === "BoxGeometry" || ((g = u.geometry) == null ? void 0 : g.type) === "BufferGeometry") && (u.material.name === "SphericalGaussianBlur" || u.material.name == "BackgroundCubeMaterial" || u.material.name === "CubemapFromEquirect" || u.material.name === "EquirectangularToCubeUV")) {
|
|
493
|
+
J && (u.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] || (u.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] = !0, console.warn("Ignoring skybox or BLIT object", u, u.material.name, u.material.type)));
|
|
471
494
|
continue;
|
|
472
495
|
}
|
|
473
496
|
const h = u.object;
|
|
474
|
-
(h instanceof
|
|
497
|
+
(h instanceof X || h.isMesh) && this.updateLODs(e, t, h, f);
|
|
475
498
|
}
|
|
476
499
|
const p = n.transparent;
|
|
477
500
|
for (const u of p) {
|
|
478
501
|
const h = u.object;
|
|
479
|
-
(h instanceof
|
|
502
|
+
(h instanceof X || h.isMesh) && this.updateLODs(e, t, h, f);
|
|
480
503
|
}
|
|
481
504
|
}
|
|
482
505
|
}
|
|
483
506
|
/** Update the LOD levels for the renderer. */
|
|
484
507
|
updateLODs(e, t, r, i) {
|
|
485
|
-
var
|
|
486
|
-
for (const f of
|
|
487
|
-
(
|
|
508
|
+
var l, g;
|
|
509
|
+
for (const f of F)
|
|
510
|
+
(l = f.onBeforeUpdateLOD) == null || l.call(f, this.renderer, e, t, r);
|
|
488
511
|
let n = r.userData.LOD_state;
|
|
489
|
-
n || (n = new
|
|
512
|
+
n || (n = new ve(), r.userData.LOD_state = n);
|
|
490
513
|
let s = this.calculateLodLevel(t, r, n, i);
|
|
491
514
|
s = Math.round(s), s >= 0 && this.loadProgressiveMeshes(r, s);
|
|
492
515
|
let o = 0;
|
|
@@ -498,7 +521,7 @@ const H = ee("debugprogressive"), xe = ee("noprogressive"), b = class {
|
|
|
498
521
|
else
|
|
499
522
|
this.loadProgressiveTextures(r.material, o);
|
|
500
523
|
}
|
|
501
|
-
for (const f of
|
|
524
|
+
for (const f of F)
|
|
502
525
|
(g = f.onAfterUpdatedLOD) == null || g.call(f, this.renderer, e, t, r, s);
|
|
503
526
|
n.lastLodLevel = s;
|
|
504
527
|
}
|
|
@@ -532,9 +555,9 @@ const H = ee("debugprogressive"), xe = ee("noprogressive"), b = class {
|
|
|
532
555
|
return -1;
|
|
533
556
|
let s = 10 + 1;
|
|
534
557
|
if (e) {
|
|
535
|
-
if (
|
|
558
|
+
if (J && t["DEBUG:LOD"] != null)
|
|
536
559
|
return t["DEBUG:LOD"];
|
|
537
|
-
const
|
|
560
|
+
const l = v.getMeshLODInformation(t.geometry), g = l == null ? void 0 : l.lods;
|
|
538
561
|
if (!g || g.length <= 0 || !((o = this.cameraFrustrum) != null && o.intersectsObject(t)))
|
|
539
562
|
return 99;
|
|
540
563
|
const f = t.geometry.boundingBox;
|
|
@@ -549,18 +572,18 @@ const H = ee("debugprogressive"), xe = ee("noprogressive"), b = class {
|
|
|
549
572
|
if (this._tempBox.copy(f), this._tempBox.applyMatrix4(t.matrixWorld), this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && p.fov > 70) {
|
|
550
573
|
const L = this._tempBox.min, y = this._tempBox.max;
|
|
551
574
|
let T = L.x, w = L.y, m = y.x, d = y.y;
|
|
552
|
-
const O = 2,
|
|
553
|
-
T = (T -
|
|
554
|
-
const
|
|
555
|
-
r.lastCentrality = (
|
|
575
|
+
const O = 2, _ = 1.5, k = (L.x + y.x) * 0.5, G = (L.y + y.y) * 0.5;
|
|
576
|
+
T = (T - k) * O + k, w = (w - G) * O + G, m = (m - k) * O + k, d = (d - G) * O + G;
|
|
577
|
+
const $ = T < 0 && m > 0 ? 0 : Math.min(Math.abs(L.x), Math.abs(y.x)), le = w < 0 && d > 0 ? 0 : Math.min(Math.abs(L.y), Math.abs(y.y)), V = Math.max($, le);
|
|
578
|
+
r.lastCentrality = (_ - V) * (_ - V) * (_ - V);
|
|
556
579
|
} else
|
|
557
580
|
r.lastCentrality = 1;
|
|
558
581
|
const u = this._tempBox.getSize(this._tempBoxSize);
|
|
559
582
|
u.multiplyScalar(0.5), screen.availHeight > 0 && u.multiplyScalar(this.renderer.domElement.clientHeight / screen.availHeight), u.x *= p.aspect;
|
|
560
583
|
const h = e.matrixWorldInverse, D = new re();
|
|
561
584
|
D.copy(f), D.applyMatrix4(t.matrixWorld), D.applyMatrix4(h);
|
|
562
|
-
const A = D.getSize(this._tempBox2Size),
|
|
563
|
-
if (Math.max(u.x, u.y) != 0 &&
|
|
585
|
+
const A = D.getSize(this._tempBox2Size), B = Math.max(A.x, A.y);
|
|
586
|
+
if (Math.max(u.x, u.y) != 0 && B != 0 && (u.z = A.z / Math.max(A.x, A.y) * Math.max(u.x, u.y)), r.lastScreenCoverage = Math.max(u.x, u.y, u.z), r.lastScreenspaceVolume.copy(u), r.lastScreenCoverage *= r.lastCentrality, J && b.debugDrawLine) {
|
|
564
587
|
const L = this.tempMatrix.copy(this.projectionScreenMatrix);
|
|
565
588
|
L.invert();
|
|
566
589
|
const y = b.corner0, T = b.corner1, w = b.corner2, m = b.corner3;
|
|
@@ -568,25 +591,25 @@ const H = ee("debugprogressive"), xe = ee("noprogressive"), b = class {
|
|
|
568
591
|
const d = (y.z + m.z) * 0.5;
|
|
569
592
|
y.z = T.z = w.z = m.z = d, y.applyMatrix4(L), T.applyMatrix4(L), w.applyMatrix4(L), m.applyMatrix4(L), b.debugDrawLine(y, T, 255), b.debugDrawLine(y, w, 255), b.debugDrawLine(T, m, 255), b.debugDrawLine(w, m, 255);
|
|
570
593
|
}
|
|
571
|
-
let
|
|
594
|
+
let R = 999;
|
|
572
595
|
if (g && r.lastScreenCoverage > 0) {
|
|
573
596
|
for (let L = 0; L < g.length; L++)
|
|
574
597
|
if (g[L].density / r.lastScreenCoverage < i) {
|
|
575
|
-
|
|
598
|
+
R = L;
|
|
576
599
|
break;
|
|
577
600
|
}
|
|
578
601
|
}
|
|
579
|
-
|
|
602
|
+
R < s && (s = R);
|
|
580
603
|
}
|
|
581
604
|
}
|
|
582
605
|
return s;
|
|
583
606
|
}
|
|
584
607
|
};
|
|
585
|
-
let
|
|
608
|
+
let P = b;
|
|
586
609
|
/** 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.
|
|
587
610
|
*/
|
|
588
|
-
c(
|
|
589
|
-
class
|
|
611
|
+
c(P, "debugDrawLine"), c(P, "corner0", new C()), c(P, "corner1", new C()), c(P, "corner2", new C()), c(P, "corner3", new C());
|
|
612
|
+
class ve {
|
|
590
613
|
constructor() {
|
|
591
614
|
c(this, "lastLodLevel", 0);
|
|
592
615
|
c(this, "lastScreenCoverage", 0);
|
|
@@ -594,19 +617,19 @@ class we {
|
|
|
594
617
|
c(this, "lastCentrality", 0);
|
|
595
618
|
}
|
|
596
619
|
}
|
|
597
|
-
const
|
|
598
|
-
function
|
|
599
|
-
if (!
|
|
620
|
+
const ne = Symbol("NEEDLE_mesh_lod"), q = Symbol("NEEDLE_texture_lod");
|
|
621
|
+
function Se(a) {
|
|
622
|
+
if (!a)
|
|
600
623
|
return null;
|
|
601
624
|
let e = null, t = null;
|
|
602
|
-
for (let r =
|
|
625
|
+
for (let r = a; r != null; r = Object.getPrototypeOf(r)) {
|
|
603
626
|
const i = Object.getOwnPropertySymbols(r), n = i.find((o) => o.toString() == "Symbol(renderer)"), s = i.find((o) => o.toString() == "Symbol(scene)");
|
|
604
|
-
!e && n != null && (e =
|
|
627
|
+
!e && n != null && (e = a[n].threeRenderer), !t && s != null && (t = a[s]);
|
|
605
628
|
}
|
|
606
629
|
if (e) {
|
|
607
630
|
console.log("Adding Needle LODs to modelviewer");
|
|
608
|
-
const r =
|
|
609
|
-
if (
|
|
631
|
+
const r = P.get(e);
|
|
632
|
+
if (P.addPlugin(new Te(a)), r.enable(), t) {
|
|
610
633
|
const i = t.camera || t.traverse((n) => n.type == "PerspectiveCamera")[0];
|
|
611
634
|
i && e.render(t, i);
|
|
612
635
|
}
|
|
@@ -616,7 +639,7 @@ function Oe(l) {
|
|
|
616
639
|
}
|
|
617
640
|
return null;
|
|
618
641
|
}
|
|
619
|
-
class
|
|
642
|
+
class Te {
|
|
620
643
|
constructor(e) {
|
|
621
644
|
c(this, "modelviewer");
|
|
622
645
|
c(this, "_didWarnAboutMissingUrl", !1);
|
|
@@ -633,23 +656,27 @@ class Me {
|
|
|
633
656
|
return e._currentGLTF;
|
|
634
657
|
}
|
|
635
658
|
tryParseTextureLOD(e, t) {
|
|
636
|
-
if (t[
|
|
659
|
+
if (t[q] == !0)
|
|
637
660
|
return;
|
|
638
|
-
t[
|
|
661
|
+
t[q] = !0;
|
|
639
662
|
const r = this.tryGetCurrentGLTF(e), i = this.getUrl();
|
|
640
663
|
if (i && r && t.material) {
|
|
641
664
|
let n = function(o) {
|
|
642
665
|
var g, f, p;
|
|
643
|
-
if (o[
|
|
666
|
+
if (o[q] == !0)
|
|
644
667
|
return;
|
|
645
|
-
o[
|
|
646
|
-
const
|
|
647
|
-
for (let u = 0; u <
|
|
648
|
-
const h =
|
|
668
|
+
o[q] = !0, o.userData && (o.userData.LOD = -1);
|
|
669
|
+
const l = Object.keys(o);
|
|
670
|
+
for (let u = 0; u < l.length; u++) {
|
|
671
|
+
const h = l[u], D = o[h];
|
|
649
672
|
if ((D == null ? void 0 : D.isTexture) === !0) {
|
|
650
|
-
const A = (f = (g = D.userData) == null ? void 0 : g.associations) == null ? void 0 : f.textures,
|
|
651
|
-
if (
|
|
652
|
-
|
|
673
|
+
const A = (f = (g = D.userData) == null ? void 0 : g.associations) == null ? void 0 : f.textures, B = r.parser.json.textures[A];
|
|
674
|
+
if (!B) {
|
|
675
|
+
console.warn("Texture data not found for texture index " + A);
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
if ((p = B == null ? void 0 : B.extensions) != null && p[E]) {
|
|
679
|
+
const x = B.extensions[E];
|
|
653
680
|
x && i && v.registerTexture(i, D, x.lods.length, x);
|
|
654
681
|
}
|
|
655
682
|
}
|
|
@@ -665,36 +692,37 @@ class Me {
|
|
|
665
692
|
}
|
|
666
693
|
tryParseMeshLOD(e, t) {
|
|
667
694
|
var n, s;
|
|
668
|
-
if (t[
|
|
695
|
+
if (t[ne] == !0)
|
|
669
696
|
return;
|
|
670
|
-
t[
|
|
697
|
+
t[ne] = !0;
|
|
671
698
|
const r = this.getUrl();
|
|
672
699
|
if (!r)
|
|
673
700
|
return;
|
|
674
|
-
const i = (s = (n = t.userData) == null ? void 0 : n.gltfExtensions) == null ? void 0 : s[
|
|
701
|
+
const i = (s = (n = t.userData) == null ? void 0 : n.gltfExtensions) == null ? void 0 : s[E];
|
|
675
702
|
if (i && r) {
|
|
676
703
|
const o = t.uuid;
|
|
677
704
|
v.registerMesh(r, o, t, 0, i.lods.length, i);
|
|
678
705
|
}
|
|
679
706
|
}
|
|
680
707
|
}
|
|
681
|
-
function
|
|
682
|
-
|
|
683
|
-
const i =
|
|
708
|
+
function Ee(a, e, t, r) {
|
|
709
|
+
oe(e), ae(t), t.register((n) => new v(n, a));
|
|
710
|
+
const i = P.get(e);
|
|
684
711
|
return (r == null ? void 0 : r.enableLODsManager) !== !1 && i.enable(), i;
|
|
685
712
|
}
|
|
686
713
|
document.addEventListener("DOMContentLoaded", () => {
|
|
687
|
-
|
|
714
|
+
Se(document.querySelector("model-viewer"));
|
|
688
715
|
});
|
|
689
716
|
export {
|
|
690
|
-
|
|
691
|
-
|
|
717
|
+
E as EXTENSION_NAME,
|
|
718
|
+
P as LODsManager,
|
|
692
719
|
v as NEEDLE_progressive,
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
720
|
+
ae as addDracoAndKTX2Loaders,
|
|
721
|
+
oe as createLoaders,
|
|
722
|
+
xe as getRaycastMesh,
|
|
723
|
+
Se as patchModelViewer,
|
|
724
|
+
Re as setDracoDecoderLocation,
|
|
725
|
+
Ce as setKTX2TranscoderLocation,
|
|
726
|
+
we as setRaycastMesh,
|
|
727
|
+
Ee as useNeedleProgressive
|
|
700
728
|
};
|