@needle-tools/engine 4.16.10 → 4.16.12
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 +9 -0
- package/SKILL.md +64 -4
- package/dist/gltf-progressive-DLDvZ8Xm.umd.cjs +10 -0
- package/dist/{gltf-progressive-CzxjNmG6.js → gltf-progressive-DMK8kKVB.js} +352 -346
- package/dist/gltf-progressive-RPgYR6rv.min.js +10 -0
- package/dist/{needle-engine.bundle-a0Pw5htf.js → needle-engine.bundle-BfsnYTeP.js} +7329 -7105
- package/dist/{needle-engine.bundle-D_nuVSFb.umd.cjs → needle-engine.bundle-COr8D1vc.umd.cjs} +132 -132
- package/dist/{needle-engine.bundle-DlyYXu9v.min.js → needle-engine.bundle-DG1sGkxn.min.js} +131 -131
- package/dist/needle-engine.d.ts +60 -3
- package/dist/needle-engine.js +3 -3
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/three-examples.js +52 -52
- package/dist/three-examples.min.js +4 -4
- package/dist/three-examples.umd.cjs +2 -2
- package/lib/engine/api.d.ts +2 -1
- package/lib/engine/api.js +1 -6
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/debug/debug_spector.js +1 -1
- package/lib/engine/debug/debug_spector.js.map +1 -1
- package/lib/engine/engine_addressables.d.ts +32 -1
- package/lib/engine/engine_addressables.js +71 -9
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_application.d.ts +2 -0
- package/lib/engine/engine_application.js +7 -3
- package/lib/engine/engine_application.js.map +1 -1
- package/lib/engine/engine_audio.d.ts +30 -1
- package/lib/engine/engine_audio.js +57 -13
- package/lib/engine/engine_audio.js.map +1 -1
- package/lib/engine/engine_context.js +25 -1
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_context_registry.js +1 -1
- package/lib/engine/engine_context_registry.js.map +1 -1
- package/lib/engine/engine_input.js +1 -1
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_license.d.ts +1 -1
- package/lib/engine/engine_license.js +31 -5
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_lifecycle_functions_internal.js +20 -2
- package/lib/engine/engine_lifecycle_functions_internal.js.map +1 -1
- package/lib/engine/engine_networking_streams.d.ts +5 -1
- package/lib/engine/engine_networking_streams.js +64 -17
- package/lib/engine/engine_networking_streams.js.map +1 -1
- package/lib/engine/engine_shims.js +1 -1
- package/lib/engine/engine_shims.js.map +1 -1
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +5 -0
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js.map +1 -1
- package/lib/engine/webcomponents/fonts.d.ts +1 -1
- package/lib/engine/webcomponents/fonts.js +7 -0
- package/lib/engine/webcomponents/fonts.js.map +1 -1
- package/lib/engine/webcomponents/icons.js +8 -1
- package/lib/engine/webcomponents/icons.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +5 -0
- package/lib/engine/webcomponents/needle menu/needle-menu.js +31 -13
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +1 -0
- package/lib/engine/webcomponents/needle-engine.js +16 -4
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.loading.d.ts +2 -0
- package/lib/engine/webcomponents/needle-engine.loading.js +10 -0
- package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
- package/lib/engine-components/AudioSource.d.ts +49 -2
- package/lib/engine-components/AudioSource.js +261 -66
- package/lib/engine-components/AudioSource.js.map +1 -1
- package/lib/engine-components/CameraUtils.js +1 -1
- package/lib/engine-components/CameraUtils.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
- package/package.json +2 -2
- package/src/engine/api.ts +3 -1
- package/src/engine/debug/debug_spector.ts +1 -1
- package/src/engine/engine_addressables.ts +75 -9
- package/src/engine/engine_application.ts +7 -2
- package/src/engine/engine_audio.ts +68 -15
- package/src/engine/engine_context.ts +25 -1
- package/src/engine/engine_context_registry.ts +1 -1
- package/src/engine/engine_input.ts +2 -2
- package/src/engine/engine_license.ts +28 -5
- package/src/engine/engine_lifecycle_functions_internal.ts +21 -2
- package/src/engine/engine_networking_streams.ts +64 -19
- package/src/engine/engine_shims.ts +1 -1
- package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +8 -1
- package/src/engine/webcomponents/fonts.ts +6 -0
- package/src/engine/webcomponents/icons.ts +9 -2
- package/src/engine/webcomponents/needle menu/needle-menu.ts +30 -12
- package/src/engine/webcomponents/needle-engine.loading.ts +13 -1
- package/src/engine/webcomponents/needle-engine.ts +15 -5
- package/src/engine-components/AudioSource.ts +244 -63
- package/src/engine-components/CameraUtils.ts +1 -1
- package/dist/gltf-progressive-BacJPTD6.umd.cjs +0 -10
- package/dist/gltf-progressive-BmXoz_HR.min.js +0 -10
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { BufferGeometry as V, Mesh as X, Box3 as pe, Vector3 as
|
|
1
|
+
import { BufferGeometry as V, Mesh as X, Box3 as pe, Vector3 as R, Sphere as Te, CompressedTexture as Fe, Texture as F, Matrix3 as We, InterleavedBuffer as Ue, InterleavedBufferAttribute as ze, BufferAttribute as qe, TextureLoader as Ne, Matrix4 as ve, Clock as Ee, MeshStandardMaterial as Ve } from "./three.js";
|
|
2
2
|
import { DRACOLoader as Xe, KTX2Loader as je, MeshoptDecoder as Ke, GLTFLoader as we } from "./three-examples.js";
|
|
3
3
|
const Ye = "";
|
|
4
4
|
globalThis.GLTF_PROGRESSIVE_VERSION = Ye;
|
|
5
5
|
console.debug("[gltf-progressive] version -");
|
|
6
|
-
let
|
|
7
|
-
const He =
|
|
6
|
+
let B = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", j = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
|
|
7
|
+
const He = B, Qe = j, Pe = new URL(B + "draco_decoder.js");
|
|
8
8
|
Pe.searchParams.append("range", "true");
|
|
9
9
|
fetch(Pe, {
|
|
10
10
|
method: "GET",
|
|
@@ -12,30 +12,30 @@ fetch(Pe, {
|
|
|
12
12
|
Range: "bytes=0-1"
|
|
13
13
|
}
|
|
14
14
|
}).catch((o) => {
|
|
15
|
-
console.debug(`Failed to fetch remote Draco decoder from ${
|
|
15
|
+
console.debug(`Failed to fetch remote Draco decoder from ${B} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), B === He && Ze("./include/draco/"), j === Qe && et("./include/ktx2/");
|
|
16
16
|
}).finally(() => {
|
|
17
17
|
Ae();
|
|
18
18
|
});
|
|
19
19
|
const Je = () => ({
|
|
20
|
-
dracoDecoderPath:
|
|
20
|
+
dracoDecoderPath: B,
|
|
21
21
|
ktx2TranscoderPath: j
|
|
22
22
|
});
|
|
23
23
|
function Ze(o) {
|
|
24
|
-
|
|
24
|
+
B = o, k && k[me] != B ? (console.debug("Updating Draco decoder path to " + o), k[me] = B, k.setDecoderPath(B), k.preload()) : console.debug("Setting Draco decoder path to " + o);
|
|
25
25
|
}
|
|
26
26
|
function et(o) {
|
|
27
|
-
j = o,
|
|
27
|
+
j = o, G && G.transcoderPath != j ? (console.debug("Updating KTX2 transcoder path to " + o), G.setTranscoderPath(j), G.init()) : console.debug("Setting KTX2 transcoder path to " + o);
|
|
28
28
|
}
|
|
29
29
|
function Le(o) {
|
|
30
|
-
return Ae(), o ?
|
|
30
|
+
return Ae(), o ? G.detectSupport(o) : o !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: k, ktx2Loader: G, meshoptDecoder: ne };
|
|
31
31
|
}
|
|
32
32
|
function Ce(o) {
|
|
33
|
-
o.dracoLoader || o.setDRACOLoader(
|
|
33
|
+
o.dracoLoader || o.setDRACOLoader(k), o.ktx2Loader || o.setKTX2Loader(G), o.meshoptDecoder || o.setMeshoptDecoder(ne);
|
|
34
34
|
}
|
|
35
35
|
const me = /* @__PURE__ */ Symbol("dracoDecoderPath");
|
|
36
|
-
let
|
|
36
|
+
let k, ne, G;
|
|
37
37
|
function Ae() {
|
|
38
|
-
|
|
38
|
+
k || (k = new Xe(), k[me] = B, k.setDecoderPath(B), k.setDecoderConfig({ type: "js" }), k.preload()), G || (G = new je(), G.setTranscoderPath(j), G.init()), ne || (ne = Ke);
|
|
39
39
|
}
|
|
40
40
|
const ye = /* @__PURE__ */ new WeakMap();
|
|
41
41
|
function ke(o, t) {
|
|
@@ -54,8 +54,8 @@ function st(...o) {
|
|
|
54
54
|
return o[0] = e, tt?.call(this, ...o);
|
|
55
55
|
}
|
|
56
56
|
we.prototype.load = st;
|
|
57
|
-
|
|
58
|
-
function
|
|
57
|
+
N("debugprogressive");
|
|
58
|
+
function N(o) {
|
|
59
59
|
if (typeof window > "u") return !1;
|
|
60
60
|
const e = new URL(window.location.href).searchParams.get(o);
|
|
61
61
|
return e == null || e === "0" || e === "false" ? !1 : e === "" ? !0 : e;
|
|
@@ -72,7 +72,7 @@ function rt(o, t) {
|
|
|
72
72
|
return t;
|
|
73
73
|
}
|
|
74
74
|
function _e() {
|
|
75
|
-
return H !== void 0 || (H = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),
|
|
75
|
+
return H !== void 0 || (H = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), N("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", H)), H;
|
|
76
76
|
}
|
|
77
77
|
let H;
|
|
78
78
|
function De() {
|
|
@@ -157,9 +157,9 @@ function ct(o) {
|
|
|
157
157
|
t.setAttribute(e, o.getAttribute(e));
|
|
158
158
|
return t.setIndex(o.getIndex()), t;
|
|
159
159
|
}
|
|
160
|
-
const
|
|
160
|
+
const q = new Array(), h = N("debugprogressive");
|
|
161
161
|
let Z, E = -1;
|
|
162
|
-
if (
|
|
162
|
+
if (h) {
|
|
163
163
|
let o = function() {
|
|
164
164
|
E += 1, E >= t && (E = -1), console.log(`Toggle LOD level [${E}]`);
|
|
165
165
|
}, t = 6;
|
|
@@ -170,7 +170,7 @@ if (f) {
|
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
172
|
function Re(o) {
|
|
173
|
-
if (
|
|
173
|
+
if (h && Z !== void 0)
|
|
174
174
|
if (Array.isArray(o))
|
|
175
175
|
for (const t of o)
|
|
176
176
|
Re(t);
|
|
@@ -182,7 +182,7 @@ const ft = _e() ? 2 : 10;
|
|
|
182
182
|
function ht(o) {
|
|
183
183
|
if (J.length < ft) {
|
|
184
184
|
const s = J.length;
|
|
185
|
-
|
|
185
|
+
h && console.warn(`[Worker] Creating new worker #${s}`);
|
|
186
186
|
const r = Me.createWorker(o || {});
|
|
187
187
|
return J.push(r), r;
|
|
188
188
|
}
|
|
@@ -223,16 +223,16 @@ class Me {
|
|
|
223
223
|
const { WebGLRenderer: u } = await import("./three.js").then((c) => c.THREE);
|
|
224
224
|
return new u();
|
|
225
225
|
})(), r = await this._webglRenderer);
|
|
226
|
-
const
|
|
226
|
+
const a = Le(r).ktx2Loader.workerConfig;
|
|
227
227
|
t instanceof URL ? t = t.toString() : t.startsWith("file:") ? t = URL.createObjectURL(new Blob([t])) : !t.startsWith("blob:") && !t.startsWith("http:") && !t.startsWith("https:") && (t = new URL(t, window.location.href).toString());
|
|
228
|
-
const
|
|
228
|
+
const l = {
|
|
229
229
|
type: "load",
|
|
230
230
|
url: t,
|
|
231
231
|
dracoDecoderPath: s.dracoDecoderPath,
|
|
232
232
|
ktx2TranscoderPath: s.ktx2TranscoderPath,
|
|
233
|
-
ktx2LoaderConfig:
|
|
233
|
+
ktx2LoaderConfig: a
|
|
234
234
|
};
|
|
235
|
-
return this._debug && console.debug("[Worker] Sending load request",
|
|
235
|
+
return this._debug && console.debug("[Worker] Sending load request", l), this.worker.postMessage(l), new Promise((u) => {
|
|
236
236
|
this._running.push({
|
|
237
237
|
url: t.toString(),
|
|
238
238
|
resolve: u
|
|
@@ -254,19 +254,19 @@ function gt(o) {
|
|
|
254
254
|
}
|
|
255
255
|
if (e.morphAttributes)
|
|
256
256
|
for (const r in e.morphAttributes) {
|
|
257
|
-
const n = e.morphAttributes[r].map((
|
|
257
|
+
const n = e.morphAttributes[r].map((a) => ue(a));
|
|
258
258
|
s.morphAttributes[r] = n;
|
|
259
259
|
}
|
|
260
|
-
if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new pe(), s.boundingBox.min = new
|
|
260
|
+
if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new pe(), s.boundingBox.min = new R(
|
|
261
261
|
e.boundingBox?.min.x,
|
|
262
262
|
e.boundingBox?.min.y,
|
|
263
263
|
e.boundingBox?.min.z
|
|
264
|
-
), s.boundingBox.max = new
|
|
264
|
+
), s.boundingBox.max = new R(
|
|
265
265
|
e.boundingBox?.max.x,
|
|
266
266
|
e.boundingBox?.max.y,
|
|
267
267
|
e.boundingBox?.max.z
|
|
268
268
|
), s.boundingSphere = new Te(
|
|
269
|
-
new
|
|
269
|
+
new R(
|
|
270
270
|
e.boundingSphere?.center.x,
|
|
271
271
|
e.boundingSphere?.center.y,
|
|
272
272
|
e.boundingSphere?.center.z
|
|
@@ -325,13 +325,13 @@ function ue(o) {
|
|
|
325
325
|
} else "isBufferAttribute" in o && o.isBufferAttribute && (t = new qe(o.array, o.itemSize, o.normalized), t.usage = o.usage, t.gpuType = o.gpuType, t.updateRanges = o.updateRanges);
|
|
326
326
|
return t;
|
|
327
327
|
}
|
|
328
|
-
const pt =
|
|
329
|
-
|
|
330
|
-
const K =
|
|
328
|
+
const pt = N("gltf-progressive-worker");
|
|
329
|
+
N("gltf-progressive-reduce-mipmaps");
|
|
330
|
+
const K = N("gltf-progressive-gc"), ce = /* @__PURE__ */ Symbol("needle-progressive-texture"), U = "NEEDLE_progressive";
|
|
331
331
|
class m {
|
|
332
332
|
/** The name of the extension */
|
|
333
333
|
get name() {
|
|
334
|
-
return
|
|
334
|
+
return U;
|
|
335
335
|
}
|
|
336
336
|
// #region PUBLIC API
|
|
337
337
|
static getMeshLODExtension(t) {
|
|
@@ -350,33 +350,33 @@ class m {
|
|
|
350
350
|
max_count: 0,
|
|
351
351
|
lods: []
|
|
352
352
|
}), Array.isArray(t)) {
|
|
353
|
-
for (const
|
|
354
|
-
this.getMaterialMinMaxLODsCount(
|
|
353
|
+
for (const a of t)
|
|
354
|
+
this.getMaterialMinMaxLODsCount(a, e);
|
|
355
355
|
return t[r] = e, e;
|
|
356
356
|
}
|
|
357
|
-
if (
|
|
358
|
-
const
|
|
359
|
-
for (const
|
|
360
|
-
const u =
|
|
357
|
+
if (h === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
|
|
358
|
+
const a = t;
|
|
359
|
+
for (const l of Object.keys(a.uniforms)) {
|
|
360
|
+
const u = a.uniforms[l].value;
|
|
361
361
|
u?.isTexture === !0 && n(u, e);
|
|
362
362
|
}
|
|
363
363
|
} else if (t.isMaterial)
|
|
364
|
-
for (const
|
|
365
|
-
const
|
|
366
|
-
|
|
364
|
+
for (const a of Object.keys(t)) {
|
|
365
|
+
const l = t[a];
|
|
366
|
+
l?.isTexture === !0 && n(l, e);
|
|
367
367
|
}
|
|
368
368
|
else
|
|
369
|
-
|
|
369
|
+
h && console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);
|
|
370
370
|
return t[r] = e, e;
|
|
371
|
-
function n(
|
|
372
|
-
const u = s.getAssignedLODInformation(
|
|
371
|
+
function n(a, l) {
|
|
372
|
+
const u = s.getAssignedLODInformation(a);
|
|
373
373
|
if (u) {
|
|
374
374
|
const c = s.lodInfos.get(u.key);
|
|
375
375
|
if (c && c.lods) {
|
|
376
|
-
|
|
377
|
-
for (let
|
|
378
|
-
const
|
|
379
|
-
|
|
376
|
+
l.min_count = Math.min(l.min_count, c.lods.length), l.max_count = Math.max(l.max_count, c.lods.length);
|
|
377
|
+
for (let g = 0; g < c.lods.length; g++) {
|
|
378
|
+
const y = c.lods[g];
|
|
379
|
+
y.width && (l.lods[g] = l.lods[g] || { min_height: 1 / 0, max_height: 0 }, l.lods[g].min_height = Math.min(l.lods[g].min_height, y.height), l.lods[g].max_height = Math.max(l.lods[g].max_height, y.height));
|
|
380
380
|
}
|
|
381
381
|
}
|
|
382
382
|
}
|
|
@@ -434,16 +434,16 @@ class m {
|
|
|
434
434
|
const s = t.geometry, r = this.getAssignedLODInformation(s);
|
|
435
435
|
if (!r)
|
|
436
436
|
return Promise.resolve(null);
|
|
437
|
-
for (const i of
|
|
437
|
+
for (const i of q)
|
|
438
438
|
i.onBeforeGetLODMesh?.(t, e);
|
|
439
439
|
return t["LOD:requested level"] = e, m.getOrLoadLOD(s, e).then((i) => {
|
|
440
440
|
if (Array.isArray(i)) {
|
|
441
441
|
const n = r.index || 0;
|
|
442
442
|
i = i[n];
|
|
443
443
|
}
|
|
444
|
-
return t["LOD:requested level"] === e && (delete t["LOD:requested level"], i && s != i && (i?.isBufferGeometry ? t.geometry = i :
|
|
444
|
+
return t["LOD:requested level"] === e && (delete t["LOD:requested level"], i && s != i && (i?.isBufferGeometry ? t.geometry = i : h && console.error("Invalid LOD geometry", i))), i;
|
|
445
445
|
}).catch((i) => (console.error("Error loading mesh LOD", t, i), null));
|
|
446
|
-
} else
|
|
446
|
+
} else h && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
|
|
447
447
|
return Promise.resolve(null);
|
|
448
448
|
}
|
|
449
449
|
static assignTextureLOD(t, e = 0) {
|
|
@@ -458,8 +458,8 @@ class m {
|
|
|
458
458
|
}
|
|
459
459
|
return Promise.all(r).then((i) => {
|
|
460
460
|
const n = new Array();
|
|
461
|
-
for (const
|
|
462
|
-
Array.isArray(
|
|
461
|
+
for (const a of i)
|
|
462
|
+
Array.isArray(a) && n.push(...a);
|
|
463
463
|
return n;
|
|
464
464
|
});
|
|
465
465
|
} else
|
|
@@ -469,28 +469,28 @@ class m {
|
|
|
469
469
|
const s = t, r = [], i = new Array();
|
|
470
470
|
if (s.uniforms && (s.isRawShaderMaterial || s.isShaderMaterial === !0)) {
|
|
471
471
|
const n = s;
|
|
472
|
-
for (const
|
|
473
|
-
const
|
|
474
|
-
if (
|
|
475
|
-
const u = this.assignTextureLODForSlot(
|
|
476
|
-
r.push(u), i.push(
|
|
472
|
+
for (const a of Object.keys(n.uniforms)) {
|
|
473
|
+
const l = n.uniforms[a].value;
|
|
474
|
+
if (l?.isTexture === !0) {
|
|
475
|
+
const u = this.assignTextureLODForSlot(l, e, s, a).then((c) => (c && n.uniforms[a].value != c && (n.uniforms[a].value = c, n.uniformsNeedUpdate = !0), c));
|
|
476
|
+
r.push(u), i.push(a);
|
|
477
477
|
}
|
|
478
478
|
}
|
|
479
479
|
} else
|
|
480
480
|
for (const n of Object.keys(s)) {
|
|
481
|
-
const
|
|
482
|
-
if (
|
|
483
|
-
const
|
|
484
|
-
r.push(
|
|
481
|
+
const a = s[n];
|
|
482
|
+
if (a?.isTexture === !0) {
|
|
483
|
+
const l = this.assignTextureLODForSlot(a, e, s, n);
|
|
484
|
+
r.push(l), i.push(n);
|
|
485
485
|
}
|
|
486
486
|
}
|
|
487
487
|
return Promise.all(r).then((n) => {
|
|
488
|
-
const
|
|
489
|
-
for (let
|
|
490
|
-
const u = n[
|
|
491
|
-
u && u.isTexture === !0 ?
|
|
488
|
+
const a = new Array();
|
|
489
|
+
for (let l = 0; l < n.length; l++) {
|
|
490
|
+
const u = n[l], c = i[l];
|
|
491
|
+
u && u.isTexture === !0 ? a.push({ material: s, slot: c, texture: u, level: e }) : a.push({ material: s, slot: c, texture: null, level: e });
|
|
492
492
|
}
|
|
493
|
-
return
|
|
493
|
+
return a;
|
|
494
494
|
});
|
|
495
495
|
}
|
|
496
496
|
if (t instanceof F || t.isTexture === !0) {
|
|
@@ -517,19 +517,19 @@ class m {
|
|
|
517
517
|
if (i?.isTexture === !0) {
|
|
518
518
|
if (i != t && s && r) {
|
|
519
519
|
const n = s[r];
|
|
520
|
-
if (n && !
|
|
521
|
-
const l = this.getAssignedLODInformation(n);
|
|
522
|
-
if (l && l?.level < e)
|
|
523
|
-
return f === "verbose" && console.warn("Assigned texture level is already higher: ", l.level, e, s, n, i), i && i !== n && ((f || K) && console.log(`[gltf-progressive] Disposing rejected lower-quality texture LOD ${e} (assigned is ${l.level})`, i.uuid), i.dispose()), null;
|
|
524
|
-
}
|
|
525
|
-
if (this.trackTextureUsage(i), n && n !== i && this.untrackTextureUsage(n) && (f || K)) {
|
|
520
|
+
if (n && !h) {
|
|
526
521
|
const a = this.getAssignedLODInformation(n);
|
|
527
|
-
|
|
522
|
+
if (a && a?.level < e)
|
|
523
|
+
return h === "verbose" && console.warn("Assigned texture level is already higher: ", a.level, e, s, n, i), i && i !== n && ((h || K) && console.log(`[gltf-progressive] Disposing rejected lower-quality texture LOD ${e} (assigned is ${a.level})`, i.uuid), i.dispose()), null;
|
|
524
|
+
}
|
|
525
|
+
if (this.trackTextureUsage(i), n && n !== i && this.untrackTextureUsage(n) && (h || K)) {
|
|
526
|
+
const l = this.getAssignedLODInformation(n);
|
|
527
|
+
console.log(`[gltf-progressive] Disposed old texture LOD ${l?.level ?? "?"} → ${e} for ${s.name || s.type}.${r}`, n.uuid);
|
|
528
528
|
}
|
|
529
529
|
s[r] = i;
|
|
530
530
|
}
|
|
531
531
|
return i;
|
|
532
|
-
} else
|
|
532
|
+
} else h == "verbose" && console.warn("No LOD found for", t, e);
|
|
533
533
|
return null;
|
|
534
534
|
}).catch((i) => (console.error("Error loading LOD", t, i), null));
|
|
535
535
|
}
|
|
@@ -537,12 +537,12 @@ class m {
|
|
|
537
537
|
url;
|
|
538
538
|
constructor(t) {
|
|
539
539
|
const e = t.options.path;
|
|
540
|
-
|
|
540
|
+
h && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
|
|
541
541
|
}
|
|
542
542
|
_isLoadingMesh;
|
|
543
543
|
loadMesh = (t) => {
|
|
544
544
|
if (this._isLoadingMesh) return null;
|
|
545
|
-
const e = this.parser.json.meshes[t]?.extensions?.[
|
|
545
|
+
const e = this.parser.json.meshes[t]?.extensions?.[U];
|
|
546
546
|
return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s && m.registerMesh(this.url, e.guid, s, e.lods?.length, 0, e), s))) : null;
|
|
547
547
|
};
|
|
548
548
|
// private _isLoadingTexture;
|
|
@@ -560,12 +560,12 @@ class m {
|
|
|
560
560
|
// });
|
|
561
561
|
// }
|
|
562
562
|
afterRoot(t) {
|
|
563
|
-
return
|
|
563
|
+
return h && console.log("AFTER", this.url, t), this.parser.json.textures?.forEach((e, s) => {
|
|
564
564
|
if (e?.extensions) {
|
|
565
|
-
const r = e?.extensions[
|
|
565
|
+
const r = e?.extensions[U];
|
|
566
566
|
if (r) {
|
|
567
567
|
if (!r.lods) {
|
|
568
|
-
|
|
568
|
+
h && console.warn("Texture has no LODs", r);
|
|
569
569
|
return;
|
|
570
570
|
}
|
|
571
571
|
let i = !1;
|
|
@@ -578,7 +578,7 @@ class m {
|
|
|
578
578
|
}
|
|
579
579
|
}), this.parser.json.meshes?.forEach((e, s) => {
|
|
580
580
|
if (e?.extensions) {
|
|
581
|
-
const r = e?.extensions[
|
|
581
|
+
const r = e?.extensions[U];
|
|
582
582
|
if (r && r.lods) {
|
|
583
583
|
for (const i of this.parser.associations.keys())
|
|
584
584
|
if (i.isMesh) {
|
|
@@ -594,12 +594,12 @@ class m {
|
|
|
594
594
|
*/
|
|
595
595
|
static registerTexture = (t, e, s, r, i) => {
|
|
596
596
|
if (!e) {
|
|
597
|
-
|
|
597
|
+
h && console.error("!! gltf-progressive: Called register texture without texture");
|
|
598
598
|
return;
|
|
599
599
|
}
|
|
600
|
-
if (
|
|
601
|
-
const
|
|
602
|
-
console.log(`> gltf-progressive: register texture[${r}] "${e.name || e.uuid}", Current: ${
|
|
600
|
+
if (h) {
|
|
601
|
+
const a = e.image?.width || e.source?.data?.width || 0, l = e.image?.height || e.source?.data?.height || 0;
|
|
602
|
+
console.log(`> gltf-progressive: register texture[${r}] "${e.name || e.uuid}", Current: ${a}x${l}, Max: ${i.lods[0]?.width}x${i.lods[0]?.height}, uuid: ${e.uuid}`, i, e);
|
|
603
603
|
}
|
|
604
604
|
e.source && (e.source[ce] = i);
|
|
605
605
|
const n = i.guid;
|
|
@@ -609,15 +609,15 @@ class m {
|
|
|
609
609
|
* Register a mesh with LOD information
|
|
610
610
|
*/
|
|
611
611
|
static registerMesh = (t, e, s, r, i, n) => {
|
|
612
|
-
const
|
|
613
|
-
if (!
|
|
614
|
-
|
|
612
|
+
const a = s.geometry;
|
|
613
|
+
if (!a) {
|
|
614
|
+
h && console.warn("gltf-progressive: Register mesh without geometry");
|
|
615
615
|
return;
|
|
616
616
|
}
|
|
617
|
-
|
|
617
|
+
a.userData || (a.userData = {}), h && console.log("> Progressive: register mesh " + s.name, { index: i, uuid: s.uuid }, n, s), m.assignLODInformation(t, a, e, r, i), m.lodInfos.set(e, n);
|
|
618
618
|
let u = m.lowresCache.get(e)?.deref();
|
|
619
|
-
u ? u.push(s.geometry) : u = [s.geometry], m.lowresCache.set(e, new WeakRef(u)), r > 0 && !ee(s) && lt(s,
|
|
620
|
-
for (const c of
|
|
619
|
+
u ? u.push(s.geometry) : u = [s.geometry], m.lowresCache.set(e, new WeakRef(u)), r > 0 && !ee(s) && lt(s, a);
|
|
620
|
+
for (const c of q)
|
|
621
621
|
c.onRegisteredNewMesh?.(s, n);
|
|
622
622
|
};
|
|
623
623
|
/**
|
|
@@ -645,7 +645,7 @@ class m {
|
|
|
645
645
|
for (const [s, r] of this.cache)
|
|
646
646
|
s.includes(t) && (this._disposeCacheEntry(r), this.cache.delete(s));
|
|
647
647
|
} else {
|
|
648
|
-
this.lodInfos.clear();
|
|
648
|
+
this.cacheGeneration++, this.lodInfos.clear();
|
|
649
649
|
for (const [, e] of this.lowresCache) {
|
|
650
650
|
const s = e.deref();
|
|
651
651
|
if (s) {
|
|
@@ -668,7 +668,7 @@ class m {
|
|
|
668
668
|
const e = t.deref();
|
|
669
669
|
e && (e.isTexture && this.textureRefCounts.delete(e.uuid), e.dispose());
|
|
670
670
|
} else
|
|
671
|
-
t.then((e) => {
|
|
671
|
+
this.disposedRequests.add(t), t.then((e) => {
|
|
672
672
|
if (e)
|
|
673
673
|
if (Array.isArray(e))
|
|
674
674
|
for (const s of e) s.dispose();
|
|
@@ -692,15 +692,15 @@ class m {
|
|
|
692
692
|
*/
|
|
693
693
|
static _resourceRegistry = new FinalizationRegistry((t) => {
|
|
694
694
|
const e = m.cache.get(t);
|
|
695
|
-
(
|
|
696
|
-
${t}`), e instanceof WeakRef && (e.deref() || (m.cache.delete(t), (
|
|
695
|
+
(h || K) && console.debug(`[gltf-progressive] Memory: Resource GC'd
|
|
696
|
+
${t}`), e instanceof WeakRef && (e.deref() || (m.cache.delete(t), (h || K) && console.log("[gltf-progressive] ↪ Cache entry deleted (GC)")));
|
|
697
697
|
});
|
|
698
698
|
/**
|
|
699
699
|
* Track texture usage by incrementing reference count
|
|
700
700
|
*/
|
|
701
701
|
static trackTextureUsage(t) {
|
|
702
702
|
const e = t.uuid, s = this.textureRefCounts.get(e) || 0;
|
|
703
|
-
this.textureRefCounts.set(e, s + 1),
|
|
703
|
+
this.textureRefCounts.set(e, s + 1), h === "verbose" && console.log(`[gltf-progressive] Track texture ${e}, refCount: ${s} → ${s + 1}`);
|
|
704
704
|
}
|
|
705
705
|
/**
|
|
706
706
|
* Untrack texture usage by decrementing reference count.
|
|
@@ -710,165 +710,171 @@ ${t}`), e instanceof WeakRef && (e.deref() || (m.cache.delete(t), (f || K) && co
|
|
|
710
710
|
static untrackTextureUsage(t) {
|
|
711
711
|
const e = t.uuid, s = this.textureRefCounts.get(e);
|
|
712
712
|
if (!s)
|
|
713
|
-
return (
|
|
713
|
+
return (h === "verbose" || K) && i("[gltf-progressive] Memory: Untrack untracked texture (dispose immediately)", 0), t.dispose(), !0;
|
|
714
714
|
const r = s - 1;
|
|
715
715
|
if (r <= 0)
|
|
716
|
-
return this.textureRefCounts.delete(e), (
|
|
717
|
-
return this.textureRefCounts.set(e, r),
|
|
718
|
-
function i(n,
|
|
719
|
-
let
|
|
720
|
-
const c =
|
|
721
|
-
let
|
|
722
|
-
|
|
716
|
+
return this.textureRefCounts.delete(e), (h || K) && i("[gltf-progressive] Memory: Dispose texture", r), t.dispose(), !0;
|
|
717
|
+
return this.textureRefCounts.set(e, r), h === "verbose" && i("[gltf-progressive] Memory: Untrack texture", r), !1;
|
|
718
|
+
function i(n, a) {
|
|
719
|
+
let l = t.image?.width || t.source?.data?.width || 0, u = t.image?.height || t.source?.data?.height || 0;
|
|
720
|
+
const c = l && u ? `${l}x${u}` : "N/A";
|
|
721
|
+
let g = "N/A";
|
|
722
|
+
l && u && (g = `~${(nt(t) / (1024 * 1024)).toFixed(2)} MB`), console.log(`${n} — ${t.name} ${c} (${g}), refCount: ${s} → ${a}
|
|
723
723
|
${e}`);
|
|
724
724
|
}
|
|
725
725
|
}
|
|
726
726
|
static workers = [];
|
|
727
|
+
static cacheGeneration = 0;
|
|
728
|
+
static disposedRequests = /* @__PURE__ */ new WeakSet();
|
|
727
729
|
static _workersIndex = 0;
|
|
728
730
|
static async getOrLoadLOD(t, e) {
|
|
729
|
-
const s =
|
|
730
|
-
if (!
|
|
731
|
-
return
|
|
732
|
-
const
|
|
733
|
-
let
|
|
731
|
+
const s = this.cacheGeneration, r = h == "verbose", i = this.getAssignedLODInformation(t);
|
|
732
|
+
if (!i)
|
|
733
|
+
return h && console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`, t), null;
|
|
734
|
+
const n = i?.key;
|
|
735
|
+
let a;
|
|
734
736
|
if (t.isTexture === !0) {
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
+
const u = t;
|
|
738
|
+
u.source && u.source[ce] && (a = u.source[ce]);
|
|
737
739
|
}
|
|
738
|
-
if (
|
|
739
|
-
|
|
740
|
+
if (a || (a = m.lodInfos.get(n)), !a)
|
|
741
|
+
h && console.warn(`Can not load LOD ${e}: no LOD info found for "${n}" ${t.name}`, t.type, m.lodInfos);
|
|
740
742
|
else {
|
|
741
743
|
if (e > 0) {
|
|
742
|
-
let
|
|
743
|
-
const y = Array.isArray(
|
|
744
|
-
if (y && e >=
|
|
745
|
-
const
|
|
746
|
-
if (
|
|
747
|
-
const
|
|
748
|
-
if (
|
|
749
|
-
this.lowresCache.delete(
|
|
744
|
+
let g = !1;
|
|
745
|
+
const y = Array.isArray(a.lods);
|
|
746
|
+
if (y && e >= a.lods.length ? g = !0 : y || (g = !0), g) {
|
|
747
|
+
const v = this.lowresCache.get(n);
|
|
748
|
+
if (v) {
|
|
749
|
+
const _ = v.deref();
|
|
750
|
+
if (_) return _;
|
|
751
|
+
this.lowresCache.delete(n), h && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${n}`);
|
|
750
752
|
}
|
|
751
753
|
return null;
|
|
752
754
|
}
|
|
753
755
|
}
|
|
754
|
-
const
|
|
755
|
-
if (!
|
|
756
|
-
return
|
|
757
|
-
const
|
|
758
|
-
if (
|
|
759
|
-
if (!
|
|
760
|
-
return console.warn("missing pointer for glb/gltf texture",
|
|
761
|
-
const
|
|
762
|
-
if (
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
756
|
+
const u = Array.isArray(a.lods) ? a.lods[e]?.path : a.lods;
|
|
757
|
+
if (!u)
|
|
758
|
+
return h && !a["missing:uri"] && (a["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, a)), null;
|
|
759
|
+
const c = rt(i.url, u);
|
|
760
|
+
if (c.endsWith(".glb") || c.endsWith(".gltf")) {
|
|
761
|
+
if (!a.guid)
|
|
762
|
+
return console.warn("missing pointer for glb/gltf texture", a), null;
|
|
763
|
+
const g = c + "_" + a.guid, y = await this.queue.slot(c);
|
|
764
|
+
if (s !== this.cacheGeneration) return null;
|
|
765
|
+
const v = this.cache.get(g);
|
|
766
|
+
if (v !== void 0)
|
|
767
|
+
if (r && console.log(`LOD ${e} was already loading/loaded: ${g}`), v instanceof WeakRef) {
|
|
768
|
+
const f = v.deref();
|
|
769
|
+
if (f) {
|
|
770
|
+
let L = f, D = !1;
|
|
771
|
+
if (L instanceof F && t instanceof F ? L.image?.data || L.source?.data ? L = this.copySettings(t, L) : D = !0 : L instanceof V && t instanceof V && (L.attributes.position?.array || (D = !0)), !D)
|
|
772
|
+
return L;
|
|
769
773
|
}
|
|
770
|
-
this.cache.delete(
|
|
774
|
+
this.cache.delete(g), h && console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${g}`);
|
|
771
775
|
} else {
|
|
772
|
-
let
|
|
773
|
-
`,
|
|
774
|
-
if (
|
|
775
|
-
|
|
776
|
+
let f = await v.catch((D) => (console.error(`Error loading LOD ${e} from ${c}
|
|
777
|
+
`, D), null));
|
|
778
|
+
if (s !== this.cacheGeneration || this.disposedRequests.has(v)) return null;
|
|
779
|
+
let L = !1;
|
|
780
|
+
if (f == null || (f instanceof F && t instanceof F ? f.image?.data || f.source?.data ? f = this.copySettings(t, f) : (L = !0, this.cache.delete(g)) : f instanceof V && t instanceof V && (f.attributes.position?.array || (L = !0, this.cache.delete(g)))), !L)
|
|
781
|
+
return f;
|
|
776
782
|
}
|
|
777
783
|
if (!y.use)
|
|
778
|
-
return
|
|
779
|
-
const
|
|
784
|
+
return h && console.log(`LOD ${e} was aborted: ${c}`), null;
|
|
785
|
+
const _ = a, P = new Promise(async (f, L) => {
|
|
780
786
|
if (pt) {
|
|
781
|
-
const
|
|
782
|
-
if (
|
|
783
|
-
for (const
|
|
784
|
-
let
|
|
785
|
-
return m.assignLODInformation(
|
|
787
|
+
const d = await (await ht({})).load(c);
|
|
788
|
+
if (d.textures.length > 0)
|
|
789
|
+
for (const p of d.textures) {
|
|
790
|
+
let w = p.texture;
|
|
791
|
+
return m.assignLODInformation(i.url, w, n, e, void 0), t instanceof F && (w = this.copySettings(t, w)), w && (w.guid = _.guid), f(w);
|
|
786
792
|
}
|
|
787
|
-
if (
|
|
788
|
-
const
|
|
789
|
-
for (const
|
|
790
|
-
const
|
|
791
|
-
m.assignLODInformation(
|
|
793
|
+
if (d.geometries.length > 0) {
|
|
794
|
+
const p = new Array();
|
|
795
|
+
for (const w of d.geometries) {
|
|
796
|
+
const M = w.geometry;
|
|
797
|
+
m.assignLODInformation(i.url, M, n, e, w.primitiveIndex), p.push(M);
|
|
792
798
|
}
|
|
793
|
-
return
|
|
799
|
+
return f(p);
|
|
794
800
|
}
|
|
795
|
-
return
|
|
801
|
+
return f(null);
|
|
796
802
|
}
|
|
797
|
-
const
|
|
798
|
-
Ce(
|
|
799
|
-
let
|
|
800
|
-
if (
|
|
801
|
-
const
|
|
802
|
-
|
|
803
|
+
const D = new we();
|
|
804
|
+
Ce(D), h && (await new Promise((O) => setTimeout(O, 1e3)), r && console.warn("Start loading (delayed) " + c, _.guid));
|
|
805
|
+
let I = c;
|
|
806
|
+
if (_ && Array.isArray(_.lods)) {
|
|
807
|
+
const O = _.lods[e];
|
|
808
|
+
O.hash && (I += "?v=" + O.hash);
|
|
803
809
|
}
|
|
804
|
-
const
|
|
805
|
-
`,
|
|
806
|
-
if (!
|
|
807
|
-
return
|
|
808
|
-
const
|
|
809
|
-
|
|
810
|
-
let
|
|
811
|
-
if (
|
|
812
|
-
let
|
|
813
|
-
for (const
|
|
814
|
-
if (
|
|
815
|
-
const
|
|
816
|
-
if (
|
|
817
|
-
|
|
810
|
+
const C = await D.loadAsync(I).catch((O) => (console.error(`Error loading LOD ${e} from ${c}
|
|
811
|
+
`, O), f(null)));
|
|
812
|
+
if (!C)
|
|
813
|
+
return f(null);
|
|
814
|
+
const W = C.parser;
|
|
815
|
+
r && console.log("Loading finished " + c, _.guid);
|
|
816
|
+
let b = 0;
|
|
817
|
+
if (C.parser.json.textures) {
|
|
818
|
+
let O = !1;
|
|
819
|
+
for (const d of C.parser.json.textures) {
|
|
820
|
+
if (d?.extensions) {
|
|
821
|
+
const p = d?.extensions[U];
|
|
822
|
+
if (p?.guid && p.guid === _.guid) {
|
|
823
|
+
O = !0;
|
|
818
824
|
break;
|
|
819
825
|
}
|
|
820
826
|
}
|
|
821
|
-
|
|
827
|
+
b++;
|
|
822
828
|
}
|
|
823
|
-
if (
|
|
824
|
-
let
|
|
825
|
-
return
|
|
826
|
-
} else
|
|
829
|
+
if (O) {
|
|
830
|
+
let d = await W.getDependency("texture", b);
|
|
831
|
+
return d && m.assignLODInformation(i.url, d, n, e, void 0), r && console.log('change "' + t.name + '" → "' + d.name + '"', c, b, d, g), t instanceof F && (d = this.copySettings(t, d)), d && (d.guid = _.guid), f(d);
|
|
832
|
+
} else h && console.warn("Could not find texture with guid", _.guid, C.parser.json);
|
|
827
833
|
}
|
|
828
|
-
if (
|
|
829
|
-
let
|
|
830
|
-
for (const
|
|
831
|
-
if (
|
|
832
|
-
const
|
|
833
|
-
if (
|
|
834
|
-
|
|
834
|
+
if (b = 0, C.parser.json.meshes) {
|
|
835
|
+
let O = !1;
|
|
836
|
+
for (const d of C.parser.json.meshes) {
|
|
837
|
+
if (d?.extensions) {
|
|
838
|
+
const p = d?.extensions[U];
|
|
839
|
+
if (p?.guid && p.guid === _.guid) {
|
|
840
|
+
O = !0;
|
|
835
841
|
break;
|
|
836
842
|
}
|
|
837
843
|
}
|
|
838
|
-
|
|
844
|
+
b++;
|
|
839
845
|
}
|
|
840
|
-
if (
|
|
841
|
-
const
|
|
842
|
-
if (
|
|
843
|
-
const
|
|
844
|
-
return m.assignLODInformation(
|
|
846
|
+
if (O) {
|
|
847
|
+
const d = await W.getDependency("mesh", b);
|
|
848
|
+
if (r && console.log(`Loaded Mesh "${d.name}"`, c, b, d, g), d.isMesh === !0) {
|
|
849
|
+
const p = d.geometry;
|
|
850
|
+
return m.assignLODInformation(i.url, p, n, e, 0), f(p);
|
|
845
851
|
} else {
|
|
846
|
-
const
|
|
847
|
-
for (let
|
|
848
|
-
const
|
|
849
|
-
if (
|
|
850
|
-
const
|
|
851
|
-
m.assignLODInformation(
|
|
852
|
+
const p = new Array();
|
|
853
|
+
for (let w = 0; w < d.children.length; w++) {
|
|
854
|
+
const M = d.children[w];
|
|
855
|
+
if (M.isMesh === !0) {
|
|
856
|
+
const A = M.geometry;
|
|
857
|
+
m.assignLODInformation(i.url, A, n, e, w), p.push(A);
|
|
852
858
|
}
|
|
853
859
|
}
|
|
854
|
-
return
|
|
860
|
+
return f(p);
|
|
855
861
|
}
|
|
856
|
-
} else
|
|
862
|
+
} else h && console.warn("Could not find mesh with guid", _.guid, C.parser.json);
|
|
857
863
|
}
|
|
858
|
-
return
|
|
864
|
+
return f(null);
|
|
859
865
|
});
|
|
860
|
-
this.cache.set(
|
|
861
|
-
const
|
|
862
|
-
return
|
|
866
|
+
this.cache.set(g, P), y.use(P);
|
|
867
|
+
const x = await P;
|
|
868
|
+
return s !== this.cacheGeneration || this.cache.get(g) !== P ? null : (x != null ? x instanceof F ? (this.cache.set(g, new WeakRef(x)), m._resourceRegistry.register(x, g)) : Array.isArray(x) ? this.cache.set(g, Promise.resolve(x)) : this.cache.set(g, Promise.resolve(x)) : this.cache.set(g, Promise.resolve(null)), x);
|
|
863
869
|
} else if (t instanceof F) {
|
|
864
|
-
|
|
865
|
-
const y = await new Ne().loadAsync(
|
|
866
|
-
return y ? (y.guid =
|
|
870
|
+
r && console.log("Load texture from uri: " + c);
|
|
871
|
+
const y = await new Ne().loadAsync(c);
|
|
872
|
+
return s !== this.cacheGeneration ? (y?.dispose(), null) : (y ? (y.guid = a.guid, y.flipY = !1, y.needsUpdate = !0, y.colorSpace = t.colorSpace, r && console.log(a, y)) : h && console.warn("failed loading", c), y);
|
|
867
873
|
}
|
|
868
874
|
}
|
|
869
875
|
return null;
|
|
870
876
|
}
|
|
871
|
-
static queue = new it(_e() ? 20 : 50, { debug:
|
|
877
|
+
static queue = new it(_e() ? 20 : 50, { debug: h != !1 });
|
|
872
878
|
static assignLODInformation(t, e, s, r, i) {
|
|
873
879
|
if (!e) return;
|
|
874
880
|
e.userData || (e.userData = {});
|
|
@@ -880,7 +886,7 @@ ${e}`);
|
|
|
880
886
|
}
|
|
881
887
|
// private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
|
|
882
888
|
static copySettings(t, e) {
|
|
883
|
-
return e ? (
|
|
889
|
+
return e ? (h === "verbose" && console.debug(`Copy texture settings
|
|
884
890
|
`, t.uuid, `
|
|
885
891
|
`, e.uuid), e = e.clone(), e.offset = t.offset, e.repeat = t.repeat, e.colorSpace = t.colorSpace, e.magFilter = t.magFilter, e.minFilter = t.minFilter, e.wrapS = t.wrapS, e.wrapT = t.wrapT, e.flipY = t.flipY, e.anisotropy = t.anisotropy, e.mipmaps || (e.generateMipmaps = t.generateMipmaps), e) : t;
|
|
886
892
|
}
|
|
@@ -945,7 +951,7 @@ class de {
|
|
|
945
951
|
_seen = /* @__PURE__ */ new WeakMap();
|
|
946
952
|
add(t, e, s) {
|
|
947
953
|
if (this._resolved) {
|
|
948
|
-
|
|
954
|
+
h && console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");
|
|
949
955
|
return;
|
|
950
956
|
}
|
|
951
957
|
if (!(this._frame_start !== void 0 && this._currentFrame > this._frame_start + this._frames_to_capture)) {
|
|
@@ -953,7 +959,7 @@ class de {
|
|
|
953
959
|
if (this._seen.has(e)) {
|
|
954
960
|
let r = this._seen.get(e);
|
|
955
961
|
if (r >= this._maxPromisesPerObject) {
|
|
956
|
-
|
|
962
|
+
h && console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");
|
|
957
963
|
return;
|
|
958
964
|
}
|
|
959
965
|
this._seen.set(e, r + 1);
|
|
@@ -972,8 +978,8 @@ class de {
|
|
|
972
978
|
});
|
|
973
979
|
}
|
|
974
980
|
}
|
|
975
|
-
const
|
|
976
|
-
let oe = class
|
|
981
|
+
const $ = N("debugprogressive"), yt = N("noprogressive"), fe = /* @__PURE__ */ Symbol("Needle:LODSManager"), he = /* @__PURE__ */ Symbol("Needle:LODState"), z = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), T = { mesh_lod: -1, texture_lod: -1 };
|
|
982
|
+
let oe = class S {
|
|
977
983
|
/**
|
|
978
984
|
* 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.
|
|
979
985
|
*/
|
|
@@ -983,11 +989,11 @@ let oe = class O {
|
|
|
983
989
|
return t[he];
|
|
984
990
|
}
|
|
985
991
|
static addPlugin(t) {
|
|
986
|
-
|
|
992
|
+
q.push(t);
|
|
987
993
|
}
|
|
988
994
|
static removePlugin(t) {
|
|
989
|
-
const e =
|
|
990
|
-
e >= 0 &&
|
|
995
|
+
const e = q.indexOf(t);
|
|
996
|
+
e >= 0 && q.splice(e, 1);
|
|
991
997
|
}
|
|
992
998
|
/**
|
|
993
999
|
* Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
|
|
@@ -997,7 +1003,7 @@ let oe = class O {
|
|
|
997
1003
|
static get(t, e) {
|
|
998
1004
|
if (t[fe])
|
|
999
1005
|
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[fe];
|
|
1000
|
-
const s = new
|
|
1006
|
+
const s = new S(t, {
|
|
1001
1007
|
engine: "unknown",
|
|
1002
1008
|
...e
|
|
1003
1009
|
});
|
|
@@ -1008,7 +1014,7 @@ let oe = class O {
|
|
|
1008
1014
|
projectionScreenMatrix = new ve();
|
|
1009
1015
|
/** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
|
|
1010
1016
|
get plugins() {
|
|
1011
|
-
return
|
|
1017
|
+
return q;
|
|
1012
1018
|
}
|
|
1013
1019
|
/**
|
|
1014
1020
|
* Force override the LOD level for all objects (meshes + textures) rendered in the scene
|
|
@@ -1097,7 +1103,7 @@ let oe = class O {
|
|
|
1097
1103
|
const e = this;
|
|
1098
1104
|
Le(this.renderer), this.renderer.render = function(s, r) {
|
|
1099
1105
|
const i = e.renderer.getRenderTarget();
|
|
1100
|
-
(i == null || "isXRRenderTarget" in i && i.isXRRenderTarget) && (t = 0, e.#r += 1, e.#i = e.#n.getDelta(), e.#o += e.#i, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#i), e.#s = e._fpsBuffer.reduce((
|
|
1106
|
+
(i == null || "isXRRenderTarget" in i && i.isXRRenderTarget) && (t = 0, e.#r += 1, e.#i = e.#n.getDelta(), e.#o += e.#i, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#i), e.#s = e._fpsBuffer.reduce((a, l) => a + l) / e._fpsBuffer.length, $ && e.#r % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
|
|
1101
1107
|
const n = t++;
|
|
1102
1108
|
e.#t.call(this, s, r), e.onAfterRender(s, r, n);
|
|
1103
1109
|
};
|
|
@@ -1113,11 +1119,11 @@ let oe = class O {
|
|
|
1113
1119
|
const i = this.renderer.renderLists.get(t, 0).opaque;
|
|
1114
1120
|
let n = !0;
|
|
1115
1121
|
if (i.length === 1) {
|
|
1116
|
-
const
|
|
1117
|
-
(
|
|
1122
|
+
const a = i[0].material;
|
|
1123
|
+
(a.name === "EffectMaterial" || a.name === "CopyShader") && (n = !1);
|
|
1118
1124
|
}
|
|
1119
1125
|
if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (n = !1), n) {
|
|
1120
|
-
if (yt || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1,
|
|
1126
|
+
if (yt || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1, $ && console.warn("↓ Reducing LOD updates", this.#e, this.#s.toFixed(0))) : this.#s >= 60 && this.#e > 1 && (this.#e -= 1, $ && console.warn("↑ Increasing LOD updates", this.#e, this.#s.toFixed(0))) : this.#e = this.updateInterval, this.#e > 0 && this.#r % this.#e != 0))
|
|
1121
1127
|
return;
|
|
1122
1128
|
this.internalUpdate(t, e), this._postprocessPromiseGroups();
|
|
1123
1129
|
}
|
|
@@ -1129,12 +1135,12 @@ let oe = class O {
|
|
|
1129
1135
|
const s = this.renderer.renderLists.get(t, 0), r = s.opaque;
|
|
1130
1136
|
this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse);
|
|
1131
1137
|
const i = this.targetTriangleDensity;
|
|
1132
|
-
for (const
|
|
1133
|
-
if (
|
|
1134
|
-
|
|
1138
|
+
for (const l of r) {
|
|
1139
|
+
if (l.material && (l.geometry?.type === "BoxGeometry" || l.geometry?.type === "BufferGeometry") && (l.material.name === "SphericalGaussianBlur" || l.material.name == "BackgroundCubeMaterial" || l.material.name === "CubemapFromEquirect" || l.material.name === "EquirectangularToCubeUV")) {
|
|
1140
|
+
$ && (l.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] || (l.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] = !0, console.warn("Ignoring skybox or BLIT object", l, l.material.name, l.material.type)));
|
|
1135
1141
|
continue;
|
|
1136
1142
|
}
|
|
1137
|
-
switch (
|
|
1143
|
+
switch (l.material.type) {
|
|
1138
1144
|
case "LineBasicMaterial":
|
|
1139
1145
|
case "LineDashedMaterial":
|
|
1140
1146
|
case "PointsMaterial":
|
|
@@ -1143,22 +1149,22 @@ let oe = class O {
|
|
|
1143
1149
|
case "MeshDepthMaterial":
|
|
1144
1150
|
continue;
|
|
1145
1151
|
}
|
|
1146
|
-
if (
|
|
1147
|
-
|
|
1148
|
-
const c = Math.random() * 16777215,
|
|
1149
|
-
|
|
1152
|
+
if ($ === "color" && l.material && !l.object.progressive_debug_color) {
|
|
1153
|
+
l.object.progressive_debug_color = !0;
|
|
1154
|
+
const c = Math.random() * 16777215, g = new Ve({ color: c });
|
|
1155
|
+
l.object.material = g;
|
|
1150
1156
|
}
|
|
1151
|
-
const u =
|
|
1157
|
+
const u = l.object;
|
|
1152
1158
|
(u instanceof X || u.isMesh) && this.updateLODs(t, e, u, i);
|
|
1153
1159
|
}
|
|
1154
1160
|
const n = s.transparent;
|
|
1155
|
-
for (const
|
|
1156
|
-
const u =
|
|
1161
|
+
for (const l of n) {
|
|
1162
|
+
const u = l.object;
|
|
1157
1163
|
(u instanceof X || u.isMesh) && this.updateLODs(t, e, u, i);
|
|
1158
1164
|
}
|
|
1159
|
-
const
|
|
1160
|
-
for (const
|
|
1161
|
-
const u =
|
|
1165
|
+
const a = s.transmissive;
|
|
1166
|
+
for (const l of a) {
|
|
1167
|
+
const u = l.object;
|
|
1162
1168
|
(u instanceof X || u.isMesh) && this.updateLODs(t, e, u, i);
|
|
1163
1169
|
}
|
|
1164
1170
|
}
|
|
@@ -1168,13 +1174,13 @@ let oe = class O {
|
|
|
1168
1174
|
let i = s[he];
|
|
1169
1175
|
if (i || (i = new xt(), s[he] = i), i.frames++ < 2)
|
|
1170
1176
|
return;
|
|
1171
|
-
for (const
|
|
1172
|
-
|
|
1177
|
+
for (const a of q)
|
|
1178
|
+
a.onBeforeUpdateLOD?.(this.renderer, t, e, s);
|
|
1173
1179
|
const n = this.overrideLodLevel !== void 0 ? this.overrideLodLevel : E;
|
|
1174
|
-
n >= 0 ? (
|
|
1175
|
-
for (const
|
|
1176
|
-
|
|
1177
|
-
i.lastLodLevel_Mesh =
|
|
1180
|
+
n >= 0 ? (T.mesh_lod = n, T.texture_lod = n) : (this.calculateLodLevel(e, s, i, r, T), T.mesh_lod = Math.round(T.mesh_lod), T.texture_lod = Math.round(T.texture_lod)), T.mesh_lod >= 0 && this.loadProgressiveMeshes(s, T.mesh_lod), s.material && T.texture_lod >= 0 && this.loadProgressiveTextures(s.material, T.texture_lod, n), h && s.material && !s.isGizmo && Re(s.material);
|
|
1181
|
+
for (const a of q)
|
|
1182
|
+
a.onAfterUpdatedLOD?.(this.renderer, t, e, s, T);
|
|
1183
|
+
i.lastLodLevel_Mesh = T.mesh_lod, i.lastLodLevel_Texture = T.texture_lod;
|
|
1178
1184
|
}
|
|
1179
1185
|
/** Load progressive textures for the given material
|
|
1180
1186
|
* @param material the material to load the textures for
|
|
@@ -1189,10 +1195,10 @@ let oe = class O {
|
|
|
1189
1195
|
return;
|
|
1190
1196
|
}
|
|
1191
1197
|
let r = !1;
|
|
1192
|
-
if ((t[
|
|
1193
|
-
t[
|
|
1198
|
+
if ((t[z] === void 0 || e < t[z]) && (r = !0), s !== void 0 && s >= 0 && (r = t[z] != s, e = s), r) {
|
|
1199
|
+
t[z] = e;
|
|
1194
1200
|
const i = m.assignTextureLOD(t, e).then((n) => {
|
|
1195
|
-
this._lodchangedlisteners.forEach((
|
|
1201
|
+
this._lodchangedlisteners.forEach((a) => a({ type: "texture", level: e, object: t }));
|
|
1196
1202
|
});
|
|
1197
1203
|
de.addPromise("texture", t, i, this._newPromiseGroups);
|
|
1198
1204
|
}
|
|
@@ -1205,11 +1211,11 @@ let oe = class O {
|
|
|
1205
1211
|
*/
|
|
1206
1212
|
loadProgressiveMeshes(t, e) {
|
|
1207
1213
|
if (!t) return Promise.resolve(null);
|
|
1208
|
-
let s = t[
|
|
1214
|
+
let s = t[z] !== e;
|
|
1209
1215
|
const r = t["DEBUG:LOD"];
|
|
1210
|
-
if (r != null && (s = t[
|
|
1211
|
-
t[
|
|
1212
|
-
const i = t.geometry, n = m.assignMeshLOD(t, e).then((
|
|
1216
|
+
if (r != null && (s = t[z] != r, e = r), s) {
|
|
1217
|
+
t[z] = e;
|
|
1218
|
+
const i = t.geometry, n = m.assignMeshLOD(t, e).then((a) => (a && t[z] == e && i != t.geometry && this._lodchangedlisteners.forEach((l) => l({ type: "mesh", level: e, object: t })), a));
|
|
1213
1219
|
return de.addPromise("mesh", t, n, this._newPromiseGroups), n;
|
|
1214
1220
|
}
|
|
1215
1221
|
return Promise.resolve(null);
|
|
@@ -1219,14 +1225,14 @@ let oe = class O {
|
|
|
1219
1225
|
_tempBox = new pe();
|
|
1220
1226
|
_tempBox2 = new pe();
|
|
1221
1227
|
tempMatrix = new ve();
|
|
1222
|
-
_tempWorldPosition = new
|
|
1223
|
-
_tempBoxSize = new
|
|
1224
|
-
_tempBox2Size = new
|
|
1225
|
-
static corner0 = new
|
|
1226
|
-
static corner1 = new
|
|
1227
|
-
static corner2 = new
|
|
1228
|
-
static corner3 = new
|
|
1229
|
-
static _tempPtInside = new
|
|
1228
|
+
_tempWorldPosition = new R();
|
|
1229
|
+
_tempBoxSize = new R();
|
|
1230
|
+
_tempBox2Size = new R();
|
|
1231
|
+
static corner0 = new R();
|
|
1232
|
+
static corner1 = new R();
|
|
1233
|
+
static corner2 = new R();
|
|
1234
|
+
static corner3 = new R();
|
|
1235
|
+
static _tempPtInside = new R();
|
|
1230
1236
|
static isInside(t, e) {
|
|
1231
1237
|
const s = t.min, r = t.max, i = (s.x + r.x) * 0.5, n = (s.y + r.y) * 0.5;
|
|
1232
1238
|
return this._tempPtInside.set(i, n, s.z).applyMatrix4(e).z < 0;
|
|
@@ -1243,105 +1249,105 @@ let oe = class O {
|
|
|
1243
1249
|
i.mesh_lod = -1, i.texture_lod = -1;
|
|
1244
1250
|
return;
|
|
1245
1251
|
}
|
|
1246
|
-
let
|
|
1247
|
-
if (
|
|
1252
|
+
let a = 10 + 1, l = !1;
|
|
1253
|
+
if ($ && e["DEBUG:LOD"] != null)
|
|
1248
1254
|
return e["DEBUG:LOD"];
|
|
1249
|
-
const u = m.getMeshLODExtension(e.geometry)?.lods, c = m.getPrimitiveIndex(e.geometry),
|
|
1250
|
-
if (!
|
|
1255
|
+
const u = m.getMeshLODExtension(e.geometry)?.lods, c = m.getPrimitiveIndex(e.geometry), g = u && u.length > 0, y = m.getMaterialMinMaxLODsCount(e.material), v = y.min_count !== 1 / 0 && y.min_count >= 0 && y.max_count >= 0;
|
|
1256
|
+
if (!g && !v) {
|
|
1251
1257
|
i.mesh_lod = 0, i.texture_lod = 0;
|
|
1252
1258
|
return;
|
|
1253
1259
|
}
|
|
1254
|
-
|
|
1255
|
-
const
|
|
1256
|
-
let
|
|
1260
|
+
g || (l = !0, a = 0);
|
|
1261
|
+
const _ = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
|
|
1262
|
+
let P = e.geometry.boundingBox;
|
|
1257
1263
|
if (e.type === "SkinnedMesh") {
|
|
1258
|
-
const
|
|
1259
|
-
if (!
|
|
1260
|
-
|
|
1264
|
+
const x = e;
|
|
1265
|
+
if (!x.boundingBox)
|
|
1266
|
+
x.computeBoundingBox();
|
|
1261
1267
|
else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
|
|
1262
|
-
if (!
|
|
1263
|
-
const
|
|
1264
|
-
|
|
1268
|
+
if (!x[S.$skinnedMeshBoundsOffset]) {
|
|
1269
|
+
const L = S.skinnedMeshBoundsFrameOffsetCounter++;
|
|
1270
|
+
x[S.$skinnedMeshBoundsOffset] = L;
|
|
1265
1271
|
}
|
|
1266
|
-
const
|
|
1267
|
-
if ((s.frames +
|
|
1268
|
-
const
|
|
1269
|
-
|
|
1272
|
+
const f = x[S.$skinnedMeshBoundsOffset];
|
|
1273
|
+
if ((s.frames + f) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
|
|
1274
|
+
const L = ee(x), D = x.geometry;
|
|
1275
|
+
L && (x.geometry = L), x.computeBoundingBox(), x.geometry = D;
|
|
1270
1276
|
}
|
|
1271
1277
|
}
|
|
1272
|
-
|
|
1278
|
+
P = x.boundingBox;
|
|
1273
1279
|
}
|
|
1274
|
-
if (
|
|
1275
|
-
const
|
|
1280
|
+
if (P) {
|
|
1281
|
+
const x = t;
|
|
1276
1282
|
if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
|
|
1277
1283
|
this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
|
|
1278
|
-
const
|
|
1279
|
-
if (this._sphere.containsPoint(
|
|
1284
|
+
const d = t.getWorldPosition(this._tempWorldPosition);
|
|
1285
|
+
if (this._sphere.containsPoint(d)) {
|
|
1280
1286
|
i.mesh_lod = 0, i.texture_lod = 0;
|
|
1281
1287
|
return;
|
|
1282
1288
|
}
|
|
1283
1289
|
}
|
|
1284
|
-
if (this._tempBox.copy(
|
|
1290
|
+
if (this._tempBox.copy(P), this._tempBox.applyMatrix4(e.matrixWorld), x.isPerspectiveCamera && S.isInside(this._tempBox, this.projectionScreenMatrix)) {
|
|
1285
1291
|
i.mesh_lod = 0, i.texture_lod = 0;
|
|
1286
1292
|
return;
|
|
1287
1293
|
}
|
|
1288
|
-
if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled &&
|
|
1289
|
-
const
|
|
1290
|
-
let
|
|
1291
|
-
const te = 2, ae = 1.5, se = (
|
|
1292
|
-
|
|
1293
|
-
const Be =
|
|
1294
|
+
if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && x.isPerspectiveCamera && x.fov > 70) {
|
|
1295
|
+
const d = this._tempBox.min, p = this._tempBox.max;
|
|
1296
|
+
let w = d.x, M = d.y, A = p.x, Y = p.y;
|
|
1297
|
+
const te = 2, ae = 1.5, se = (d.x + p.x) * 0.5, re = (d.y + p.y) * 0.5;
|
|
1298
|
+
w = (w - se) * te + se, M = (M - re) * te + re, A = (A - se) * te + se, Y = (Y - re) * te + re;
|
|
1299
|
+
const Be = w < 0 && A > 0 ? 0 : Math.min(Math.abs(d.x), Math.abs(p.x)), Ge = M < 0 && Y > 0 ? 0 : Math.min(Math.abs(d.y), Math.abs(p.y)), le = Math.max(Be, Ge);
|
|
1294
1300
|
s.lastCentrality = (ae - le) * (ae - le) * (ae - le);
|
|
1295
1301
|
} else
|
|
1296
1302
|
s.lastCentrality = 1;
|
|
1297
|
-
const
|
|
1298
|
-
|
|
1299
|
-
const
|
|
1300
|
-
|
|
1301
|
-
const
|
|
1302
|
-
if (Math.max(
|
|
1303
|
-
const
|
|
1304
|
-
|
|
1305
|
-
const p =
|
|
1306
|
-
p.copy(this._tempBox.min),
|
|
1307
|
-
const Y = (p.z +
|
|
1308
|
-
p.z =
|
|
1303
|
+
const f = this._tempBox.getSize(this._tempBoxSize);
|
|
1304
|
+
f.multiplyScalar(0.5), screen.availHeight > 0 && _ > 0 && f.multiplyScalar(_ / screen.availHeight), t.isPerspectiveCamera ? f.x *= t.aspect : t.isOrthographicCamera;
|
|
1305
|
+
const L = t.matrixWorldInverse, D = this._tempBox2;
|
|
1306
|
+
D.copy(P), D.applyMatrix4(e.matrixWorld), D.applyMatrix4(L);
|
|
1307
|
+
const I = D.getSize(this._tempBox2Size), C = Math.max(I.x, I.y);
|
|
1308
|
+
if (Math.max(f.x, f.y) != 0 && C != 0 && (f.z = I.z / Math.max(I.x, I.y) * Math.max(f.x, f.y)), s.lastScreenCoverage = Math.max(f.x, f.y, f.z), s.lastScreenspaceVolume.copy(f), s.lastScreenCoverage *= s.lastCentrality, $ && S.debugDrawLine) {
|
|
1309
|
+
const d = this.tempMatrix.copy(this.projectionScreenMatrix);
|
|
1310
|
+
d.invert();
|
|
1311
|
+
const p = S.corner0, w = S.corner1, M = S.corner2, A = S.corner3;
|
|
1312
|
+
p.copy(this._tempBox.min), w.copy(this._tempBox.max), w.x = p.x, M.copy(this._tempBox.max), M.y = p.y, A.copy(this._tempBox.max);
|
|
1313
|
+
const Y = (p.z + A.z) * 0.5;
|
|
1314
|
+
p.z = w.z = M.z = A.z = Y, p.applyMatrix4(d), w.applyMatrix4(d), M.applyMatrix4(d), A.applyMatrix4(d), S.debugDrawLine(p, w, 255), S.debugDrawLine(p, M, 255), S.debugDrawLine(w, A, 255), S.debugDrawLine(M, A, 255);
|
|
1309
1315
|
}
|
|
1310
|
-
let
|
|
1316
|
+
let b = 999;
|
|
1311
1317
|
if (u && s.lastScreenCoverage > 0)
|
|
1312
|
-
for (let
|
|
1313
|
-
const p = u[
|
|
1314
|
-
if (c > 0 && De() && !p.densities && !globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] && (window["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] = !0, console.warn("[Needle Progressive] Detected usage of mesh without primitive densities. This might cause incorrect LOD level selection: Consider re-optimizing your model by updating your Needle Integration, Needle glTF Pipeline or running optimization again on Needle Cloud.")),
|
|
1315
|
-
|
|
1318
|
+
for (let d = 0; d < u.length; d++) {
|
|
1319
|
+
const p = u[d], M = (p.densities?.[c] || p.density || 1e-5) / s.lastScreenCoverage;
|
|
1320
|
+
if (c > 0 && De() && !p.densities && !globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] && (window["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"] = !0, console.warn("[Needle Progressive] Detected usage of mesh without primitive densities. This might cause incorrect LOD level selection: Consider re-optimizing your model by updating your Needle Integration, Needle glTF Pipeline or running optimization again on Needle Cloud.")), M < r) {
|
|
1321
|
+
b = d;
|
|
1316
1322
|
break;
|
|
1317
1323
|
}
|
|
1318
1324
|
}
|
|
1319
|
-
|
|
1325
|
+
b < a && (a = b, l = !0);
|
|
1320
1326
|
}
|
|
1321
|
-
if (
|
|
1322
|
-
const
|
|
1323
|
-
|
|
1327
|
+
if (l ? i.mesh_lod = a : i.mesh_lod = s.lastLodLevel_Mesh, $ && i.mesh_lod != s.lastLodLevel_Mesh) {
|
|
1328
|
+
const f = u?.[i.mesh_lod];
|
|
1329
|
+
f && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${i.mesh_lod} (density: ${f.densities?.[c].toFixed(0)}) | ${e.name}`);
|
|
1324
1330
|
}
|
|
1325
|
-
if (
|
|
1326
|
-
const
|
|
1331
|
+
if (v) {
|
|
1332
|
+
const x = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
|
|
1327
1333
|
if (s.lastLodLevel_Texture < 0) {
|
|
1328
|
-
if (i.texture_lod =
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1334
|
+
if (i.texture_lod = y.max_count - 1, $) {
|
|
1335
|
+
const f = y.lods[y.max_count - 1];
|
|
1336
|
+
$ && console.log(`First Texture LOD ${i.texture_lod} (${f.max_height}px) - ${e.name}`);
|
|
1331
1337
|
}
|
|
1332
1338
|
} else {
|
|
1333
|
-
const
|
|
1334
|
-
let
|
|
1335
|
-
this.context?.engine === "model-viewer" && (
|
|
1336
|
-
const
|
|
1337
|
-
let
|
|
1338
|
-
for (let
|
|
1339
|
-
const
|
|
1340
|
-
if (!(
|
|
1341
|
-
if (
|
|
1342
|
-
const
|
|
1343
|
-
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${i.texture_lod} = ${
|
|
1344
|
-
Screensize: ${
|
|
1339
|
+
const f = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
|
|
1340
|
+
let L = s.lastScreenCoverage * 4;
|
|
1341
|
+
this.context?.engine === "model-viewer" && (L *= 1.5);
|
|
1342
|
+
const I = _ / window.devicePixelRatio * L;
|
|
1343
|
+
let C = !1;
|
|
1344
|
+
for (let W = y.lods.length - 1; W >= 0; W--) {
|
|
1345
|
+
const b = y.lods[W];
|
|
1346
|
+
if (!(x && b.max_height >= 2048) && !(_e() && b.max_height > 4096) && (b.max_height > I || !C && W === 0)) {
|
|
1347
|
+
if (C = !0, i.texture_lod = W, $ && i.texture_lod < s.lastLodLevel_Texture) {
|
|
1348
|
+
const O = b.max_height;
|
|
1349
|
+
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${i.texture_lod} = ${O}px
|
|
1350
|
+
Screensize: ${I.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${f.toFixed(1)}
|
|
1345
1351
|
${e.name}`);
|
|
1346
1352
|
}
|
|
1347
1353
|
break;
|
|
@@ -1357,7 +1363,7 @@ class xt {
|
|
|
1357
1363
|
lastLodLevel_Mesh = -1;
|
|
1358
1364
|
lastLodLevel_Texture = -1;
|
|
1359
1365
|
lastScreenCoverage = 0;
|
|
1360
|
-
lastScreenspaceVolume = new
|
|
1366
|
+
lastScreenspaceVolume = new R();
|
|
1361
1367
|
lastCentrality = 0;
|
|
1362
1368
|
}
|
|
1363
1369
|
const be = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), ie = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
|
|
@@ -1396,15 +1402,15 @@ function $e(o) {
|
|
|
1396
1402
|
`, o.getAttribute("src"));
|
|
1397
1403
|
let t = null, e = null, s = null;
|
|
1398
1404
|
for (let r = o; r != null; r = Object.getPrototypeOf(r)) {
|
|
1399
|
-
const i = Object.getOwnPropertySymbols(r), n = i.find((u) => u.toString() == "Symbol(renderer)"),
|
|
1400
|
-
!t && n != null && (t = o[n].threeRenderer), !e &&
|
|
1405
|
+
const i = Object.getOwnPropertySymbols(r), n = i.find((u) => u.toString() == "Symbol(renderer)"), a = i.find((u) => u.toString() == "Symbol(scene)"), l = i.find((u) => u.toString() == "Symbol(needsRender)");
|
|
1406
|
+
!t && n != null && (t = o[n].threeRenderer), !e && a != null && (e = o[a]), !s && l != null && (s = o[l]);
|
|
1401
1407
|
}
|
|
1402
1408
|
if (t && e) {
|
|
1403
1409
|
let r = function() {
|
|
1404
1410
|
if (s) {
|
|
1405
|
-
let n = 0,
|
|
1411
|
+
let n = 0, a = setInterval(() => {
|
|
1406
1412
|
if (n++ > 5) {
|
|
1407
|
-
clearInterval(
|
|
1413
|
+
clearInterval(a);
|
|
1408
1414
|
return;
|
|
1409
1415
|
}
|
|
1410
1416
|
s?.call(o);
|
|
@@ -1447,30 +1453,30 @@ class _t {
|
|
|
1447
1453
|
e[ie] = !0;
|
|
1448
1454
|
const s = this.tryGetCurrentGLTF(t), r = this.tryGetCurrentModelViewer(t), i = this.getUrl(r);
|
|
1449
1455
|
if (i && s && e.material) {
|
|
1450
|
-
let n = function(
|
|
1451
|
-
if (
|
|
1452
|
-
|
|
1453
|
-
const u = Object.keys(
|
|
1456
|
+
let n = function(l) {
|
|
1457
|
+
if (l[ie] == !0) return;
|
|
1458
|
+
l[ie] = !0, l.userData && (l.userData.LOD = -1);
|
|
1459
|
+
const u = Object.keys(l);
|
|
1454
1460
|
for (let c = 0; c < u.length; c++) {
|
|
1455
|
-
const
|
|
1456
|
-
if (
|
|
1457
|
-
const
|
|
1458
|
-
if (
|
|
1459
|
-
const
|
|
1460
|
-
if (!
|
|
1461
|
-
console.warn("Texture data not found for texture index " +
|
|
1461
|
+
const g = u[c], y = l[g];
|
|
1462
|
+
if (y?.isTexture === !0) {
|
|
1463
|
+
const v = y.userData?.associations?.textures;
|
|
1464
|
+
if (v == null) continue;
|
|
1465
|
+
const _ = s.parser.json.textures[v];
|
|
1466
|
+
if (!_) {
|
|
1467
|
+
console.warn("Texture data not found for texture index " + v);
|
|
1462
1468
|
continue;
|
|
1463
1469
|
}
|
|
1464
|
-
if (
|
|
1465
|
-
const
|
|
1466
|
-
|
|
1470
|
+
if (_?.extensions?.[U]) {
|
|
1471
|
+
const P = _.extensions[U];
|
|
1472
|
+
P && i && m.registerTexture(i, y, P.lods.length, v, P);
|
|
1467
1473
|
}
|
|
1468
1474
|
}
|
|
1469
1475
|
}
|
|
1470
1476
|
};
|
|
1471
|
-
const
|
|
1472
|
-
if (Array.isArray(
|
|
1473
|
-
else n(
|
|
1477
|
+
const a = e.material;
|
|
1478
|
+
if (Array.isArray(a)) for (const l of a) n(l);
|
|
1479
|
+
else n(a);
|
|
1474
1480
|
}
|
|
1475
1481
|
}
|
|
1476
1482
|
tryParseMeshLOD(t, e) {
|
|
@@ -1479,7 +1485,7 @@ class _t {
|
|
|
1479
1485
|
const s = this.tryGetCurrentModelViewer(t), r = this.getUrl(s);
|
|
1480
1486
|
if (!r)
|
|
1481
1487
|
return;
|
|
1482
|
-
const i = e.userData?.gltfExtensions?.[
|
|
1488
|
+
const i = e.userData?.gltfExtensions?.[U];
|
|
1483
1489
|
if (i && r) {
|
|
1484
1490
|
const n = e.uuid;
|
|
1485
1491
|
m.registerMesh(r, n, e, 0, i.lods.length, i);
|