@needle-tools/engine 4.13.1 → 4.14.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.
Files changed (141) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/components.needle.json +1 -1
  3. package/dist/generateMeshBVH.worker-DiCnZlf3.js +21 -0
  4. package/dist/gltf-progressive-Bm_6aEi4.js +1528 -0
  5. package/dist/gltf-progressive-BttGBXw6.umd.cjs +10 -0
  6. package/dist/gltf-progressive-T5WKTux5.min.js +10 -0
  7. package/dist/loader.worker-BqODMeeW.js +23 -0
  8. package/dist/{materialx-B9ddsHcF.min.js → materialx-CJyQZtjt.min.js} +1 -1
  9. package/dist/{materialx-fkoFuRh3.js → materialx-DMs1E08Z.js} +2 -2
  10. package/dist/{materialx-BF23AVE8.umd.cjs → materialx-DaKKOoVk.umd.cjs} +1 -1
  11. package/dist/needle-engine.bundle-BW2VusZV.min.js +1646 -0
  12. package/dist/{needle-engine.bundle-tjI5Fq2c.umd.cjs → needle-engine.bundle-Cb5bKEqa.umd.cjs} +152 -159
  13. package/dist/{needle-engine.bundle-DauZUYl7.js → needle-engine.bundle-D9VPvp5o.js} +7798 -7497
  14. package/dist/needle-engine.d.ts +779 -42
  15. package/dist/needle-engine.js +416 -415
  16. package/dist/needle-engine.min.js +1 -1
  17. package/dist/needle-engine.umd.cjs +1 -1
  18. package/dist/{postprocessing-BVNrgYZK.min.js → postprocessing-CctM1XIO.min.js} +1 -1
  19. package/dist/{postprocessing-DdM-tz1j.js → postprocessing-DGm6qJ-I.js} +2 -2
  20. package/dist/{postprocessing-CI2TjWpu.umd.cjs → postprocessing-Dbl2PJpd.umd.cjs} +1 -1
  21. package/dist/{three-BW2s1Yl-.umd.cjs → three-BjYim-vL.umd.cjs} +4 -4
  22. package/dist/{three-VvRoMeIN.js → three-Bvk2VKbF.js} +4210 -4210
  23. package/dist/{three-I__hSXzr.min.js → three-IG2qPafA.min.js} +33 -33
  24. package/dist/{three-examples-Bpfu6ke_.umd.cjs → three-examples-BMmNgNCN.umd.cjs} +1 -1
  25. package/dist/{three-examples-BhfOE7NG.js → three-examples-CMYCd5nH.js} +1 -1
  26. package/dist/{three-examples-D8zAE_7t.min.js → three-examples-CQl1fFZp.min.js} +1 -1
  27. package/dist/{three-mesh-ui-C3QbemOV.min.js → three-mesh-ui-5HVE2RV-.min.js} +1 -1
  28. package/dist/{three-mesh-ui-CcMp-FQm.js → three-mesh-ui-BlakAItG.js} +1 -1
  29. package/dist/{three-mesh-ui-BU55xDxJ.umd.cjs → three-mesh-ui-D828VbQp.umd.cjs} +1 -1
  30. package/dist/{vendor-DW7zqjuT.min.js → vendor-BxK0WKmT.min.js} +1 -1
  31. package/dist/{vendor-COVQl0b8.umd.cjs → vendor-CIDkyBaO.umd.cjs} +1 -1
  32. package/dist/{vendor-BiyIZ61v.js → vendor-ixwD-vv2.js} +1 -1
  33. package/lib/engine/api.d.ts +1 -0
  34. package/lib/engine/api.js +1 -0
  35. package/lib/engine/api.js.map +1 -1
  36. package/lib/engine/engine_context.js +12 -2
  37. package/lib/engine/engine_context.js.map +1 -1
  38. package/lib/engine/engine_lightdata.js +8 -6
  39. package/lib/engine/engine_lightdata.js.map +1 -1
  40. package/lib/engine/engine_materialpropertyblock.d.ts +259 -0
  41. package/lib/engine/engine_materialpropertyblock.js +682 -0
  42. package/lib/engine/engine_materialpropertyblock.js.map +1 -0
  43. package/lib/engine/engine_utils.d.ts +1 -0
  44. package/lib/engine/engine_utils.js +1 -0
  45. package/lib/engine/engine_utils.js.map +1 -1
  46. package/lib/engine/engine_utils_screenshot.d.ts +171 -14
  47. package/lib/engine/engine_utils_screenshot.js +65 -0
  48. package/lib/engine/engine_utils_screenshot.js.map +1 -1
  49. package/lib/engine/engine_utils_screenshot.xr.d.ts +1 -1
  50. package/lib/engine/engine_utils_screenshot.xr.js +1 -1
  51. package/lib/engine/extensions/NEEDLE_techniques_webgl.js +3 -0
  52. package/lib/engine/extensions/NEEDLE_techniques_webgl.js.map +1 -1
  53. package/lib/engine/xr/NeedleXRSession.d.ts +5 -0
  54. package/lib/engine/xr/NeedleXRSession.js +5 -0
  55. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  56. package/lib/engine-components/Camera.js.map +1 -1
  57. package/lib/engine-components/DropListener.js.map +1 -1
  58. package/lib/engine-components/Duplicatable.js.map +1 -1
  59. package/lib/engine-components/GroundProjection.js.map +1 -1
  60. package/lib/engine-components/NeedleMenu.js.map +1 -1
  61. package/lib/engine-components/NestedGltf.js.map +1 -1
  62. package/lib/engine-components/ReflectionProbe.d.ts +32 -4
  63. package/lib/engine-components/ReflectionProbe.js +58 -88
  64. package/lib/engine-components/ReflectionProbe.js.map +1 -1
  65. package/lib/engine-components/Renderer.d.ts +2 -0
  66. package/lib/engine-components/Renderer.js +30 -6
  67. package/lib/engine-components/Renderer.js.map +1 -1
  68. package/lib/engine-components/RendererLightmap.d.ts +13 -9
  69. package/lib/engine-components/RendererLightmap.js +67 -81
  70. package/lib/engine-components/RendererLightmap.js.map +1 -1
  71. package/lib/engine-components/SeeThrough.d.ts +0 -2
  72. package/lib/engine-components/SeeThrough.js +114 -88
  73. package/lib/engine-components/SeeThrough.js.map +1 -1
  74. package/lib/engine-components/SmoothFollow.js.map +1 -1
  75. package/lib/engine-components/VideoPlayer.js +6 -0
  76. package/lib/engine-components/VideoPlayer.js.map +1 -1
  77. package/lib/engine-components/ui/Button.js.map +1 -1
  78. package/lib/engine-components/ui/Raycaster.js.map +1 -1
  79. package/lib/engine-components/utils/OpenURL.d.ts +1 -0
  80. package/lib/engine-components/utils/OpenURL.js +1 -0
  81. package/lib/engine-components/utils/OpenURL.js.map +1 -1
  82. package/lib/engine-components/web/CursorFollow.d.ts +1 -0
  83. package/lib/engine-components/web/CursorFollow.js +1 -0
  84. package/lib/engine-components/web/CursorFollow.js.map +1 -1
  85. package/lib/engine-components/web/ScrollFollow.d.ts +1 -0
  86. package/lib/engine-components/web/ScrollFollow.js +1 -0
  87. package/lib/engine-components/web/ScrollFollow.js.map +1 -1
  88. package/lib/engine-components/web/ViewBox.d.ts +2 -2
  89. package/lib/engine-components/web/ViewBox.js +2 -2
  90. package/lib/engine-components/web/ViewBox.js.map +1 -1
  91. package/lib/engine-components/webxr/WebARCameraBackground.d.ts +9 -0
  92. package/lib/engine-components/webxr/WebARCameraBackground.js +9 -0
  93. package/lib/engine-components/webxr/WebARCameraBackground.js.map +1 -1
  94. package/lib/engine-components/webxr/WebXR.d.ts +1 -0
  95. package/lib/engine-components/webxr/WebXR.js +1 -0
  96. package/lib/engine-components/webxr/WebXR.js.map +1 -1
  97. package/lib/engine-components/webxr/WebXRPlaneTracking.js.map +1 -1
  98. package/lib/engine-components/webxr/controllers/XRControllerFollow.js.map +1 -1
  99. package/lib/engine-components/webxr/controllers/XRControllerMovement.js.map +1 -1
  100. package/package.json +5 -5
  101. package/plugins/vite/build-pipeline.js +16 -2
  102. package/src/engine/api.ts +1 -0
  103. package/src/engine/engine_context.ts +17 -3
  104. package/src/engine/engine_lightdata.ts +8 -6
  105. package/src/engine/engine_materialpropertyblock.ts +866 -0
  106. package/src/engine/engine_utils.ts +1 -0
  107. package/src/engine/engine_utils_screenshot.ts +241 -17
  108. package/src/engine/engine_utils_screenshot.xr.ts +1 -1
  109. package/src/engine/extensions/NEEDLE_techniques_webgl.ts +3 -0
  110. package/src/engine/xr/NeedleXRSession.ts +5 -0
  111. package/src/engine-components/Camera.ts +2 -2
  112. package/src/engine-components/ContactShadows.ts +1 -1
  113. package/src/engine-components/DropListener.ts +1 -1
  114. package/src/engine-components/Duplicatable.ts +1 -1
  115. package/src/engine-components/GroundProjection.ts +3 -0
  116. package/src/engine-components/NeedleMenu.ts +3 -0
  117. package/src/engine-components/NestedGltf.ts +1 -1
  118. package/src/engine-components/ReflectionProbe.ts +64 -105
  119. package/src/engine-components/Renderer.ts +34 -6
  120. package/src/engine-components/RendererLightmap.ts +75 -87
  121. package/src/engine-components/SeeThrough.ts +124 -109
  122. package/src/engine-components/SmoothFollow.ts +2 -2
  123. package/src/engine-components/VideoPlayer.ts +6 -0
  124. package/src/engine-components/ui/Button.ts +1 -1
  125. package/src/engine-components/ui/Raycaster.ts +1 -1
  126. package/src/engine-components/utils/OpenURL.ts +1 -0
  127. package/src/engine-components/web/CursorFollow.ts +1 -0
  128. package/src/engine-components/web/ScrollFollow.ts +1 -0
  129. package/src/engine-components/web/ViewBox.ts +9 -2
  130. package/src/engine-components/webxr/WebARCameraBackground.ts +12 -3
  131. package/src/engine-components/webxr/WebXR.ts +1 -0
  132. package/src/engine-components/webxr/WebXRPlaneTracking.ts +3 -3
  133. package/src/engine-components/webxr/controllers/XRControllerFollow.ts +1 -1
  134. package/src/engine-components/webxr/controllers/XRControllerMovement.ts +4 -4
  135. package/dist/generateMeshBVH.worker-iyfPIK6R.js +0 -21
  136. package/dist/gltf-progressive-BURrJW0U.umd.cjs +0 -8
  137. package/dist/gltf-progressive-DHLDFNvQ.min.js +0 -8
  138. package/dist/gltf-progressive-eiJCrjLb.js +0 -1400
  139. package/dist/loader.worker-C1GG9A7C.js +0 -23
  140. package/dist/needle-engine.bundle-BNIUpreS.min.js +0 -1653
  141. package/src/include/three/DragControls.js +0 -232
