@needle-tools/gltf-progressive 1.0.0-alpha.9 → 1.1.0-alpha.1

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.
@@ -1,74 +1,86 @@
1
- var oe = Object.defineProperty;
2
- var ae = (l, e, t) => e in l ? oe(l, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[e] = t;
3
- var u = (l, e, t) => (ae(l, typeof e != "symbol" ? e + "" : e, t), t);
4
- import { Mesh as q, BufferGeometry as X, Material as le, Texture as U, TextureLoader as ue, Matrix4 as j, Frustum as ce, Sphere as fe, Box3 as ee, Vector3 as k } from "three";
5
- import { GLTFLoader as de } from "three/examples/jsm/loaders/GLTFLoader.js";
6
- import { MeshoptDecoder as ge } from "three/examples/jsm/libs/meshopt_decoder.module.js";
7
- import { DRACOLoader as he } from "three/examples/jsm/loaders/DRACOLoader.js";
8
- import { KTX2Loader as pe } from "three/examples/jsm/loaders/KTX2Loader.js";
9
- const ye = "https://www.gstatic.com/draco/versioned/decoders/1.4.1/", me = "https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";
10
- let F, H, W;
11
- function se(l) {
12
- F || (F = new he(), F.setDecoderPath(ye), F.setDecoderConfig({ type: "js" })), W || (W = new pe(), W.setTranscoderPath(me)), H || (H = ge), l ? W.detectSupport(l) : console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail");
1
+ var ge = Object.defineProperty;
2
+ var pe = (a, e, t) => e in a ? ge(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
3
+ var f = (a, e, t) => (pe(a, typeof e != "symbol" ? e + "" : e, t), t);
4
+ import { MeshoptDecoder as ye } from "three/examples/jsm/libs/meshopt_decoder.module.js";
5
+ import { DRACOLoader as me } from "three/examples/jsm/loaders/DRACOLoader.js";
6
+ import { KTX2Loader as Le } from "three/examples/jsm/loaders/KTX2Loader.js";
7
+ import { BufferGeometry as Y, Mesh as V, Material as xe, Texture as N, TextureLoader as De, Matrix4 as ne, Frustum as Me, Sphere as Oe, Box3 as oe, Vector3 as k } from "three";
8
+ import { GLTFLoader as we } from "three/examples/jsm/loaders/GLTFLoader.js";
9
+ let H = "https://www.gstatic.com/draco/versioned/decoders/1.4.1/", se = "https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";
10
+ fetch(H + "draco_decoder.js", { method: "head" }).catch((a) => {
11
+ H = "./include/draco/", se = "./include/ktx2/";
12
+ });
13
+ function Ue(a) {
14
+ H = a;
15
+ }
16
+ function Ne(a) {
17
+ se = a;
13
18
  }
14
- function ie(l) {
15
- l.dracoLoader || l.setDRACOLoader(F), l.ktx2Loader || l.setKTX2Loader(W), l.meshoptDecoder || l.setMeshoptDecoder(H);
19
+ let z, te, W;
20
+ function fe(a) {
21
+ z || (z = new me(), z.setDecoderPath(H), z.setDecoderConfig({ type: "js" })), W || (W = new Le(), W.setTranscoderPath(se)), te || (te = ye), a ? W.detectSupport(a) : console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail");
16
22
  }
17
- function Z(l) {
18
- const t = new URL(window.location.href).searchParams.get(l);
23
+ function ue(a) {
24
+ a.dracoLoader || a.setDRACOLoader(z), a.ktx2Loader || a.setKTX2Loader(W), a.meshoptDecoder || a.setMeshoptDecoder(te);
25
+ }
26
+ function ie(a) {
27
+ const t = new URL(window.location.href).searchParams.get(a);
19
28
  return t == null || t === "0" || t === "false" ? !1 : t === "" ? !0 : t;
20
29
  }
21
- function Le(l, e) {
22
- if (e === void 0 || e.startsWith("./") || e.startsWith("http") || l === void 0)
30
+ function ve(a, e) {
31
+ if (e === void 0 || e.startsWith("./") || e.startsWith("http") || a === void 0)
23
32
  return e;
24
- const t = l.lastIndexOf("/");
33
+ const t = a.lastIndexOf("/");
25
34
  if (t >= 0) {
26
- const r = l.substring(0, t + 1);
35
+ const r = a.substring(0, t + 1);
27
36
  for (; r.endsWith("/") && e.startsWith("/"); )
28
37
  e = e.substring(1);
29
38
  return r + e;
30
39
  }
31
40
  return e;
32
41
  }
33
- const J = new Array();
34
- function _e(l) {
35
- J.push(l);
42
+ function Se(a) {
43
+ var e;
44
+ return ((e = a.userData) == null ? void 0 : e["needle:raycast-mesh"]) instanceof Y ? a.userData["needle:raycast-mesh"] : null;
45
+ }
46
+ function _e(a, e) {
47
+ (a.type === "Mesh" || a.type === "SkinnedMesh") && (a.userData || (a.userData = {}), a.userData["needle:raycast-mesh"] = e);
36
48
  }
37
- const R = "NEEDLE_progressive", S = Z("debugprogressive"), V = Symbol("needle-progressive-texture"), z = /* @__PURE__ */ new Map(), Q = /* @__PURE__ */ new Set();
38
- if (S) {
39
- let l = function() {
40
- e += 1, console.log("Toggle LOD level", e, z), z.forEach((i, n) => {
49
+ const B = new Array(), R = "NEEDLE_progressive", w = ie("debugprogressive"), j = Symbol("needle-progressive-texture"), $ = /* @__PURE__ */ new Map(), re = /* @__PURE__ */ new Set();
50
+ if (w) {
51
+ let a = function() {
52
+ e += 1, console.log("Toggle LOD level", e, $), $.forEach((i, n) => {
41
53
  for (const s of i.keys) {
42
54
  const o = n[s];
43
55
  if (o.isBufferGeometry === !0) {
44
- const a = v.getMeshLODInformation(o), h = a ? Math.min(e, a.lods.length) : 0;
45
- n["DEBUG:LOD"] = e, v.assignMeshLOD(n, h), a && (t = Math.max(t, a.lods.length - 1));
56
+ const l = S.getMeshLODInformation(o), d = l ? Math.min(e, l.lods.length) : 0;
57
+ n["DEBUG:LOD"] = e, S.assignMeshLOD(n, d), l && (t = Math.max(t, l.lods.length - 1));
46
58
  } else if (n.isMaterial === !0) {
47
- n["DEBUG:LOD"] = e, v.assignTextureLOD(n, e);
59
+ n["DEBUG:LOD"] = e, S.assignTextureLOD(n, e);
48
60
  break;
49
61
  }
50
62
  }
51
63
  }), e >= t && (e = -1);
52
64
  }, e = -1, t = 2, r = !1;
53
65
  window.addEventListener("keyup", (i) => {
54
- i.key === "p" && l(), i.key === "w" && (r = !r, Q && Q.forEach((n) => {
66
+ i.key === "p" && a(), i.key === "w" && (r = !r, re && re.forEach((n) => {
55
67
  n.name != "BackgroundCubeMaterial" && "wireframe" in n && (n.wireframe = r);
56
68
  }));
57
69
  });
58
70
  }
59
- function te(l, e, t) {
71
+ function ae(a, e, t) {
60
72
  var i;
61
- if (!S)
73
+ if (!w)
62
74
  return;
63
- z.has(l) || z.set(l, { keys: [], sourceId: t });
64
- const r = z.get(l);
75
+ $.has(a) || $.set(a, { keys: [], sourceId: t });
76
+ const r = $.get(a);
65
77
  ((i = r == null ? void 0 : r.keys) == null ? void 0 : i.includes(e)) == !1 && r.keys.push(e);
66
78
  }
67
- const M = class {
79
+ const v = class {
68
80
  constructor(e, t) {
69
- u(this, "parser");
70
- u(this, "url");
71
- S && console.log("Progressive extension registered for", t), this.parser = e, this.url = t;
81
+ f(this, "parser");
82
+ f(this, "url");
83
+ w && console.log("Progressive extension registered for", t), this.parser = e, this.url = t;
72
84
  }
73
85
  /** The name of the extension */
74
86
  get name() {
@@ -78,6 +90,38 @@ const M = class {
78
90
  const t = this.getAssignedLODInformation(e);
79
91
  return t != null && t.key ? this.lodInfos.get(t.key) : null;
80
92
  }
93
+ static getMaterialMinMaxLODsCount(e, t = { min: 1 / 0, max: -1 }) {
94
+ if (Array.isArray(e)) {
95
+ for (const n of e)
96
+ this.getMaterialMinMaxLODsCount(n, t);
97
+ return t;
98
+ }
99
+ let r = t.min, i = t.max;
100
+ if (e.type === "ShaderMaterial" || e.type === "RawShaderMaterial") {
101
+ const n = e;
102
+ for (const s of Object.keys(n.uniforms)) {
103
+ const o = n.uniforms[s].value;
104
+ if ((o == null ? void 0 : o.isTexture) === !0) {
105
+ const l = this.getAssignedLODInformation(o);
106
+ if (l) {
107
+ const d = this.lodInfos.get(l.key);
108
+ d && d.lods && (r = Math.min(r, d.lods.length), i = Math.max(i, d.lods.length));
109
+ }
110
+ }
111
+ }
112
+ } else if (e.isMaterial)
113
+ for (const n of Object.keys(e)) {
114
+ const s = e[n];
115
+ if ((s == null ? void 0 : s.isTexture) === !0) {
116
+ const o = this.getAssignedLODInformation(s);
117
+ if (o) {
118
+ const l = this.lodInfos.get(o.key);
119
+ l && l.lods && (r = Math.min(r, l.lods.length), i = Math.max(i, l.lods.length));
120
+ }
121
+ }
122
+ }
123
+ return t.min = r, t.max = i, t;
124
+ }
81
125
  /** Check if a LOD level is available for a mesh or a texture
82
126
  * @param obj the mesh or texture to check
83
127
  * @param level the level of detail to check for (0 is the highest resolution). If undefined, the function checks if any LOD level is available
@@ -85,10 +129,16 @@ const M = class {
85
129
  */
86
130
  static hasLODLevelAvailable(e, t) {
87
131
  var n;
132
+ if (Array.isArray(e)) {
133
+ for (const s of e)
134
+ if (this.hasLODLevelAvailable(s, t))
135
+ return !0;
136
+ return !1;
137
+ }
88
138
  if (e.isMaterial === !0) {
89
139
  for (const s of Object.keys(e)) {
90
140
  const o = e[s];
91
- if (o.isTexture && this.hasLODLevelAvailable(o, t))
141
+ if (o && o.isTexture && this.hasLODLevelAvailable(o, t))
92
142
  return !0;
93
143
  }
94
144
  return !1;
@@ -125,24 +175,24 @@ const M = class {
125
175
  var r;
126
176
  if (!e)
127
177
  return Promise.resolve(null);
128
- if (e instanceof q || e.isMesh === !0) {
178
+ if (e instanceof V || e.isMesh === !0) {
129
179
  const i = e.geometry, n = this.getAssignedLODInformation(i);
130
180
  if (!n)
131
181
  return Promise.resolve(null);
132
- for (const s of J)
182
+ for (const s of B)
133
183
  (r = s.onBeforeGetLODMesh) == null || r.call(s, e, t);
134
- return e["LOD:requested level"] = t, M.getOrLoadLOD(i, t).then((s) => {
184
+ return e["LOD:requested level"] = t, v.getOrLoadLOD(i, t).then((s) => {
135
185
  if (e["LOD:requested level"] === t) {
136
186
  if (delete e["LOD:requested level"], Array.isArray(s)) {
137
187
  const o = n.index || 0;
138
188
  s = s[o];
139
189
  }
140
- s && i != s && s instanceof X && (e.geometry = s, S && te(e, "geometry", n.url));
190
+ s && i != s && s instanceof Y && (e.geometry = s, w && ae(e, "geometry", n.url));
141
191
  }
142
192
  return s;
143
193
  }).catch((s) => (console.error("Error loading mesh LOD", e, s), null));
144
194
  } else
145
- S && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", e);
195
+ w && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", e);
146
196
  return Promise.resolve(null);
147
197
  }
148
198
  /** Load a different resolution of a texture (if available)
@@ -155,66 +205,71 @@ const M = class {
155
205
  static assignTextureLOD(e, t = 0) {
156
206
  if (!e)
157
207
  return Promise.resolve(null);
158
- if (e instanceof le || e.isMaterial === !0) {
208
+ if (e instanceof xe || e.isMaterial === !0) {
159
209
  const r = e, i = [], n = new Array();
160
- if (S && Q.add(r), r.uniforms && r.isRawShaderMaterial || r.isShaderMaterial === !0) {
210
+ if (w && re.add(r), r.uniforms && r.isRawShaderMaterial || r.isShaderMaterial === !0) {
161
211
  const s = r;
162
212
  for (const o of Object.keys(s.uniforms)) {
163
- const a = s.uniforms[o].value;
164
- if ((a == null ? void 0 : a.isTexture) === !0) {
165
- const h = this.assignTextureLODForSlot(a, t, r, o);
166
- i.push(h), n.push(o);
213
+ const l = s.uniforms[o].value;
214
+ if ((l == null ? void 0 : l.isTexture) === !0) {
215
+ const d = this.assignTextureLODForSlot(l, t, r, o);
216
+ i.push(d), n.push(o);
167
217
  }
168
218
  }
169
219
  } else
170
220
  for (const s of Object.keys(r)) {
171
221
  const o = r[s];
172
222
  if ((o == null ? void 0 : o.isTexture) === !0) {
173
- const a = this.assignTextureLODForSlot(o, t, r, s);
174
- i.push(a), n.push(s);
223
+ const l = this.assignTextureLODForSlot(o, t, r, s);
224
+ i.push(l), n.push(s);
175
225
  }
176
226
  }
177
227
  return Promise.all(i).then((s) => {
178
228
  const o = new Array();
179
- for (let a = 0; a < s.length; a++) {
180
- const h = s[a], d = n[a];
181
- h && h.isTexture === !0 ? o.push({ material: r, slot: d, texture: h, level: t }) : o.push({ material: r, slot: d, texture: null, level: t });
229
+ for (let l = 0; l < s.length; l++) {
230
+ const d = s[l], h = n[l];
231
+ d && d.isTexture === !0 ? o.push({ material: r, slot: h, texture: d, level: t }) : o.push({ material: r, slot: h, texture: null, level: t });
182
232
  }
183
233
  return o;
184
234
  });
185
235
  }
186
- if (e instanceof U || e.isTexture === !0) {
236
+ if (e instanceof N || e.isTexture === !0) {
187
237
  const r = e;
188
238
  return this.assignTextureLODForSlot(r, t, null, null);
189
239
  }
190
240
  return Promise.resolve(null);
191
241
  }
192
242
  static assignTextureLODForSlot(e, t, r, i) {
193
- return (e == null ? void 0 : e.isTexture) !== !0 ? Promise.resolve(null) : M.getOrLoadLOD(e, t).then((n) => {
194
- if (Array.isArray(n))
243
+ if ((e == null ? void 0 : e.isTexture) !== !0)
244
+ return Promise.resolve(null);
245
+ if (i === "glyphMap")
246
+ return Promise.resolve(e);
247
+ const n = "LOD:requested level:" + i;
248
+ return r && (r[n] = t), v.getOrLoadLOD(e, t).then((s) => {
249
+ if (r && r[n] != t || Array.isArray(s))
195
250
  return null;
196
- if ((n == null ? void 0 : n.isTexture) === !0) {
197
- if (n != e && (r && i && (r[i] = n), S && i && r)) {
198
- const s = this.getAssignedLODInformation(e);
199
- s && te(r, i, s.url);
251
+ if ((s == null ? void 0 : s.isTexture) === !0) {
252
+ if (s != e && (r && i && (r[i] = s), w && i && r)) {
253
+ const o = this.getAssignedLODInformation(e);
254
+ o && ae(r, i, o.url);
200
255
  }
201
- return n;
256
+ return s;
202
257
  } else
203
- S == "verbose" && console.warn("No LOD found for", e, t);
258
+ w == "verbose" && console.warn("No LOD found for", e, t);
204
259
  return null;
205
- }).catch((n) => (console.error("Error loading LOD", e, n), null));
260
+ }).catch((s) => (console.error("Error loading LOD", e, s), null));
206
261
  }
207
262
  afterRoot(e) {
208
263
  var t, r;
209
- return S && console.log("AFTER", this.url, e), (t = this.parser.json.textures) == null || t.forEach((i, n) => {
264
+ return w && console.log("AFTER", this.url, e), (t = this.parser.json.textures) == null || t.forEach((i, n) => {
210
265
  if (i != null && i.extensions) {
211
266
  const s = i == null ? void 0 : i.extensions[R];
212
267
  if (s) {
213
268
  let o = !1;
214
- for (const a of this.parser.associations.keys())
215
- a.isTexture === !0 && this.parser.associations.get(a).textures === n && (o = !0, M.registerTexture(this.url, a, n, s));
216
- o || this.parser.getDependency("texture", n).then((a) => {
217
- a && M.registerTexture(this.url, a, n, s);
269
+ for (const l of this.parser.associations.keys())
270
+ l.isTexture === !0 && this.parser.associations.get(l).textures === n && (o = !0, v.registerTexture(this.url, l, n, s));
271
+ o || this.parser.getDependency("texture", n).then((l) => {
272
+ l && v.registerTexture(this.url, l, n, s);
218
273
  });
219
274
  }
220
275
  }
@@ -224,195 +279,205 @@ const M = class {
224
279
  if (s && s.lods) {
225
280
  for (const o of this.parser.associations.keys())
226
281
  if (o.isMesh) {
227
- const a = this.parser.associations.get(o);
228
- a.meshes === n && M.registerMesh(this.url, s.guid, o, s.lods.length, a.primitives, s);
282
+ const l = this.parser.associations.get(o);
283
+ l.meshes === n && v.registerMesh(this.url, s.guid, o, s.lods.length, l.primitives, s);
229
284
  }
230
285
  }
231
286
  }
232
287
  }), null;
233
288
  }
234
289
  static async getOrLoadLOD(e, t) {
235
- var o, a, h;
236
- const r = S == "verbose", i = e.userData.LODS;
290
+ var o, l, d, h;
291
+ const r = w == "verbose", i = e.userData.LODS;
237
292
  if (!i)
238
293
  return null;
239
294
  const n = i == null ? void 0 : i.key;
240
295
  let s;
241
296
  if (e.isTexture === !0) {
242
- const d = e;
243
- d.source && d.source[V] && (s = d.source[V]);
297
+ const m = e;
298
+ m.source && m.source[j] && (s = m.source[j]);
244
299
  }
245
- if (s || (s = M.lodInfos.get(n)), s) {
300
+ if (s || (s = v.lodInfos.get(n)), s) {
246
301
  if (t > 0) {
247
- let f = !1;
248
- const w = Array.isArray(s.lods);
249
- if (w && t >= s.lods.length ? f = !0 : w || (f = !0), f)
302
+ let y = !1;
303
+ const x = Array.isArray(s.lods);
304
+ if (x && t >= s.lods.length ? y = !0 : x || (y = !0), y)
250
305
  return this.lowresCache.get(n);
251
306
  }
252
- const d = Array.isArray(s.lods) ? s.lods[t].path : s.lods;
253
- if (!d)
254
- return S && !s["missing:uri"] && (s["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + t, s)), null;
255
- const c = Le(i.url, d);
256
- if (c.endsWith(".glb") || c.endsWith(".gltf")) {
307
+ const m = Array.isArray(s.lods) ? (o = s.lods[t]) == null ? void 0 : o.path : s.lods;
308
+ if (!m)
309
+ return w && !s["missing:uri"] && (s["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + t, s)), null;
310
+ const u = ve(i.url, m);
311
+ if (u.endsWith(".glb") || u.endsWith(".gltf")) {
257
312
  if (!s.guid)
258
313
  return console.warn("missing pointer for glb/gltf texture", s), null;
259
- const f = c + "_" + s.guid, w = this.previouslyLoaded.get(f);
260
- if (w !== void 0) {
261
- r && console.log(`LOD ${t} was already loading/loaded: ${f}`);
262
- let D = await w.catch((I) => (console.error(`Error loading LOD ${t} from ${c}
263
- `, I), null)), C = !1;
264
- if (D == null || (D instanceof U && e instanceof U ? (o = D.image) != null && o.data || (a = D.source) != null && a.data ? D = this.copySettings(e, D) : (C = !0, this.previouslyLoaded.delete(f)) : D instanceof X && e instanceof X && ((h = D.attributes.position) != null && h.array || (C = !0, this.previouslyLoaded.delete(f)))), !C)
265
- return D;
314
+ const y = u + "_" + s.guid, x = this.previouslyLoaded.get(y);
315
+ if (x !== void 0) {
316
+ r && console.log(`LOD ${t} was already loading/loaded: ${y}`);
317
+ let O = await x.catch((F) => (console.error(`Error loading LOD ${t} from ${u}
318
+ `, F), null)), P = !1;
319
+ if (O == null || (O instanceof N && e instanceof N ? (l = O.image) != null && l.data || (d = O.source) != null && d.data ? O = this.copySettings(e, O) : (P = !0, this.previouslyLoaded.delete(y)) : O instanceof Y && e instanceof Y && ((h = O.attributes.position) != null && h.array || (P = !0, this.previouslyLoaded.delete(y)))), !P)
320
+ return O;
266
321
  }
267
- const L = s, A = new Promise(async (D, C) => {
268
- const I = new de();
269
- ie(I), S && (await new Promise((y) => setTimeout(y, 1e3)), r && console.warn("Start loading (delayed) " + c, L.guid));
270
- let m = c;
271
- if (L && Array.isArray(L.lods)) {
272
- const y = L.lods[t];
273
- y.hash && (m += "?v=" + y.hash);
322
+ const M = s, D = new Promise(async (O, P) => {
323
+ const F = new we();
324
+ ue(F), w && (await new Promise((g) => setTimeout(g, 1e3)), r && console.warn("Start loading (delayed) " + u, M.guid));
325
+ let J = u;
326
+ if (M && Array.isArray(M.lods)) {
327
+ const g = M.lods[t];
328
+ g.hash && (J += "?v=" + g.hash);
274
329
  }
275
- const p = await I.loadAsync(m).catch((y) => (console.error(`Error loading LOD ${t} from ${c}
276
- `, y), null));
277
- if (!p)
330
+ const E = await F.loadAsync(J).catch((g) => (console.error(`Error loading LOD ${t} from ${u}
331
+ `, g), null));
332
+ if (!E)
278
333
  return null;
279
- const b = p.parser;
280
- r && console.log("Loading finished " + c, L.guid);
281
- let x = 0;
282
- if (p.parser.json.textures) {
283
- let y = !1;
284
- for (const g of p.parser.json.textures) {
285
- if (g != null && g.extensions) {
286
- const O = g == null ? void 0 : g.extensions[R];
287
- if (O != null && O.guid && O.guid === L.guid) {
288
- y = !0;
334
+ const Q = E.parser;
335
+ r && console.log("Loading finished " + u, M.guid);
336
+ let p = 0;
337
+ if (E.parser.json.textures) {
338
+ let g = !1;
339
+ for (const c of E.parser.json.textures) {
340
+ if (c != null && c.extensions) {
341
+ const L = c == null ? void 0 : c.extensions[R];
342
+ if (L != null && L.guid && L.guid === M.guid) {
343
+ g = !0;
289
344
  break;
290
345
  }
291
346
  }
292
- x++;
293
- }
294
- if (y) {
295
- let g = await b.getDependency("texture", x);
296
- return r && console.log('change "' + e.name + '" → "' + g.name + '"', c, x, g, f), e instanceof U && (g = this.copySettings(e, g)), g && (g.guid = L.guid), D(g);
347
+ p++;
297
348
  }
349
+ if (g) {
350
+ let c = await Q.getDependency("texture", p);
351
+ return c && v.assignLODInformation(i.url, c, n, t, void 0, void 0), r && console.log('change "' + e.name + '" → "' + c.name + '"', u, p, c, y), e instanceof N && (c = this.copySettings(e, c)), c && (c.guid = M.guid), O(c);
352
+ } else
353
+ w && console.warn("Could not find texture with guid", M.guid);
298
354
  }
299
- if (x = 0, p.parser.json.meshes) {
300
- let y = !1;
301
- for (const g of p.parser.json.meshes) {
302
- if (g != null && g.extensions) {
303
- const O = g == null ? void 0 : g.extensions[R];
304
- if (O != null && O.guid && O.guid === L.guid) {
305
- y = !0;
355
+ if (p = 0, E.parser.json.meshes) {
356
+ let g = !1;
357
+ for (const c of E.parser.json.meshes) {
358
+ if (c != null && c.extensions) {
359
+ const L = c == null ? void 0 : c.extensions[R];
360
+ if (L != null && L.guid && L.guid === M.guid) {
361
+ g = !0;
306
362
  break;
307
363
  }
308
364
  }
309
- x++;
365
+ p++;
310
366
  }
311
- if (y) {
312
- const g = await b.getDependency("mesh", x), O = L;
313
- if (r && console.log(`Loaded Mesh "${g.name}"`, c, x, g, f), g.isMesh === !0) {
314
- const P = g.geometry;
315
- return M.assignLODInformation(i.url, P, n, t, void 0, O.density), D(P);
367
+ if (g) {
368
+ const c = await Q.getDependency("mesh", p), L = M;
369
+ if (r && console.log(`Loaded Mesh "${c.name}"`, u, p, c, y), c.isMesh === !0) {
370
+ const _ = c.geometry;
371
+ return v.assignLODInformation(i.url, _, n, t, void 0, L.density), O(_);
316
372
  } else {
317
- const P = new Array();
318
- for (let _ = 0; _ < g.children.length; _++) {
319
- const E = g.children[_];
320
- if (E instanceof q) {
321
- const N = E.geometry;
322
- M.assignLODInformation(i.url, N, n, t, _, O.density), P.push(N);
373
+ const _ = new Array();
374
+ for (let C = 0; C < c.children.length; C++) {
375
+ const I = c.children[C];
376
+ if (I instanceof V) {
377
+ const U = I.geometry;
378
+ v.assignLODInformation(i.url, U, n, t, C, L.density), _.push(U);
323
379
  }
324
380
  }
325
- return D(P);
381
+ return O(_);
326
382
  }
327
383
  }
328
384
  }
329
- return D(null);
385
+ return O(null);
330
386
  });
331
- return this.previouslyLoaded.set(f, A), await A;
332
- } else if (e instanceof U) {
333
- r && console.log("Load texture from uri: " + c);
334
- const w = await new ue().loadAsync(c);
335
- return w ? (w.guid = s.guid, w.flipY = !1, w.needsUpdate = !0, w.colorSpace = e.colorSpace, r && console.log(s, w)) : S && console.warn("failed loading", c), w;
387
+ return this.previouslyLoaded.set(y, D), await D;
388
+ } else if (e instanceof N) {
389
+ r && console.log("Load texture from uri: " + u);
390
+ const x = await new De().loadAsync(u);
391
+ return x ? (x.guid = s.guid, x.flipY = !1, x.needsUpdate = !0, x.colorSpace = e.colorSpace, r && console.log(s, x)) : w && console.warn("failed loading", u), x;
336
392
  }
337
393
  } else
338
- S && console.warn(`Can not load LOD ${t}: no LOD info found for "${n}" ${e.name}`, e.type);
394
+ w && console.warn(`Can not load LOD ${t}: no LOD info found for "${n}" ${e.name}`, e.type);
339
395
  return null;
340
396
  }
341
397
  static assignLODInformation(e, t, r, i, n, s) {
342
398
  if (!t)
343
399
  return;
344
400
  t.userData || (t.userData = {});
345
- const o = new De(e, r, i, n, s);
401
+ const o = new Te(e, r, i, n, s);
346
402
  t.userData.LODS = o, t.userData.LOD = i;
347
403
  }
348
404
  static getAssignedLODInformation(e) {
349
405
  var t;
350
406
  return ((t = e == null ? void 0 : e.userData) == null ? void 0 : t.LODS) || null;
351
407
  }
408
+ // private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
352
409
  static copySettings(e, t) {
353
- const r = this._copiedTextures.get(e);
354
- return r || (t = t.clone(), this._copiedTextures.set(e, t), t.offset = e.offset, t.repeat = e.repeat, t.colorSpace = e.colorSpace, t);
410
+ return t = t.clone(), w && console.warn(`Copying texture settings
411
+ `, e.uuid, `
412
+ `, t.uuid), t.offset = e.offset, t.repeat = e.repeat, t.colorSpace = e.colorSpace, t.magFilter = e.magFilter, t.minFilter = e.minFilter, t.wrapS = e.wrapS, t.wrapT = e.wrapT, t.flipY = e.flipY, t.anisotropy = e.anisotropy, t.mipmaps || (t.generateMipmaps = e.generateMipmaps), t;
355
413
  }
356
414
  };
357
- let v = M;
415
+ let S = v;
358
416
  /**
359
417
  * Register a texture with LOD information
360
418
  */
361
- u(v, "registerTexture", (e, t, r, i) => {
362
- S && console.log("> Progressive: register texture", r, t.name, t.uuid, t, i), t.source && (t.source[V] = i);
419
+ f(S, "registerTexture", (e, t, r, i) => {
420
+ w && console.log("> Progressive: register texture", r, t.name, t.uuid, t, i), t.source && (t.source[j] = i);
363
421
  const n = i.guid;
364
- M.assignLODInformation(e, t, n, 0, 0, void 0), M.lodInfos.set(n, i), M.lowresCache.set(n, t);
422
+ v.assignLODInformation(e, t, n, 0, 0, void 0), v.lodInfos.set(n, i), v.lowresCache.set(n, t);
365
423
  }), /**
366
424
  * Register a mesh with LOD information
367
425
  */
368
- u(v, "registerMesh", (e, t, r, i, n, s) => {
369
- var h;
370
- S && console.log("> Progressive: register mesh", n, r.name, s, r.uuid, r);
426
+ f(S, "registerMesh", (e, t, r, i, n, s) => {
427
+ var d;
428
+ w && console.log("> Progressive: register mesh", n, r.name, s, r.uuid, r);
371
429
  const o = r.geometry;
372
- o.userData || (o.userData = {}), M.assignLODInformation(e, o, t, i, n, s.density), M.lodInfos.set(t, s);
373
- let a = M.lowresCache.get(t);
374
- a ? a.push(r.geometry) : a = [r.geometry], M.lowresCache.set(t, a);
375
- for (const d of J)
376
- (h = d.onRegisteredNewMesh) == null || h.call(d, r, s);
430
+ o.userData || (o.userData = {}), v.assignLODInformation(e, o, t, i, n, s.density), v.lodInfos.set(t, s);
431
+ let l = v.lowresCache.get(t);
432
+ l ? l.push(r.geometry) : l = [r.geometry], v.lowresCache.set(t, l), i > 0 && !Se(r) && _e(r, o);
433
+ for (const h of B)
434
+ (d = h.onRegisteredNewMesh) == null || d.call(h, r, s);
377
435
  }), /** A map of key = asset uuid and value = LOD information */
378
- u(v, "lodInfos", /* @__PURE__ */ new Map()), /** cache of already loaded mesh lods */
379
- u(v, "previouslyLoaded", /* @__PURE__ */ new Map()), /** this contains the geometry/textures that were originally loaded */
380
- u(v, "lowresCache", /* @__PURE__ */ new Map()), u(v, "_copiedTextures", /* @__PURE__ */ new Map());
381
- class De {
436
+ f(S, "lodInfos", /* @__PURE__ */ new Map()), /** cache of already loaded mesh lods */
437
+ f(S, "previouslyLoaded", /* @__PURE__ */ new Map()), /** this contains the geometry/textures that were originally loaded */
438
+ f(S, "lowresCache", /* @__PURE__ */ new Map());
439
+ class Te {
382
440
  constructor(e, t, r, i, n) {
383
- u(this, "url");
441
+ f(this, "url");
384
442
  /** the key to lookup the LOD information */
385
- u(this, "key");
386
- u(this, "level");
443
+ f(this, "key");
444
+ f(this, "level");
387
445
  /** For multi objects (e.g. a group of meshes) this is the index of the object */
388
- u(this, "index");
446
+ f(this, "index");
389
447
  /** the mesh density */
390
- u(this, "density");
448
+ f(this, "density");
391
449
  this.url = e, this.key = t, this.level = r, i != null && (this.index = i), n != null && (this.density = n);
392
450
  }
393
451
  }
394
- const Y = Z("debugprogressive"), xe = Z("noprogressive"), T = class {
452
+ const ee = ie("debugprogressive"), Ae = ie("noprogressive"), le = Symbol("Needle:LODSManager"), A = { mesh_lod: -1, texture_lod: -1 }, T = class {
453
+ // readonly plugins: NEEDLE_progressive_plugin[] = [];
395
454
  constructor(e) {
396
- u(this, "renderer");
397
- u(this, "projectionScreenMatrix", new j());
398
- u(this, "cameraFrustrum", new ce());
455
+ f(this, "renderer");
456
+ f(this, "projectionScreenMatrix", new ne());
457
+ f(this, "cameraFrustrum", new Me());
458
+ /**
459
+ * The target triangle density is the desired max amount of triangles on screen when the mesh is filling the screen.
460
+ * @default 200_000
461
+ */
462
+ f(this, "targetTriangleDensity", 2e5);
399
463
  /**
400
464
  * The update interval in frames. If set to 0, the LODs will be updated every frame. If set to 1, the LODs will be updated every second frame, etc.
401
465
  */
402
- u(this, "updateInterval", 0);
466
+ f(this, "updateInterval", 0);
403
467
  /**
404
468
  * If set to true, the LODsManager will not update the LODs.
405
469
  */
406
- u(this, "pause", !1);
407
- u(this, "plugins", []);
408
- u(this, "_originalRender");
470
+ f(this, "pause", !1);
471
+ f(this, "_frame", 0);
472
+ f(this, "_originalRender");
409
473
  // private testIfLODLevelsAreAvailable() {
410
- u(this, "_sphere", new fe());
411
- u(this, "_tempBox", new ee());
412
- u(this, "tempMatrix", new j());
413
- u(this, "_tempWorldPosition", new k());
414
- u(this, "_tempBoxSize", new k());
415
- u(this, "_tempBox2Size", new k());
474
+ f(this, "_sphere", new Oe());
475
+ f(this, "_tempBox", new oe());
476
+ f(this, "_tempBox2", new oe());
477
+ f(this, "tempMatrix", new ne());
478
+ f(this, "_tempWorldPosition", new k());
479
+ f(this, "_tempBoxSize", new k());
480
+ f(this, "_tempBox2Size", new k());
416
481
  this.renderer = e;
417
482
  }
418
483
  /** @internal */
@@ -420,6 +485,25 @@ const Y = Z("debugprogressive"), xe = Z("noprogressive"), T = class {
420
485
  var t;
421
486
  return (t = e.userData) == null ? void 0 : t.LOD_state;
422
487
  }
488
+ static addPlugin(e) {
489
+ B.push(e);
490
+ }
491
+ static removePlugin(e) {
492
+ const t = B.indexOf(e);
493
+ t >= 0 && B.splice(t, 1);
494
+ }
495
+ /**
496
+ * Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
497
+ * @param renderer The renderer to get the LODsManager for.
498
+ * @returns The LODsManager instance.
499
+ */
500
+ static get(e) {
501
+ return e[le] ? e[le] : new T(e);
502
+ }
503
+ /** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
504
+ get plugins() {
505
+ return B;
506
+ }
423
507
  /**
424
508
  * Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
425
509
  */
@@ -429,10 +513,10 @@ const Y = Z("debugprogressive"), xe = Z("noprogressive"), T = class {
429
513
  let e = 0;
430
514
  this._originalRender = this.renderer.render;
431
515
  const t = this;
432
- let r = 0;
433
- se(this.renderer), this.renderer.render = function(i, n) {
434
- const s = r++, o = e++;
435
- t.onBeforeRender(i, n, o, s), t._originalRender.call(this, i, n), t.onAfterRender(i, n, o, s), e--;
516
+ fe(this.renderer), this.renderer.render = function(r, i) {
517
+ t.renderer.getRenderTarget() == null && (e = 0, t._frame += 1);
518
+ const s = t._frame, o = e++;
519
+ t.onBeforeRender(r, i, o, s), t._originalRender.call(this, r, i), t.onAfterRender(r, i, o, s);
436
520
  };
437
521
  }
438
522
  disable() {
@@ -441,46 +525,61 @@ const Y = Z("debugprogressive"), xe = Z("noprogressive"), T = class {
441
525
  onBeforeRender(e, t, r, i) {
442
526
  }
443
527
  onAfterRender(e, t, r, i) {
444
- var h, d;
445
- if (xe || this.pause || this.updateInterval > 0 && i % this.updateInterval != 0)
528
+ var l, d;
529
+ if (this.pause)
446
530
  return;
447
- this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix, t.matrixWorldInverse), this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix, this.renderer.coordinateSystem);
448
- const n = 1e5, s = this.renderer.renderLists.get(e, r), o = s.opaque;
449
- for (const c of o) {
450
- if (c.material && (((h = c.geometry) == null ? void 0 : h.type) === "BoxGeometry" || ((d = c.geometry) == null ? void 0 : d.type) === "BufferGeometry") && (c.material.name === "SphericalGaussianBlur" || c.material.name == "BackgroundCubeMaterial" || c.material.name === "CubemapFromEquirect" || c.material.name === "EquirectangularToCubeUV")) {
451
- Y && (c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] || (c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] = !0, console.warn("Ignoring skybox or BLIT object", c, c.material.name, c.material.type)));
452
- continue;
453
- }
454
- const f = c.object;
455
- (f instanceof q || f.isMesh) && this.updateLODs(e, t, f, n);
531
+ const n = this.renderer.renderLists.get(e, 0), s = n.opaque;
532
+ let o = !0;
533
+ if (s.length === 1) {
534
+ const h = s[0].material;
535
+ (h.name === "EffectMaterial" || h.name === "CopyShader") && (o = !1);
456
536
  }
457
- const a = s.transparent;
458
- for (const c of a) {
459
- const f = c.object;
460
- (f instanceof q || f.isMesh) && this.updateLODs(e, t, f, n);
537
+ if (t.parent && t.parent.type === "CubeCamera" && (o = !1), o) {
538
+ if (Ae || this.updateInterval > 0 && i % this.updateInterval != 0)
539
+ return;
540
+ this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix, t.matrixWorldInverse), this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix, this.renderer.coordinateSystem);
541
+ const h = this.targetTriangleDensity;
542
+ for (const u of s) {
543
+ if (u.material && (((l = u.geometry) == null ? void 0 : l.type) === "BoxGeometry" || ((d = u.geometry) == null ? void 0 : d.type) === "BufferGeometry") && (u.material.name === "SphericalGaussianBlur" || u.material.name == "BackgroundCubeMaterial" || u.material.name === "CubemapFromEquirect" || u.material.name === "EquirectangularToCubeUV")) {
544
+ ee && (u.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] || (u.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"] = !0, console.warn("Ignoring skybox or BLIT object", u, u.material.name, u.material.type)));
545
+ continue;
546
+ }
547
+ switch (u.material.type) {
548
+ case "LineBasicMaterial":
549
+ case "LineDashedMaterial":
550
+ case "PointsMaterial":
551
+ case "ShadowMaterial":
552
+ case "MeshDistanceMaterial":
553
+ case "MeshDepthMaterial":
554
+ continue;
555
+ }
556
+ const y = u.object;
557
+ (y instanceof V || y.isMesh) && this.updateLODs(e, t, y, h, i);
558
+ }
559
+ const m = n.transparent;
560
+ for (const u of m) {
561
+ const y = u.object;
562
+ (y instanceof V || y.isMesh) && this.updateLODs(e, t, y, h, i);
563
+ }
461
564
  }
462
565
  }
463
566
  /** Update the LOD levels for the renderer. */
464
- updateLODs(e, t, r, i) {
465
- var a, h;
466
- for (const d of this.plugins)
467
- (a = d.onBeforeUpdateLOD) == null || a.call(d, this.renderer, e, t, r);
468
- let n = r.userData.LOD_state;
469
- n || (n = new we(), r.userData.LOD_state = n);
470
- let s = this.calculateLodLevel(t, r, n, i);
471
- s = Math.round(s), s >= 0 && this.loadProgressiveMeshes(r, s);
472
- let o = 0;
473
- if (r.material) {
474
- const d = r["DEBUG:LOD"];
475
- if (d != null && (o = d), Array.isArray(r.material))
476
- for (const c of r.material)
477
- this.loadProgressiveTextures(c, o);
478
- else
479
- this.loadProgressiveTextures(r.material, o);
567
+ updateLODs(e, t, r, i, n) {
568
+ var l, d;
569
+ let s = r.userData.LOD_state;
570
+ if (s || (s = new Pe(), r.userData.LOD_state = s), s.frames++ < 2)
571
+ return;
572
+ for (const h of B)
573
+ (l = h.onBeforeUpdateLOD) == null || l.call(h, this.renderer, e, t, r);
574
+ this.calculateLodLevel(t, r, s, i, A), A.mesh_lod = Math.round(A.mesh_lod), A.texture_lod = Math.round(A.texture_lod), A.mesh_lod >= 0 && this.loadProgressiveMeshes(r, A.mesh_lod);
575
+ let o = A.texture_lod;
576
+ if (r.material && o >= 0) {
577
+ const h = r["DEBUG:LOD"];
578
+ h != null && (o = h), this.loadProgressiveTextures(r.material, o);
480
579
  }
481
- for (const d of this.plugins)
482
- (h = d.onAfterUpdatedLOD) == null || h.call(d, this.renderer, e, t, r, s);
483
- n.lastLodLevel = s;
580
+ for (const h of B)
581
+ (d = h.onAfterUpdatedLOD) == null || d.call(h, this.renderer, e, t, r, A);
582
+ s.lastLodLevel_Mesh = A.mesh_lod, s.lasLodLevel_Texture = A.texture_lod;
484
583
  }
485
584
  /** Load progressive textures for the given material
486
585
  * @param material the material to load the textures for
@@ -488,7 +587,16 @@ const Y = Z("debugprogressive"), xe = Z("noprogressive"), T = class {
488
587
  * @returns Promise with true if the LOD was loaded, false if not
489
588
  */
490
589
  loadProgressiveTextures(e, t) {
491
- return e && e.userData && e.userData.LOD !== t ? (e.userData.LOD = t, v.assignTextureLOD(e, t)) : Promise.resolve(null);
590
+ if (!e)
591
+ return;
592
+ if (Array.isArray(e)) {
593
+ for (const n of e)
594
+ this.loadProgressiveTextures(n, t);
595
+ return;
596
+ }
597
+ const r = e;
598
+ let i = !1;
599
+ (r.NEEDLE_LOD == null || t < r.NEEDLE_LOD) && (i = !0), i && (r.NEEDLE_LOD = t, S.assignTextureLOD(e, t));
492
600
  }
493
601
  /** Load progressive meshes for the given mesh
494
602
  * @param mesh the mesh to load the LOD for
@@ -502,91 +610,120 @@ const Y = Z("debugprogressive"), xe = Z("noprogressive"), T = class {
502
610
  if (e.userData || (e.userData = {}), e.userData.LOD !== t) {
503
611
  e.userData.LOD = t;
504
612
  const r = e.geometry;
505
- return v.assignMeshLOD(e, t).then((i) => (i && e.userData.LOD == t && r != e.geometry, i));
613
+ return S.assignMeshLOD(e, t).then((i) => (i && e.userData.LOD == t && r != e.geometry, i));
506
614
  }
507
615
  return Promise.resolve(null);
508
616
  }
509
- calculateLodLevel(e, t, r, i) {
510
- var o;
511
- if (!t)
512
- return -1;
513
- let s = 10 + 1;
514
- if (e) {
515
- if (Y && t["DEBUG:LOD"] != null)
516
- return t["DEBUG:LOD"];
517
- const a = v.getMeshLODInformation(t.geometry), h = a == null ? void 0 : a.lods;
518
- if (!h || h.length <= 0 || !((o = this.cameraFrustrum) != null && o.intersectsObject(t)))
519
- return 99;
520
- const d = t.geometry.boundingBox;
521
- if (d && e.isPerspectiveCamera) {
522
- const c = e;
523
- if (t.geometry.attributes.color && t.geometry.attributes.color.count < 100 && t.geometry.boundingSphere) {
524
- this._sphere.copy(t.geometry.boundingSphere), this._sphere.applyMatrix4(t.matrixWorld);
525
- const m = e.getWorldPosition(this._tempWorldPosition);
526
- if (this._sphere.containsPoint(m))
527
- return 0;
528
- }
529
- if (this._tempBox.copy(d), this._tempBox.applyMatrix4(t.matrixWorld), this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && c.fov > 70) {
530
- const m = this._tempBox.min, p = this._tempBox.max;
531
- let b = m.x, x = m.y, y = p.x, g = p.y;
532
- const O = 2, P = 1.5, _ = (m.x + p.x) * 0.5, E = (m.y + p.y) * 0.5;
533
- b = (b - _) * O + _, x = (x - E) * O + E, y = (y - _) * O + _, g = (g - E) * O + E;
534
- const N = b < 0 && y > 0 ? 0 : Math.min(Math.abs(m.x), Math.abs(p.x)), ne = x < 0 && g > 0 ? 0 : Math.min(Math.abs(m.y), Math.abs(p.y)), K = Math.max(N, ne);
535
- r.lastCentrality = (P - K) * (P - K) * (P - K);
536
- } else
537
- r.lastCentrality = 1;
538
- const f = this._tempBox.getSize(this._tempBoxSize);
539
- f.multiplyScalar(0.5), screen.availHeight > 0 && f.multiplyScalar(this.renderer.domElement.clientHeight / screen.availHeight), f.x *= c.aspect;
540
- const w = e.matrixWorldInverse, L = new ee();
541
- L.copy(d), L.applyMatrix4(t.matrixWorld), L.applyMatrix4(w);
542
- const A = L.getSize(this._tempBox2Size), G = Math.max(A.x, A.y);
543
- if (Math.max(f.x, f.y) != 0 && G != 0 && (f.z = A.z / Math.max(A.x, A.y) * Math.max(f.x, f.y)), r.lastScreenCoverage = Math.max(f.x, f.y, f.z), r.lastScreenspaceVolume.copy(f), r.lastScreenCoverage *= r.lastCentrality, Y && T.debugDrawLine) {
544
- const m = this.tempMatrix.copy(this.projectionScreenMatrix);
545
- m.invert();
546
- const p = T.corner0, b = T.corner1, x = T.corner2, y = T.corner3;
547
- p.copy(this._tempBox.min), b.copy(this._tempBox.max), b.x = p.x, x.copy(this._tempBox.max), x.y = p.y, y.copy(this._tempBox.max);
548
- const g = (p.z + y.z) * 0.5;
549
- p.z = b.z = x.z = y.z = g, p.applyMatrix4(m), b.applyMatrix4(m), x.applyMatrix4(m), y.applyMatrix4(m), T.debugDrawLine(p, b, 255), T.debugDrawLine(p, x, 255), T.debugDrawLine(b, y, 255), T.debugDrawLine(x, y, 255);
550
- }
551
- let C = 999;
552
- if (h && r.lastScreenCoverage > 0) {
553
- for (let m = 0; m < h.length; m++)
554
- if (h[m].density / r.lastScreenCoverage < i) {
555
- C = m;
556
- break;
557
- }
617
+ static isInside(e, t) {
618
+ const r = e.min, i = e.max, n = (r.x + i.x) * 0.5, s = (r.y + i.y) * 0.5;
619
+ return this._tempPtInside.set(n, s, r.z).applyMatrix4(t).z < 0;
620
+ }
621
+ calculateLodLevel(e, t, r, i, n) {
622
+ var x;
623
+ if (!t) {
624
+ n.mesh_lod = -1, n.texture_lod = -1;
625
+ return;
626
+ }
627
+ if (!e) {
628
+ n.mesh_lod = -1, n.texture_lod = -1;
629
+ return;
630
+ }
631
+ let o = 10 + 1;
632
+ if (ee && t["DEBUG:LOD"] != null)
633
+ return t["DEBUG:LOD"];
634
+ const l = S.getMeshLODInformation(t.geometry), d = l == null ? void 0 : l.lods, h = d && d.length > 0, m = S.getMaterialMinMaxLODsCount(t.material), u = (m == null ? void 0 : m.min) != 1 / 0 && m.min > 0 && m.max > 0;
635
+ if (!h && !u) {
636
+ n.mesh_lod = 0, n.texture_lod = 0;
637
+ return;
638
+ }
639
+ if (h || (o = 0), !((x = this.cameraFrustrum) != null && x.intersectsObject(t))) {
640
+ n.mesh_lod = 99, n.texture_lod = 99;
641
+ return;
642
+ }
643
+ const y = t.geometry.boundingBox;
644
+ if (y && e.isPerspectiveCamera) {
645
+ const M = e;
646
+ if (t.geometry.attributes.color && t.geometry.attributes.color.count < 100 && t.geometry.boundingSphere) {
647
+ this._sphere.copy(t.geometry.boundingSphere), this._sphere.applyMatrix4(t.matrixWorld);
648
+ const p = e.getWorldPosition(this._tempWorldPosition);
649
+ if (this._sphere.containsPoint(p)) {
650
+ n.mesh_lod = 0, n.texture_lod = 0;
651
+ return;
558
652
  }
559
- C < s && (s = C);
560
653
  }
654
+ if (this._tempBox.copy(y), this._tempBox.applyMatrix4(t.matrixWorld), T.isInside(this._tempBox, this.projectionScreenMatrix)) {
655
+ n.mesh_lod = 0, n.texture_lod = 0;
656
+ return;
657
+ }
658
+ if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && M.fov > 70) {
659
+ const p = this._tempBox.min, g = this._tempBox.max;
660
+ let c = p.x, L = p.y, _ = g.x, C = g.y;
661
+ const I = 2, U = 1.5, q = (p.x + g.x) * 0.5, K = (p.y + g.y) * 0.5;
662
+ c = (c - q) * I + q, L = (L - K) * I + K, _ = (_ - q) * I + q, C = (C - K) * I + K;
663
+ const de = c < 0 && _ > 0 ? 0 : Math.min(Math.abs(p.x), Math.abs(g.x)), he = L < 0 && C > 0 ? 0 : Math.min(Math.abs(p.y), Math.abs(g.y)), Z = Math.max(de, he);
664
+ r.lastCentrality = (U - Z) * (U - Z) * (U - Z);
665
+ } else
666
+ r.lastCentrality = 1;
667
+ const D = this._tempBox.getSize(this._tempBoxSize);
668
+ D.multiplyScalar(0.5), screen.availHeight > 0 && D.multiplyScalar(this.renderer.domElement.clientHeight / screen.availHeight), D.x *= M.aspect;
669
+ const G = e.matrixWorldInverse, O = this._tempBox2;
670
+ O.copy(y), O.applyMatrix4(t.matrixWorld), O.applyMatrix4(G);
671
+ const P = O.getSize(this._tempBox2Size), F = Math.max(P.x, P.y);
672
+ if (Math.max(D.x, D.y) != 0 && F != 0 && (D.z = P.z / Math.max(P.x, P.y) * Math.max(D.x, D.y)), r.lastScreenCoverage = Math.max(D.x, D.y, D.z), r.lastScreenspaceVolume.copy(D), r.lastScreenCoverage *= r.lastCentrality, ee && T.debugDrawLine) {
673
+ const p = this.tempMatrix.copy(this.projectionScreenMatrix);
674
+ p.invert();
675
+ const g = T.corner0, c = T.corner1, L = T.corner2, _ = T.corner3;
676
+ g.copy(this._tempBox.min), c.copy(this._tempBox.max), c.x = g.x, L.copy(this._tempBox.max), L.y = g.y, _.copy(this._tempBox.max);
677
+ const C = (g.z + _.z) * 0.5;
678
+ g.z = c.z = L.z = _.z = C, g.applyMatrix4(p), c.applyMatrix4(p), L.applyMatrix4(p), _.applyMatrix4(p), T.debugDrawLine(g, c, 255), T.debugDrawLine(g, L, 255), T.debugDrawLine(c, _, 255), T.debugDrawLine(L, _, 255);
679
+ }
680
+ let E = 999;
681
+ if (d && r.lastScreenCoverage > 0) {
682
+ for (let p = 0; p < d.length; p++)
683
+ if (d[p].density / r.lastScreenCoverage < i) {
684
+ E = p;
685
+ break;
686
+ }
687
+ }
688
+ E < o && (o = E);
561
689
  }
562
- return s;
690
+ if (n.mesh_lod = o, m != null && m.min && m.min > 0 && m.max > 0) {
691
+ const M = Math.min(1, Math.max(0, r.lastScreenCoverage * 3));
692
+ n.texture_lod = be(m.max, 0, M);
693
+ } else
694
+ n.texture_lod = 0;
563
695
  }
564
696
  };
565
- let B = T;
697
+ let b = T;
566
698
  /** 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.
567
699
  */
568
- u(B, "debugDrawLine"), u(B, "corner0", new k()), u(B, "corner1", new k()), u(B, "corner2", new k()), u(B, "corner3", new k());
569
- class we {
700
+ f(b, "debugDrawLine"), f(b, "corner0", new k()), f(b, "corner1", new k()), f(b, "corner2", new k()), f(b, "corner3", new k()), f(b, "_tempPtInside", new k());
701
+ function be(a, e, t) {
702
+ return a + (e - a) * t;
703
+ }
704
+ class Pe {
570
705
  constructor() {
571
- u(this, "lastLodLevel", 0);
572
- u(this, "lastScreenCoverage", 0);
573
- u(this, "lastScreenspaceVolume", new k());
574
- u(this, "lastCentrality", 0);
706
+ f(this, "frames", 0);
707
+ f(this, "lastLodLevel_Mesh", 0);
708
+ f(this, "lasLodLevel_Texture", 0);
709
+ f(this, "lastScreenCoverage", 0);
710
+ f(this, "lastScreenspaceVolume", new k());
711
+ f(this, "lastCentrality", 0);
575
712
  }
576
713
  }
577
- const re = Symbol("NEEDLE_mesh_lod"), $ = Symbol("NEEDLE_texture_lod");
578
- function Oe(l) {
579
- if (!l)
714
+ const ce = Symbol("NEEDLE_mesh_lod"), X = Symbol("NEEDLE_texture_lod");
715
+ function Ee(a) {
716
+ if (!a)
580
717
  return null;
581
718
  let e = null, t = null;
582
- for (let r = l; r != null; r = Object.getPrototypeOf(r)) {
719
+ for (let r = a; r != null; r = Object.getPrototypeOf(r)) {
583
720
  const i = Object.getOwnPropertySymbols(r), n = i.find((o) => o.toString() == "Symbol(renderer)"), s = i.find((o) => o.toString() == "Symbol(scene)");
584
- !e && n != null && (e = l[n].threeRenderer), !t && s != null && (t = l[s]);
721
+ !e && n != null && (e = a[n].threeRenderer), !t && s != null && (t = a[s]);
585
722
  }
586
723
  if (e) {
587
724
  console.log("Adding Needle LODs to modelviewer");
588
- const r = new B(e);
589
- if (r.plugins.push(new Me(l)), r.enable(), t) {
725
+ const r = b.get(e);
726
+ if (b.addPlugin(new Ce(a)), r.enable(), t) {
590
727
  const i = t.camera || t.traverse((n) => n.type == "PerspectiveCamera")[0];
591
728
  i && e.render(t, i);
592
729
  }
@@ -596,10 +733,10 @@ function Oe(l) {
596
733
  }
597
734
  return null;
598
735
  }
599
- class Me {
736
+ class Ce {
600
737
  constructor(e) {
601
- u(this, "modelviewer");
602
- u(this, "_didWarnAboutMissingUrl", !1);
738
+ f(this, "modelviewer");
739
+ f(this, "_didWarnAboutMissingUrl", !1);
603
740
  this.modelviewer = e;
604
741
  }
605
742
  onBeforeUpdateLOD(e, t, r, i) {
@@ -613,24 +750,28 @@ class Me {
613
750
  return e._currentGLTF;
614
751
  }
615
752
  tryParseTextureLOD(e, t) {
616
- if (t[$] == !0)
753
+ if (t[X] == !0)
617
754
  return;
618
- t[$] = !0;
755
+ t[X] = !0;
619
756
  const r = this.tryGetCurrentGLTF(e), i = this.getUrl();
620
757
  if (i && r && t.material) {
621
758
  let n = function(o) {
622
- var h, d, c;
623
- if (o[$] == !0)
759
+ var d, h, m;
760
+ if (o[X] == !0)
624
761
  return;
625
- o[$] = !0, o.userData && (o.userData.LOD = -1);
626
- const a = Object.keys(o);
627
- for (let f = 0; f < a.length; f++) {
628
- const w = a[f], L = o[w];
629
- if ((L == null ? void 0 : L.isTexture) === !0) {
630
- const A = (d = (h = L.userData) == null ? void 0 : h.associations) == null ? void 0 : d.textures, G = r.parser.json.textures[A];
631
- if ((c = G.extensions) != null && c[R]) {
632
- const D = G.extensions[R];
633
- D && i && v.registerTexture(i, L, D.lods.length, D);
762
+ o[X] = !0, o.userData && (o.userData.LOD = -1);
763
+ const l = Object.keys(o);
764
+ for (let u = 0; u < l.length; u++) {
765
+ const y = l[u], x = o[y];
766
+ if ((x == null ? void 0 : x.isTexture) === !0) {
767
+ const M = (h = (d = x.userData) == null ? void 0 : d.associations) == null ? void 0 : h.textures, D = r.parser.json.textures[M];
768
+ if (!D) {
769
+ console.warn("Texture data not found for texture index " + M);
770
+ continue;
771
+ }
772
+ if ((m = D == null ? void 0 : D.extensions) != null && m[R]) {
773
+ const G = D.extensions[R];
774
+ G && i && S.registerTexture(i, x, G.lods.length, G);
634
775
  }
635
776
  }
636
777
  }
@@ -645,32 +786,37 @@ class Me {
645
786
  }
646
787
  tryParseMeshLOD(e, t) {
647
788
  var n, s;
648
- if (t[re] == !0)
789
+ if (t[ce] == !0)
649
790
  return;
650
- t[re] = !0;
791
+ t[ce] = !0;
651
792
  const r = this.getUrl();
652
793
  if (!r)
653
794
  return;
654
795
  const i = (s = (n = t.userData) == null ? void 0 : n.gltfExtensions) == null ? void 0 : s[R];
655
796
  if (i && r) {
656
797
  const o = t.uuid;
657
- v.registerMesh(r, o, t, 0, i.lods.length, i);
798
+ S.registerMesh(r, o, t, 0, i.lods.length, i);
658
799
  }
659
800
  }
660
801
  }
661
- function Be(l, e, t, r) {
662
- se(e), ie(t), t.register((n) => new v(n, l));
663
- const i = new B(e);
802
+ function ze(a, e, t, r) {
803
+ fe(e), ue(t), t.register((n) => new S(n, a));
804
+ const i = b.get(e);
664
805
  return (r == null ? void 0 : r.enableLODsManager) !== !1 && i.enable(), i;
665
806
  }
666
807
  document.addEventListener("DOMContentLoaded", () => {
667
- Oe(document.querySelector("model-viewer"));
808
+ Ee(document.querySelector("model-viewer"));
668
809
  });
669
810
  export {
670
811
  R as EXTENSION_NAME,
671
- B as LODsManager,
672
- v as NEEDLE_progressive,
673
- Oe as patchModelViewer,
674
- _e as registerPlugin,
675
- Be as useNeedleProgressive
812
+ b as LODsManager,
813
+ S as NEEDLE_progressive,
814
+ ue as addDracoAndKTX2Loaders,
815
+ fe as createLoaders,
816
+ Se as getRaycastMesh,
817
+ Ee as patchModelViewer,
818
+ Ue as setDracoDecoderLocation,
819
+ Ne as setKTX2TranscoderLocation,
820
+ _e as setRaycastMesh,
821
+ ze as useNeedleProgressive
676
822
  };