@needle-tools/gltf-progressive 3.3.4 → 3.4.0-beta
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 +3 -0
- package/NEEDLE_progressive/README.md +45 -47
- package/gltf-progressive.js +535 -458
- package/gltf-progressive.min.js +8 -7
- package/gltf-progressive.umd.cjs +8 -7
- package/lib/extension.d.ts +18 -3
- package/lib/extension.js +203 -40
- package/lib/lods.manager.js +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
package/gltf-progressive.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { BufferGeometry as
|
|
1
|
+
import { BufferGeometry as E, Mesh as V, Box3 as he, Vector3 as C, Sphere as De, CompressedTexture as Be, Texture as F, Matrix3 as Ge, InterleavedBuffer as Fe, InterleavedBufferAttribute as We, BufferAttribute as Ue, TextureLoader as ze, Matrix4 as _e, Clock as Ne, MeshStandardMaterial as qe } from "three";
|
|
2
2
|
import { GLTFLoader as ye } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
3
|
-
import { MeshoptDecoder as
|
|
3
|
+
import { MeshoptDecoder as Ee } from "three/examples/jsm/libs/meshopt_decoder.module.js";
|
|
4
4
|
import { DRACOLoader as Ve } from "three/examples/jsm/loaders/DRACOLoader.js";
|
|
5
5
|
import { KTX2Loader as Xe } from "three/examples/jsm/loaders/KTX2Loader.js";
|
|
6
6
|
const je = "";
|
|
7
7
|
globalThis.GLTF_PROGRESSIVE_VERSION = je;
|
|
8
8
|
console.debug("[gltf-progressive] version -");
|
|
9
|
-
let
|
|
10
|
-
const
|
|
9
|
+
let R = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", X = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
|
|
10
|
+
const Ye = R, Ke = X, Oe = new URL(R + "draco_decoder.js");
|
|
11
11
|
Oe.searchParams.append("range", "true");
|
|
12
12
|
fetch(Oe, {
|
|
13
13
|
method: "GET",
|
|
@@ -15,30 +15,30 @@ fetch(Oe, {
|
|
|
15
15
|
Range: "bytes=0-1"
|
|
16
16
|
}
|
|
17
17
|
}).catch((i) => {
|
|
18
|
-
console.debug(`Failed to fetch remote Draco decoder from ${
|
|
18
|
+
console.debug(`Failed to fetch remote Draco decoder from ${R} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), R === Ye && Qe("./include/draco/"), X === Ke && Je("./include/ktx2/");
|
|
19
19
|
}).finally(() => {
|
|
20
20
|
Pe();
|
|
21
21
|
});
|
|
22
22
|
const He = () => ({
|
|
23
|
-
dracoDecoderPath:
|
|
24
|
-
ktx2TranscoderPath:
|
|
23
|
+
dracoDecoderPath: R,
|
|
24
|
+
ktx2TranscoderPath: X
|
|
25
25
|
});
|
|
26
26
|
function Qe(i) {
|
|
27
|
-
|
|
27
|
+
R = i, A && A[ge] != R ? (console.debug("Updating Draco decoder path to " + i), A[ge] = R, A.setDecoderPath(R), A.preload()) : console.debug("Setting Draco decoder path to " + i);
|
|
28
28
|
}
|
|
29
29
|
function Je(i) {
|
|
30
|
-
|
|
30
|
+
X = i, $ && $.transcoderPath != X ? (console.debug("Updating KTX2 transcoder path to " + i), $.setTranscoderPath(X), $.init()) : console.debug("Setting KTX2 transcoder path to " + i);
|
|
31
31
|
}
|
|
32
32
|
function xe(i) {
|
|
33
|
-
return Pe(), i ?
|
|
33
|
+
return Pe(), i ? $.detectSupport(i) : i !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: A, ktx2Loader: $, meshoptDecoder: oe };
|
|
34
34
|
}
|
|
35
35
|
function Se(i) {
|
|
36
|
-
i.dracoLoader || i.setDRACOLoader(
|
|
36
|
+
i.dracoLoader || i.setDRACOLoader(A), i.ktx2Loader || i.setKTX2Loader($), i.meshoptDecoder || i.setMeshoptDecoder(oe);
|
|
37
37
|
}
|
|
38
|
-
const ge = Symbol("dracoDecoderPath");
|
|
39
|
-
let
|
|
38
|
+
const ge = /* @__PURE__ */ Symbol("dracoDecoderPath");
|
|
39
|
+
let A, oe, $;
|
|
40
40
|
function Pe() {
|
|
41
|
-
|
|
41
|
+
A || (A = new Ve(), A[ge] = R, A.setDecoderPath(R), A.setDecoderConfig({ type: "js" }), A.preload()), $ || ($ = new Xe(), $.setTranscoderPath(X), $.init()), oe || (oe = Ee);
|
|
42
42
|
}
|
|
43
43
|
const pe = /* @__PURE__ */ new WeakMap();
|
|
44
44
|
function Te(i, t) {
|
|
@@ -51,14 +51,14 @@ function et(...i) {
|
|
|
51
51
|
let e = i[0];
|
|
52
52
|
const s = new URL(e, window.location.href);
|
|
53
53
|
if (s.hostname.endsWith("needle.tools")) {
|
|
54
|
-
const r = t?.progressive !== void 0 ? t.progressive : !0,
|
|
55
|
-
r ? this.requestHeader.Accept = `*/*;progressive=allowed;usecase=${
|
|
54
|
+
const r = t?.progressive !== void 0 ? t.progressive : !0, n = t?.usecase ? t.usecase : "default";
|
|
55
|
+
r ? this.requestHeader.Accept = `*/*;progressive=allowed;usecase=${n}` : this.requestHeader.Accept = `*/*;usecase=${n}`, e = s.toString();
|
|
56
56
|
}
|
|
57
57
|
return i[0] = e, Ze?.call(this, ...i);
|
|
58
58
|
}
|
|
59
59
|
ye.prototype.load = et;
|
|
60
|
-
|
|
61
|
-
function
|
|
60
|
+
j("debugprogressive");
|
|
61
|
+
function j(i) {
|
|
62
62
|
if (typeof window > "u") return !1;
|
|
63
63
|
const e = new URL(window.location.href).searchParams.get(i);
|
|
64
64
|
return e == null || e === "0" || e === "false" ? !1 : e === "" ? !0 : e;
|
|
@@ -75,7 +75,7 @@ function tt(i, t) {
|
|
|
75
75
|
return t;
|
|
76
76
|
}
|
|
77
77
|
function Ae() {
|
|
78
|
-
return K !== void 0 || (K = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),
|
|
78
|
+
return K !== void 0 || (K = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), j("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", K)), K;
|
|
79
79
|
}
|
|
80
80
|
let K;
|
|
81
81
|
function Le() {
|
|
@@ -110,87 +110,87 @@ class st {
|
|
|
110
110
|
const t = this.maxConcurrent - this._running.size;
|
|
111
111
|
for (let e = 0; e < t && this._queue.length > 0; e++) {
|
|
112
112
|
this.debug && console.debug(`[PromiseQueue]: Running ${this._running.size} promises, waiting for ${this._queue.length} more.`);
|
|
113
|
-
const { key: s, resolve:
|
|
114
|
-
|
|
113
|
+
const { key: s, resolve: o } = this._queue.shift();
|
|
114
|
+
o({
|
|
115
115
|
use: (r) => this.add(s, r)
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
const rt = typeof window > "u" && typeof document > "u", me = Symbol("needle:raycast-mesh");
|
|
120
|
+
const rt = typeof window > "u" && typeof document > "u", me = /* @__PURE__ */ Symbol("needle:raycast-mesh");
|
|
121
121
|
function Z(i) {
|
|
122
|
-
return i?.[me] instanceof
|
|
122
|
+
return i?.[me] instanceof E ? i[me] : null;
|
|
123
123
|
}
|
|
124
|
-
function
|
|
124
|
+
function ot(i, t) {
|
|
125
125
|
if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !Z(i)) {
|
|
126
126
|
const s = it(t);
|
|
127
127
|
s.userData = { isRaycastMesh: !0 }, i[me] = s;
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
|
-
function
|
|
130
|
+
function nt(i = !0) {
|
|
131
131
|
if (i) {
|
|
132
|
-
if (
|
|
133
|
-
const t =
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
let
|
|
137
|
-
r &&
|
|
132
|
+
if (H) return;
|
|
133
|
+
const t = H = V.prototype.raycast;
|
|
134
|
+
V.prototype.raycast = function(e, s) {
|
|
135
|
+
const o = this, r = Z(o);
|
|
136
|
+
let n;
|
|
137
|
+
r && o.isMesh && (n = o.geometry, o.geometry = r), t.call(this, e, s), n && (o.geometry = n);
|
|
138
138
|
};
|
|
139
139
|
} else {
|
|
140
|
-
if (!
|
|
141
|
-
|
|
140
|
+
if (!H) return;
|
|
141
|
+
V.prototype.raycast = H, H = null;
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
-
let
|
|
144
|
+
let H = null;
|
|
145
145
|
function it(i) {
|
|
146
|
-
const t = new
|
|
146
|
+
const t = new E();
|
|
147
147
|
for (const e in i.attributes)
|
|
148
148
|
t.setAttribute(e, i.getAttribute(e));
|
|
149
149
|
return t.setIndex(i.getIndex()), t;
|
|
150
150
|
}
|
|
151
|
-
const
|
|
152
|
-
let
|
|
153
|
-
if (
|
|
151
|
+
const z = new Array(), h = j("debugprogressive");
|
|
152
|
+
let J, q = -1;
|
|
153
|
+
if (h) {
|
|
154
154
|
let i = function() {
|
|
155
|
-
|
|
155
|
+
q += 1, q >= t && (q = -1), console.log(`Toggle LOD level [${q}]`);
|
|
156
156
|
}, t = 6;
|
|
157
157
|
window.addEventListener("keyup", (e) => {
|
|
158
|
-
e.key === "p" && i(), e.key === "w" && (
|
|
158
|
+
e.key === "p" && i(), e.key === "w" && (J = !J, console.log(`Toggle wireframe [${J}]`));
|
|
159
159
|
const s = parseInt(e.key);
|
|
160
|
-
!isNaN(s) && s >= 0 && (
|
|
160
|
+
!isNaN(s) && s >= 0 && (q = s, console.log(`Set LOD level to [${q}]`));
|
|
161
161
|
});
|
|
162
162
|
}
|
|
163
|
-
function
|
|
164
|
-
if (
|
|
163
|
+
function Ce(i) {
|
|
164
|
+
if (h && J !== void 0)
|
|
165
165
|
if (Array.isArray(i))
|
|
166
166
|
for (const t of i)
|
|
167
|
-
|
|
168
|
-
else i && "wireframe" in i && (i.wireframe =
|
|
167
|
+
Ce(t);
|
|
168
|
+
else i && "wireframe" in i && (i.wireframe = J === !0);
|
|
169
169
|
}
|
|
170
|
-
const
|
|
170
|
+
const Q = new Array();
|
|
171
171
|
let at = 0;
|
|
172
172
|
const lt = Ae() ? 2 : 10;
|
|
173
173
|
function ut(i) {
|
|
174
|
-
if (
|
|
175
|
-
const s =
|
|
176
|
-
|
|
177
|
-
const
|
|
178
|
-
return
|
|
179
|
-
}
|
|
180
|
-
const t = at++ %
|
|
181
|
-
return
|
|
174
|
+
if (Q.length < lt) {
|
|
175
|
+
const s = Q.length;
|
|
176
|
+
h && console.warn(`[Worker] Creating new worker #${s}`);
|
|
177
|
+
const o = we.createWorker(i || {});
|
|
178
|
+
return Q.push(o), o;
|
|
179
|
+
}
|
|
180
|
+
const t = at++ % Q.length;
|
|
181
|
+
return Q[t];
|
|
182
182
|
}
|
|
183
183
|
class we {
|
|
184
184
|
constructor(t, e) {
|
|
185
185
|
this.worker = t, this._debug = e.debug ?? !1, t.onmessage = (s) => {
|
|
186
|
-
const
|
|
187
|
-
switch (this._debug && console.log("[Worker] EVENT",
|
|
186
|
+
const o = s.data;
|
|
187
|
+
switch (this._debug && console.log("[Worker] EVENT", o), o.type) {
|
|
188
188
|
case "loaded-gltf":
|
|
189
189
|
for (const r of this._running)
|
|
190
|
-
if (r.url ===
|
|
191
|
-
dt(
|
|
192
|
-
const
|
|
193
|
-
|
|
190
|
+
if (r.url === o.result.url) {
|
|
191
|
+
dt(o.result), r.resolve(o.result);
|
|
192
|
+
const n = r.url;
|
|
193
|
+
n.startsWith("blob:") && URL.revokeObjectURL(n);
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
}, t.onerror = (s) => {
|
|
@@ -202,7 +202,7 @@ class we {
|
|
|
202
202
|
static async createWorker(t) {
|
|
203
203
|
const e = new Worker(new URL(
|
|
204
204
|
/* @vite-ignore */
|
|
205
|
-
"/assets/loader.worker-
|
|
205
|
+
"/assets/loader.worker-CCrD-Ycm.js",
|
|
206
206
|
import.meta.url
|
|
207
207
|
), {
|
|
208
208
|
type: "module"
|
|
@@ -213,12 +213,12 @@ class we {
|
|
|
213
213
|
_webglRenderer = null;
|
|
214
214
|
async load(t, e) {
|
|
215
215
|
const s = He();
|
|
216
|
-
let
|
|
217
|
-
|
|
216
|
+
let o = e?.renderer;
|
|
217
|
+
o || (this._webglRenderer ??= (async () => {
|
|
218
218
|
const { WebGLRenderer: u } = await import("three");
|
|
219
219
|
return new u();
|
|
220
|
-
})(),
|
|
221
|
-
const l = xe(
|
|
220
|
+
})(), o = await this._webglRenderer);
|
|
221
|
+
const l = xe(o).ktx2Loader.workerConfig;
|
|
222
222
|
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());
|
|
223
223
|
const a = {
|
|
224
224
|
type: "load",
|
|
@@ -238,49 +238,49 @@ class we {
|
|
|
238
238
|
}
|
|
239
239
|
function dt(i) {
|
|
240
240
|
for (const t of i.geometries) {
|
|
241
|
-
const e = t.geometry, s = new
|
|
241
|
+
const e = t.geometry, s = new E();
|
|
242
242
|
if (s.name = e.name || "", e.index) {
|
|
243
|
-
const
|
|
244
|
-
s.setIndex(ae(
|
|
243
|
+
const o = e.index;
|
|
244
|
+
s.setIndex(ae(o));
|
|
245
245
|
}
|
|
246
|
-
for (const
|
|
247
|
-
const r = e.attributes[
|
|
248
|
-
s.setAttribute(
|
|
246
|
+
for (const o in e.attributes) {
|
|
247
|
+
const r = e.attributes[o], n = ae(r);
|
|
248
|
+
s.setAttribute(o, n);
|
|
249
249
|
}
|
|
250
250
|
if (e.morphAttributes)
|
|
251
|
-
for (const
|
|
252
|
-
const
|
|
253
|
-
s.morphAttributes[
|
|
251
|
+
for (const o in e.morphAttributes) {
|
|
252
|
+
const n = e.morphAttributes[o].map((l) => ae(l));
|
|
253
|
+
s.morphAttributes[o] = n;
|
|
254
254
|
}
|
|
255
|
-
if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new he(), s.boundingBox.min = new
|
|
255
|
+
if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new he(), s.boundingBox.min = new C(
|
|
256
256
|
e.boundingBox?.min.x,
|
|
257
257
|
e.boundingBox?.min.y,
|
|
258
258
|
e.boundingBox?.min.z
|
|
259
|
-
), s.boundingBox.max = new
|
|
259
|
+
), s.boundingBox.max = new C(
|
|
260
260
|
e.boundingBox?.max.x,
|
|
261
261
|
e.boundingBox?.max.y,
|
|
262
262
|
e.boundingBox?.max.z
|
|
263
263
|
), s.boundingSphere = new De(
|
|
264
|
-
new
|
|
264
|
+
new C(
|
|
265
265
|
e.boundingSphere?.center.x,
|
|
266
266
|
e.boundingSphere?.center.y,
|
|
267
267
|
e.boundingSphere?.center.z
|
|
268
268
|
),
|
|
269
269
|
e.boundingSphere?.radius
|
|
270
270
|
), e.groups)
|
|
271
|
-
for (const
|
|
272
|
-
s.addGroup(
|
|
271
|
+
for (const o of e.groups)
|
|
272
|
+
s.addGroup(o.start, o.count, o.materialIndex);
|
|
273
273
|
e.userData && (s.userData = e.userData), t.geometry = s;
|
|
274
274
|
}
|
|
275
275
|
for (const t of i.textures) {
|
|
276
276
|
const e = t.texture;
|
|
277
277
|
let s = null;
|
|
278
278
|
if (e.isCompressedTexture) {
|
|
279
|
-
const
|
|
280
|
-
s = new
|
|
281
|
-
n,
|
|
282
|
-
r,
|
|
279
|
+
const o = e.mipmaps, r = e.image?.width || e.source?.data?.width || -1, n = e.image?.height || e.source?.data?.height || -1;
|
|
280
|
+
s = new Be(
|
|
283
281
|
o,
|
|
282
|
+
r,
|
|
283
|
+
n,
|
|
284
284
|
e.format,
|
|
285
285
|
e.type,
|
|
286
286
|
e.mapping,
|
|
@@ -292,7 +292,7 @@ function dt(i) {
|
|
|
292
292
|
e.colorSpace
|
|
293
293
|
);
|
|
294
294
|
} else
|
|
295
|
-
s = new
|
|
295
|
+
s = new F(
|
|
296
296
|
e.image,
|
|
297
297
|
e.mapping,
|
|
298
298
|
e.wrapS,
|
|
@@ -315,16 +315,16 @@ function dt(i) {
|
|
|
315
315
|
function ae(i) {
|
|
316
316
|
let t = i;
|
|
317
317
|
if ("isInterleavedBufferAttribute" in i && i.isInterleavedBufferAttribute) {
|
|
318
|
-
const e = i.data, s = e.array,
|
|
319
|
-
t = new We(
|
|
318
|
+
const e = i.data, s = e.array, o = new Fe(s, e.stride);
|
|
319
|
+
t = new We(o, i.itemSize, s.byteOffset, i.normalized), t.offset = i.offset;
|
|
320
320
|
} else "isBufferAttribute" in i && i.isBufferAttribute && (t = new Ue(i.array, i.itemSize, i.normalized), t.usage = i.usage, t.gpuType = i.gpuType, t.updateRanges = i.updateRanges);
|
|
321
321
|
return t;
|
|
322
322
|
}
|
|
323
|
-
const ct =
|
|
324
|
-
class
|
|
323
|
+
const ct = j("gltf-progressive-worker"), ft = j("gltf-progressive-reduce-mipmaps"), le = /* @__PURE__ */ Symbol("needle-progressive-texture"), W = "NEEDLE_progressive";
|
|
324
|
+
class m {
|
|
325
325
|
/** The name of the extension */
|
|
326
326
|
get name() {
|
|
327
|
-
return
|
|
327
|
+
return W;
|
|
328
328
|
}
|
|
329
329
|
// #region PUBLIC API
|
|
330
330
|
static getMeshLODExtension(t) {
|
|
@@ -336,7 +336,7 @@ class y {
|
|
|
336
336
|
return e ?? -1;
|
|
337
337
|
}
|
|
338
338
|
static getMaterialMinMaxLODsCount(t, e) {
|
|
339
|
-
const s = this,
|
|
339
|
+
const s = this, o = "LODS:minmax", r = t[o];
|
|
340
340
|
if (r != null) return r;
|
|
341
341
|
if (e || (e = {
|
|
342
342
|
min_count: 1 / 0,
|
|
@@ -345,31 +345,31 @@ class y {
|
|
|
345
345
|
}), Array.isArray(t)) {
|
|
346
346
|
for (const l of t)
|
|
347
347
|
this.getMaterialMinMaxLODsCount(l, e);
|
|
348
|
-
return t[
|
|
348
|
+
return t[o] = e, e;
|
|
349
349
|
}
|
|
350
|
-
if (
|
|
350
|
+
if (h === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
|
|
351
351
|
const l = t;
|
|
352
352
|
for (const a of Object.keys(l.uniforms)) {
|
|
353
353
|
const u = l.uniforms[a].value;
|
|
354
|
-
u?.isTexture === !0 &&
|
|
354
|
+
u?.isTexture === !0 && n(u, e);
|
|
355
355
|
}
|
|
356
356
|
} else if (t.isMaterial)
|
|
357
357
|
for (const l of Object.keys(t)) {
|
|
358
358
|
const a = t[l];
|
|
359
|
-
a?.isTexture === !0 &&
|
|
359
|
+
a?.isTexture === !0 && n(a, e);
|
|
360
360
|
}
|
|
361
361
|
else
|
|
362
|
-
|
|
363
|
-
return t[
|
|
364
|
-
function
|
|
362
|
+
h && console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);
|
|
363
|
+
return t[o] = e, e;
|
|
364
|
+
function n(l, a) {
|
|
365
365
|
const u = s.getAssignedLODInformation(l);
|
|
366
366
|
if (u) {
|
|
367
|
-
const
|
|
368
|
-
if (
|
|
369
|
-
a.min_count = Math.min(a.min_count,
|
|
370
|
-
for (let
|
|
371
|
-
const
|
|
372
|
-
|
|
367
|
+
const d = s.lodInfos.get(u.key);
|
|
368
|
+
if (d && d.lods) {
|
|
369
|
+
a.min_count = Math.min(a.min_count, d.lods.length), a.max_count = Math.max(a.max_count, d.lods.length);
|
|
370
|
+
for (let y = 0; y < d.lods.length; y++) {
|
|
371
|
+
const w = d.lods[y];
|
|
372
|
+
w.width && (a.lods[y] = a.lods[y] || { min_height: 1 / 0, max_height: 0 }, a.lods[y].min_height = Math.min(a.lods[y].min_height, w.height), a.lods[y].max_height = Math.max(a.lods[y].max_height, w.height));
|
|
373
373
|
}
|
|
374
374
|
}
|
|
375
375
|
}
|
|
@@ -388,8 +388,8 @@ class y {
|
|
|
388
388
|
}
|
|
389
389
|
if (t.isMaterial === !0) {
|
|
390
390
|
for (const r of Object.keys(t)) {
|
|
391
|
-
const
|
|
392
|
-
if (
|
|
391
|
+
const n = t[r];
|
|
392
|
+
if (n && n.isTexture && this.hasLODLevelAvailable(n, e))
|
|
393
393
|
return !0;
|
|
394
394
|
}
|
|
395
395
|
return !1;
|
|
@@ -398,12 +398,12 @@ class y {
|
|
|
398
398
|
if (r.isMesh === !0 && this.hasLODLevelAvailable(r, e))
|
|
399
399
|
return !0;
|
|
400
400
|
}
|
|
401
|
-
let s,
|
|
401
|
+
let s, o;
|
|
402
402
|
if (t.isMesh ? s = t.geometry : (t.isBufferGeometry || t.isTexture) && (s = t), s && s?.userData?.LODS) {
|
|
403
403
|
const r = s.userData.LODS;
|
|
404
|
-
if (
|
|
405
|
-
if (
|
|
406
|
-
return Array.isArray(
|
|
404
|
+
if (o = this.lodInfos.get(r.key), e === void 0) return o != null;
|
|
405
|
+
if (o)
|
|
406
|
+
return Array.isArray(o.lods) ? e < o.lods.length : e === 0;
|
|
407
407
|
}
|
|
408
408
|
return !1;
|
|
409
409
|
}
|
|
@@ -423,20 +423,20 @@ class y {
|
|
|
423
423
|
*/
|
|
424
424
|
static assignMeshLOD(t, e) {
|
|
425
425
|
if (!t) return Promise.resolve(null);
|
|
426
|
-
if (t instanceof
|
|
427
|
-
const s = t.geometry,
|
|
428
|
-
if (!
|
|
426
|
+
if (t instanceof V || t.isMesh === !0) {
|
|
427
|
+
const s = t.geometry, o = this.getAssignedLODInformation(s);
|
|
428
|
+
if (!o)
|
|
429
429
|
return Promise.resolve(null);
|
|
430
|
-
for (const r of
|
|
430
|
+
for (const r of z)
|
|
431
431
|
r.onBeforeGetLODMesh?.(t, e);
|
|
432
|
-
return t["LOD:requested level"] = e,
|
|
432
|
+
return t["LOD:requested level"] = e, m.getOrLoadLOD(s, e).then((r) => {
|
|
433
433
|
if (Array.isArray(r)) {
|
|
434
|
-
const
|
|
435
|
-
r = r[
|
|
434
|
+
const n = o.index || 0;
|
|
435
|
+
r = r[n];
|
|
436
436
|
}
|
|
437
|
-
return t["LOD:requested level"] === e && (delete t["LOD:requested level"], r && s != r && (r?.isBufferGeometry ? t.geometry = r :
|
|
437
|
+
return t["LOD:requested level"] === e && (delete t["LOD:requested level"], r && s != r && (r?.isBufferGeometry ? t.geometry = r : h && console.error("Invalid LOD geometry", r))), r;
|
|
438
438
|
}).catch((r) => (console.error("Error loading mesh LOD", t, r), null));
|
|
439
|
-
} else
|
|
439
|
+
} else h && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
|
|
440
440
|
return Promise.resolve(null);
|
|
441
441
|
}
|
|
442
442
|
static assignTextureLOD(t, e = 0) {
|
|
@@ -444,75 +444,75 @@ class y {
|
|
|
444
444
|
if (t.isMesh === !0) {
|
|
445
445
|
const s = t;
|
|
446
446
|
if (Array.isArray(s.material)) {
|
|
447
|
-
const
|
|
447
|
+
const o = new Array();
|
|
448
448
|
for (const r of s.material) {
|
|
449
|
-
const
|
|
450
|
-
|
|
449
|
+
const n = this.assignTextureLOD(r, e);
|
|
450
|
+
o.push(n);
|
|
451
451
|
}
|
|
452
|
-
return Promise.all(
|
|
453
|
-
const
|
|
452
|
+
return Promise.all(o).then((r) => {
|
|
453
|
+
const n = new Array();
|
|
454
454
|
for (const l of r)
|
|
455
|
-
Array.isArray(l) &&
|
|
456
|
-
return
|
|
455
|
+
Array.isArray(l) && n.push(...l);
|
|
456
|
+
return n;
|
|
457
457
|
});
|
|
458
458
|
} else
|
|
459
459
|
return this.assignTextureLOD(s.material, e);
|
|
460
460
|
}
|
|
461
461
|
if (t.isMaterial === !0) {
|
|
462
|
-
const s = t,
|
|
462
|
+
const s = t, o = [], r = new Array();
|
|
463
463
|
if (s.uniforms && (s.isRawShaderMaterial || s.isShaderMaterial === !0)) {
|
|
464
|
-
const
|
|
465
|
-
for (const l of Object.keys(
|
|
466
|
-
const a =
|
|
464
|
+
const n = s;
|
|
465
|
+
for (const l of Object.keys(n.uniforms)) {
|
|
466
|
+
const a = n.uniforms[l].value;
|
|
467
467
|
if (a?.isTexture === !0) {
|
|
468
|
-
const u = this.assignTextureLODForSlot(a, e, s, l).then((
|
|
469
|
-
|
|
468
|
+
const u = this.assignTextureLODForSlot(a, e, s, l).then((d) => (d && n.uniforms[l].value != d && (n.uniforms[l].value = d, n.uniformsNeedUpdate = !0), d));
|
|
469
|
+
o.push(u), r.push(l);
|
|
470
470
|
}
|
|
471
471
|
}
|
|
472
472
|
} else
|
|
473
|
-
for (const
|
|
474
|
-
const l = s[
|
|
473
|
+
for (const n of Object.keys(s)) {
|
|
474
|
+
const l = s[n];
|
|
475
475
|
if (l?.isTexture === !0) {
|
|
476
|
-
const a = this.assignTextureLODForSlot(l, e, s,
|
|
477
|
-
|
|
476
|
+
const a = this.assignTextureLODForSlot(l, e, s, n);
|
|
477
|
+
o.push(a), r.push(n);
|
|
478
478
|
}
|
|
479
479
|
}
|
|
480
|
-
return Promise.all(
|
|
480
|
+
return Promise.all(o).then((n) => {
|
|
481
481
|
const l = new Array();
|
|
482
|
-
for (let a = 0; a <
|
|
483
|
-
const u =
|
|
484
|
-
u && u.isTexture === !0 ? l.push({ material: s, slot:
|
|
482
|
+
for (let a = 0; a < n.length; a++) {
|
|
483
|
+
const u = n[a], d = r[a];
|
|
484
|
+
u && u.isTexture === !0 ? l.push({ material: s, slot: d, texture: u, level: e }) : l.push({ material: s, slot: d, texture: null, level: e });
|
|
485
485
|
}
|
|
486
486
|
return l;
|
|
487
487
|
});
|
|
488
488
|
}
|
|
489
|
-
if (t instanceof
|
|
489
|
+
if (t instanceof F || t.isTexture === !0) {
|
|
490
490
|
const s = t;
|
|
491
491
|
return this.assignTextureLODForSlot(s, e, null, null);
|
|
492
492
|
}
|
|
493
493
|
return Promise.resolve(null);
|
|
494
494
|
}
|
|
495
495
|
// #region INTERNAL
|
|
496
|
-
static assignTextureLODForSlot(t, e, s,
|
|
497
|
-
return t?.isTexture !== !0 ? Promise.resolve(null) :
|
|
496
|
+
static assignTextureLODForSlot(t, e, s, o) {
|
|
497
|
+
return t?.isTexture !== !0 ? Promise.resolve(null) : o === "glyphMap" ? Promise.resolve(t) : m.getOrLoadLOD(t, e).then((r) => {
|
|
498
498
|
if (Array.isArray(r))
|
|
499
499
|
return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen..."), null;
|
|
500
500
|
if (r?.isTexture === !0) {
|
|
501
|
-
if (r != t && s &&
|
|
502
|
-
const
|
|
503
|
-
if (
|
|
504
|
-
const l = this.getAssignedLODInformation(
|
|
501
|
+
if (r != t && s && o) {
|
|
502
|
+
const n = s[o];
|
|
503
|
+
if (n && !h) {
|
|
504
|
+
const l = this.getAssignedLODInformation(n);
|
|
505
505
|
if (l && l?.level < e)
|
|
506
|
-
return
|
|
506
|
+
return h === "verbose" && console.warn("Assigned texture level is already higher: ", l.level, e, s, n, r), null;
|
|
507
507
|
}
|
|
508
508
|
if (ft && r.mipmaps) {
|
|
509
509
|
const l = r.mipmaps.length;
|
|
510
|
-
r.mipmaps.length = Math.min(r.mipmaps.length, 3), l !== r.mipmaps.length &&
|
|
510
|
+
r.mipmaps.length = Math.min(r.mipmaps.length, 3), l !== r.mipmaps.length && h && console.debug(`Reduced mipmap count from ${l} to ${r.mipmaps.length} for ${r.uuid}: ${r.image?.width}x${r.image?.height}.`);
|
|
511
511
|
}
|
|
512
|
-
s[
|
|
512
|
+
s[o] = r;
|
|
513
513
|
}
|
|
514
514
|
return r;
|
|
515
|
-
} else
|
|
515
|
+
} else h == "verbose" && console.warn("No LOD found for", t, e);
|
|
516
516
|
return null;
|
|
517
517
|
}).catch((r) => (console.error("Error loading LOD", t, r), null));
|
|
518
518
|
}
|
|
@@ -520,13 +520,13 @@ class y {
|
|
|
520
520
|
url;
|
|
521
521
|
constructor(t) {
|
|
522
522
|
const e = t.options.path;
|
|
523
|
-
|
|
523
|
+
h && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
|
|
524
524
|
}
|
|
525
525
|
_isLoadingMesh;
|
|
526
526
|
loadMesh = (t) => {
|
|
527
527
|
if (this._isLoadingMesh) return null;
|
|
528
|
-
const e = this.parser.json.meshes[t]?.extensions?.[
|
|
529
|
-
return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s &&
|
|
528
|
+
const e = this.parser.json.meshes[t]?.extensions?.[W];
|
|
529
|
+
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;
|
|
530
530
|
};
|
|
531
531
|
// private _isLoadingTexture;
|
|
532
532
|
// loadTexture = (textureIndex: number) => {
|
|
@@ -543,30 +543,30 @@ class y {
|
|
|
543
543
|
// });
|
|
544
544
|
// }
|
|
545
545
|
afterRoot(t) {
|
|
546
|
-
return
|
|
546
|
+
return h && console.log("AFTER", this.url, t), this.parser.json.textures?.forEach((e, s) => {
|
|
547
547
|
if (e?.extensions) {
|
|
548
|
-
const
|
|
549
|
-
if (
|
|
550
|
-
if (!
|
|
551
|
-
|
|
548
|
+
const o = e?.extensions[W];
|
|
549
|
+
if (o) {
|
|
550
|
+
if (!o.lods) {
|
|
551
|
+
h && console.warn("Texture has no LODs", o);
|
|
552
552
|
return;
|
|
553
553
|
}
|
|
554
554
|
let r = !1;
|
|
555
|
-
for (const
|
|
556
|
-
|
|
557
|
-
r || this.parser.getDependency("texture", s).then((
|
|
558
|
-
|
|
555
|
+
for (const n of this.parser.associations.keys())
|
|
556
|
+
n.isTexture === !0 && this.parser.associations.get(n)?.textures === s && (r = !0, m.registerTexture(this.url, n, o.lods?.length, s, o));
|
|
557
|
+
r || this.parser.getDependency("texture", s).then((n) => {
|
|
558
|
+
n && m.registerTexture(this.url, n, o.lods?.length, s, o);
|
|
559
559
|
});
|
|
560
560
|
}
|
|
561
561
|
}
|
|
562
562
|
}), this.parser.json.meshes?.forEach((e, s) => {
|
|
563
563
|
if (e?.extensions) {
|
|
564
|
-
const
|
|
565
|
-
if (
|
|
564
|
+
const o = e?.extensions[W];
|
|
565
|
+
if (o && o.lods) {
|
|
566
566
|
for (const r of this.parser.associations.keys())
|
|
567
567
|
if (r.isMesh) {
|
|
568
|
-
const
|
|
569
|
-
|
|
568
|
+
const n = this.parser.associations.get(r);
|
|
569
|
+
n?.meshes === s && m.registerMesh(this.url, o.guid, r, o.lods.length, n.primitives, o);
|
|
570
570
|
}
|
|
571
571
|
}
|
|
572
572
|
}
|
|
@@ -575,182 +575,259 @@ class y {
|
|
|
575
575
|
/**
|
|
576
576
|
* Register a texture with LOD information
|
|
577
577
|
*/
|
|
578
|
-
static registerTexture = (t, e, s,
|
|
578
|
+
static registerTexture = (t, e, s, o, r) => {
|
|
579
579
|
if (!e) {
|
|
580
|
-
|
|
580
|
+
h && console.error("!! gltf-progressive: Called register texture without texture");
|
|
581
581
|
return;
|
|
582
582
|
}
|
|
583
|
-
if (
|
|
583
|
+
if (h) {
|
|
584
584
|
const l = e.image?.width || e.source?.data?.width || 0, a = e.image?.height || e.source?.data?.height || 0;
|
|
585
|
-
console.log(`> gltf-progressive: register texture[${
|
|
585
|
+
console.log(`> gltf-progressive: register texture[${o}] "${e.name || e.uuid}", Current: ${l}x${a}, Max: ${r.lods[0]?.width}x${r.lods[0]?.height}, uuid: ${e.uuid}`, r, e);
|
|
586
586
|
}
|
|
587
587
|
e.source && (e.source[le] = r);
|
|
588
|
-
const
|
|
589
|
-
|
|
588
|
+
const n = r.guid;
|
|
589
|
+
m.assignLODInformation(t, e, n, s, o), m.lodInfos.set(n, r), m.lowresCache.set(n, new WeakRef(e));
|
|
590
590
|
};
|
|
591
591
|
/**
|
|
592
592
|
* Register a mesh with LOD information
|
|
593
593
|
*/
|
|
594
|
-
static registerMesh = (t, e, s,
|
|
594
|
+
static registerMesh = (t, e, s, o, r, n) => {
|
|
595
595
|
const l = s.geometry;
|
|
596
596
|
if (!l) {
|
|
597
|
-
|
|
597
|
+
h && console.warn("gltf-progressive: Register mesh without geometry");
|
|
598
598
|
return;
|
|
599
599
|
}
|
|
600
|
-
l.userData || (l.userData = {}),
|
|
601
|
-
let
|
|
602
|
-
|
|
603
|
-
for (const
|
|
604
|
-
|
|
600
|
+
l.userData || (l.userData = {}), h && console.log("> Progressive: register mesh " + s.name, { index: r, uuid: s.uuid }, n, s), m.assignLODInformation(t, l, e, o, r), m.lodInfos.set(e, n);
|
|
601
|
+
let u = m.lowresCache.get(e)?.deref();
|
|
602
|
+
u ? u.push(s.geometry) : u = [s.geometry], m.lowresCache.set(e, new WeakRef(u)), o > 0 && !Z(s) && ot(s, l);
|
|
603
|
+
for (const d of z)
|
|
604
|
+
d.onRegisteredNewMesh?.(s, n);
|
|
605
605
|
};
|
|
606
|
+
/**
|
|
607
|
+
* Dispose cached resources to free memory.
|
|
608
|
+
* Call this when a model is removed from the scene to allow garbage collection of its LOD resources.
|
|
609
|
+
* Calls three.js `.dispose()` on cached Textures and BufferGeometries to free GPU memory.
|
|
610
|
+
* @param guid Optional GUID to dispose resources for a specific model. If omitted, all cached resources are cleared.
|
|
611
|
+
*/
|
|
612
|
+
static dispose(t) {
|
|
613
|
+
if (t) {
|
|
614
|
+
this.lodInfos.delete(t);
|
|
615
|
+
const e = this.lowresCache.get(t);
|
|
616
|
+
if (e) {
|
|
617
|
+
const s = e.deref();
|
|
618
|
+
if (s) {
|
|
619
|
+
if (s.isTexture)
|
|
620
|
+
s.dispose();
|
|
621
|
+
else if (Array.isArray(s))
|
|
622
|
+
for (const o of s) o.dispose();
|
|
623
|
+
}
|
|
624
|
+
this.lowresCache.delete(t);
|
|
625
|
+
}
|
|
626
|
+
for (const [s, o] of this.cache)
|
|
627
|
+
s.includes(t) && (this._disposeCacheEntry(o), this.cache.delete(s));
|
|
628
|
+
} else {
|
|
629
|
+
this.lodInfos.clear();
|
|
630
|
+
for (const [, e] of this.lowresCache) {
|
|
631
|
+
const s = e.deref();
|
|
632
|
+
if (s) {
|
|
633
|
+
if (s.isTexture)
|
|
634
|
+
s.dispose();
|
|
635
|
+
else if (Array.isArray(s))
|
|
636
|
+
for (const o of s) o.dispose();
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
this.lowresCache.clear();
|
|
640
|
+
for (const [, e] of this.cache)
|
|
641
|
+
this._disposeCacheEntry(e);
|
|
642
|
+
this.cache.clear();
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
/** Dispose a single cache entry's three.js resource(s) to free GPU memory. */
|
|
646
|
+
static _disposeCacheEntry(t) {
|
|
647
|
+
t instanceof WeakRef ? t.deref()?.dispose() : t.then((e) => {
|
|
648
|
+
if (e)
|
|
649
|
+
if (Array.isArray(e))
|
|
650
|
+
for (const s of e) s.dispose();
|
|
651
|
+
else
|
|
652
|
+
e.dispose();
|
|
653
|
+
}).catch(() => {
|
|
654
|
+
});
|
|
655
|
+
}
|
|
606
656
|
/** A map of key = asset uuid and value = LOD information */
|
|
607
657
|
static lodInfos = /* @__PURE__ */ new Map();
|
|
608
|
-
/** cache of already loaded mesh lods */
|
|
609
|
-
static
|
|
610
|
-
/** this contains the geometry/textures that were originally loaded */
|
|
658
|
+
/** cache of already loaded mesh lods. Uses WeakRef for single resources to allow garbage collection when unused. */
|
|
659
|
+
static cache = /* @__PURE__ */ new Map();
|
|
660
|
+
/** this contains the geometry/textures that were originally loaded. Uses WeakRef to allow garbage collection when unused. */
|
|
611
661
|
static lowresCache = /* @__PURE__ */ new Map();
|
|
662
|
+
/**
|
|
663
|
+
* FinalizationRegistry to automatically clean up `previouslyLoaded` cache entries
|
|
664
|
+
* when their associated three.js resources are garbage collected by the browser.
|
|
665
|
+
* The held value is the cache key string used in `previouslyLoaded`.
|
|
666
|
+
*/
|
|
667
|
+
static _resourceRegistry = new FinalizationRegistry((t) => {
|
|
668
|
+
const e = m.cache.get(t);
|
|
669
|
+
h && console.debug(`[gltf-progressive] Resource GC'd
|
|
670
|
+
${t}`), e instanceof WeakRef && (e.deref() || (m.cache.delete(t), h && console.log(`[gltf-progressive] Cache entry auto-cleaned (GC'd): ${t}`)));
|
|
671
|
+
});
|
|
612
672
|
static workers = [];
|
|
613
673
|
static _workersIndex = 0;
|
|
614
674
|
static async getOrLoadLOD(t, e) {
|
|
615
|
-
const s =
|
|
616
|
-
if (!
|
|
617
|
-
return
|
|
618
|
-
const r =
|
|
619
|
-
let
|
|
675
|
+
const s = h == "verbose", o = this.getAssignedLODInformation(t);
|
|
676
|
+
if (!o)
|
|
677
|
+
return h && console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`, t), null;
|
|
678
|
+
const r = o?.key;
|
|
679
|
+
let n;
|
|
620
680
|
if (t.isTexture === !0) {
|
|
621
681
|
const a = t;
|
|
622
|
-
a.source && a.source[le] && (
|
|
682
|
+
a.source && a.source[le] && (n = a.source[le]);
|
|
623
683
|
}
|
|
624
|
-
if (
|
|
625
|
-
|
|
684
|
+
if (n || (n = m.lodInfos.get(r)), !n)
|
|
685
|
+
h && console.warn(`Can not load LOD ${e}: no LOD info found for "${r}" ${t.name}`, t.type, m.lodInfos);
|
|
626
686
|
else {
|
|
627
687
|
if (e > 0) {
|
|
628
|
-
let
|
|
629
|
-
const
|
|
630
|
-
if (
|
|
631
|
-
|
|
688
|
+
let d = !1;
|
|
689
|
+
const y = Array.isArray(n.lods);
|
|
690
|
+
if (y && e >= n.lods.length ? d = !0 : y || (d = !0), d) {
|
|
691
|
+
const w = this.lowresCache.get(r);
|
|
692
|
+
if (w) {
|
|
693
|
+
const _ = w.deref();
|
|
694
|
+
if (_) return _;
|
|
695
|
+
this.lowresCache.delete(r), h && console.log(`[gltf-progressive] Lowres cache entry was GC'd: ${r}`);
|
|
696
|
+
}
|
|
697
|
+
return null;
|
|
698
|
+
}
|
|
632
699
|
}
|
|
633
|
-
const a = Array.isArray(
|
|
700
|
+
const a = Array.isArray(n.lods) ? n.lods[e]?.path : n.lods;
|
|
634
701
|
if (!a)
|
|
635
|
-
return
|
|
636
|
-
const u = tt(
|
|
702
|
+
return h && !n["missing:uri"] && (n["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, n)), null;
|
|
703
|
+
const u = tt(o.url, a);
|
|
637
704
|
if (u.endsWith(".glb") || u.endsWith(".gltf")) {
|
|
638
|
-
if (!
|
|
639
|
-
return console.warn("missing pointer for glb/gltf texture",
|
|
640
|
-
const
|
|
641
|
-
if (
|
|
642
|
-
s && console.log(`LOD ${e} was already loading/loaded: ${
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
705
|
+
if (!n.guid)
|
|
706
|
+
return console.warn("missing pointer for glb/gltf texture", n), null;
|
|
707
|
+
const d = u + "_" + n.guid, y = await this.queue.slot(u), w = this.cache.get(d);
|
|
708
|
+
if (w !== void 0)
|
|
709
|
+
if (s && console.log(`LOD ${e} was already loading/loaded: ${d}`), w instanceof WeakRef) {
|
|
710
|
+
const c = w.deref();
|
|
711
|
+
if (c) {
|
|
712
|
+
let g = c, b = !1;
|
|
713
|
+
if (g instanceof F && t instanceof F ? g.image?.data || g.source?.data ? g = this.copySettings(t, g) : b = !0 : g instanceof E && t instanceof E && (g.attributes.position?.array || (b = !0)), !b)
|
|
714
|
+
return g;
|
|
715
|
+
}
|
|
716
|
+
this.cache.delete(d), h && console.log(`[gltf-progressive] Re-loading GC'd/disposed resource: ${d}`);
|
|
717
|
+
} else {
|
|
718
|
+
let c = await w.catch((b) => (console.error(`Error loading LOD ${e} from ${u}
|
|
719
|
+
`, b), null)), g = !1;
|
|
720
|
+
if (c == null || (c instanceof F && t instanceof F ? c.image?.data || c.source?.data ? c = this.copySettings(t, c) : (g = !0, this.cache.delete(d)) : c instanceof E && t instanceof E && (c.attributes.position?.array || (g = !0, this.cache.delete(d)))), !g)
|
|
721
|
+
return c;
|
|
722
|
+
}
|
|
723
|
+
if (!y.use)
|
|
724
|
+
return h && console.log(`LOD ${e} was aborted: ${u}`), null;
|
|
725
|
+
const _ = n, I = new Promise(async (c, g) => {
|
|
651
726
|
if (ct) {
|
|
652
|
-
const
|
|
653
|
-
if (
|
|
654
|
-
for (const f of
|
|
655
|
-
let
|
|
656
|
-
return
|
|
727
|
+
const x = await (await ut({})).load(u);
|
|
728
|
+
if (x.textures.length > 0)
|
|
729
|
+
for (const f of x.textures) {
|
|
730
|
+
let p = f.texture;
|
|
731
|
+
return m.assignLODInformation(o.url, p, r, e, void 0), t instanceof F && (p = this.copySettings(t, p)), p && (p.guid = _.guid), c(p);
|
|
657
732
|
}
|
|
658
|
-
if (
|
|
733
|
+
if (x.geometries.length > 0) {
|
|
659
734
|
const f = new Array();
|
|
660
|
-
for (const
|
|
661
|
-
const
|
|
662
|
-
|
|
735
|
+
for (const p of x.geometries) {
|
|
736
|
+
const O = p.geometry;
|
|
737
|
+
m.assignLODInformation(o.url, O, r, e, p.primitiveIndex), f.push(O);
|
|
663
738
|
}
|
|
664
|
-
return
|
|
739
|
+
return c(f);
|
|
665
740
|
}
|
|
666
|
-
return
|
|
741
|
+
return c(null);
|
|
667
742
|
}
|
|
668
|
-
const
|
|
669
|
-
Se(
|
|
743
|
+
const b = new ye();
|
|
744
|
+
Se(b), h && (await new Promise((L) => setTimeout(L, 1e3)), s && console.warn("Start loading (delayed) " + u, _.guid));
|
|
670
745
|
let B = u;
|
|
671
|
-
if (
|
|
672
|
-
const
|
|
673
|
-
|
|
746
|
+
if (_ && Array.isArray(_.lods)) {
|
|
747
|
+
const L = _.lods[e];
|
|
748
|
+
L.hash && (B += "?v=" + L.hash);
|
|
674
749
|
}
|
|
675
|
-
const
|
|
676
|
-
`,
|
|
677
|
-
if (!
|
|
678
|
-
return
|
|
679
|
-
const
|
|
680
|
-
s && console.log("Loading finished " + u,
|
|
681
|
-
let
|
|
682
|
-
if (
|
|
683
|
-
let
|
|
684
|
-
for (const
|
|
685
|
-
if (
|
|
686
|
-
const f =
|
|
687
|
-
if (f?.guid && f.guid ===
|
|
688
|
-
|
|
750
|
+
const D = await b.loadAsync(B).catch((L) => (console.error(`Error loading LOD ${e} from ${u}
|
|
751
|
+
`, L), c(null)));
|
|
752
|
+
if (!D)
|
|
753
|
+
return c(null);
|
|
754
|
+
const N = D.parser;
|
|
755
|
+
s && console.log("Loading finished " + u, _.guid);
|
|
756
|
+
let P = 0;
|
|
757
|
+
if (D.parser.json.textures) {
|
|
758
|
+
let L = !1;
|
|
759
|
+
for (const x of D.parser.json.textures) {
|
|
760
|
+
if (x?.extensions) {
|
|
761
|
+
const f = x?.extensions[W];
|
|
762
|
+
if (f?.guid && f.guid === _.guid) {
|
|
763
|
+
L = !0;
|
|
689
764
|
break;
|
|
690
765
|
}
|
|
691
766
|
}
|
|
692
|
-
|
|
767
|
+
P++;
|
|
693
768
|
}
|
|
694
|
-
if (
|
|
695
|
-
let
|
|
696
|
-
return
|
|
697
|
-
} else
|
|
769
|
+
if (L) {
|
|
770
|
+
let x = await N.getDependency("texture", P);
|
|
771
|
+
return x && m.assignLODInformation(o.url, x, r, e, void 0), s && console.log('change "' + t.name + '" → "' + x.name + '"', u, P, x, d), t instanceof F && (x = this.copySettings(t, x)), x && (x.guid = _.guid), c(x);
|
|
772
|
+
} else h && console.warn("Could not find texture with guid", _.guid, D.parser.json);
|
|
698
773
|
}
|
|
699
|
-
if (
|
|
700
|
-
let
|
|
701
|
-
for (const
|
|
702
|
-
if (
|
|
703
|
-
const f =
|
|
704
|
-
if (f?.guid && f.guid ===
|
|
705
|
-
|
|
774
|
+
if (P = 0, D.parser.json.meshes) {
|
|
775
|
+
let L = !1;
|
|
776
|
+
for (const x of D.parser.json.meshes) {
|
|
777
|
+
if (x?.extensions) {
|
|
778
|
+
const f = x?.extensions[W];
|
|
779
|
+
if (f?.guid && f.guid === _.guid) {
|
|
780
|
+
L = !0;
|
|
706
781
|
break;
|
|
707
782
|
}
|
|
708
783
|
}
|
|
709
|
-
|
|
784
|
+
P++;
|
|
710
785
|
}
|
|
711
|
-
if (
|
|
712
|
-
const
|
|
713
|
-
if (s && console.log(`Loaded Mesh "${
|
|
714
|
-
const f =
|
|
715
|
-
return
|
|
786
|
+
if (L) {
|
|
787
|
+
const x = await N.getDependency("mesh", P);
|
|
788
|
+
if (s && console.log(`Loaded Mesh "${x.name}"`, u, P, x, d), x.isMesh === !0) {
|
|
789
|
+
const f = x.geometry;
|
|
790
|
+
return m.assignLODInformation(o.url, f, r, e, 0), c(f);
|
|
716
791
|
} else {
|
|
717
792
|
const f = new Array();
|
|
718
|
-
for (let
|
|
719
|
-
const
|
|
720
|
-
if (
|
|
721
|
-
const
|
|
722
|
-
|
|
793
|
+
for (let p = 0; p < x.children.length; p++) {
|
|
794
|
+
const O = x.children[p];
|
|
795
|
+
if (O.isMesh === !0) {
|
|
796
|
+
const S = O.geometry;
|
|
797
|
+
m.assignLODInformation(o.url, S, r, e, p), f.push(S);
|
|
723
798
|
}
|
|
724
799
|
}
|
|
725
|
-
return
|
|
800
|
+
return c(f);
|
|
726
801
|
}
|
|
727
|
-
} else
|
|
802
|
+
} else h && console.warn("Could not find mesh with guid", _.guid, D.parser.json);
|
|
728
803
|
}
|
|
729
|
-
return
|
|
804
|
+
return c(null);
|
|
730
805
|
});
|
|
731
|
-
|
|
732
|
-
|
|
806
|
+
this.cache.set(d, I), y.use(I);
|
|
807
|
+
const M = await I;
|
|
808
|
+
return M != null ? M instanceof F ? (this.cache.set(d, new WeakRef(M)), m._resourceRegistry.register(M, d)) : Array.isArray(M) ? this.cache.set(d, Promise.resolve(M)) : this.cache.set(d, Promise.resolve(M)) : this.cache.set(d, Promise.resolve(null)), M;
|
|
809
|
+
} else if (t instanceof F) {
|
|
733
810
|
s && console.log("Load texture from uri: " + u);
|
|
734
|
-
const
|
|
735
|
-
return
|
|
811
|
+
const y = await new ze().loadAsync(u);
|
|
812
|
+
return y ? (y.guid = n.guid, y.flipY = !1, y.needsUpdate = !0, y.colorSpace = t.colorSpace, s && console.log(n, y)) : h && console.warn("failed loading", u), y;
|
|
736
813
|
}
|
|
737
814
|
}
|
|
738
815
|
return null;
|
|
739
816
|
}
|
|
740
817
|
static maxConcurrent = 50;
|
|
741
|
-
static queue = new st(
|
|
742
|
-
static assignLODInformation(t, e, s,
|
|
818
|
+
static queue = new st(m.maxConcurrent, { debug: h != !1 });
|
|
819
|
+
static assignLODInformation(t, e, s, o, r) {
|
|
743
820
|
if (!e) return;
|
|
744
821
|
e.userData || (e.userData = {});
|
|
745
|
-
const
|
|
746
|
-
e.userData.LODS =
|
|
822
|
+
const n = new ht(t, s, o, r);
|
|
823
|
+
e.userData.LODS = n, "source" in e && typeof e.source == "object" && (e.source.LODS = n);
|
|
747
824
|
}
|
|
748
825
|
static getAssignedLODInformation(t) {
|
|
749
826
|
return t ? t.userData?.LODS ? t.userData.LODS : "source" in t && t.source?.LODS ? t.source.LODS : null : null;
|
|
750
827
|
}
|
|
751
828
|
// private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
|
|
752
829
|
static copySettings(t, e) {
|
|
753
|
-
return e ? (
|
|
830
|
+
return e ? (h === "verbose" && console.debug(`Copy texture settings
|
|
754
831
|
`, t.uuid, `
|
|
755
832
|
`, 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;
|
|
756
833
|
}
|
|
@@ -762,13 +839,13 @@ class ht {
|
|
|
762
839
|
level;
|
|
763
840
|
/** For multi objects (e.g. a group of meshes) this is the index of the object */
|
|
764
841
|
index;
|
|
765
|
-
constructor(t, e, s,
|
|
766
|
-
this.url = t, this.key = e, this.level = s,
|
|
842
|
+
constructor(t, e, s, o) {
|
|
843
|
+
this.url = t, this.key = e, this.level = s, o != null && (this.index = o);
|
|
767
844
|
}
|
|
768
845
|
}
|
|
769
846
|
class ue {
|
|
770
|
-
static addPromise = (t, e, s,
|
|
771
|
-
|
|
847
|
+
static addPromise = (t, e, s, o) => {
|
|
848
|
+
o.forEach((r) => {
|
|
772
849
|
r.add(t, e, s);
|
|
773
850
|
});
|
|
774
851
|
};
|
|
@@ -799,8 +876,8 @@ class ue {
|
|
|
799
876
|
_awaiting = [];
|
|
800
877
|
_maxPromisesPerObject = 1;
|
|
801
878
|
constructor(t, e) {
|
|
802
|
-
const
|
|
803
|
-
this._frame_start = e.waitForFirstCapture ? void 0 : t, this._frames_to_capture =
|
|
879
|
+
const o = Math.max(e.frames ?? 2, 2);
|
|
880
|
+
this._frame_start = e.waitForFirstCapture ? void 0 : t, this._frames_to_capture = o, this.ready = new Promise((r) => {
|
|
804
881
|
this._resolve = r;
|
|
805
882
|
}), this.ready.finally(() => {
|
|
806
883
|
this._resolved = !0, this._awaiting.length = 0;
|
|
@@ -815,18 +892,18 @@ class ue {
|
|
|
815
892
|
_seen = /* @__PURE__ */ new WeakMap();
|
|
816
893
|
add(t, e, s) {
|
|
817
894
|
if (this._resolved) {
|
|
818
|
-
|
|
895
|
+
h && console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");
|
|
819
896
|
return;
|
|
820
897
|
}
|
|
821
898
|
if (!(this._frame_start !== void 0 && this._currentFrame > this._frame_start + this._frames_to_capture)) {
|
|
822
899
|
if (this._maxPromisesPerObject >= 1)
|
|
823
900
|
if (this._seen.has(e)) {
|
|
824
|
-
let
|
|
825
|
-
if (
|
|
826
|
-
|
|
901
|
+
let o = this._seen.get(e);
|
|
902
|
+
if (o >= this._maxPromisesPerObject) {
|
|
903
|
+
h && console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");
|
|
827
904
|
return;
|
|
828
905
|
}
|
|
829
|
-
this._seen.set(e,
|
|
906
|
+
this._seen.set(e, o + 1);
|
|
830
907
|
} else
|
|
831
908
|
this._seen.set(e, 1);
|
|
832
909
|
this._awaiting.push(s), this._addedCount++, s.finally(() => {
|
|
@@ -842,8 +919,8 @@ class ue {
|
|
|
842
919
|
});
|
|
843
920
|
}
|
|
844
921
|
}
|
|
845
|
-
const k =
|
|
846
|
-
class
|
|
922
|
+
const k = j("debugprogressive"), gt = j("noprogressive"), de = /* @__PURE__ */ Symbol("Needle:LODSManager"), ce = /* @__PURE__ */ Symbol("Needle:LODState"), U = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), T = { mesh_lod: -1, texture_lod: -1 };
|
|
923
|
+
class v {
|
|
847
924
|
/**
|
|
848
925
|
* 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.
|
|
849
926
|
*/
|
|
@@ -853,11 +930,11 @@ class L {
|
|
|
853
930
|
return t[ce];
|
|
854
931
|
}
|
|
855
932
|
static addPlugin(t) {
|
|
856
|
-
|
|
933
|
+
z.push(t);
|
|
857
934
|
}
|
|
858
935
|
static removePlugin(t) {
|
|
859
|
-
const e =
|
|
860
|
-
e >= 0 &&
|
|
936
|
+
const e = z.indexOf(t);
|
|
937
|
+
e >= 0 && z.splice(e, 1);
|
|
861
938
|
}
|
|
862
939
|
/**
|
|
863
940
|
* Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
|
|
@@ -867,7 +944,7 @@ class L {
|
|
|
867
944
|
static get(t, e) {
|
|
868
945
|
if (t[de])
|
|
869
946
|
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[de];
|
|
870
|
-
const s = new
|
|
947
|
+
const s = new v(t, {
|
|
871
948
|
engine: "unknown",
|
|
872
949
|
...e
|
|
873
950
|
});
|
|
@@ -878,7 +955,7 @@ class L {
|
|
|
878
955
|
projectionScreenMatrix = new _e();
|
|
879
956
|
/** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
|
|
880
957
|
get plugins() {
|
|
881
|
-
return
|
|
958
|
+
return z;
|
|
882
959
|
}
|
|
883
960
|
/**
|
|
884
961
|
* Force override the LOD level for all objects (meshes + textures) rendered in the scene
|
|
@@ -921,11 +998,11 @@ class L {
|
|
|
921
998
|
awaitLoading(t) {
|
|
922
999
|
const e = this._promiseGroupIds++, s = new ue(this.#r, { ...t });
|
|
923
1000
|
this._newPromiseGroups.push(s);
|
|
924
|
-
const
|
|
1001
|
+
const o = performance.now();
|
|
925
1002
|
return s.ready.finally(() => {
|
|
926
1003
|
const r = this._newPromiseGroups.indexOf(s);
|
|
927
1004
|
r >= 0 && (this._newPromiseGroups.splice(r, 1), Le() && performance.measure("LODsManager:awaitLoading", {
|
|
928
|
-
start:
|
|
1005
|
+
start: o,
|
|
929
1006
|
detail: { id: e, name: t?.name, awaited: s.awaitedCount, resolved: s.resolvedCount }
|
|
930
1007
|
}));
|
|
931
1008
|
}), s.ready;
|
|
@@ -950,9 +1027,9 @@ class L {
|
|
|
950
1027
|
this.renderer = t, this.context = { ...e };
|
|
951
1028
|
}
|
|
952
1029
|
#t;
|
|
953
|
-
#
|
|
1030
|
+
#n = new Ne();
|
|
954
1031
|
#r = 0;
|
|
955
|
-
#
|
|
1032
|
+
#o = 0;
|
|
956
1033
|
#i = 0;
|
|
957
1034
|
#s = 0;
|
|
958
1035
|
_fpsBuffer = [60, 60, 60, 60, 60];
|
|
@@ -965,11 +1042,11 @@ class L {
|
|
|
965
1042
|
let t = 0;
|
|
966
1043
|
this.#t = this.renderer.render;
|
|
967
1044
|
const e = this;
|
|
968
|
-
xe(this.renderer), this.renderer.render = function(s,
|
|
1045
|
+
xe(this.renderer), this.renderer.render = function(s, o) {
|
|
969
1046
|
const r = e.renderer.getRenderTarget();
|
|
970
|
-
(r == null || "isXRRenderTarget" in r && r.isXRRenderTarget) && (t = 0, e.#r += 1, e.#
|
|
971
|
-
const
|
|
972
|
-
e.#t.call(this, s,
|
|
1047
|
+
(r == null || "isXRRenderTarget" in r && r.isXRRenderTarget) && (t = 0, e.#r += 1, e.#o = e.#n.getDelta(), e.#i += e.#o, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#o), e.#s = e._fpsBuffer.reduce((l, a) => l + a) / e._fpsBuffer.length, k && e.#r % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
|
|
1048
|
+
const n = t++;
|
|
1049
|
+
e.#t.call(this, s, o), e.onAfterRender(s, o, n);
|
|
973
1050
|
};
|
|
974
1051
|
}
|
|
975
1052
|
disable() {
|
|
@@ -981,12 +1058,12 @@ class L {
|
|
|
981
1058
|
onAfterRender(t, e, s) {
|
|
982
1059
|
if (this.pause) return;
|
|
983
1060
|
const r = this.renderer.renderLists.get(t, 0).opaque;
|
|
984
|
-
let
|
|
1061
|
+
let n = !0;
|
|
985
1062
|
if (r.length === 1) {
|
|
986
1063
|
const l = r[0].material;
|
|
987
|
-
(l.name === "EffectMaterial" || l.name === "CopyShader") && (
|
|
1064
|
+
(l.name === "EffectMaterial" || l.name === "CopyShader") && (n = !1);
|
|
988
1065
|
}
|
|
989
|
-
if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (
|
|
1066
|
+
if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (n = !1), n) {
|
|
990
1067
|
if (gt || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1, k && console.warn("↓ Reducing LOD updates", this.#e, this.#s.toFixed(0))) : this.#s >= 60 && this.#e > 1 && (this.#e -= 1, k && console.warn("↑ Increasing LOD updates", this.#e, this.#s.toFixed(0))) : this.#e = this.updateInterval, this.#e > 0 && this.#r % this.#e != 0))
|
|
991
1068
|
return;
|
|
992
1069
|
this.internalUpdate(t, e), this._postprocessPromiseGroups();
|
|
@@ -996,10 +1073,10 @@ class L {
|
|
|
996
1073
|
* Update LODs in a scene
|
|
997
1074
|
*/
|
|
998
1075
|
internalUpdate(t, e) {
|
|
999
|
-
const s = this.renderer.renderLists.get(t, 0),
|
|
1076
|
+
const s = this.renderer.renderLists.get(t, 0), o = s.opaque;
|
|
1000
1077
|
this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse);
|
|
1001
1078
|
const r = this.targetTriangleDensity;
|
|
1002
|
-
for (const a of
|
|
1079
|
+
for (const a of o) {
|
|
1003
1080
|
if (a.material && (a.geometry?.type === "BoxGeometry" || a.geometry?.type === "BufferGeometry") && (a.material.name === "SphericalGaussianBlur" || a.material.name == "BackgroundCubeMaterial" || a.material.name === "CubemapFromEquirect" || a.material.name === "EquirectangularToCubeUV")) {
|
|
1004
1081
|
k && (a.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] || (a.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] = !0, console.warn("Ignoring skybox or BLIT object", a, a.material.name, a.material.type)));
|
|
1005
1082
|
continue;
|
|
@@ -1015,36 +1092,36 @@ class L {
|
|
|
1015
1092
|
}
|
|
1016
1093
|
if (k === "color" && a.material && !a.object.progressive_debug_color) {
|
|
1017
1094
|
a.object.progressive_debug_color = !0;
|
|
1018
|
-
const
|
|
1019
|
-
a.object.material =
|
|
1095
|
+
const d = Math.random() * 16777215, y = new qe({ color: d });
|
|
1096
|
+
a.object.material = y;
|
|
1020
1097
|
}
|
|
1021
1098
|
const u = a.object;
|
|
1022
|
-
(u instanceof
|
|
1099
|
+
(u instanceof V || u.isMesh) && this.updateLODs(t, e, u, r);
|
|
1023
1100
|
}
|
|
1024
|
-
const
|
|
1025
|
-
for (const a of
|
|
1101
|
+
const n = s.transparent;
|
|
1102
|
+
for (const a of n) {
|
|
1026
1103
|
const u = a.object;
|
|
1027
|
-
(u instanceof
|
|
1104
|
+
(u instanceof V || u.isMesh) && this.updateLODs(t, e, u, r);
|
|
1028
1105
|
}
|
|
1029
1106
|
const l = s.transmissive;
|
|
1030
1107
|
for (const a of l) {
|
|
1031
1108
|
const u = a.object;
|
|
1032
|
-
(u instanceof
|
|
1109
|
+
(u instanceof V || u.isMesh) && this.updateLODs(t, e, u, r);
|
|
1033
1110
|
}
|
|
1034
1111
|
}
|
|
1035
1112
|
/** Update the LOD levels for the renderer. */
|
|
1036
|
-
updateLODs(t, e, s,
|
|
1113
|
+
updateLODs(t, e, s, o) {
|
|
1037
1114
|
s.userData || (s.userData = {});
|
|
1038
1115
|
let r = s[ce];
|
|
1039
1116
|
if (r || (r = new pt(), s[ce] = r), r.frames++ < 2)
|
|
1040
1117
|
return;
|
|
1041
|
-
for (const l of
|
|
1118
|
+
for (const l of z)
|
|
1042
1119
|
l.onBeforeUpdateLOD?.(this.renderer, t, e, s);
|
|
1043
|
-
const
|
|
1044
|
-
|
|
1045
|
-
for (const l of
|
|
1046
|
-
l.onAfterUpdatedLOD?.(this.renderer, t, e, s,
|
|
1047
|
-
r.lastLodLevel_Mesh =
|
|
1120
|
+
const n = this.overrideLodLevel !== void 0 ? this.overrideLodLevel : q;
|
|
1121
|
+
n >= 0 ? (T.mesh_lod = n, T.texture_lod = n) : (this.calculateLodLevel(e, s, r, o, 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 && Ce(s.material);
|
|
1122
|
+
for (const l of z)
|
|
1123
|
+
l.onAfterUpdatedLOD?.(this.renderer, t, e, s, T);
|
|
1124
|
+
r.lastLodLevel_Mesh = T.mesh_lod, r.lastLodLevel_Texture = T.texture_lod;
|
|
1048
1125
|
}
|
|
1049
1126
|
/** Load progressive textures for the given material
|
|
1050
1127
|
* @param material the material to load the textures for
|
|
@@ -1058,10 +1135,10 @@ class L {
|
|
|
1058
1135
|
this.loadProgressiveTextures(r, e);
|
|
1059
1136
|
return;
|
|
1060
1137
|
}
|
|
1061
|
-
let
|
|
1062
|
-
if ((t[
|
|
1063
|
-
t[
|
|
1064
|
-
const r =
|
|
1138
|
+
let o = !1;
|
|
1139
|
+
if ((t[U] === void 0 || e < t[U]) && (o = !0), s !== void 0 && s >= 0 && (o = t[U] != s, e = s), o) {
|
|
1140
|
+
t[U] = e;
|
|
1141
|
+
const r = m.assignTextureLOD(t, e).then((n) => {
|
|
1065
1142
|
this._lodchangedlisteners.forEach((l) => l({ type: "texture", level: e, object: t }));
|
|
1066
1143
|
});
|
|
1067
1144
|
ue.addPromise("texture", t, r, this._newPromiseGroups);
|
|
@@ -1075,12 +1152,12 @@ class L {
|
|
|
1075
1152
|
*/
|
|
1076
1153
|
loadProgressiveMeshes(t, e) {
|
|
1077
1154
|
if (!t) return Promise.resolve(null);
|
|
1078
|
-
let s = t[
|
|
1079
|
-
const
|
|
1080
|
-
if (
|
|
1081
|
-
t[
|
|
1082
|
-
const r = t.geometry,
|
|
1083
|
-
return ue.addPromise("mesh", t,
|
|
1155
|
+
let s = t[U] !== e;
|
|
1156
|
+
const o = t["DEBUG:LOD"];
|
|
1157
|
+
if (o != null && (s = t[U] != o, e = o), s) {
|
|
1158
|
+
t[U] = e;
|
|
1159
|
+
const r = t.geometry, n = m.assignMeshLOD(t, e).then((l) => (l && t[U] == e && r != t.geometry && this._lodchangedlisteners.forEach((a) => a({ type: "mesh", level: e, object: t })), l));
|
|
1160
|
+
return ue.addPromise("mesh", t, n, this._newPromiseGroups), n;
|
|
1084
1161
|
}
|
|
1085
1162
|
return Promise.resolve(null);
|
|
1086
1163
|
}
|
|
@@ -1089,22 +1166,22 @@ class L {
|
|
|
1089
1166
|
_tempBox = new he();
|
|
1090
1167
|
_tempBox2 = new he();
|
|
1091
1168
|
tempMatrix = new _e();
|
|
1092
|
-
_tempWorldPosition = new
|
|
1093
|
-
_tempBoxSize = new
|
|
1094
|
-
_tempBox2Size = new
|
|
1095
|
-
static corner0 = new
|
|
1096
|
-
static corner1 = new
|
|
1097
|
-
static corner2 = new
|
|
1098
|
-
static corner3 = new
|
|
1099
|
-
static _tempPtInside = new
|
|
1169
|
+
_tempWorldPosition = new C();
|
|
1170
|
+
_tempBoxSize = new C();
|
|
1171
|
+
_tempBox2Size = new C();
|
|
1172
|
+
static corner0 = new C();
|
|
1173
|
+
static corner1 = new C();
|
|
1174
|
+
static corner2 = new C();
|
|
1175
|
+
static corner3 = new C();
|
|
1176
|
+
static _tempPtInside = new C();
|
|
1100
1177
|
static isInside(t, e) {
|
|
1101
|
-
const s = t.min,
|
|
1102
|
-
return this._tempPtInside.set(r,
|
|
1178
|
+
const s = t.min, o = t.max, r = (s.x + o.x) * 0.5, n = (s.y + o.y) * 0.5;
|
|
1179
|
+
return this._tempPtInside.set(r, n, s.z).applyMatrix4(e).z < 0;
|
|
1103
1180
|
}
|
|
1104
1181
|
static skinnedMeshBoundsFrameOffsetCounter = 0;
|
|
1105
|
-
static $skinnedMeshBoundsOffset = Symbol("gltf-progressive-skinnedMeshBoundsOffset");
|
|
1182
|
+
static $skinnedMeshBoundsOffset = /* @__PURE__ */ Symbol("gltf-progressive-skinnedMeshBoundsOffset");
|
|
1106
1183
|
// #region calculateLodLevel
|
|
1107
|
-
calculateLodLevel(t, e, s,
|
|
1184
|
+
calculateLodLevel(t, e, s, o, r) {
|
|
1108
1185
|
if (!e) {
|
|
1109
1186
|
r.mesh_lod = -1, r.texture_lod = -1;
|
|
1110
1187
|
return;
|
|
@@ -1116,33 +1193,33 @@ class L {
|
|
|
1116
1193
|
let l = 10 + 1, a = !1;
|
|
1117
1194
|
if (k && e["DEBUG:LOD"] != null)
|
|
1118
1195
|
return e["DEBUG:LOD"];
|
|
1119
|
-
const u =
|
|
1120
|
-
if (!
|
|
1196
|
+
const u = m.getMeshLODExtension(e.geometry)?.lods, d = m.getPrimitiveIndex(e.geometry), y = u && u.length > 0, w = m.getMaterialMinMaxLODsCount(e.material), _ = w.min_count !== 1 / 0 && w.min_count >= 0 && w.max_count >= 0;
|
|
1197
|
+
if (!y && !_) {
|
|
1121
1198
|
r.mesh_lod = 0, r.texture_lod = 0;
|
|
1122
1199
|
return;
|
|
1123
1200
|
}
|
|
1124
|
-
|
|
1201
|
+
y || (a = !0, l = 0);
|
|
1125
1202
|
const I = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
|
|
1126
|
-
let
|
|
1203
|
+
let M = e.geometry.boundingBox;
|
|
1127
1204
|
if (e.type === "SkinnedMesh") {
|
|
1128
|
-
const
|
|
1129
|
-
if (!
|
|
1130
|
-
|
|
1205
|
+
const c = e;
|
|
1206
|
+
if (!c.boundingBox)
|
|
1207
|
+
c.computeBoundingBox();
|
|
1131
1208
|
else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
|
|
1132
|
-
if (!
|
|
1133
|
-
const
|
|
1134
|
-
|
|
1209
|
+
if (!c[v.$skinnedMeshBoundsOffset]) {
|
|
1210
|
+
const b = v.skinnedMeshBoundsFrameOffsetCounter++;
|
|
1211
|
+
c[v.$skinnedMeshBoundsOffset] = b;
|
|
1135
1212
|
}
|
|
1136
|
-
const
|
|
1137
|
-
if ((s.frames +
|
|
1138
|
-
const
|
|
1139
|
-
|
|
1213
|
+
const g = c[v.$skinnedMeshBoundsOffset];
|
|
1214
|
+
if ((s.frames + g) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
|
|
1215
|
+
const b = Z(c), B = c.geometry;
|
|
1216
|
+
b && (c.geometry = b), c.computeBoundingBox(), c.geometry = B;
|
|
1140
1217
|
}
|
|
1141
1218
|
}
|
|
1142
|
-
|
|
1219
|
+
M = c.boundingBox;
|
|
1143
1220
|
}
|
|
1144
|
-
if (
|
|
1145
|
-
const
|
|
1221
|
+
if (M) {
|
|
1222
|
+
const c = t;
|
|
1146
1223
|
if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
|
|
1147
1224
|
this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
|
|
1148
1225
|
const f = t.getWorldPosition(this._tempWorldPosition);
|
|
@@ -1151,67 +1228,67 @@ class L {
|
|
|
1151
1228
|
return;
|
|
1152
1229
|
}
|
|
1153
1230
|
}
|
|
1154
|
-
if (this._tempBox.copy(
|
|
1231
|
+
if (this._tempBox.copy(M), this._tempBox.applyMatrix4(e.matrixWorld), c.isPerspectiveCamera && v.isInside(this._tempBox, this.projectionScreenMatrix)) {
|
|
1155
1232
|
r.mesh_lod = 0, r.texture_lod = 0;
|
|
1156
1233
|
return;
|
|
1157
1234
|
}
|
|
1158
|
-
if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled &&
|
|
1159
|
-
const f = this._tempBox.min,
|
|
1160
|
-
let
|
|
1161
|
-
const ee = 2,
|
|
1162
|
-
|
|
1163
|
-
const Re =
|
|
1164
|
-
s.lastCentrality = (
|
|
1235
|
+
if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && c.isPerspectiveCamera && c.fov > 70) {
|
|
1236
|
+
const f = this._tempBox.min, p = this._tempBox.max;
|
|
1237
|
+
let O = f.x, S = f.y, G = p.x, Y = p.y;
|
|
1238
|
+
const ee = 2, ne = 1.5, te = (f.x + p.x) * 0.5, se = (f.y + p.y) * 0.5;
|
|
1239
|
+
O = (O - te) * ee + te, S = (S - se) * ee + se, G = (G - te) * ee + te, Y = (Y - se) * ee + se;
|
|
1240
|
+
const Re = O < 0 && G > 0 ? 0 : Math.min(Math.abs(f.x), Math.abs(p.x)), $e = S < 0 && Y > 0 ? 0 : Math.min(Math.abs(f.y), Math.abs(p.y)), ie = Math.max(Re, $e);
|
|
1241
|
+
s.lastCentrality = (ne - ie) * (ne - ie) * (ne - ie);
|
|
1165
1242
|
} else
|
|
1166
1243
|
s.lastCentrality = 1;
|
|
1167
|
-
const
|
|
1168
|
-
|
|
1169
|
-
const
|
|
1170
|
-
B.copy(
|
|
1171
|
-
const
|
|
1172
|
-
if (Math.max(
|
|
1244
|
+
const g = this._tempBox.getSize(this._tempBoxSize);
|
|
1245
|
+
g.multiplyScalar(0.5), screen.availHeight > 0 && I > 0 && g.multiplyScalar(I / screen.availHeight), t.isPerspectiveCamera ? g.x *= t.aspect : t.isOrthographicCamera;
|
|
1246
|
+
const b = t.matrixWorldInverse, B = this._tempBox2;
|
|
1247
|
+
B.copy(M), B.applyMatrix4(e.matrixWorld), B.applyMatrix4(b);
|
|
1248
|
+
const D = B.getSize(this._tempBox2Size), N = Math.max(D.x, D.y);
|
|
1249
|
+
if (Math.max(g.x, g.y) != 0 && N != 0 && (g.z = D.z / Math.max(D.x, D.y) * Math.max(g.x, g.y)), s.lastScreenCoverage = Math.max(g.x, g.y, g.z), s.lastScreenspaceVolume.copy(g), s.lastScreenCoverage *= s.lastCentrality, k && v.debugDrawLine) {
|
|
1173
1250
|
const f = this.tempMatrix.copy(this.projectionScreenMatrix);
|
|
1174
1251
|
f.invert();
|
|
1175
|
-
const
|
|
1176
|
-
|
|
1177
|
-
const
|
|
1178
|
-
|
|
1252
|
+
const p = v.corner0, O = v.corner1, S = v.corner2, G = v.corner3;
|
|
1253
|
+
p.copy(this._tempBox.min), O.copy(this._tempBox.max), O.x = p.x, S.copy(this._tempBox.max), S.y = p.y, G.copy(this._tempBox.max);
|
|
1254
|
+
const Y = (p.z + G.z) * 0.5;
|
|
1255
|
+
p.z = O.z = S.z = G.z = Y, p.applyMatrix4(f), O.applyMatrix4(f), S.applyMatrix4(f), G.applyMatrix4(f), v.debugDrawLine(p, O, 255), v.debugDrawLine(p, S, 255), v.debugDrawLine(O, G, 255), v.debugDrawLine(S, G, 255);
|
|
1179
1256
|
}
|
|
1180
|
-
let
|
|
1257
|
+
let L = 999;
|
|
1181
1258
|
if (u && s.lastScreenCoverage > 0)
|
|
1182
1259
|
for (let f = 0; f < u.length; f++) {
|
|
1183
|
-
const
|
|
1184
|
-
if (
|
|
1185
|
-
|
|
1260
|
+
const p = u[f], S = (p.densities?.[d] || p.density || 1e-5) / s.lastScreenCoverage;
|
|
1261
|
+
if (d > 0 && Le() && !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.")), S < o) {
|
|
1262
|
+
L = f;
|
|
1186
1263
|
break;
|
|
1187
1264
|
}
|
|
1188
1265
|
}
|
|
1189
|
-
|
|
1266
|
+
L < l && (l = L, a = !0);
|
|
1190
1267
|
}
|
|
1191
1268
|
if (a ? r.mesh_lod = l : r.mesh_lod = s.lastLodLevel_Mesh, k && r.mesh_lod != s.lastLodLevel_Mesh) {
|
|
1192
|
-
const
|
|
1193
|
-
|
|
1269
|
+
const g = u?.[r.mesh_lod];
|
|
1270
|
+
g && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${r.mesh_lod} (density: ${g.densities?.[d].toFixed(0)}) | ${e.name}`);
|
|
1194
1271
|
}
|
|
1195
|
-
if (
|
|
1196
|
-
const
|
|
1272
|
+
if (_) {
|
|
1273
|
+
const c = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
|
|
1197
1274
|
if (s.lastLodLevel_Texture < 0) {
|
|
1198
|
-
if (r.texture_lod =
|
|
1199
|
-
const
|
|
1200
|
-
k && console.log(`First Texture LOD ${r.texture_lod} (${
|
|
1275
|
+
if (r.texture_lod = w.max_count - 1, k) {
|
|
1276
|
+
const g = w.lods[w.max_count - 1];
|
|
1277
|
+
k && console.log(`First Texture LOD ${r.texture_lod} (${g.max_height}px) - ${e.name}`);
|
|
1201
1278
|
}
|
|
1202
1279
|
} else {
|
|
1203
|
-
const
|
|
1204
|
-
let
|
|
1205
|
-
this.context?.engine === "model-viewer" && (
|
|
1206
|
-
const
|
|
1207
|
-
let
|
|
1208
|
-
for (let
|
|
1209
|
-
const
|
|
1210
|
-
if (!(
|
|
1211
|
-
if (
|
|
1212
|
-
const
|
|
1213
|
-
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${r.texture_lod} = ${
|
|
1214
|
-
Screensize: ${
|
|
1280
|
+
const g = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
|
|
1281
|
+
let b = s.lastScreenCoverage * 4;
|
|
1282
|
+
this.context?.engine === "model-viewer" && (b *= 1.5);
|
|
1283
|
+
const D = I / window.devicePixelRatio * b;
|
|
1284
|
+
let N = !1;
|
|
1285
|
+
for (let P = w.lods.length - 1; P >= 0; P--) {
|
|
1286
|
+
const L = w.lods[P];
|
|
1287
|
+
if (!(c && L.max_height >= 2048) && !(Ae() && L.max_height > 4096) && (L.max_height > D || !N && P === 0)) {
|
|
1288
|
+
if (N = !0, r.texture_lod = P, k && r.texture_lod < s.lastLodLevel_Texture) {
|
|
1289
|
+
const x = L.max_height;
|
|
1290
|
+
console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${r.texture_lod} = ${x}px
|
|
1291
|
+
Screensize: ${D.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${g.toFixed(1)}
|
|
1215
1292
|
${e.name}`);
|
|
1216
1293
|
}
|
|
1217
1294
|
break;
|
|
@@ -1227,19 +1304,19 @@ class pt {
|
|
|
1227
1304
|
lastLodLevel_Mesh = -1;
|
|
1228
1305
|
lastLodLevel_Texture = -1;
|
|
1229
1306
|
lastScreenCoverage = 0;
|
|
1230
|
-
lastScreenspaceVolume = new
|
|
1307
|
+
lastScreenspaceVolume = new C();
|
|
1231
1308
|
lastCentrality = 0;
|
|
1232
1309
|
}
|
|
1233
|
-
const ve = Symbol("NEEDLE_mesh_lod"), re = Symbol("NEEDLE_texture_lod");
|
|
1310
|
+
const ve = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), re = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
|
|
1234
1311
|
let fe = null;
|
|
1235
|
-
function
|
|
1312
|
+
function Ie() {
|
|
1236
1313
|
const i = mt();
|
|
1237
1314
|
i && (i.mapURLs(function(t) {
|
|
1238
1315
|
return be(), t;
|
|
1239
1316
|
}), be(), fe?.disconnect(), fe = new MutationObserver((t) => {
|
|
1240
1317
|
t.forEach((e) => {
|
|
1241
1318
|
e.addedNodes.forEach((s) => {
|
|
1242
|
-
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" &&
|
|
1319
|
+
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && ke(s);
|
|
1243
1320
|
});
|
|
1244
1321
|
});
|
|
1245
1322
|
}), fe.observe(document, { childList: !0, subtree: !0 }));
|
|
@@ -1248,32 +1325,32 @@ function mt() {
|
|
|
1248
1325
|
if (typeof customElements > "u") return null;
|
|
1249
1326
|
const i = customElements.get("model-viewer");
|
|
1250
1327
|
return i || (customElements.whenDefined("model-viewer").then(() => {
|
|
1251
|
-
console.debug("[gltf-progressive] model-viewer defined"),
|
|
1328
|
+
console.debug("[gltf-progressive] model-viewer defined"), Ie();
|
|
1252
1329
|
}), null);
|
|
1253
1330
|
}
|
|
1254
1331
|
function be() {
|
|
1255
1332
|
if (typeof document > "u") return;
|
|
1256
1333
|
document.querySelectorAll("model-viewer").forEach((t) => {
|
|
1257
|
-
|
|
1334
|
+
ke(t);
|
|
1258
1335
|
});
|
|
1259
1336
|
}
|
|
1260
1337
|
const Me = /* @__PURE__ */ new WeakSet();
|
|
1261
1338
|
let yt = 0;
|
|
1262
|
-
function
|
|
1339
|
+
function ke(i) {
|
|
1263
1340
|
if (!i || Me.has(i))
|
|
1264
1341
|
return null;
|
|
1265
1342
|
Me.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++yt + `
|
|
1266
1343
|
`, i.getAttribute("src"));
|
|
1267
1344
|
let t = null, e = null, s = null;
|
|
1268
|
-
for (let
|
|
1269
|
-
const r = Object.getOwnPropertySymbols(
|
|
1270
|
-
!t &&
|
|
1345
|
+
for (let o = i; o != null; o = Object.getPrototypeOf(o)) {
|
|
1346
|
+
const r = Object.getOwnPropertySymbols(o), n = r.find((u) => u.toString() == "Symbol(renderer)"), l = r.find((u) => u.toString() == "Symbol(scene)"), a = r.find((u) => u.toString() == "Symbol(needsRender)");
|
|
1347
|
+
!t && n != null && (t = i[n].threeRenderer), !e && l != null && (e = i[l]), !s && a != null && (s = i[a]);
|
|
1271
1348
|
}
|
|
1272
1349
|
if (t && e) {
|
|
1273
|
-
let
|
|
1350
|
+
let o = function() {
|
|
1274
1351
|
if (s) {
|
|
1275
|
-
let
|
|
1276
|
-
if (
|
|
1352
|
+
let n = 0, l = setInterval(() => {
|
|
1353
|
+
if (n++ > 5) {
|
|
1277
1354
|
clearInterval(l);
|
|
1278
1355
|
return;
|
|
1279
1356
|
}
|
|
@@ -1282,13 +1359,13 @@ function Ce(i) {
|
|
|
1282
1359
|
}
|
|
1283
1360
|
};
|
|
1284
1361
|
console.debug("[gltf-progressive] setup model-viewer");
|
|
1285
|
-
const r =
|
|
1286
|
-
return
|
|
1362
|
+
const r = v.get(t, { engine: "model-viewer" });
|
|
1363
|
+
return v.addPlugin(new xt()), r.enable(), r.addEventListener("changed", () => {
|
|
1287
1364
|
s?.call(i);
|
|
1288
|
-
}), i.addEventListener("model-visibility", (
|
|
1289
|
-
|
|
1365
|
+
}), i.addEventListener("model-visibility", (n) => {
|
|
1366
|
+
n.detail.visible && s?.call(i);
|
|
1290
1367
|
}), i.addEventListener("load", () => {
|
|
1291
|
-
|
|
1368
|
+
o();
|
|
1292
1369
|
}), () => {
|
|
1293
1370
|
r.disable();
|
|
1294
1371
|
};
|
|
@@ -1297,8 +1374,8 @@ function Ce(i) {
|
|
|
1297
1374
|
}
|
|
1298
1375
|
class xt {
|
|
1299
1376
|
_didWarnAboutMissingUrl = !1;
|
|
1300
|
-
onBeforeUpdateLOD(t, e, s,
|
|
1301
|
-
this.tryParseMeshLOD(e,
|
|
1377
|
+
onBeforeUpdateLOD(t, e, s, o) {
|
|
1378
|
+
this.tryParseMeshLOD(e, o), this.tryParseTextureLOD(e, o);
|
|
1302
1379
|
}
|
|
1303
1380
|
getUrl(t) {
|
|
1304
1381
|
if (!t)
|
|
@@ -1315,78 +1392,78 @@ class xt {
|
|
|
1315
1392
|
tryParseTextureLOD(t, e) {
|
|
1316
1393
|
if (e[re] == !0) return;
|
|
1317
1394
|
e[re] = !0;
|
|
1318
|
-
const s = this.tryGetCurrentGLTF(t),
|
|
1395
|
+
const s = this.tryGetCurrentGLTF(t), o = this.tryGetCurrentModelViewer(t), r = this.getUrl(o);
|
|
1319
1396
|
if (r && s && e.material) {
|
|
1320
|
-
let
|
|
1397
|
+
let n = function(a) {
|
|
1321
1398
|
if (a[re] == !0) return;
|
|
1322
1399
|
a[re] = !0, a.userData && (a.userData.LOD = -1);
|
|
1323
1400
|
const u = Object.keys(a);
|
|
1324
|
-
for (let
|
|
1325
|
-
const
|
|
1326
|
-
if (
|
|
1327
|
-
const
|
|
1328
|
-
if (
|
|
1329
|
-
const I = s.parser.json.textures[
|
|
1401
|
+
for (let d = 0; d < u.length; d++) {
|
|
1402
|
+
const y = u[d], w = a[y];
|
|
1403
|
+
if (w?.isTexture === !0) {
|
|
1404
|
+
const _ = w.userData?.associations?.textures;
|
|
1405
|
+
if (_ == null) continue;
|
|
1406
|
+
const I = s.parser.json.textures[_];
|
|
1330
1407
|
if (!I) {
|
|
1331
|
-
console.warn("Texture data not found for texture index " +
|
|
1408
|
+
console.warn("Texture data not found for texture index " + _);
|
|
1332
1409
|
continue;
|
|
1333
1410
|
}
|
|
1334
|
-
if (I?.extensions?.[
|
|
1335
|
-
const
|
|
1336
|
-
|
|
1411
|
+
if (I?.extensions?.[W]) {
|
|
1412
|
+
const M = I.extensions[W];
|
|
1413
|
+
M && r && m.registerTexture(r, w, M.lods.length, _, M);
|
|
1337
1414
|
}
|
|
1338
1415
|
}
|
|
1339
1416
|
}
|
|
1340
1417
|
};
|
|
1341
1418
|
const l = e.material;
|
|
1342
|
-
if (Array.isArray(l)) for (const a of l)
|
|
1343
|
-
else
|
|
1419
|
+
if (Array.isArray(l)) for (const a of l) n(a);
|
|
1420
|
+
else n(l);
|
|
1344
1421
|
}
|
|
1345
1422
|
}
|
|
1346
1423
|
tryParseMeshLOD(t, e) {
|
|
1347
1424
|
if (e[ve] == !0) return;
|
|
1348
1425
|
e[ve] = !0;
|
|
1349
|
-
const s = this.tryGetCurrentModelViewer(t),
|
|
1350
|
-
if (!
|
|
1426
|
+
const s = this.tryGetCurrentModelViewer(t), o = this.getUrl(s);
|
|
1427
|
+
if (!o)
|
|
1351
1428
|
return;
|
|
1352
|
-
const r = e.userData?.gltfExtensions?.[
|
|
1353
|
-
if (r &&
|
|
1354
|
-
const
|
|
1355
|
-
|
|
1429
|
+
const r = e.userData?.gltfExtensions?.[W];
|
|
1430
|
+
if (r && o) {
|
|
1431
|
+
const n = e.uuid;
|
|
1432
|
+
m.registerMesh(o, n, e, 0, r.lods.length, r);
|
|
1356
1433
|
}
|
|
1357
1434
|
}
|
|
1358
1435
|
}
|
|
1359
1436
|
function wt(...i) {
|
|
1360
|
-
let t, e, s,
|
|
1437
|
+
let t, e, s, o;
|
|
1361
1438
|
switch (i.length) {
|
|
1362
1439
|
case 2:
|
|
1363
|
-
[s, e] = i,
|
|
1440
|
+
[s, e] = i, o = {};
|
|
1364
1441
|
break;
|
|
1365
1442
|
case 3:
|
|
1366
|
-
[s, e,
|
|
1443
|
+
[s, e, o] = i;
|
|
1367
1444
|
break;
|
|
1368
1445
|
case 4:
|
|
1369
|
-
[t, e, s,
|
|
1446
|
+
[t, e, s, o] = i;
|
|
1370
1447
|
break;
|
|
1371
1448
|
default:
|
|
1372
1449
|
throw new Error("Invalid arguments");
|
|
1373
1450
|
}
|
|
1374
1451
|
xe(e), Se(s), Te(s, {
|
|
1375
1452
|
progressive: !0,
|
|
1376
|
-
...
|
|
1377
|
-
}), s.register((
|
|
1378
|
-
const r =
|
|
1379
|
-
return
|
|
1453
|
+
...o?.hints
|
|
1454
|
+
}), s.register((n) => new m(n));
|
|
1455
|
+
const r = v.get(e);
|
|
1456
|
+
return o?.enableLODsManager !== !1 && r.enable(), r;
|
|
1380
1457
|
}
|
|
1381
|
-
|
|
1458
|
+
Ie();
|
|
1382
1459
|
if (!rt) {
|
|
1383
1460
|
const i = {
|
|
1384
1461
|
gltfProgressive: {
|
|
1385
1462
|
useNeedleProgressive: wt,
|
|
1386
|
-
LODsManager:
|
|
1463
|
+
LODsManager: v,
|
|
1387
1464
|
configureLoader: Te,
|
|
1388
1465
|
getRaycastMesh: Z,
|
|
1389
|
-
useRaycastMeshes:
|
|
1466
|
+
useRaycastMeshes: nt
|
|
1390
1467
|
}
|
|
1391
1468
|
};
|
|
1392
1469
|
if (!globalThis.Needle)
|
|
@@ -1396,18 +1473,18 @@ if (!rt) {
|
|
|
1396
1473
|
globalThis.Needle[t] = i[t];
|
|
1397
1474
|
}
|
|
1398
1475
|
export {
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1476
|
+
W as EXTENSION_NAME,
|
|
1477
|
+
v as LODsManager,
|
|
1478
|
+
m as NEEDLE_progressive,
|
|
1402
1479
|
je as VERSION,
|
|
1403
1480
|
Se as addDracoAndKTX2Loaders,
|
|
1404
1481
|
Te as configureLoader,
|
|
1405
1482
|
xe as createLoaders,
|
|
1406
1483
|
Z as getRaycastMesh,
|
|
1407
|
-
|
|
1408
|
-
|
|
1484
|
+
Ie as patchModelViewer,
|
|
1485
|
+
ot as registerRaycastMesh,
|
|
1409
1486
|
Qe as setDracoDecoderLocation,
|
|
1410
1487
|
Je as setKTX2TranscoderLocation,
|
|
1411
1488
|
wt as useNeedleProgressive,
|
|
1412
|
-
|
|
1489
|
+
nt as useRaycastMeshes
|
|
1413
1490
|
};
|