@@ -1,1400 +0,0 @@
1
- import { BufferGeometry as J, Mesh as q, Box3 as ge, Vector3 as A, Sphere as Oe, CompressedTexture as Ge, Texture as E, Matrix3 as Fe, InterleavedBuffer as We, InterleavedBufferAttribute as Ue, BufferAttribute as ze, TextureLoader as Ee, Matrix4 as _e, Clock as Ne, MeshStandardMaterial as qe } from "./three-VvRoMeIN.js";
2
- import { DRACOLoader as Ve, KTX2Loader as Xe, MeshoptDecoder as je, GLTFLoader as xe } from "./three-examples-BhfOE7NG.js";
3
- const Ke = "";
4
- globalThis.GLTF_PROGRESSIVE_VERSION = Ke;
5
- console.debug("[gltf-progressive] version -");
6
- let k = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", V = "https://cdn.needle.tools/static/three/0.179.1/basis2/";
7
- const Ye = k, He = V, Se = new URL(k + "draco_decoder.js");
8
- Se.searchParams.append("range", "true");
9
- fetch(Se, {
10
- method: "GET",
11
- headers: {
12
- Range: "bytes=0-1"
13
- }
14
- }).catch((i) => {
15
- console.debug(`Failed to fetch remote Draco decoder from ${k} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), k === Ye && Je("./include/draco/"), V === He && Ze("./include/ktx2/");
16
- }).finally(() => {
17
- Pe();
18
- });
19
- const Qe = () => ({
20
- dracoDecoderPath: k,
21
- ktx2TranscoderPath: V
22
- });
23
- function Je(i) {
24
- k = i, P && P[pe] != k ? (console.debug("Updating Draco decoder path to " + i), P[pe] = k, P.setDecoderPath(k), P.preload()) : console.debug("Setting Draco decoder path to " + i);
25
- }
26
- function Ze(i) {
27
- V = i, R && R.transcoderPath != V ? (console.debug("Updating KTX2 transcoder path to " + i), R.setTranscoderPath(V), R.init()) : console.debug("Setting KTX2 transcoder path to " + i);
28
- }
29
- function we(i) {
30
- return Pe(), i ? R.detectSupport(i) : i !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: P, ktx2Loader: R, meshoptDecoder: ne };
31
- }
32
- function Te(i) {
33
- i.dracoLoader || i.setDRACOLoader(P), i.ktx2Loader || i.setKTX2Loader(R), i.meshoptDecoder || i.setMeshoptDecoder(ne);
34
- }
35
- const pe = /* @__PURE__ */ Symbol("dracoDecoderPath");
36
- let P, ne, R;
37
- function Pe() {
38
- P || (P = new Ve(), P[pe] = k, P.setDecoderPath(k), P.setDecoderConfig({ type: "js" }), P.preload()), R || (R = new Xe(), R.setTranscoderPath(V), R.init()), ne || (ne = je);
39
- }
40
- const me = /* @__PURE__ */ new WeakMap();
41
- function Ae(i, t) {
42
- let e = me.get(i);
43
- e ? e = Object.assign(e, t) : e = t, me.set(i, e);
44
- }
45
- const et = xe.prototype.load;
46
- function tt(...i) {
47
- const t = me.get(this);
48
- let e = i[0];
49
- const s = new URL(e, window.location.href);
50
- if (s.hostname.endsWith("needle.tools")) {
51
- const r = t?.progressive !== void 0 ? t.progressive : !0, o = t?.usecase ? t.usecase : "default";
52
- r ? this.requestHeader.Accept = `*/*;progressive=allowed;usecase=${o}` : this.requestHeader.Accept = `*/*;usecase=${o}`, e = s.toString();
53
- }
54
- return i[0] = e, et?.call(this, ...i);
55
- }
56
- xe.prototype.load = tt;
57
- X("debugprogressive");
58
- function X(i) {
59
- if (typeof window > "u") return !1;
60
- const e = new URL(window.location.href).searchParams.get(i);
61
- return e == null || e === "0" || e === "false" ? !1 : e === "" ? !0 : e;
62
- }
63
- function st(i, t) {
64
- if (t === void 0 || i === void 0 || t.startsWith("./") || t.startsWith("http") || t.startsWith("data:") || t.startsWith("blob:"))
65
- return t;
66
- const e = i.lastIndexOf("/");
67
- if (e >= 0) {
68
- const s = i.substring(0, e + 1);
69
- for (; s.endsWith("/") && t.startsWith("/"); ) t = t.substring(1);
70
- return s + t;
71
- }
72
- return t;
73
- }
74
- function Ie() {
75
- return K !== void 0 || (K = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), X("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", K)), K;
76
- }
77
- let K;
78
- function Me() {
79
- if (typeof window > "u") return !1;
80
- const i = new URL(window.location.href), t = i.hostname === "localhost" || /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(i.hostname);
81
- return i.hostname === "127.0.0.1" || t;
82
- }
83
- class rt {
84
- constructor(t = 100, e = {}) {
85
- this.maxConcurrent = t, this.debug = e.debug ?? !1, window.requestAnimationFrame(this.tick);
86
- }
87
- _running = /* @__PURE__ */ new Map();
88
- _queue = [];
89
- debug = !1;
90
- tick = () => {
91
- this.internalUpdate(), setTimeout(this.tick, 10);
92
- };
93
- /**
94
- * Request a slot for a promise with a specific key. This function returns a promise with a `use` method that can be called to add the promise to the queue.
95
- */
96
- slot(t) {
97
- return this.debug && console.debug(`[PromiseQueue]: Requesting slot for key ${t}, running: ${this._running.size}, waiting: ${this._queue.length}`), new Promise((e) => {
98
- this._queue.push({ key: t, resolve: e });
99
- });
100
- }
101
- add(t, e) {
102
- this._running.has(t) || (this._running.set(t, e), e.finally(() => {
103
- this._running.delete(t), this.debug && console.debug(`[PromiseQueue]: Promise finished now running: ${this._running.size}, waiting: ${this._queue.length}. (finished ${t})`);
104
- }), this.debug && console.debug(`[PromiseQueue]: Added new promise, now running: ${this._running.size}, waiting: ${this._queue.length}. (added ${t})`));
105
- }
106
- internalUpdate() {
107
- const t = this.maxConcurrent - this._running.size;
108
- for (let e = 0; e < t && this._queue.length > 0; e++) {
109
- this.debug && console.debug(`[PromiseQueue]: Running ${this._running.size} promises, waiting for ${this._queue.length} more.`);
110
- const { key: s, resolve: n } = this._queue.shift();
111
- n({
112
- use: (r) => this.add(s, r)
113
- });
114
- }
115
- }
116
- }
117
- const nt = typeof window > "u" && typeof document > "u", ye = /* @__PURE__ */ Symbol("needle:raycast-mesh");
118
- function Z(i) {
119
- return i?.[ye] instanceof J ? i[ye] : null;
120
- }
121
- function ot(i, t) {
122
- if ((i.type === "Mesh" || i.type === "SkinnedMesh") && !Z(i)) {
123
- const s = at(t);
124
- s.userData = { isRaycastMesh: !0 }, i[ye] = s;
125
- }
126
- }
127
- function it(i = !0) {
128
- if (i) {
129
- if (Y) return;
130
- const t = Y = q.prototype.raycast;
131
- q.prototype.raycast = function(e, s) {
132
- const n = this, r = Z(n);
133
- let o;
134
- r && n.isMesh && (o = n.geometry, n.geometry = r), t.call(this, e, s), o && (n.geometry = o);
135
- };
136
- } else {
137
- if (!Y) return;
138
- q.prototype.raycast = Y, Y = null;
139
- }
140
- }
141
- let Y = null;
142
- function at(i) {
143
- const t = new J();
144
- for (const e in i.attributes)
145
- t.setAttribute(e, i.getAttribute(e));
146
- return t.setIndex(i.getIndex()), t;
147
- }
148
- const U = new Array(), g = X("debugprogressive");
149
- let Q, N = -1;
150
- if (g) {
151
- let i = function() {
152
- N += 1, N >= t && (N = -1), console.log(`Toggle LOD level [${N}]`);
153
- }, t = 6;
154
- window.addEventListener("keyup", (e) => {
155
- e.key === "p" && i(), e.key === "w" && (Q = !Q, console.log(`Toggle wireframe [${Q}]`));
156
- const s = parseInt(e.key);
157
- !isNaN(s) && s >= 0 && (N = s, console.log(`Set LOD level to [${N}]`));
158
- });
159
- }
160
- function Ce(i) {
161
- if (g && Q !== void 0)
162
- if (Array.isArray(i))
163
- for (const t of i)
164
- Ce(t);
165
- else i && "wireframe" in i && (i.wireframe = Q === !0);
166
- }
167
- const H = new Array();
168
- let lt = 0;
169
- const ut = Ie() ? 2 : 10;
170
- function dt(i) {
171
- if (H.length < ut) {
172
- const s = H.length;
173
- g && console.warn(`[Worker] Creating new worker #${s}`);
174
- const n = Le.createWorker(i || {});
175
- return H.push(n), n;
176
- }
177
- const t = lt++ % H.length;
178
- return H[t];
179
- }
180
- class Le {
181
- constructor(t, e) {
182
- this.worker = t, this._debug = e.debug ?? !1, t.onmessage = (s) => {
183
- const n = s.data;
184
- switch (this._debug && console.log("[Worker] EVENT", n), n.type) {
185
- case "loaded-gltf":
186
- for (const r of this._running)
187
- if (r.url === n.result.url) {
188
- ct(n.result), r.resolve(n.result);
189
- const o = r.url;
190
- o.startsWith("blob:") && URL.revokeObjectURL(o);
191
- }
192
- }
193
- }, t.onerror = (s) => {
194
- console.error("[Worker] Error in gltf-progressive worker:", s);
195
- }, t.postMessage({
196
- type: "init"
197
- });
198
- }
199
- static async createWorker(t) {
200
- const e = /* new-worker */ new Worker(URL.createObjectURL(new Blob(["import '" + `${new URL('./loader.worker-C1GG9A7C.js', import.meta.url).toString()}` + "';"], { type: 'text/javascript' })), {
201
- type: "module"
202
- });
203
- return new Le(e, t);
204
- }
205
- _running = [];
206
- _webglRenderer = null;
207
- async load(t, e) {
208
- const s = Qe();
209
- let n = e?.renderer;
210
- n || (this._webglRenderer ??= (async () => {
211
- const { WebGLRenderer: u } = await import("./three-VvRoMeIN.js").then((d) => d.THREE);
212
- return new u();
213
- })(), n = await this._webglRenderer);
214
- const l = we(n).ktx2Loader.workerConfig;
215
- 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());
216
- const a = {
217
- type: "load",
218
- url: t,
219
- dracoDecoderPath: s.dracoDecoderPath,
220
- ktx2TranscoderPath: s.ktx2TranscoderPath,
221
- ktx2LoaderConfig: l
222
- };
223
- return this._debug && console.debug("[Worker] Sending load request", a), this.worker.postMessage(a), new Promise((u) => {
224
- this._running.push({
225
- url: t.toString(),
226
- resolve: u
227
- });
228
- });
229
- }
230
- _debug = !1;
231
- }
232
- function ct(i) {
233
- for (const t of i.geometries) {
234
- const e = t.geometry, s = new J();
235
- if (s.name = e.name || "", e.index) {
236
- const n = e.index;
237
- s.setIndex(le(n));
238
- }
239
- for (const n in e.attributes) {
240
- const r = e.attributes[n], o = le(r);
241
- s.setAttribute(n, o);
242
- }
243
- if (e.morphAttributes)
244
- for (const n in e.morphAttributes) {
245
- const o = e.morphAttributes[n].map((l) => le(l));
246
- s.morphAttributes[n] = o;
247
- }
248
- if (s.morphTargetsRelative = e.morphTargetsRelative ?? !1, s.boundingBox = new ge(), s.boundingBox.min = new A(
249
- e.boundingBox?.min.x,
250
- e.boundingBox?.min.y,
251
- e.boundingBox?.min.z
252
- ), s.boundingBox.max = new A(
253
- e.boundingBox?.max.x,
254
- e.boundingBox?.max.y,
255
- e.boundingBox?.max.z
256
- ), s.boundingSphere = new Oe(
257
- new A(
258
- e.boundingSphere?.center.x,
259
- e.boundingSphere?.center.y,
260
- e.boundingSphere?.center.z
261
- ),
262
- e.boundingSphere?.radius
263
- ), e.groups)
264
- for (const n of e.groups)
265
- s.addGroup(n.start, n.count, n.materialIndex);
266
- e.userData && (s.userData = e.userData), t.geometry = s;
267
- }
268
- for (const t of i.textures) {
269
- const e = t.texture;
270
- let s = null;
271
- if (e.isCompressedTexture) {
272
- const n = e.mipmaps, r = e.image?.width || e.source?.data?.width || -1, o = e.image?.height || e.source?.data?.height || -1;
273
- s = new Ge(
274
- n,
275
- r,
276
- o,
277
- e.format,
278
- e.type,
279
- e.mapping,
280
- e.wrapS,
281
- e.wrapT,
282
- e.magFilter,
283
- e.minFilter,
284
- e.anisotropy,
285
- e.colorSpace
286
- );
287
- } else
288
- s = new E(
289
- e.image,
290
- e.mapping,
291
- e.wrapS,
292
- e.wrapT,
293
- e.magFilter,
294
- e.minFilter,
295
- e.format,
296
- e.type,
297
- e.anisotropy,
298
- e.colorSpace
299
- ), s.mipmaps = e.mipmaps, s.channel = e.channel, s.source.data = e.source.data, s.flipY = e.flipY, s.premultiplyAlpha = e.premultiplyAlpha, s.unpackAlignment = e.unpackAlignment, s.matrix = new Fe(...e.matrix.elements);
300
- if (!s) {
301
- console.error("[Worker] Failed to create new texture from received data. Texture is not a CompressedTexture or Texture.");
302
- continue;
303
- }
304
- t.texture = s;
305
- }
306
- return i;
307
- }
308
- function le(i) {
309
- let t = i;
310
- if ("isInterleavedBufferAttribute" in i && i.isInterleavedBufferAttribute) {
311
- const e = i.data, s = e.array, n = new We(s, e.stride);
312
- t = new Ue(n, i.itemSize, s.byteOffset, i.normalized), t.offset = i.offset;
313
- } else "isBufferAttribute" in i && i.isBufferAttribute && (t = new ze(i.array, i.itemSize, i.normalized), t.usage = i.usage, t.gpuType = i.gpuType, t.updateRanges = i.updateRanges);
314
- return t;
315
- }
316
- const ft = X("gltf-progressive-worker"), ht = X("gltf-progressive-reduce-mipmaps"), ue = /* @__PURE__ */ Symbol("needle-progressive-texture"), F = "NEEDLE_progressive";
317
- class y {
318
- /** The name of the extension */
319
- get name() {
320
- return F;
321
- }
322
- // #region PUBLIC API
323
- static getMeshLODExtension(t) {
324
- const e = this.getAssignedLODInformation(t);
325
- return e?.key ? this.lodInfos.get(e.key) : null;
326
- }
327
- static getPrimitiveIndex(t) {
328
- const e = this.getAssignedLODInformation(t)?.index;
329
- return e ?? -1;
330
- }
331
- static getMaterialMinMaxLODsCount(t, e) {
332
- const s = this, n = "LODS:minmax", r = t[n];
333
- if (r != null) return r;
334
- if (e || (e = {
335
- min_count: 1 / 0,
336
- max_count: 0,
337
- lods: []
338
- }), Array.isArray(t)) {
339
- for (const l of t)
340
- this.getMaterialMinMaxLODsCount(l, e);
341
- return t[n] = e, e;
342
- }
343
- if (g === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
344
- const l = t;
345
- for (const a of Object.keys(l.uniforms)) {
346
- const u = l.uniforms[a].value;
347
- u?.isTexture === !0 && o(u, e);
348
- }
349
- } else if (t.isMaterial)
350
- for (const l of Object.keys(t)) {
351
- const a = t[l];
352
- a?.isTexture === !0 && o(a, e);
353
- }
354
- else
355
- g && console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${t.type}`);
356
- return t[n] = e, e;
357
- function o(l, a) {
358
- const u = s.getAssignedLODInformation(l);
359
- if (u) {
360
- const d = s.lodInfos.get(u.key);
361
- if (d && d.lods) {
362
- a.min_count = Math.min(a.min_count, d.lods.length), a.max_count = Math.max(a.max_count, d.lods.length);
363
- for (let p = 0; p < d.lods.length; p++) {
364
- const L = d.lods[p];
365
- L.width && (a.lods[p] = a.lods[p] || { min_height: 1 / 0, max_height: 0 }, a.lods[p].min_height = Math.min(a.lods[p].min_height, L.height), a.lods[p].max_height = Math.max(a.lods[p].max_height, L.height));
366
- }
367
- }
368
- }
369
- }
370
- }
371
- /** Check if a LOD level is available for a mesh or a texture
372
- * @param obj the mesh or texture to check
373
- * @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
374
- * @returns true if the LOD level is available (or if any LOD level is available if level is undefined)
375
- */
376
- static hasLODLevelAvailable(t, e) {
377
- if (Array.isArray(t)) {
378
- for (const r of t)
379
- if (this.hasLODLevelAvailable(r, e)) return !0;
380
- return !1;
381
- }
382
- if (t.isMaterial === !0) {
383
- for (const r of Object.keys(t)) {
384
- const o = t[r];
385
- if (o && o.isTexture && this.hasLODLevelAvailable(o, e))
386
- return !0;
387
- }
388
- return !1;
389
- } else if (t.isGroup === !0) {
390
- for (const r of t.children)
391
- if (r.isMesh === !0 && this.hasLODLevelAvailable(r, e))
392
- return !0;
393
- }
394
- let s, n;
395
- if (t.isMesh ? s = t.geometry : (t.isBufferGeometry || t.isTexture) && (s = t), s && s?.userData?.LODS) {
396
- const r = s.userData.LODS;
397
- if (n = this.lodInfos.get(r.key), e === void 0) return n != null;
398
- if (n)
399
- return Array.isArray(n.lods) ? e < n.lods.length : e === 0;
400
- }
401
- return !1;
402
- }
403
- /** Load a different resolution of a mesh (if available)
404
- * @param context the context
405
- * @param source the sourceid of the file from which the mesh is loaded (this is usually the component's sourceId)
406
- * @param mesh the mesh to load the LOD for
407
- * @param level the level of detail to load (0 is the highest resolution)
408
- * @returns a promise that resolves to the mesh with the requested LOD level
409
- * @example
410
- * ```javascript
411
- * const mesh = this.gameObject as Mesh;
412
- * NEEDLE_progressive.assignMeshLOD(context, sourceId, mesh, 1).then(mesh => {
413
- * console.log("Mesh with LOD level 1 loaded", mesh);
414
- * });
415
- * ```
416
- */
417
- static assignMeshLOD(t, e) {
418
- if (!t) return Promise.resolve(null);
419
- if (t instanceof q || t.isMesh === !0) {
420
- const s = t.geometry, n = this.getAssignedLODInformation(s);
421
- if (!n)
422
- return Promise.resolve(null);
423
- for (const r of U)
424
- r.onBeforeGetLODMesh?.(t, e);
425
- return t["LOD:requested level"] = e, y.getOrLoadLOD(s, e).then((r) => {
426
- if (Array.isArray(r)) {
427
- const o = n.index || 0;
428
- r = r[o];
429
- }
430
- return t["LOD:requested level"] === e && (delete t["LOD:requested level"], r && s != r && (r?.isBufferGeometry ? t.geometry = r : g && console.error("Invalid LOD geometry", r))), r;
431
- }).catch((r) => (console.error("Error loading mesh LOD", t, r), null));
432
- } else g && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
433
- return Promise.resolve(null);
434
- }
435
- static assignTextureLOD(t, e = 0) {
436
- if (!t) return Promise.resolve(null);
437
- if (t.isMesh === !0) {
438
- const s = t;
439
- if (Array.isArray(s.material)) {
440
- const n = new Array();
441
- for (const r of s.material) {
442
- const o = this.assignTextureLOD(r, e);
443
- n.push(o);
444
- }
445
- return Promise.all(n).then((r) => {
446
- const o = new Array();
447
- for (const l of r)
448
- Array.isArray(l) && o.push(...l);
449
- return o;
450
- });
451
- } else
452
- return this.assignTextureLOD(s.material, e);
453
- }
454
- if (t.isMaterial === !0) {
455
- const s = t, n = [], r = new Array();
456
- if (s.uniforms && (s.isRawShaderMaterial || s.isShaderMaterial === !0)) {
457
- const o = s;
458
- for (const l of Object.keys(o.uniforms)) {
459
- const a = o.uniforms[l].value;
460
- if (a?.isTexture === !0) {
461
- const u = this.assignTextureLODForSlot(a, e, s, l).then((d) => (d && o.uniforms[l].value != d && (o.uniforms[l].value = d, o.uniformsNeedUpdate = !0), d));
462
- n.push(u), r.push(l);
463
- }
464
- }
465
- } else
466
- for (const o of Object.keys(s)) {
467
- const l = s[o];
468
- if (l?.isTexture === !0) {
469
- const a = this.assignTextureLODForSlot(l, e, s, o);
470
- n.push(a), r.push(o);
471
- }
472
- }
473
- return Promise.all(n).then((o) => {
474
- const l = new Array();
475
- for (let a = 0; a < o.length; a++) {
476
- const u = o[a], d = r[a];
477
- u && u.isTexture === !0 ? l.push({ material: s, slot: d, texture: u, level: e }) : l.push({ material: s, slot: d, texture: null, level: e });
478
- }
479
- return l;
480
- });
481
- }
482
- if (t instanceof E || t.isTexture === !0) {
483
- const s = t;
484
- return this.assignTextureLODForSlot(s, e, null, null);
485
- }
486
- return Promise.resolve(null);
487
- }
488
- // #region INTERNAL
489
- static assignTextureLODForSlot(t, e, s, n) {
490
- return t?.isTexture !== !0 ? Promise.resolve(null) : n === "glyphMap" ? Promise.resolve(t) : y.getOrLoadLOD(t, e).then((r) => {
491
- if (Array.isArray(r))
492
- return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen..."), null;
493
- if (r?.isTexture === !0) {
494
- if (r != t && s && n) {
495
- const o = s[n];
496
- if (o && !g) {
497
- const l = this.getAssignedLODInformation(o);
498
- if (l && l?.level < e)
499
- return g === "verbose" && console.warn("Assigned texture level is already higher: ", l.level, e, s, o, r), null;
500
- }
501
- if (ht && r.mipmaps) {
502
- const l = r.mipmaps.length;
503
- r.mipmaps.length = Math.min(r.mipmaps.length, 3), l !== r.mipmaps.length && g && console.debug(`Reduced mipmap count from ${l} to ${r.mipmaps.length} for ${r.uuid}: ${r.image?.width}x${r.image?.height}.`);
504
- }
505
- s[n] = r;
506
- }
507
- return r;
508
- } else g == "verbose" && console.warn("No LOD found for", t, e);
509
- return null;
510
- }).catch((r) => (console.error("Error loading LOD", t, r), null));
511
- }
512
- parser;
513
- url;
514
- constructor(t) {
515
- const e = t.options.path;
516
- g && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
517
- }
518
- _isLoadingMesh;
519
- loadMesh = (t) => {
520
- if (this._isLoadingMesh) return null;
521
- const e = this.parser.json.meshes[t]?.extensions?.[F];
522
- return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((s) => (this._isLoadingMesh = !1, s && y.registerMesh(this.url, e.guid, s, e.lods?.length, 0, e), s))) : null;
523
- };
524
- // private _isLoadingTexture;
525
- // loadTexture = (textureIndex: number) => {
526
- // if (this._isLoadingTexture) return null;
527
- // const ext = this.parser.json.textures[textureIndex]?.extensions?.[EXTENSION_NAME] as NEEDLE_ext_progressive_texture;
528
- // if (!ext) return null;
529
- // this._isLoadingTexture = true;
530
- // return this.parser.getDependency("texture", textureIndex).then(tex => {
531
- // this._isLoadingTexture = false;
532
- // if (tex) {
533
- // NEEDLE_progressive.registerTexture(this.url, tex as Texture, ext.lods?.length, textureIndex, ext);
534
- // }
535
- // return tex;
536
- // });
537
- // }
538
- afterRoot(t) {
539
- return g && console.log("AFTER", this.url, t), this.parser.json.textures?.forEach((e, s) => {
540
- if (e?.extensions) {
541
- const n = e?.extensions[F];
542
- if (n) {
543
- if (!n.lods) {
544
- g && console.warn("Texture has no LODs", n);
545
- return;
546
- }
547
- let r = !1;
548
- for (const o of this.parser.associations.keys())
549
- o.isTexture === !0 && this.parser.associations.get(o)?.textures === s && (r = !0, y.registerTexture(this.url, o, n.lods?.length, s, n));
550
- r || this.parser.getDependency("texture", s).then((o) => {
551
- o && y.registerTexture(this.url, o, n.lods?.length, s, n);
552
- });
553
- }
554
- }
555
- }), this.parser.json.meshes?.forEach((e, s) => {
556
- if (e?.extensions) {
557
- const n = e?.extensions[F];
558
- if (n && n.lods) {
559
- for (const r of this.parser.associations.keys())
560
- if (r.isMesh) {
561
- const o = this.parser.associations.get(r);
562
- o?.meshes === s && y.registerMesh(this.url, n.guid, r, n.lods.length, o.primitives, n);
563
- }
564
- }
565
- }
566
- }), null;
567
- }
568
- /**
569
- * Register a texture with LOD information
570
- */
571
- static registerTexture = (t, e, s, n, r) => {
572
- if (!e) {
573
- g && console.error("!! gltf-progressive: Called register texture without texture");
574
- return;
575
- }
576
- if (g) {
577
- const l = e.image?.width || e.source?.data?.width || 0, a = e.image?.height || e.source?.data?.height || 0;
578
- console.log(`> gltf-progressive: register texture[${n}] "${e.name || e.uuid}", Current: ${l}x${a}, Max: ${r.lods[0]?.width}x${r.lods[0]?.height}, uuid: ${e.uuid}`, r, e);
579
- }
580
- e.source && (e.source[ue] = r);
581
- const o = r.guid;
582
- y.assignLODInformation(t, e, o, s, n), y.lodInfos.set(o, r), y.lowresCache.set(o, e);
583
- };
584
- /**
585
- * Register a mesh with LOD information
586
- */
587
- static registerMesh = (t, e, s, n, r, o) => {
588
- const l = s.geometry;
589
- if (!l) {
590
- g && console.warn("gltf-progressive: Register mesh without geometry");
591
- return;
592
- }
593
- l.userData || (l.userData = {}), g && console.log("> Progressive: register mesh " + s.name, { index: r, uuid: s.uuid }, o, s), y.assignLODInformation(t, l, e, n, r), y.lodInfos.set(e, o);
594
- let a = y.lowresCache.get(e);
595
- a ? a.push(s.geometry) : a = [s.geometry], y.lowresCache.set(e, a), n > 0 && !Z(s) && ot(s, l);
596
- for (const u of U)
597
- u.onRegisteredNewMesh?.(s, o);
598
- };
599
- /** A map of key = asset uuid and value = LOD information */
600
- static lodInfos = /* @__PURE__ */ new Map();
601
- /** cache of already loaded mesh lods */
602
- static previouslyLoaded = /* @__PURE__ */ new Map();
603
- /** this contains the geometry/textures that were originally loaded */
604
- static lowresCache = /* @__PURE__ */ new Map();
605
- static workers = [];
606
- static _workersIndex = 0;
607
- static async getOrLoadLOD(t, e) {
608
- const s = g == "verbose", n = this.getAssignedLODInformation(t);
609
- if (!n)
610
- return g && console.warn(`[gltf-progressive] No LOD information found: ${t.name}, uuid: ${t.uuid}, type: ${t.type}`, t), null;
611
- const r = n?.key;
612
- let o;
613
- if (t.isTexture === !0) {
614
- const a = t;
615
- a.source && a.source[ue] && (o = a.source[ue]);
616
- }
617
- if (o || (o = y.lodInfos.get(r)), !o)
618
- g && console.warn(`Can not load LOD ${e}: no LOD info found for "${r}" ${t.name}`, t.type, y.lodInfos);
619
- else {
620
- if (e > 0) {
621
- let d = !1;
622
- const p = Array.isArray(o.lods);
623
- if (p && e >= o.lods.length ? d = !0 : p || (d = !0), d)
624
- return this.lowresCache.get(r);
625
- }
626
- const a = Array.isArray(o.lods) ? o.lods[e]?.path : o.lods;
627
- if (!a)
628
- return g && !o["missing:uri"] && (o["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, o)), null;
629
- const u = st(n.url, a);
630
- if (u.endsWith(".glb") || u.endsWith(".gltf")) {
631
- if (!o.guid)
632
- return console.warn("missing pointer for glb/gltf texture", o), null;
633
- const d = u + "_" + o.guid, p = await this.queue.slot(u), L = this.previouslyLoaded.get(d);
634
- if (L !== void 0) {
635
- s && console.log(`LOD ${e} was already loading/loaded: ${d}`);
636
- let c = await L.catch((O) => (console.error(`Error loading LOD ${e} from ${u}
637
- `, O), null)), x = !1;
638
- if (c == null || (c instanceof E && t instanceof E ? c.image?.data || c.source?.data ? c = this.copySettings(t, c) : (x = !0, this.previouslyLoaded.delete(d)) : c instanceof J && t instanceof J && (c.attributes.position?.array || (x = !0, this.previouslyLoaded.delete(d)))), !x)
639
- return c;
640
- }
641
- if (!p.use)
642
- return g && console.log(`LOD ${e} was aborted: ${u}`), null;
643
- const _ = o, I = new Promise(async (c, x) => {
644
- if (ft) {
645
- const m = await (await dt({})).load(u);
646
- if (m.textures.length > 0)
647
- for (const f of m.textures) {
648
- let h = f.texture;
649
- return y.assignLODInformation(n.url, h, r, e, void 0), t instanceof E && (h = this.copySettings(t, h)), h && (h.guid = _.guid), c(h);
650
- }
651
- if (m.geometries.length > 0) {
652
- const f = new Array();
653
- for (const h of m.geometries) {
654
- const v = h.geometry;
655
- y.assignLODInformation(n.url, v, r, e, h.primitiveIndex), f.push(v);
656
- }
657
- return c(f);
658
- }
659
- return c(null);
660
- }
661
- const O = new xe();
662
- Te(O), g && (await new Promise((w) => setTimeout(w, 1e3)), s && console.warn("Start loading (delayed) " + u, _.guid));
663
- let B = u;
664
- if (_ && Array.isArray(_.lods)) {
665
- const w = _.lods[e];
666
- w.hash && (B += "?v=" + w.hash);
667
- }
668
- const M = await O.loadAsync(B).catch((w) => (console.error(`Error loading LOD ${e} from ${u}
669
- `, w), c(null)));
670
- if (!M)
671
- return c(null);
672
- const z = M.parser;
673
- s && console.log("Loading finished " + u, _.guid);
674
- let S = 0;
675
- if (M.parser.json.textures) {
676
- let w = !1;
677
- for (const m of M.parser.json.textures) {
678
- if (m?.extensions) {
679
- const f = m?.extensions[F];
680
- if (f?.guid && f.guid === _.guid) {
681
- w = !0;
682
- break;
683
- }
684
- }
685
- S++;
686
- }
687
- if (w) {
688
- let m = await z.getDependency("texture", S);
689
- return m && y.assignLODInformation(n.url, m, r, e, void 0), s && console.log('change "' + t.name + '" → "' + m.name + '"', u, S, m, d), t instanceof E && (m = this.copySettings(t, m)), m && (m.guid = _.guid), c(m);
690
- } else g && console.warn("Could not find texture with guid", _.guid, M.parser.json);
691
- }
692
- if (S = 0, M.parser.json.meshes) {
693
- let w = !1;
694
- for (const m of M.parser.json.meshes) {
695
- if (m?.extensions) {
696
- const f = m?.extensions[F];
697
- if (f?.guid && f.guid === _.guid) {
698
- w = !0;
699
- break;
700
- }
701
- }
702
- S++;
703
- }
704
- if (w) {
705
- const m = await z.getDependency("mesh", S);
706
- if (s && console.log(`Loaded Mesh "${m.name}"`, u, S, m, d), m.isMesh === !0) {
707
- const f = m.geometry;
708
- return y.assignLODInformation(n.url, f, r, e, 0), c(f);
709
- } else {
710
- const f = new Array();
711
- for (let h = 0; h < m.children.length; h++) {
712
- const v = m.children[h];
713
- if (v.isMesh === !0) {
714
- const b = v.geometry;
715
- y.assignLODInformation(n.url, b, r, e, h), f.push(b);
716
- }
717
- }
718
- return c(f);
719
- }
720
- } else g && console.warn("Could not find mesh with guid", _.guid, M.parser.json);
721
- }
722
- return c(null);
723
- });
724
- return this.previouslyLoaded.set(d, I), p.use(I), await I;
725
- } else if (t instanceof E) {
726
- s && console.log("Load texture from uri: " + u);
727
- const p = await new Ee().loadAsync(u);
728
- return p ? (p.guid = o.guid, p.flipY = !1, p.needsUpdate = !0, p.colorSpace = t.colorSpace, s && console.log(o, p)) : g && console.warn("failed loading", u), p;
729
- }
730
- }
731
- return null;
732
- }
733
- static maxConcurrent = 50;
734
- static queue = new rt(y.maxConcurrent, { debug: g != !1 });
735
- static assignLODInformation(t, e, s, n, r) {
736
- if (!e) return;
737
- e.userData || (e.userData = {});
738
- const o = new gt(t, s, n, r);
739
- e.userData.LODS = o, "source" in e && typeof e.source == "object" && (e.source.LODS = o);
740
- }
741
- static getAssignedLODInformation(t) {
742
- return t ? t.userData?.LODS ? t.userData.LODS : "source" in t && t.source?.LODS ? t.source.LODS : null : null;
743
- }
744
- // private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
745
- static copySettings(t, e) {
746
- return e ? (g === "verbose" && console.debug(`Copy texture settings
747
- `, t.uuid, `
748
- `, 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;
749
- }
750
- }
751
- class gt {
752
- url;
753
- /** the key to lookup the LOD information */
754
- key;
755
- level;
756
- /** For multi objects (e.g. a group of meshes) this is the index of the object */
757
- index;
758
- constructor(t, e, s, n) {
759
- this.url = t, this.key = e, this.level = s, n != null && (this.index = n);
760
- }
761
- }
762
- class de {
763
- static addPromise = (t, e, s, n) => {
764
- n.forEach((r) => {
765
- r.add(t, e, s);
766
- });
767
- };
768
- ready;
769
- /** The number of promises that have been added to this group so far */
770
- get awaitedCount() {
771
- return this._addedCount;
772
- }
773
- /** The number of promises that have been resolved */
774
- get resolvedCount() {
775
- return this._resolvedCount;
776
- }
777
- /** The number of promises that are in-flight */
778
- get currentlyAwaiting() {
779
- return this._awaiting.length;
780
- }
781
- _resolve;
782
- _signal;
783
- /** start frame can be undefined if the user configured this group to wait for the first promise.
784
- * Then the start frame will be set when the first promise has been added to the group */
785
- _frame_start;
786
- /** How many frames to capture since the start frame */
787
- _frames_to_capture;
788
- _resolved = !1;
789
- _addedCount = 0;
790
- _resolvedCount = 0;
791
- /** These promises are currently being awaited */
792
- _awaiting = [];
793
- _maxPromisesPerObject = 1;
794
- constructor(t, e) {
795
- const n = Math.max(e.frames ?? 2, 2);
796
- this._frame_start = e.waitForFirstCapture ? void 0 : t, this._frames_to_capture = n, this.ready = new Promise((r) => {
797
- this._resolve = r;
798
- }), this.ready.finally(() => {
799
- this._resolved = !0, this._awaiting.length = 0;
800
- }), this._signal = e.signal, this._signal?.addEventListener("abort", () => {
801
- this.resolveNow();
802
- }), this._maxPromisesPerObject = Math.max(1, e.maxPromisesPerObject ?? 1);
803
- }
804
- _currentFrame = 0;
805
- update(t) {
806
- this._currentFrame = t, this._frame_start === void 0 && this._addedCount > 0 && (this._frame_start = t), (this._signal?.aborted || this._awaiting.length === 0 && this._frame_start !== void 0 && t > this._frame_start + this._frames_to_capture) && this.resolveNow();
807
- }
808
- _seen = /* @__PURE__ */ new WeakMap();
809
- add(t, e, s) {
810
- if (this._resolved) {
811
- g && console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");
812
- return;
813
- }
814
- if (!(this._frame_start !== void 0 && this._currentFrame > this._frame_start + this._frames_to_capture)) {
815
- if (this._maxPromisesPerObject >= 1)
816
- if (this._seen.has(e)) {
817
- let n = this._seen.get(e);
818
- if (n >= this._maxPromisesPerObject) {
819
- g && console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");
820
- return;
821
- }
822
- this._seen.set(e, n + 1);
823
- } else
824
- this._seen.set(e, 1);
825
- this._awaiting.push(s), this._addedCount++, s.finally(() => {
826
- this._resolvedCount++, this._awaiting.splice(this._awaiting.indexOf(s), 1);
827
- });
828
- }
829
- }
830
- resolveNow() {
831
- this._resolved || this._resolve?.({
832
- awaited_count: this._addedCount,
833
- resolved_count: this._resolvedCount,
834
- cancelled: this._signal?.aborted ?? !1
835
- });
836
- }
837
- }
838
- const C = X("debugprogressive"), pt = X("noprogressive"), ce = /* @__PURE__ */ Symbol("Needle:LODSManager"), fe = /* @__PURE__ */ Symbol("Needle:LODState"), W = /* @__PURE__ */ Symbol("Needle:CurrentLOD"), T = { mesh_lod: -1, texture_lod: -1 };
839
- let oe = class D {
840
- /**
841
- * 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.
842
- */
843
- static debugDrawLine;
844
- /** @internal */
845
- static getObjectLODState(t) {
846
- return t[fe];
847
- }
848
- static addPlugin(t) {
849
- U.push(t);
850
- }
851
- static removePlugin(t) {
852
- const e = U.indexOf(t);
853
- e >= 0 && U.splice(e, 1);
854
- }
855
- /**
856
- * Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
857
- * @param renderer The renderer to get the LODsManager for.
858
- * @returns The LODsManager instance.
859
- */
860
- static get(t, e) {
861
- if (t[ce])
862
- return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[ce];
863
- const s = new D(t, {
864
- engine: "unknown",
865
- ...e
866
- });
867
- return t[ce] = s, s;
868
- }
869
- renderer;
870
- context;
871
- projectionScreenMatrix = new _e();
872
- /** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
873
- get plugins() {
874
- return U;
875
- }
876
- /**
877
- * Force override the LOD level for all objects (meshes + textures) rendered in the scene
878
- * @default undefined automatically calculate LOD level
879
- */
880
- overrideLodLevel = void 0;
881
- /**
882
- * The target triangle density is the desired max amount of triangles on screen when the mesh is filling the screen.
883
- * @default 200_000
884
- */
885
- targetTriangleDensity = 2e5;
886
- /**
887
- * The interval in frames to automatically update the bounds of skinned meshes.
888
- * Set to 0 or a negative value to disable automatic bounds updates.
889
- * @default 30
890
- */
891
- skinnedMeshAutoUpdateBoundsInterval = 30;
892
- /**
893
- * The update interval in frames. If set to 0, the LODs will be updated every frame. If set to 2, the LODs will be updated every second frame, etc.
894
- * @default "auto"
895
- */
896
- updateInterval = "auto";
897
- #e = 1;
898
- /**
899
- * If set to true, the LODsManager will not update the LODs.
900
- * @default false
901
- */
902
- pause = !1;
903
- /**
904
- * When set to true the LODsManager will not update the LODs. This can be used to manually update the LODs using the `update` method.
905
- * Otherwise the LODs will be updated automatically when the renderer renders the scene.
906
- * @default false
907
- */
908
- manual = !1;
909
- _newPromiseGroups = [];
910
- _promiseGroupIds = 0;
911
- /**
912
- * Call to await LODs loading during the next render cycle.
913
- */
914
- awaitLoading(t) {
915
- const e = this._promiseGroupIds++, s = new de(this.#r, { ...t });
916
- this._newPromiseGroups.push(s);
917
- const n = performance.now();
918
- return s.ready.finally(() => {
919
- const r = this._newPromiseGroups.indexOf(s);
920
- r >= 0 && (this._newPromiseGroups.splice(r, 1), Me() && performance.measure("LODsManager:awaitLoading", {
921
- start: n,
922
- detail: { id: e, name: t?.name, awaited: s.awaitedCount, resolved: s.resolvedCount }
923
- }));
924
- }), s.ready;
925
- }
926
- _postprocessPromiseGroups() {
927
- if (this._newPromiseGroups.length !== 0)
928
- for (let t = this._newPromiseGroups.length - 1; t >= 0; t--)
929
- this._newPromiseGroups[t].update(this.#r);
930
- }
931
- _lodchangedlisteners = [];
932
- addEventListener(t, e) {
933
- t === "changed" && this._lodchangedlisteners.push(e);
934
- }
935
- removeEventListener(t, e) {
936
- if (t === "changed") {
937
- const s = this._lodchangedlisteners.indexOf(e);
938
- s >= 0 && this._lodchangedlisteners.splice(s, 1);
939
- }
940
- }
941
- // readonly plugins: NEEDLE_progressive_plugin[] = [];
942
- constructor(t, e) {
943
- this.renderer = t, this.context = { ...e };
944
- }
945
- #t;
946
- #o = new Ne();
947
- #r = 0;
948
- #n = 0;
949
- #i = 0;
950
- #s = 0;
951
- _fpsBuffer = [60, 60, 60, 60, 60];
952
- /**
953
- * Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
954
- */
955
- enable() {
956
- if (this.#t) return;
957
- console.debug("[gltf-progressive] Enabling LODsManager for renderer");
958
- let t = 0;
959
- this.#t = this.renderer.render;
960
- const e = this;
961
- we(this.renderer), this.renderer.render = function(s, n) {
962
- const r = e.renderer.getRenderTarget();
963
- (r == null || "isXRRenderTarget" in r && r.isXRRenderTarget) && (t = 0, e.#r += 1, e.#n = e.#o.getDelta(), e.#i += e.#n, e._fpsBuffer.shift(), e._fpsBuffer.push(1 / e.#n), e.#s = e._fpsBuffer.reduce((l, a) => l + a) / e._fpsBuffer.length, C && e.#r % 200 === 0 && console.log("FPS", Math.round(e.#s), "Interval:", e.#e));
964
- const o = t++;
965
- e.#t.call(this, s, n), e.onAfterRender(s, n, o);
966
- };
967
- }
968
- disable() {
969
- this.#t && (console.debug("[gltf-progressive] Disabling LODsManager for renderer"), this.renderer.render = this.#t, this.#t = void 0);
970
- }
971
- update(t, e) {
972
- this.internalUpdate(t, e);
973
- }
974
- onAfterRender(t, e, s) {
975
- if (this.pause) return;
976
- const r = this.renderer.renderLists.get(t, 0).opaque;
977
- let o = !0;
978
- if (r.length === 1) {
979
- const l = r[0].material;
980
- (l.name === "EffectMaterial" || l.name === "CopyShader") && (o = !1);
981
- }
982
- if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (o = !1), o) {
983
- if (pt || (this.updateInterval === "auto" ? this.#s < 40 && this.#e < 10 ? (this.#e += 1, C && console.warn("↓ Reducing LOD updates", this.#e, this.#s.toFixed(0))) : this.#s >= 60 && this.#e > 1 && (this.#e -= 1, C && console.warn("↑ Increasing LOD updates", this.#e, this.#s.toFixed(0))) : this.#e = this.updateInterval, this.#e > 0 && this.#r % this.#e != 0))
984
- return;
985
- this.internalUpdate(t, e), this._postprocessPromiseGroups();
986
- }
987
- }
988
- /**
989
- * Update LODs in a scene
990
- */
991
- internalUpdate(t, e) {
992
- const s = this.renderer.renderLists.get(t, 0), n = s.opaque;
993
- this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse);
994
- const r = this.targetTriangleDensity;
995
- for (const a of n) {
996
- 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")) {
997
- C && (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)));
998
- continue;
999
- }
1000
- switch (a.material.type) {
1001
- case "LineBasicMaterial":
1002
- case "LineDashedMaterial":
1003
- case "PointsMaterial":
1004
- case "ShadowMaterial":
1005
- case "MeshDistanceMaterial":
1006
- case "MeshDepthMaterial":
1007
- continue;
1008
- }
1009
- if (C === "color" && a.material && !a.object.progressive_debug_color) {
1010
- a.object.progressive_debug_color = !0;
1011
- const d = Math.random() * 16777215, p = new qe({ color: d });
1012
- a.object.material = p;
1013
- }
1014
- const u = a.object;
1015
- (u instanceof q || u.isMesh) && this.updateLODs(t, e, u, r);
1016
- }
1017
- const o = s.transparent;
1018
- for (const a of o) {
1019
- const u = a.object;
1020
- (u instanceof q || u.isMesh) && this.updateLODs(t, e, u, r);
1021
- }
1022
- const l = s.transmissive;
1023
- for (const a of l) {
1024
- const u = a.object;
1025
- (u instanceof q || u.isMesh) && this.updateLODs(t, e, u, r);
1026
- }
1027
- }
1028
- /** Update the LOD levels for the renderer. */
1029
- updateLODs(t, e, s, n) {
1030
- s.userData || (s.userData = {});
1031
- let r = s[fe];
1032
- if (r || (r = new mt(), s[fe] = r), r.frames++ < 2)
1033
- return;
1034
- for (const l of U)
1035
- l.onBeforeUpdateLOD?.(this.renderer, t, e, s);
1036
- const o = this.overrideLodLevel !== void 0 ? this.overrideLodLevel : N;
1037
- o >= 0 ? (T.mesh_lod = o, T.texture_lod = o) : (this.calculateLodLevel(e, s, r, n, 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, o), g && s.material && !s.isGizmo && Ce(s.material);
1038
- for (const l of U)
1039
- l.onAfterUpdatedLOD?.(this.renderer, t, e, s, T);
1040
- r.lastLodLevel_Mesh = T.mesh_lod, r.lastLodLevel_Texture = T.texture_lod;
1041
- }
1042
- /** Load progressive textures for the given material
1043
- * @param material the material to load the textures for
1044
- * @param level the LOD level to load. Level 0 is the best quality, higher levels are lower quality
1045
- * @returns Promise with true if the LOD was loaded, false if not
1046
- */
1047
- loadProgressiveTextures(t, e, s) {
1048
- if (!t) return;
1049
- if (Array.isArray(t)) {
1050
- for (const r of t)
1051
- this.loadProgressiveTextures(r, e);
1052
- return;
1053
- }
1054
- let n = !1;
1055
- if ((t[W] === void 0 || e < t[W]) && (n = !0), s !== void 0 && s >= 0 && (n = t[W] != s, e = s), n) {
1056
- t[W] = e;
1057
- const r = y.assignTextureLOD(t, e).then((o) => {
1058
- this._lodchangedlisteners.forEach((l) => l({ type: "texture", level: e, object: t }));
1059
- });
1060
- de.addPromise("texture", t, r, this._newPromiseGroups);
1061
- }
1062
- }
1063
- /** Load progressive meshes for the given mesh
1064
- * @param mesh the mesh to load the LOD for
1065
- * @param index the index of the mesh if it's part of a group
1066
- * @param level the LOD level to load. Level 0 is the best quality, higher levels are lower quality
1067
- * @returns Promise with true if the LOD was loaded, false if not
1068
- */
1069
- loadProgressiveMeshes(t, e) {
1070
- if (!t) return Promise.resolve(null);
1071
- let s = t[W] !== e;
1072
- const n = t["DEBUG:LOD"];
1073
- if (n != null && (s = t[W] != n, e = n), s) {
1074
- t[W] = e;
1075
- const r = t.geometry, o = y.assignMeshLOD(t, e).then((l) => (l && t[W] == e && r != t.geometry && this._lodchangedlisteners.forEach((a) => a({ type: "mesh", level: e, object: t })), l));
1076
- return de.addPromise("mesh", t, o, this._newPromiseGroups), o;
1077
- }
1078
- return Promise.resolve(null);
1079
- }
1080
- // private testIfLODLevelsAreAvailable() {
1081
- _sphere = new Oe();
1082
- _tempBox = new ge();
1083
- _tempBox2 = new ge();
1084
- tempMatrix = new _e();
1085
- _tempWorldPosition = new A();
1086
- _tempBoxSize = new A();
1087
- _tempBox2Size = new A();
1088
- static corner0 = new A();
1089
- static corner1 = new A();
1090
- static corner2 = new A();
1091
- static corner3 = new A();
1092
- static _tempPtInside = new A();
1093
- static isInside(t, e) {
1094
- const s = t.min, n = t.max, r = (s.x + n.x) * 0.5, o = (s.y + n.y) * 0.5;
1095
- return this._tempPtInside.set(r, o, s.z).applyMatrix4(e).z < 0;
1096
- }
1097
- static skinnedMeshBoundsFrameOffsetCounter = 0;
1098
- static $skinnedMeshBoundsOffset = /* @__PURE__ */ Symbol("gltf-progressive-skinnedMeshBoundsOffset");
1099
- // #region calculateLodLevel
1100
- calculateLodLevel(t, e, s, n, r) {
1101
- if (!e) {
1102
- r.mesh_lod = -1, r.texture_lod = -1;
1103
- return;
1104
- }
1105
- if (!t) {
1106
- r.mesh_lod = -1, r.texture_lod = -1;
1107
- return;
1108
- }
1109
- let l = 10 + 1, a = !1;
1110
- if (C && e["DEBUG:LOD"] != null)
1111
- return e["DEBUG:LOD"];
1112
- const u = y.getMeshLODExtension(e.geometry)?.lods, d = y.getPrimitiveIndex(e.geometry), p = u && u.length > 0, L = y.getMaterialMinMaxLODsCount(e.material), _ = L.min_count !== 1 / 0 && L.min_count >= 0 && L.max_count >= 0;
1113
- if (!p && !_) {
1114
- r.mesh_lod = 0, r.texture_lod = 0;
1115
- return;
1116
- }
1117
- p || (a = !0, l = 0);
1118
- const I = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
1119
- let G = e.geometry.boundingBox;
1120
- if (e.type === "SkinnedMesh") {
1121
- const c = e;
1122
- if (!c.boundingBox)
1123
- c.computeBoundingBox();
1124
- else if (this.skinnedMeshAutoUpdateBoundsInterval > 0) {
1125
- if (!c[D.$skinnedMeshBoundsOffset]) {
1126
- const O = D.skinnedMeshBoundsFrameOffsetCounter++;
1127
- c[D.$skinnedMeshBoundsOffset] = O;
1128
- }
1129
- const x = c[D.$skinnedMeshBoundsOffset];
1130
- if ((s.frames + x) % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
1131
- const O = Z(c), B = c.geometry;
1132
- O && (c.geometry = O), c.computeBoundingBox(), c.geometry = B;
1133
- }
1134
- }
1135
- G = c.boundingBox;
1136
- }
1137
- if (G) {
1138
- const c = t;
1139
- if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
1140
- this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
1141
- const f = t.getWorldPosition(this._tempWorldPosition);
1142
- if (this._sphere.containsPoint(f)) {
1143
- r.mesh_lod = 0, r.texture_lod = 0;
1144
- return;
1145
- }
1146
- }
1147
- if (this._tempBox.copy(G), this._tempBox.applyMatrix4(e.matrixWorld), c.isPerspectiveCamera && D.isInside(this._tempBox, this.projectionScreenMatrix)) {
1148
- r.mesh_lod = 0, r.texture_lod = 0;
1149
- return;
1150
- }
1151
- if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && c.isPerspectiveCamera && c.fov > 70) {
1152
- const f = this._tempBox.min, h = this._tempBox.max;
1153
- let v = f.x, b = f.y, $ = h.x, j = h.y;
1154
- const ee = 2, ie = 1.5, te = (f.x + h.x) * 0.5, se = (f.y + h.y) * 0.5;
1155
- v = (v - te) * ee + te, b = (b - se) * ee + se, $ = ($ - te) * ee + te, j = (j - se) * ee + se;
1156
- const Be = v < 0 && $ > 0 ? 0 : Math.min(Math.abs(f.x), Math.abs(h.x)), $e = b < 0 && j > 0 ? 0 : Math.min(Math.abs(f.y), Math.abs(h.y)), ae = Math.max(Be, $e);
1157
- s.lastCentrality = (ie - ae) * (ie - ae) * (ie - ae);
1158
- } else
1159
- s.lastCentrality = 1;
1160
- const x = this._tempBox.getSize(this._tempBoxSize);
1161
- x.multiplyScalar(0.5), screen.availHeight > 0 && I > 0 && x.multiplyScalar(I / screen.availHeight), t.isPerspectiveCamera ? x.x *= t.aspect : t.isOrthographicCamera;
1162
- const O = t.matrixWorldInverse, B = this._tempBox2;
1163
- B.copy(G), B.applyMatrix4(e.matrixWorld), B.applyMatrix4(O);
1164
- const M = B.getSize(this._tempBox2Size), z = Math.max(M.x, M.y);
1165
- if (Math.max(x.x, x.y) != 0 && z != 0 && (x.z = M.z / Math.max(M.x, M.y) * Math.max(x.x, x.y)), s.lastScreenCoverage = Math.max(x.x, x.y, x.z), s.lastScreenspaceVolume.copy(x), s.lastScreenCoverage *= s.lastCentrality, C && D.debugDrawLine) {
1166
- const f = this.tempMatrix.copy(this.projectionScreenMatrix);
1167
- f.invert();
1168
- const h = D.corner0, v = D.corner1, b = D.corner2, $ = D.corner3;
1169
- h.copy(this._tempBox.min), v.copy(this._tempBox.max), v.x = h.x, b.copy(this._tempBox.max), b.y = h.y, $.copy(this._tempBox.max);
1170
- const j = (h.z + $.z) * 0.5;
1171
- h.z = v.z = b.z = $.z = j, h.applyMatrix4(f), v.applyMatrix4(f), b.applyMatrix4(f), $.applyMatrix4(f), D.debugDrawLine(h, v, 255), D.debugDrawLine(h, b, 255), D.debugDrawLine(v, $, 255), D.debugDrawLine(b, $, 255);
1172
- }
1173
- let w = 999;
1174
- if (u && s.lastScreenCoverage > 0)
1175
- for (let f = 0; f < u.length; f++) {
1176
- const h = u[f], b = (h.densities?.[d] || h.density || 1e-5) / s.lastScreenCoverage;
1177
- if (d > 0 && Me() && !h.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.")), b < n) {
1178
- w = f;
1179
- break;
1180
- }
1181
- }
1182
- w < l && (l = w, a = !0);
1183
- }
1184
- if (a ? r.mesh_lod = l : r.mesh_lod = s.lastLodLevel_Mesh, C && r.mesh_lod != s.lastLodLevel_Mesh) {
1185
- const x = u?.[r.mesh_lod];
1186
- x && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${r.mesh_lod} (density: ${x.densities?.[d].toFixed(0)}) | ${e.name}`);
1187
- }
1188
- if (_) {
1189
- const c = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
1190
- if (s.lastLodLevel_Texture < 0) {
1191
- if (r.texture_lod = L.max_count - 1, C) {
1192
- const x = L.lods[L.max_count - 1];
1193
- C && console.log(`First Texture LOD ${r.texture_lod} (${x.max_height}px) - ${e.name}`);
1194
- }
1195
- } else {
1196
- const x = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
1197
- let O = s.lastScreenCoverage * 4;
1198
- this.context?.engine === "model-viewer" && (O *= 1.5);
1199
- const M = I / window.devicePixelRatio * O;
1200
- let z = !1;
1201
- for (let S = L.lods.length - 1; S >= 0; S--) {
1202
- const w = L.lods[S];
1203
- if (!(c && w.max_height >= 2048) && !(Ie() && w.max_height > 4096) && (w.max_height > M || !z && S === 0)) {
1204
- if (z = !0, r.texture_lod = S, C && r.texture_lod < s.lastLodLevel_Texture) {
1205
- const m = w.max_height;
1206
- console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${r.texture_lod} = ${m}px
1207
- Screensize: ${M.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${x.toFixed(1)}
1208
- ${e.name}`);
1209
- }
1210
- break;
1211
- }
1212
- }
1213
- }
1214
- } else
1215
- r.texture_lod = 0;
1216
- }
1217
- };
1218
- class mt {
1219
- frames = 0;
1220
- lastLodLevel_Mesh = -1;
1221
- lastLodLevel_Texture = -1;
1222
- lastScreenCoverage = 0;
1223
- lastScreenspaceVolume = new A();
1224
- lastCentrality = 0;
1225
- }
1226
- const ve = /* @__PURE__ */ Symbol("NEEDLE_mesh_lod"), re = /* @__PURE__ */ Symbol("NEEDLE_texture_lod");
1227
- let he = null;
1228
- function ke() {
1229
- const i = yt();
1230
- i && (i.mapURLs(function(t) {
1231
- return De(), t;
1232
- }), De(), he?.disconnect(), he = new MutationObserver((t) => {
1233
- t.forEach((e) => {
1234
- e.addedNodes.forEach((s) => {
1235
- s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Re(s);
1236
- });
1237
- });
1238
- }), he.observe(document, { childList: !0, subtree: !0 }));
1239
- }
1240
- function yt() {
1241
- if (typeof customElements > "u") return null;
1242
- const i = customElements.get("model-viewer");
1243
- return i || (customElements.whenDefined("model-viewer").then(() => {
1244
- console.debug("[gltf-progressive] model-viewer defined"), ke();
1245
- }), null);
1246
- }
1247
- function De() {
1248
- if (typeof document > "u") return;
1249
- document.querySelectorAll("model-viewer").forEach((t) => {
1250
- Re(t);
1251
- });
1252
- }
1253
- const be = /* @__PURE__ */ new WeakSet();
1254
- let xt = 0;
1255
- function Re(i) {
1256
- if (!i || be.has(i))
1257
- return null;
1258
- be.add(i), console.debug("[gltf-progressive] found new model-viewer..." + ++xt + `
1259
- `, i.getAttribute("src"));
1260
- let t = null, e = null, s = null;
1261
- for (let n = i; n != null; n = Object.getPrototypeOf(n)) {
1262
- const r = Object.getOwnPropertySymbols(n), o = r.find((u) => u.toString() == "Symbol(renderer)"), l = r.find((u) => u.toString() == "Symbol(scene)"), a = r.find((u) => u.toString() == "Symbol(needsRender)");
1263
- !t && o != null && (t = i[o].threeRenderer), !e && l != null && (e = i[l]), !s && a != null && (s = i[a]);
1264
- }
1265
- if (t && e) {
1266
- let n = function() {
1267
- if (s) {
1268
- let o = 0, l = setInterval(() => {
1269
- if (o++ > 5) {
1270
- clearInterval(l);
1271
- return;
1272
- }
1273
- s?.call(i);
1274
- }, 300);
1275
- }
1276
- };
1277
- console.debug("[gltf-progressive] setup model-viewer");
1278
- const r = oe.get(t, { engine: "model-viewer" });
1279
- return oe.addPlugin(new wt()), r.enable(), r.addEventListener("changed", () => {
1280
- s?.call(i);
1281
- }), i.addEventListener("model-visibility", (o) => {
1282
- o.detail.visible && s?.call(i);
1283
- }), i.addEventListener("load", () => {
1284
- n();
1285
- }), () => {
1286
- r.disable();
1287
- };
1288
- }
1289
- return null;
1290
- }
1291
- class wt {
1292
- _didWarnAboutMissingUrl = !1;
1293
- onBeforeUpdateLOD(t, e, s, n) {
1294
- this.tryParseMeshLOD(e, n), this.tryParseTextureLOD(e, n);
1295
- }
1296
- getUrl(t) {
1297
- if (!t)
1298
- return null;
1299
- let e = t.getAttribute("src");
1300
- return e || (e = t.src), e || (this._didWarnAboutMissingUrl || console.warn("No url found in modelviewer", t), this._didWarnAboutMissingUrl = !0), e;
1301
- }
1302
- tryGetCurrentGLTF(t) {
1303
- return t._currentGLTF;
1304
- }
1305
- tryGetCurrentModelViewer(t) {
1306
- return t.element;
1307
- }
1308
- tryParseTextureLOD(t, e) {
1309
- if (e[re] == !0) return;
1310
- e[re] = !0;
1311
- const s = this.tryGetCurrentGLTF(t), n = this.tryGetCurrentModelViewer(t), r = this.getUrl(n);
1312
- if (r && s && e.material) {
1313
- let o = function(a) {
1314
- if (a[re] == !0) return;
1315
- a[re] = !0, a.userData && (a.userData.LOD = -1);
1316
- const u = Object.keys(a);
1317
- for (let d = 0; d < u.length; d++) {
1318
- const p = u[d], L = a[p];
1319
- if (L?.isTexture === !0) {
1320
- const _ = L.userData?.associations?.textures;
1321
- if (_ == null) continue;
1322
- const I = s.parser.json.textures[_];
1323
- if (!I) {
1324
- console.warn("Texture data not found for texture index " + _);
1325
- continue;
1326
- }
1327
- if (I?.extensions?.[F]) {
1328
- const G = I.extensions[F];
1329
- G && r && y.registerTexture(r, L, G.lods.length, _, G);
1330
- }
1331
- }
1332
- }
1333
- };
1334
- const l = e.material;
1335
- if (Array.isArray(l)) for (const a of l) o(a);
1336
- else o(l);
1337
- }
1338
- }
1339
- tryParseMeshLOD(t, e) {
1340
- if (e[ve] == !0) return;
1341
- e[ve] = !0;
1342
- const s = this.tryGetCurrentModelViewer(t), n = this.getUrl(s);
1343
- if (!n)
1344
- return;
1345
- const r = e.userData?.gltfExtensions?.[F];
1346
- if (r && n) {
1347
- const o = e.uuid;
1348
- y.registerMesh(n, o, e, 0, r.lods.length, r);
1349
- }
1350
- }
1351
- }
1352
- function Lt(...i) {
1353
- let t, e, s, n;
1354
- switch (i.length) {
1355
- case 2:
1356
- [s, e] = i, n = {};
1357
- break;
1358
- case 3:
1359
- [s, e, n] = i;
1360
- break;
1361
- case 4:
1362
- [t, e, s, n] = i;
1363
- break;
1364
- default:
1365
- throw new Error("Invalid arguments");
1366
- }
1367
- we(e), Te(s), Ae(s, {
1368
- progressive: !0,
1369
- ...n?.hints
1370
- }), s.register((o) => new y(o));
1371
- const r = oe.get(e);
1372
- return n?.enableLODsManager !== !1 && r.enable(), r;
1373
- }
1374
- ke();
1375
- if (!nt) {
1376
- const i = {
1377
- gltfProgressive: {
1378
- useNeedleProgressive: Lt,
1379
- LODsManager: oe,
1380
- configureLoader: Ae,
1381
- getRaycastMesh: Z,
1382
- useRaycastMeshes: it
1383
- }
1384
- };
1385
- if (!globalThis.Needle)
1386
- globalThis.Needle = i;
1387
- else
1388
- for (const t in i)
1389
- globalThis.Needle[t] = i[t];
1390
- }
1391
- export {
1392
- oe as LODsManager,
1393
- y as NEEDLE_progressive,
1394
- Te as addDracoAndKTX2Loaders,
1395
- Ae as configureLoader,
1396
- we as createLoaders,
1397
- Z as getRaycastMesh,
1398
- Je as setDracoDecoderLocation,
1399
- Ze as setKTX2TranscoderLocation
1400
- };