@needle-tools/gltf-progressive 3.0.0 → 3.0.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.
- package/CHANGELOG.md +2 -1
- package/gltf-progressive.js +602 -494
- package/gltf-progressive.min.js +7 -7
- package/gltf-progressive.umd.cjs +7 -7
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -2
- package/lib/{lods_manager.d.ts → lods.manager.d.ts} +15 -3
- package/lib/{lods_manager.js → lods.manager.js} +40 -11
- package/lib/lods.promise.d.ts +61 -0
- package/lib/lods.promise.js +101 -0
- package/lib/plugins/modelviewer.js +1 -1
- package/lib/utils.internal.d.ts +1 -0
- package/lib/utils.internal.js +8 -0
- package/lib/version.js +1 -1
- package/package.json +2 -2
package/gltf-progressive.js
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var d = (n, t, e) => (
|
|
1
|
+
var Ye = Object.defineProperty;
|
|
2
|
+
var He = (n, t, e) => t in n ? Ye(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
|
|
3
|
+
var d = (n, t, e) => (He(n, typeof t != "symbol" ? t + "" : t, e), e), Ee = (n, t, e) => {
|
|
4
4
|
if (!t.has(n))
|
|
5
5
|
throw TypeError("Cannot " + e);
|
|
6
6
|
};
|
|
7
|
-
var
|
|
7
|
+
var p = (n, t, e) => (Ee(n, t, "read from private field"), e ? e.call(n) : t.get(n)), J = (n, t, e) => {
|
|
8
8
|
if (t.has(n))
|
|
9
9
|
throw TypeError("Cannot add the same private member more than once");
|
|
10
10
|
t instanceof WeakSet ? t.add(n) : t.set(n, e);
|
|
11
|
-
}, V = (n, t, e,
|
|
12
|
-
import { BufferGeometry as
|
|
13
|
-
import { GLTFLoader as
|
|
14
|
-
import { MeshoptDecoder as
|
|
15
|
-
import { DRACOLoader as
|
|
16
|
-
import { KTX2Loader as
|
|
11
|
+
}, V = (n, t, e, s) => (Ee(n, t, "write to private field"), s ? s.call(n, e) : t.set(n, e), e);
|
|
12
|
+
import { BufferGeometry as xe, Mesh as se, Texture as ne, TextureLoader as je, Matrix4 as Ge, Clock as Je, MeshStandardMaterial as Qe, Sphere as Ze, Box3 as Ie, Vector3 as K } from "three";
|
|
13
|
+
import { GLTFLoader as Ce } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
14
|
+
import { MeshoptDecoder as et } from "three/examples/jsm/libs/meshopt_decoder.module.js";
|
|
15
|
+
import { DRACOLoader as tt } from "three/examples/jsm/loaders/DRACOLoader.js";
|
|
16
|
+
import { KTX2Loader as st } from "three/examples/jsm/loaders/KTX2Loader.js";
|
|
17
17
|
const rt = "";
|
|
18
18
|
globalThis.GLTF_PROGRESSIVE_VERSION = rt;
|
|
19
19
|
console.debug("[gltf-progressive] version -");
|
|
20
20
|
let W = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/", re = "https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
fetch(
|
|
21
|
+
const it = W, ot = re, $e = new URL(W + "draco_decoder.js");
|
|
22
|
+
$e.searchParams.append("range", "true");
|
|
23
|
+
fetch($e, {
|
|
24
24
|
method: "GET",
|
|
25
25
|
headers: {
|
|
26
26
|
Range: "bytes=0-1"
|
|
27
27
|
}
|
|
28
28
|
}).catch((n) => {
|
|
29
|
-
console.debug(`Failed to fetch remote Draco decoder from ${W} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), W ===
|
|
29
|
+
console.debug(`Failed to fetch remote Draco decoder from ${W} (offline: ${typeof navigator < "u" ? navigator.onLine : "unknown"})`), W === it && nt("./include/draco/"), re === ot && at("./include/ktx2/");
|
|
30
30
|
}).finally(() => {
|
|
31
|
-
|
|
31
|
+
Fe();
|
|
32
32
|
});
|
|
33
|
-
function it(n) {
|
|
34
|
-
W = n, R && R[Se] != W ? (console.debug("Updating Draco decoder path to " + n), R[Se] = W, R.setDecoderPath(W), R.preload()) : console.debug("Setting Draco decoder path to " + n);
|
|
35
|
-
}
|
|
36
33
|
function nt(n) {
|
|
37
|
-
|
|
34
|
+
W = n, B && B[Pe] != W ? (console.debug("Updating Draco decoder path to " + n), B[Pe] = W, B.setDecoderPath(W), B.preload()) : console.debug("Setting Draco decoder path to " + n);
|
|
35
|
+
}
|
|
36
|
+
function at(n) {
|
|
37
|
+
re = n, U && U.transcoderPath != re ? (console.debug("Updating KTX2 transcoder path to " + n), U.setTranscoderPath(re), U.init()) : console.debug("Setting KTX2 transcoder path to " + n);
|
|
38
38
|
}
|
|
39
|
-
const
|
|
40
|
-
let
|
|
41
|
-
function
|
|
42
|
-
|
|
39
|
+
const Pe = Symbol("dracoDecoderPath");
|
|
40
|
+
let B, Le, U;
|
|
41
|
+
function Fe() {
|
|
42
|
+
B || (B = new tt(), B[Pe] = W, B.setDecoderPath(W), B.setDecoderConfig({ type: "js" }), B.preload()), U || (U = new st(), U.setTranscoderPath(re), U.init()), Le || (Le = et);
|
|
43
43
|
}
|
|
44
44
|
function Ue(n) {
|
|
45
|
-
return
|
|
45
|
+
return Fe(), n ? U.detectSupport(n) : n !== null && console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"), { dracoLoader: B, ktx2Loader: U, meshoptDecoder: Le };
|
|
46
46
|
}
|
|
47
|
-
function
|
|
48
|
-
n.dracoLoader || n.setDRACOLoader(
|
|
47
|
+
function Ne(n) {
|
|
48
|
+
n.dracoLoader || n.setDRACOLoader(B), n.ktx2Loader || n.setKTX2Loader(U), n.meshoptDecoder || n.setMeshoptDecoder(Le);
|
|
49
49
|
}
|
|
50
50
|
const Te = /* @__PURE__ */ new WeakMap();
|
|
51
|
-
function
|
|
51
|
+
function ze(n, t) {
|
|
52
52
|
let e = Te.get(n);
|
|
53
53
|
e ? e = Object.assign(e, t) : e = t, Te.set(n, e);
|
|
54
54
|
}
|
|
55
|
-
const
|
|
56
|
-
function
|
|
55
|
+
const Me = Ce.prototype.load;
|
|
56
|
+
function lt(...n) {
|
|
57
57
|
const t = Te.get(this);
|
|
58
58
|
let e = n[0];
|
|
59
|
-
const
|
|
60
|
-
if (
|
|
61
|
-
const
|
|
62
|
-
|
|
59
|
+
const s = new URL(e, window.location.href);
|
|
60
|
+
if (s.hostname.endsWith("needle.tools")) {
|
|
61
|
+
const r = (t == null ? void 0 : t.progressive) !== void 0 ? t.progressive : !0, i = t != null && t.usecase ? t.usecase : "default";
|
|
62
|
+
r ? this.requestHeader.Accept = `*/*;progressive=allowed;usecase=${i}` : this.requestHeader.Accept = `*/*;usecase=${i}`, e = s.toString();
|
|
63
63
|
}
|
|
64
|
-
return n[0] = e,
|
|
64
|
+
return n[0] = e, Me == null ? void 0 : Me.call(this, ...n);
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
Ce.prototype.load = lt;
|
|
67
67
|
ue("debugprogressive");
|
|
68
68
|
function ue(n) {
|
|
69
69
|
if (typeof window > "u")
|
|
@@ -71,91 +71,97 @@ function ue(n) {
|
|
|
71
71
|
const e = new URL(window.location.href).searchParams.get(n);
|
|
72
72
|
return e == null || e === "0" || e === "false" ? !1 : e === "" ? !0 : e;
|
|
73
73
|
}
|
|
74
|
-
function
|
|
74
|
+
function dt(n, t) {
|
|
75
75
|
if (t === void 0 || t.startsWith("./") || t.startsWith("http") || n === void 0)
|
|
76
76
|
return t;
|
|
77
77
|
const e = n.lastIndexOf("/");
|
|
78
78
|
if (e >= 0) {
|
|
79
|
-
const
|
|
80
|
-
for (;
|
|
79
|
+
const s = n.substring(0, e + 1);
|
|
80
|
+
for (; s.endsWith("/") && t.startsWith("/"); )
|
|
81
81
|
t = t.substring(1);
|
|
82
|
-
return
|
|
82
|
+
return s + t;
|
|
83
83
|
}
|
|
84
84
|
return t;
|
|
85
85
|
}
|
|
86
86
|
let ae;
|
|
87
|
-
function
|
|
87
|
+
function ut() {
|
|
88
88
|
return ae !== void 0 || (ae = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), ue("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", ae)), ae;
|
|
89
89
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
function ct() {
|
|
91
|
+
if (typeof window > "u")
|
|
92
|
+
return !1;
|
|
93
|
+
const n = new URL(window.location.href), t = n.hostname === "localhost" || /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(n.hostname);
|
|
94
|
+
return n.hostname === "127.0.0.1" || t;
|
|
95
|
+
}
|
|
96
|
+
const ft = typeof window > "u" && typeof document > "u", Ae = Symbol("needle:raycast-mesh");
|
|
97
|
+
function ce(n) {
|
|
98
|
+
return (n == null ? void 0 : n[Ae]) instanceof xe ? n[Ae] : null;
|
|
93
99
|
}
|
|
94
|
-
function
|
|
95
|
-
if ((n.type === "Mesh" || n.type === "SkinnedMesh") && !
|
|
96
|
-
const
|
|
97
|
-
|
|
100
|
+
function ht(n, t) {
|
|
101
|
+
if ((n.type === "Mesh" || n.type === "SkinnedMesh") && !ce(n)) {
|
|
102
|
+
const s = pt(t);
|
|
103
|
+
s.userData = { isRaycastMesh: !0 }, n[Ae] = s;
|
|
98
104
|
}
|
|
99
105
|
}
|
|
100
|
-
function
|
|
106
|
+
function gt(n = !0) {
|
|
101
107
|
if (n) {
|
|
102
108
|
if (le)
|
|
103
109
|
return;
|
|
104
|
-
const t = le =
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
let
|
|
108
|
-
|
|
110
|
+
const t = le = se.prototype.raycast;
|
|
111
|
+
se.prototype.raycast = function(e, s) {
|
|
112
|
+
const o = this, r = ce(o);
|
|
113
|
+
let i;
|
|
114
|
+
r && o.isMesh && (i = o.geometry, o.geometry = r), t.call(this, e, s), i && (o.geometry = i);
|
|
109
115
|
};
|
|
110
116
|
} else {
|
|
111
117
|
if (!le)
|
|
112
118
|
return;
|
|
113
|
-
|
|
119
|
+
se.prototype.raycast = le, le = null;
|
|
114
120
|
}
|
|
115
121
|
}
|
|
116
122
|
let le = null;
|
|
117
|
-
function
|
|
118
|
-
const t = new
|
|
123
|
+
function pt(n) {
|
|
124
|
+
const t = new xe();
|
|
119
125
|
for (const e in n.attributes)
|
|
120
126
|
t.setAttribute(e, n.getAttribute(e));
|
|
121
127
|
return t.setIndex(n.getIndex()), t;
|
|
122
128
|
}
|
|
123
|
-
const Z = new Array(),
|
|
124
|
-
let
|
|
125
|
-
if (
|
|
129
|
+
const Z = new Array(), y = ue("debugprogressive");
|
|
130
|
+
let me, te = -1;
|
|
131
|
+
if (y) {
|
|
126
132
|
let n = function() {
|
|
127
|
-
|
|
133
|
+
te += 1, te >= t && (te = -1), console.log(`Toggle LOD level [${te}]`);
|
|
128
134
|
}, t = 6;
|
|
129
135
|
window.addEventListener("keyup", (e) => {
|
|
130
|
-
e.key === "p" && n(), e.key === "w" && (
|
|
131
|
-
const
|
|
132
|
-
!isNaN(
|
|
136
|
+
e.key === "p" && n(), e.key === "w" && (me = !me, console.log(`Toggle wireframe [${me}]`));
|
|
137
|
+
const s = parseInt(e.key);
|
|
138
|
+
!isNaN(s) && s >= 0 && (te = s, console.log(`Set LOD level to [${te}]`));
|
|
133
139
|
});
|
|
134
140
|
}
|
|
135
|
-
function
|
|
136
|
-
if (
|
|
141
|
+
function Ve(n) {
|
|
142
|
+
if (y)
|
|
137
143
|
if (Array.isArray(n))
|
|
138
144
|
for (const t of n)
|
|
139
|
-
|
|
145
|
+
Ve(t);
|
|
140
146
|
else
|
|
141
|
-
n && "wireframe" in n && (n.wireframe =
|
|
147
|
+
n && "wireframe" in n && (n.wireframe = me === !0);
|
|
142
148
|
}
|
|
143
|
-
const Y = "NEEDLE_progressive",
|
|
149
|
+
const Y = "NEEDLE_progressive", Oe = Symbol("needle-progressive-texture"), b = class {
|
|
144
150
|
constructor(t, e) {
|
|
145
151
|
d(this, "parser");
|
|
146
152
|
d(this, "url");
|
|
147
153
|
d(this, "_isLoadingMesh");
|
|
148
154
|
d(this, "loadMesh", (t) => {
|
|
149
|
-
var
|
|
155
|
+
var s, o;
|
|
150
156
|
if (this._isLoadingMesh)
|
|
151
157
|
return null;
|
|
152
|
-
const e = (
|
|
153
|
-
return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((
|
|
154
|
-
var
|
|
155
|
-
return this._isLoadingMesh = !1,
|
|
158
|
+
const e = (o = (s = this.parser.json.meshes[t]) == null ? void 0 : s.extensions) == null ? void 0 : o[Y];
|
|
159
|
+
return e ? (this._isLoadingMesh = !0, this.parser.getDependency("mesh", t).then((r) => {
|
|
160
|
+
var i;
|
|
161
|
+
return this._isLoadingMesh = !1, r && b.registerMesh(this.url, e.guid, r, (i = e.lods) == null ? void 0 : i.length, 0, e), r;
|
|
156
162
|
})) : null;
|
|
157
163
|
});
|
|
158
|
-
|
|
164
|
+
y && console.log("Progressive extension registered for", e), this.parser = t, this.url = e;
|
|
159
165
|
}
|
|
160
166
|
/** The name of the extension */
|
|
161
167
|
get name() {
|
|
@@ -166,14 +172,14 @@ const Y = "NEEDLE_progressive", _e = Symbol("needle-progressive-texture"), b = c
|
|
|
166
172
|
return e != null && e.key ? this.lodInfos.get(e.key) : null;
|
|
167
173
|
}
|
|
168
174
|
static getPrimitiveIndex(t) {
|
|
169
|
-
var
|
|
170
|
-
const e = (
|
|
175
|
+
var s;
|
|
176
|
+
const e = (s = this.getAssignedLODInformation(t)) == null ? void 0 : s.index;
|
|
171
177
|
return e ?? -1;
|
|
172
178
|
}
|
|
173
179
|
static getMaterialMinMaxLODsCount(t, e) {
|
|
174
|
-
const
|
|
175
|
-
if (
|
|
176
|
-
return
|
|
180
|
+
const s = this, o = "LODS:minmax", r = t[o];
|
|
181
|
+
if (r != null)
|
|
182
|
+
return r;
|
|
177
183
|
if (e || (e = {
|
|
178
184
|
min_count: 1 / 0,
|
|
179
185
|
max_count: 0,
|
|
@@ -181,28 +187,28 @@ const Y = "NEEDLE_progressive", _e = Symbol("needle-progressive-texture"), b = c
|
|
|
181
187
|
}), Array.isArray(t)) {
|
|
182
188
|
for (const a of t)
|
|
183
189
|
this.getMaterialMinMaxLODsCount(a, e);
|
|
184
|
-
return t[
|
|
190
|
+
return t[o] = e, e;
|
|
185
191
|
}
|
|
186
|
-
if (
|
|
192
|
+
if (y === "verbose" && console.log("getMaterialMinMaxLODsCount", t), t.type === "ShaderMaterial" || t.type === "RawShaderMaterial") {
|
|
187
193
|
const a = t;
|
|
188
194
|
for (const l of Object.keys(a.uniforms)) {
|
|
189
|
-
const
|
|
190
|
-
(
|
|
195
|
+
const c = a.uniforms[l].value;
|
|
196
|
+
(c == null ? void 0 : c.isTexture) === !0 && i(c, e);
|
|
191
197
|
}
|
|
192
198
|
} else if (t.isMaterial)
|
|
193
199
|
for (const a of Object.keys(t)) {
|
|
194
200
|
const l = t[a];
|
|
195
|
-
(l == null ? void 0 : l.isTexture) === !0 &&
|
|
201
|
+
(l == null ? void 0 : l.isTexture) === !0 && i(l, e);
|
|
196
202
|
}
|
|
197
|
-
return t[
|
|
198
|
-
function
|
|
199
|
-
const
|
|
200
|
-
if (
|
|
201
|
-
const
|
|
202
|
-
if (
|
|
203
|
-
l.min_count = Math.min(l.min_count,
|
|
204
|
-
for (let h = 0; h <
|
|
205
|
-
const g =
|
|
203
|
+
return t[o] = e, e;
|
|
204
|
+
function i(a, l) {
|
|
205
|
+
const c = s.getAssignedLODInformation(a);
|
|
206
|
+
if (c) {
|
|
207
|
+
const u = s.lodInfos.get(c.key);
|
|
208
|
+
if (u && u.lods) {
|
|
209
|
+
l.min_count = Math.min(l.min_count, u.lods.length), l.max_count = Math.max(l.max_count, u.lods.length);
|
|
210
|
+
for (let h = 0; h < u.lods.length; h++) {
|
|
211
|
+
const g = u.lods[h];
|
|
206
212
|
g.width && (l.lods[h] = l.lods[h] || { min_height: 1 / 0, max_height: 0 }, l.lods[h].min_height = Math.min(l.lods[h].min_height, g.height), l.lods[h].max_height = Math.max(l.lods[h].max_height, g.height));
|
|
207
213
|
}
|
|
208
214
|
}
|
|
@@ -215,32 +221,32 @@ const Y = "NEEDLE_progressive", _e = Symbol("needle-progressive-texture"), b = c
|
|
|
215
221
|
* @returns true if the LOD level is available (or if any LOD level is available if level is undefined)
|
|
216
222
|
*/
|
|
217
223
|
static hasLODLevelAvailable(t, e) {
|
|
218
|
-
var
|
|
224
|
+
var r;
|
|
219
225
|
if (Array.isArray(t)) {
|
|
220
|
-
for (const
|
|
221
|
-
if (this.hasLODLevelAvailable(
|
|
226
|
+
for (const i of t)
|
|
227
|
+
if (this.hasLODLevelAvailable(i, e))
|
|
222
228
|
return !0;
|
|
223
229
|
return !1;
|
|
224
230
|
}
|
|
225
231
|
if (t.isMaterial === !0) {
|
|
226
|
-
for (const
|
|
227
|
-
const a = t[
|
|
232
|
+
for (const i of Object.keys(t)) {
|
|
233
|
+
const a = t[i];
|
|
228
234
|
if (a && a.isTexture && this.hasLODLevelAvailable(a, e))
|
|
229
235
|
return !0;
|
|
230
236
|
}
|
|
231
237
|
return !1;
|
|
232
238
|
} else if (t.isGroup === !0) {
|
|
233
|
-
for (const
|
|
234
|
-
if (
|
|
239
|
+
for (const i of t.children)
|
|
240
|
+
if (i.isMesh === !0 && this.hasLODLevelAvailable(i, e))
|
|
235
241
|
return !0;
|
|
236
242
|
}
|
|
237
|
-
let
|
|
238
|
-
if (t.isMesh ?
|
|
239
|
-
const
|
|
240
|
-
if (
|
|
241
|
-
return
|
|
242
|
-
if (
|
|
243
|
-
return Array.isArray(
|
|
243
|
+
let s, o;
|
|
244
|
+
if (t.isMesh ? s = t.geometry : (t.isBufferGeometry || t.isTexture) && (s = t), s && (r = s == null ? void 0 : s.userData) != null && r.LODS) {
|
|
245
|
+
const i = s.userData.LODS;
|
|
246
|
+
if (o = this.lodInfos.get(i.key), e === void 0)
|
|
247
|
+
return o != null;
|
|
248
|
+
if (o)
|
|
249
|
+
return Array.isArray(o.lods) ? e < o.lods.length : e === 0;
|
|
244
250
|
}
|
|
245
251
|
return !1;
|
|
246
252
|
}
|
|
@@ -259,251 +265,251 @@ const Y = "NEEDLE_progressive", _e = Symbol("needle-progressive-texture"), b = c
|
|
|
259
265
|
* ```
|
|
260
266
|
*/
|
|
261
267
|
static assignMeshLOD(t, e) {
|
|
262
|
-
var
|
|
268
|
+
var s;
|
|
263
269
|
if (!t)
|
|
264
270
|
return Promise.resolve(null);
|
|
265
|
-
if (t instanceof
|
|
266
|
-
const
|
|
267
|
-
if (!
|
|
271
|
+
if (t instanceof se || t.isMesh === !0) {
|
|
272
|
+
const o = t.geometry, r = this.getAssignedLODInformation(o);
|
|
273
|
+
if (!r)
|
|
268
274
|
return Promise.resolve(null);
|
|
269
|
-
for (const
|
|
270
|
-
(
|
|
271
|
-
return t["LOD:requested level"] = e, b.getOrLoadLOD(
|
|
272
|
-
if (Array.isArray(
|
|
273
|
-
const a =
|
|
274
|
-
|
|
275
|
+
for (const i of Z)
|
|
276
|
+
(s = i.onBeforeGetLODMesh) == null || s.call(i, t, e);
|
|
277
|
+
return t["LOD:requested level"] = e, b.getOrLoadLOD(o, e).then((i) => {
|
|
278
|
+
if (Array.isArray(i)) {
|
|
279
|
+
const a = r.index || 0;
|
|
280
|
+
i = i[a];
|
|
275
281
|
}
|
|
276
|
-
return t["LOD:requested level"] === e && (delete t["LOD:requested level"],
|
|
277
|
-
}).catch((
|
|
282
|
+
return t["LOD:requested level"] === e && (delete t["LOD:requested level"], i && o != i && ((i == null ? void 0 : i.isBufferGeometry) ? t.geometry = i : y && console.error("Invalid LOD geometry", i))), i;
|
|
283
|
+
}).catch((i) => (console.error("Error loading mesh LOD", t, i), null));
|
|
278
284
|
} else
|
|
279
|
-
|
|
285
|
+
y && console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh", t);
|
|
280
286
|
return Promise.resolve(null);
|
|
281
287
|
}
|
|
282
288
|
static assignTextureLOD(t, e = 0) {
|
|
283
289
|
if (!t)
|
|
284
290
|
return Promise.resolve(null);
|
|
285
291
|
if (t.isMesh === !0) {
|
|
286
|
-
const
|
|
287
|
-
if (Array.isArray(
|
|
288
|
-
const
|
|
289
|
-
for (const
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
+
const s = t;
|
|
293
|
+
if (Array.isArray(s.material)) {
|
|
294
|
+
const o = new Array();
|
|
295
|
+
for (const r of s.material) {
|
|
296
|
+
const i = this.assignTextureLOD(r, e);
|
|
297
|
+
o.push(i);
|
|
292
298
|
}
|
|
293
|
-
return Promise.all(
|
|
294
|
-
const
|
|
295
|
-
for (const a of
|
|
296
|
-
Array.isArray(a) &&
|
|
297
|
-
return
|
|
299
|
+
return Promise.all(o).then((r) => {
|
|
300
|
+
const i = new Array();
|
|
301
|
+
for (const a of r)
|
|
302
|
+
Array.isArray(a) && i.push(...a);
|
|
303
|
+
return i;
|
|
298
304
|
});
|
|
299
305
|
} else
|
|
300
|
-
return this.assignTextureLOD(
|
|
306
|
+
return this.assignTextureLOD(s.material, e);
|
|
301
307
|
}
|
|
302
308
|
if (t.isMaterial === !0) {
|
|
303
|
-
const
|
|
304
|
-
if (
|
|
305
|
-
const
|
|
306
|
-
for (const a of Object.keys(
|
|
307
|
-
const l =
|
|
309
|
+
const s = t, o = [], r = new Array();
|
|
310
|
+
if (s.uniforms && (s.isRawShaderMaterial || s.isShaderMaterial === !0)) {
|
|
311
|
+
const i = s;
|
|
312
|
+
for (const a of Object.keys(i.uniforms)) {
|
|
313
|
+
const l = i.uniforms[a].value;
|
|
308
314
|
if ((l == null ? void 0 : l.isTexture) === !0) {
|
|
309
|
-
const
|
|
310
|
-
|
|
315
|
+
const c = this.assignTextureLODForSlot(l, e, s, a).then((u) => (u && i.uniforms[a].value != u && (i.uniforms[a].value = u, i.uniformsNeedUpdate = !0), u));
|
|
316
|
+
o.push(c), r.push(a);
|
|
311
317
|
}
|
|
312
318
|
}
|
|
313
319
|
} else
|
|
314
|
-
for (const
|
|
315
|
-
const a =
|
|
320
|
+
for (const i of Object.keys(s)) {
|
|
321
|
+
const a = s[i];
|
|
316
322
|
if ((a == null ? void 0 : a.isTexture) === !0) {
|
|
317
|
-
const l = this.assignTextureLODForSlot(a, e,
|
|
318
|
-
|
|
323
|
+
const l = this.assignTextureLODForSlot(a, e, s, i);
|
|
324
|
+
o.push(l), r.push(i);
|
|
319
325
|
}
|
|
320
326
|
}
|
|
321
|
-
return Promise.all(
|
|
327
|
+
return Promise.all(o).then((i) => {
|
|
322
328
|
const a = new Array();
|
|
323
|
-
for (let l = 0; l <
|
|
324
|
-
const
|
|
325
|
-
|
|
329
|
+
for (let l = 0; l < i.length; l++) {
|
|
330
|
+
const c = i[l], u = r[l];
|
|
331
|
+
c && c.isTexture === !0 ? a.push({ material: s, slot: u, texture: c, level: e }) : a.push({ material: s, slot: u, texture: null, level: e });
|
|
326
332
|
}
|
|
327
333
|
return a;
|
|
328
334
|
});
|
|
329
335
|
}
|
|
330
336
|
if (t instanceof ne || t.isTexture === !0) {
|
|
331
|
-
const
|
|
332
|
-
return this.assignTextureLODForSlot(
|
|
337
|
+
const s = t;
|
|
338
|
+
return this.assignTextureLODForSlot(s, e, null, null);
|
|
333
339
|
}
|
|
334
340
|
return Promise.resolve(null);
|
|
335
341
|
}
|
|
336
|
-
static assignTextureLODForSlot(t, e,
|
|
337
|
-
return (t == null ? void 0 : t.isTexture) !== !0 ? Promise.resolve(null) :
|
|
338
|
-
if (Array.isArray(
|
|
342
|
+
static assignTextureLODForSlot(t, e, s, o) {
|
|
343
|
+
return (t == null ? void 0 : t.isTexture) !== !0 ? Promise.resolve(null) : o === "glyphMap" ? Promise.resolve(t) : b.getOrLoadLOD(t, e).then((r) => {
|
|
344
|
+
if (Array.isArray(r))
|
|
339
345
|
return null;
|
|
340
|
-
if ((
|
|
341
|
-
if (
|
|
342
|
-
const
|
|
343
|
-
if (
|
|
344
|
-
const a = this.getAssignedLODInformation(
|
|
346
|
+
if ((r == null ? void 0 : r.isTexture) === !0) {
|
|
347
|
+
if (r != t && s && o) {
|
|
348
|
+
const i = s[o];
|
|
349
|
+
if (i && !y) {
|
|
350
|
+
const a = this.getAssignedLODInformation(i);
|
|
345
351
|
if (a && (a == null ? void 0 : a.level) < e)
|
|
346
|
-
return
|
|
352
|
+
return y === "verbose" && console.warn("Assigned texture level is already higher: ", a.level, e, s, i, r), null;
|
|
347
353
|
}
|
|
348
|
-
|
|
354
|
+
s[o] = r;
|
|
349
355
|
}
|
|
350
|
-
return
|
|
356
|
+
return r;
|
|
351
357
|
} else
|
|
352
|
-
|
|
358
|
+
y == "verbose" && console.warn("No LOD found for", t, e);
|
|
353
359
|
return null;
|
|
354
|
-
}).catch((
|
|
360
|
+
}).catch((r) => (console.error("Error loading LOD", t, r), null));
|
|
355
361
|
}
|
|
356
362
|
afterRoot(t) {
|
|
357
|
-
var e,
|
|
358
|
-
return
|
|
359
|
-
var
|
|
360
|
-
if (
|
|
361
|
-
const a =
|
|
363
|
+
var e, s;
|
|
364
|
+
return y && console.log("AFTER", this.url, t), (e = this.parser.json.textures) == null || e.forEach((o, r) => {
|
|
365
|
+
var i;
|
|
366
|
+
if (o != null && o.extensions) {
|
|
367
|
+
const a = o == null ? void 0 : o.extensions[Y];
|
|
362
368
|
if (a) {
|
|
363
369
|
if (!a.lods) {
|
|
364
|
-
|
|
370
|
+
y && console.warn("Texture has no LODs", a);
|
|
365
371
|
return;
|
|
366
372
|
}
|
|
367
373
|
let l = !1;
|
|
368
|
-
for (const
|
|
369
|
-
if (
|
|
370
|
-
const
|
|
371
|
-
(
|
|
374
|
+
for (const c of this.parser.associations.keys())
|
|
375
|
+
if (c.isTexture === !0) {
|
|
376
|
+
const u = this.parser.associations.get(c);
|
|
377
|
+
(u == null ? void 0 : u.textures) === r && (l = !0, b.registerTexture(this.url, c, (i = a.lods) == null ? void 0 : i.length, r, a));
|
|
372
378
|
}
|
|
373
|
-
l || this.parser.getDependency("texture",
|
|
374
|
-
var
|
|
375
|
-
|
|
379
|
+
l || this.parser.getDependency("texture", r).then((c) => {
|
|
380
|
+
var u;
|
|
381
|
+
c && b.registerTexture(this.url, c, (u = a.lods) == null ? void 0 : u.length, r, a);
|
|
376
382
|
});
|
|
377
383
|
}
|
|
378
384
|
}
|
|
379
|
-
}), (
|
|
380
|
-
if (
|
|
381
|
-
const
|
|
382
|
-
if (
|
|
385
|
+
}), (s = this.parser.json.meshes) == null || s.forEach((o, r) => {
|
|
386
|
+
if (o != null && o.extensions) {
|
|
387
|
+
const i = o == null ? void 0 : o.extensions[Y];
|
|
388
|
+
if (i && i.lods) {
|
|
383
389
|
for (const a of this.parser.associations.keys())
|
|
384
390
|
if (a.isMesh) {
|
|
385
391
|
const l = this.parser.associations.get(a);
|
|
386
|
-
(l == null ? void 0 : l.meshes) ===
|
|
392
|
+
(l == null ? void 0 : l.meshes) === r && b.registerMesh(this.url, i.guid, a, i.lods.length, l.primitives, i);
|
|
387
393
|
}
|
|
388
394
|
}
|
|
389
395
|
}
|
|
390
396
|
}), null;
|
|
391
397
|
}
|
|
392
398
|
static async getOrLoadLOD(t, e) {
|
|
393
|
-
var a, l,
|
|
394
|
-
const
|
|
395
|
-
if (!
|
|
399
|
+
var a, l, c, u;
|
|
400
|
+
const s = y == "verbose", o = t.userData.LODS;
|
|
401
|
+
if (!o)
|
|
396
402
|
return null;
|
|
397
|
-
const
|
|
398
|
-
let
|
|
403
|
+
const r = o == null ? void 0 : o.key;
|
|
404
|
+
let i;
|
|
399
405
|
if (t.isTexture === !0) {
|
|
400
406
|
const h = t;
|
|
401
|
-
h.source && h.source[
|
|
407
|
+
h.source && h.source[Oe] && (i = h.source[Oe]);
|
|
402
408
|
}
|
|
403
|
-
if (
|
|
409
|
+
if (i || (i = b.lodInfos.get(r)), i) {
|
|
404
410
|
if (e > 0) {
|
|
405
|
-
let
|
|
406
|
-
const
|
|
407
|
-
if (
|
|
408
|
-
return this.lowresCache.get(
|
|
411
|
+
let _ = !1;
|
|
412
|
+
const M = Array.isArray(i.lods);
|
|
413
|
+
if (M && e >= i.lods.length ? _ = !0 : M || (_ = !0), _)
|
|
414
|
+
return this.lowresCache.get(r);
|
|
409
415
|
}
|
|
410
|
-
const h = Array.isArray(
|
|
416
|
+
const h = Array.isArray(i.lods) ? (a = i.lods[e]) == null ? void 0 : a.path : i.lods;
|
|
411
417
|
if (!h)
|
|
412
|
-
return
|
|
413
|
-
const g =
|
|
418
|
+
return y && !i["missing:uri"] && (i["missing:uri"] = !0, console.warn("Missing uri for progressive asset for LOD " + e, i)), null;
|
|
419
|
+
const g = dt(o.url, h);
|
|
414
420
|
if (g.endsWith(".glb") || g.endsWith(".gltf")) {
|
|
415
|
-
if (!
|
|
416
|
-
return console.warn("missing pointer for glb/gltf texture",
|
|
417
|
-
const
|
|
418
|
-
if (
|
|
419
|
-
|
|
420
|
-
let
|
|
421
|
-
`,
|
|
422
|
-
if (
|
|
423
|
-
return
|
|
421
|
+
if (!i.guid)
|
|
422
|
+
return console.warn("missing pointer for glb/gltf texture", i), null;
|
|
423
|
+
const _ = g + "_" + i.guid, M = this.previouslyLoaded.get(_);
|
|
424
|
+
if (M !== void 0) {
|
|
425
|
+
s && console.log(`LOD ${e} was already loading/loaded: ${_}`);
|
|
426
|
+
let w = await M.catch((m) => (console.error(`Error loading LOD ${e} from ${g}
|
|
427
|
+
`, m), null)), D = !1;
|
|
428
|
+
if (w == null || (w instanceof ne && t instanceof ne ? (l = w.image) != null && l.data || (c = w.source) != null && c.data ? w = this.copySettings(t, w) : (D = !0, this.previouslyLoaded.delete(_)) : w instanceof xe && t instanceof xe && ((u = w.attributes.position) != null && u.array || (D = !0, this.previouslyLoaded.delete(_)))), !D)
|
|
429
|
+
return w;
|
|
424
430
|
}
|
|
425
|
-
const
|
|
426
|
-
const
|
|
427
|
-
|
|
431
|
+
const L = i, N = new Promise(async (w, D) => {
|
|
432
|
+
const m = new Ce();
|
|
433
|
+
Ne(m), y && (await new Promise((O) => setTimeout(O, 1e3)), s && console.warn("Start loading (delayed) " + g, L.guid));
|
|
428
434
|
let q = g;
|
|
429
|
-
if (
|
|
430
|
-
const O =
|
|
435
|
+
if (L && Array.isArray(L.lods)) {
|
|
436
|
+
const O = L.lods[e];
|
|
431
437
|
O.hash && (q += "?v=" + O.hash);
|
|
432
438
|
}
|
|
433
|
-
const
|
|
439
|
+
const A = await m.loadAsync(q).catch((O) => (console.error(`Error loading LOD ${e} from ${g}
|
|
434
440
|
`, O), null));
|
|
435
|
-
if (!
|
|
441
|
+
if (!A)
|
|
436
442
|
return null;
|
|
437
|
-
const
|
|
438
|
-
|
|
439
|
-
let
|
|
440
|
-
if (
|
|
443
|
+
const k = A.parser;
|
|
444
|
+
s && console.log("Loading finished " + g, L.guid);
|
|
445
|
+
let R = 0;
|
|
446
|
+
if (A.parser.json.textures) {
|
|
441
447
|
let O = !1;
|
|
442
|
-
for (const f of
|
|
448
|
+
for (const f of A.parser.json.textures) {
|
|
443
449
|
if (f != null && f.extensions) {
|
|
444
450
|
const S = f == null ? void 0 : f.extensions[Y];
|
|
445
|
-
if (S != null && S.guid && S.guid ===
|
|
451
|
+
if (S != null && S.guid && S.guid === L.guid) {
|
|
446
452
|
O = !0;
|
|
447
453
|
break;
|
|
448
454
|
}
|
|
449
455
|
}
|
|
450
|
-
|
|
456
|
+
R++;
|
|
451
457
|
}
|
|
452
458
|
if (O) {
|
|
453
|
-
let f = await
|
|
454
|
-
return f && b.assignLODInformation(
|
|
459
|
+
let f = await k.getDependency("texture", R);
|
|
460
|
+
return f && b.assignLODInformation(o.url, f, r, e, void 0), s && console.log('change "' + t.name + '" → "' + f.name + '"', g, R, f, _), t instanceof ne && (f = this.copySettings(t, f)), f && (f.guid = L.guid), w(f);
|
|
455
461
|
} else
|
|
456
|
-
|
|
462
|
+
y && console.warn("Could not find texture with guid", L.guid, A.parser.json);
|
|
457
463
|
}
|
|
458
|
-
if (
|
|
464
|
+
if (R = 0, A.parser.json.meshes) {
|
|
459
465
|
let O = !1;
|
|
460
|
-
for (const f of
|
|
466
|
+
for (const f of A.parser.json.meshes) {
|
|
461
467
|
if (f != null && f.extensions) {
|
|
462
468
|
const S = f == null ? void 0 : f.extensions[Y];
|
|
463
|
-
if (S != null && S.guid && S.guid ===
|
|
469
|
+
if (S != null && S.guid && S.guid === L.guid) {
|
|
464
470
|
O = !0;
|
|
465
471
|
break;
|
|
466
472
|
}
|
|
467
473
|
}
|
|
468
|
-
|
|
474
|
+
R++;
|
|
469
475
|
}
|
|
470
476
|
if (O) {
|
|
471
|
-
const f = await
|
|
472
|
-
if (
|
|
477
|
+
const f = await k.getDependency("mesh", R);
|
|
478
|
+
if (s && console.log(`Loaded Mesh "${f.name}"`, g, R, f, _), f.isMesh === !0) {
|
|
473
479
|
const S = f.geometry;
|
|
474
|
-
return b.assignLODInformation(
|
|
480
|
+
return b.assignLODInformation(o.url, S, r, e, 0), w(S);
|
|
475
481
|
} else {
|
|
476
482
|
const S = new Array();
|
|
477
|
-
for (let
|
|
478
|
-
const v = f.children[
|
|
483
|
+
for (let x = 0; x < f.children.length; x++) {
|
|
484
|
+
const v = f.children[x];
|
|
479
485
|
if (v.isMesh === !0) {
|
|
480
486
|
const C = v.geometry;
|
|
481
|
-
b.assignLODInformation(
|
|
487
|
+
b.assignLODInformation(o.url, C, r, e, x), S.push(C);
|
|
482
488
|
}
|
|
483
489
|
}
|
|
484
|
-
return
|
|
490
|
+
return w(S);
|
|
485
491
|
}
|
|
486
492
|
} else
|
|
487
|
-
|
|
493
|
+
y && console.warn("Could not find mesh with guid", L.guid, A.parser.json);
|
|
488
494
|
}
|
|
489
|
-
return
|
|
495
|
+
return w(null);
|
|
490
496
|
});
|
|
491
|
-
return this.previouslyLoaded.set(
|
|
497
|
+
return this.previouslyLoaded.set(_, N), await N;
|
|
492
498
|
} else if (t instanceof ne) {
|
|
493
|
-
|
|
494
|
-
const
|
|
495
|
-
return
|
|
499
|
+
s && console.log("Load texture from uri: " + g);
|
|
500
|
+
const M = await new je().loadAsync(g);
|
|
501
|
+
return M ? (M.guid = i.guid, M.flipY = !1, M.needsUpdate = !0, M.colorSpace = t.colorSpace, s && console.log(i, M)) : y && console.warn("failed loading", g), M;
|
|
496
502
|
}
|
|
497
503
|
} else
|
|
498
|
-
|
|
504
|
+
y && console.warn(`Can not load LOD ${e}: no LOD info found for "${r}" ${t.name}`, t.type);
|
|
499
505
|
return null;
|
|
500
506
|
}
|
|
501
|
-
static assignLODInformation(t, e,
|
|
507
|
+
static assignLODInformation(t, e, s, o, r) {
|
|
502
508
|
if (!e)
|
|
503
509
|
return;
|
|
504
510
|
e.userData || (e.userData = {});
|
|
505
|
-
const
|
|
506
|
-
e.userData.LODS =
|
|
511
|
+
const i = new mt(t, s, o, r);
|
|
512
|
+
e.userData.LODS = i;
|
|
507
513
|
}
|
|
508
514
|
static getAssignedLODInformation(t) {
|
|
509
515
|
var e;
|
|
@@ -511,61 +517,137 @@ const Y = "NEEDLE_progressive", _e = Symbol("needle-progressive-texture"), b = c
|
|
|
511
517
|
}
|
|
512
518
|
// private static readonly _copiedTextures: WeakMap<Texture, Texture> = new Map();
|
|
513
519
|
static copySettings(t, e) {
|
|
514
|
-
return e ? (
|
|
520
|
+
return e ? (y && console.warn(`Copy texture settings
|
|
515
521
|
`, t.uuid, `
|
|
516
522
|
`, 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;
|
|
517
523
|
}
|
|
518
524
|
};
|
|
519
|
-
let
|
|
525
|
+
let T = b;
|
|
520
526
|
/**
|
|
521
527
|
* Register a texture with LOD information
|
|
522
528
|
*/
|
|
523
|
-
d(
|
|
524
|
-
if (
|
|
525
|
-
|
|
529
|
+
d(T, "registerTexture", (t, e, s, o, r) => {
|
|
530
|
+
if (y && console.log("> Progressive: register texture", o, e.name, e.uuid, e, r), !e) {
|
|
531
|
+
y && console.error("gltf-progressive: Register texture without texture");
|
|
526
532
|
return;
|
|
527
533
|
}
|
|
528
|
-
e.source && (e.source[
|
|
529
|
-
const
|
|
530
|
-
b.assignLODInformation(t, e,
|
|
534
|
+
e.source && (e.source[Oe] = r);
|
|
535
|
+
const i = r.guid;
|
|
536
|
+
b.assignLODInformation(t, e, i, s, o), b.lodInfos.set(i, r), b.lowresCache.set(i, e);
|
|
531
537
|
}), /**
|
|
532
538
|
* Register a mesh with LOD information
|
|
533
539
|
*/
|
|
534
|
-
d(
|
|
535
|
-
var
|
|
536
|
-
const a =
|
|
540
|
+
d(T, "registerMesh", (t, e, s, o, r, i) => {
|
|
541
|
+
var c;
|
|
542
|
+
const a = s.geometry;
|
|
537
543
|
if (!a) {
|
|
538
|
-
|
|
544
|
+
y && console.warn("gltf-progressive: Register mesh without geometry");
|
|
539
545
|
return;
|
|
540
546
|
}
|
|
541
|
-
a.userData || (a.userData = {}),
|
|
547
|
+
a.userData || (a.userData = {}), y && console.log("> Progressive: register mesh " + s.name, { index: r, uuid: s.uuid }, i, s), b.assignLODInformation(t, a, e, o, r), b.lodInfos.set(e, i);
|
|
542
548
|
let l = b.lowresCache.get(e);
|
|
543
|
-
l ? l.push(
|
|
544
|
-
for (const
|
|
545
|
-
(
|
|
549
|
+
l ? l.push(s.geometry) : l = [s.geometry], b.lowresCache.set(e, l), o > 0 && !ce(s) && ht(s, a);
|
|
550
|
+
for (const u of Z)
|
|
551
|
+
(c = u.onRegisteredNewMesh) == null || c.call(u, s, i);
|
|
546
552
|
}), /** A map of key = asset uuid and value = LOD information */
|
|
547
|
-
d(
|
|
548
|
-
d(
|
|
549
|
-
d(
|
|
550
|
-
class
|
|
551
|
-
constructor(t, e,
|
|
553
|
+
d(T, "lodInfos", /* @__PURE__ */ new Map()), /** cache of already loaded mesh lods */
|
|
554
|
+
d(T, "previouslyLoaded", /* @__PURE__ */ new Map()), /** this contains the geometry/textures that were originally loaded */
|
|
555
|
+
d(T, "lowresCache", /* @__PURE__ */ new Map());
|
|
556
|
+
class mt {
|
|
557
|
+
constructor(t, e, s, o) {
|
|
552
558
|
d(this, "url");
|
|
553
559
|
/** the key to lookup the LOD information */
|
|
554
560
|
d(this, "key");
|
|
555
561
|
d(this, "level");
|
|
556
562
|
/** For multi objects (e.g. a group of meshes) this is the index of the object */
|
|
557
563
|
d(this, "index");
|
|
558
|
-
this.url = t, this.key = e, this.level =
|
|
564
|
+
this.url = t, this.key = e, this.level = s, o != null && (this.index = o);
|
|
559
565
|
}
|
|
560
566
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
567
|
+
class ye {
|
|
568
|
+
constructor(t, e) {
|
|
569
|
+
d(this, "frame_start");
|
|
570
|
+
d(this, "frame_capture_end");
|
|
571
|
+
d(this, "ready");
|
|
572
|
+
d(this, "_resolve");
|
|
573
|
+
d(this, "_signal");
|
|
574
|
+
d(this, "_resolved", !1);
|
|
575
|
+
d(this, "_addedCount", 0);
|
|
576
|
+
d(this, "_resolvedCount", 0);
|
|
577
|
+
/** These promises are currently being awaited */
|
|
578
|
+
d(this, "_awaiting", []);
|
|
579
|
+
d(this, "_maxPromisesPerObject", 1);
|
|
580
|
+
d(this, "_currentFrame", 0);
|
|
581
|
+
d(this, "_seen", /* @__PURE__ */ new WeakMap());
|
|
582
|
+
var r;
|
|
583
|
+
const o = Math.max(e.frames ?? 2, 2);
|
|
584
|
+
this.frame_start = t, this.frame_capture_end = t + o, this.ready = new Promise((i) => {
|
|
585
|
+
this._resolve = i;
|
|
586
|
+
}), this.ready.finally(() => {
|
|
587
|
+
this._resolved = !0, this._awaiting.length = 0;
|
|
588
|
+
}), this._signal = e.signal, (r = this._signal) == null || r.addEventListener("abort", () => {
|
|
589
|
+
this.resolveNow();
|
|
590
|
+
}), this._maxPromisesPerObject = Math.max(1, e.maxPromisesPerObject ?? 1);
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* The number of promises that have been added to this group so far.
|
|
594
|
+
*/
|
|
595
|
+
get awaitedCount() {
|
|
596
|
+
return this._addedCount;
|
|
597
|
+
}
|
|
598
|
+
get resolvedCount() {
|
|
599
|
+
return this._resolvedCount;
|
|
600
|
+
}
|
|
601
|
+
get currentlyAwaiting() {
|
|
602
|
+
return this._awaiting.length;
|
|
603
|
+
}
|
|
604
|
+
update(t) {
|
|
605
|
+
var e;
|
|
606
|
+
this._currentFrame = t, ((e = this._signal) != null && e.aborted || this._currentFrame > this.frame_capture_end && this._awaiting.length === 0) && this.resolveNow();
|
|
607
|
+
}
|
|
608
|
+
add(t, e, s) {
|
|
609
|
+
if (this._resolved) {
|
|
610
|
+
y && console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
if (!(this._currentFrame > this.frame_capture_end)) {
|
|
614
|
+
if (this._maxPromisesPerObject >= 1)
|
|
615
|
+
if (this._seen.has(e)) {
|
|
616
|
+
let o = this._seen.get(e);
|
|
617
|
+
if (o >= this._maxPromisesPerObject) {
|
|
618
|
+
y && console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
this._seen.set(e, o + 1);
|
|
622
|
+
} else
|
|
623
|
+
this._seen.set(e, 1);
|
|
624
|
+
this._awaiting.push(s), this._addedCount++, s.finally(() => {
|
|
625
|
+
this._resolvedCount++, this._awaiting.splice(this._awaiting.indexOf(s), 1);
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
resolveNow() {
|
|
630
|
+
var t, e;
|
|
631
|
+
this._resolved || (e = this._resolve) == null || e.call(this, {
|
|
632
|
+
awaited_count: this._addedCount,
|
|
633
|
+
resolved_count: this._resolvedCount,
|
|
634
|
+
cancelled: ((t = this._signal) == null ? void 0 : t.aborted) ?? !1
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
d(ye, "addPromise", (t, e, s, o) => {
|
|
639
|
+
o.forEach((r) => {
|
|
640
|
+
r.add(t, e, s);
|
|
641
|
+
});
|
|
642
|
+
});
|
|
643
|
+
const F = ue("debugprogressive"), yt = ue("noprogressive"), be = Symbol("Needle:LODSManager"), Se = Symbol("Needle:LODState"), Q = Symbol("Needle:CurrentLOD"), E = { mesh_lod: -1, texture_lod: -1 };
|
|
644
|
+
var G, H, _e, ee, ie, we, j;
|
|
645
|
+
const P = class {
|
|
564
646
|
// readonly plugins: NEEDLE_progressive_plugin[] = [];
|
|
565
647
|
constructor(t, e) {
|
|
566
|
-
d(this, "context");
|
|
567
648
|
d(this, "renderer");
|
|
568
|
-
d(this, "
|
|
649
|
+
d(this, "context");
|
|
650
|
+
d(this, "projectionScreenMatrix", new Ge());
|
|
569
651
|
/**
|
|
570
652
|
* The target triangle density is the desired max amount of triangles on screen when the mesh is filling the screen.
|
|
571
653
|
* @default 200_000
|
|
@@ -582,7 +664,7 @@ const T = class {
|
|
|
582
664
|
* @default "auto"
|
|
583
665
|
*/
|
|
584
666
|
d(this, "updateInterval", "auto");
|
|
585
|
-
J(this,
|
|
667
|
+
J(this, G, 1);
|
|
586
668
|
/**
|
|
587
669
|
* If set to true, the LODsManager will not update the LODs.
|
|
588
670
|
* @default false
|
|
@@ -594,19 +676,21 @@ const T = class {
|
|
|
594
676
|
* @default false
|
|
595
677
|
*/
|
|
596
678
|
d(this, "manual", !1);
|
|
679
|
+
d(this, "_newPromiseGroups", []);
|
|
680
|
+
d(this, "_promiseGroupIds", 0);
|
|
597
681
|
d(this, "_lodchangedlisteners", []);
|
|
598
682
|
J(this, H, void 0);
|
|
599
|
-
J(this,
|
|
600
|
-
J(this,
|
|
601
|
-
J(this,
|
|
602
|
-
J(this,
|
|
683
|
+
J(this, _e, new Je());
|
|
684
|
+
J(this, ee, 0);
|
|
685
|
+
J(this, ie, 0);
|
|
686
|
+
J(this, we, 0);
|
|
603
687
|
J(this, j, 0);
|
|
604
688
|
d(this, "_fpsBuffer", [60, 60, 60, 60, 60]);
|
|
605
689
|
// private testIfLODLevelsAreAvailable() {
|
|
606
|
-
d(this, "_sphere", new
|
|
607
|
-
d(this, "_tempBox", new
|
|
608
|
-
d(this, "_tempBox2", new
|
|
609
|
-
d(this, "tempMatrix", new
|
|
690
|
+
d(this, "_sphere", new Ze());
|
|
691
|
+
d(this, "_tempBox", new Ie());
|
|
692
|
+
d(this, "_tempBox2", new Ie());
|
|
693
|
+
d(this, "tempMatrix", new Ge());
|
|
610
694
|
d(this, "_tempWorldPosition", new K());
|
|
611
695
|
d(this, "_tempBoxSize", new K());
|
|
612
696
|
d(this, "_tempBox2Size", new K());
|
|
@@ -614,7 +698,7 @@ const T = class {
|
|
|
614
698
|
}
|
|
615
699
|
/** @internal */
|
|
616
700
|
static getObjectLODState(t) {
|
|
617
|
-
return t[
|
|
701
|
+
return t[Se];
|
|
618
702
|
}
|
|
619
703
|
static addPlugin(t) {
|
|
620
704
|
Z.push(t);
|
|
@@ -629,79 +713,99 @@ const T = class {
|
|
|
629
713
|
* @returns The LODsManager instance.
|
|
630
714
|
*/
|
|
631
715
|
static get(t, e) {
|
|
632
|
-
if (t[
|
|
633
|
-
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[
|
|
634
|
-
const
|
|
716
|
+
if (t[be])
|
|
717
|
+
return console.debug("[gltf-progressive] LODsManager already exists for this renderer"), t[be];
|
|
718
|
+
const s = new P(t, {
|
|
635
719
|
engine: "unknown",
|
|
636
720
|
...e
|
|
637
721
|
});
|
|
638
|
-
return t[
|
|
722
|
+
return t[be] = s, s;
|
|
639
723
|
}
|
|
640
724
|
/** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
|
|
641
725
|
get plugins() {
|
|
642
726
|
return Z;
|
|
643
727
|
}
|
|
728
|
+
/**
|
|
729
|
+
* Call to await LODs loading during the next render cycle.
|
|
730
|
+
*/
|
|
731
|
+
awaitLoading(t) {
|
|
732
|
+
const e = this._promiseGroupIds++, s = new ye(p(this, ee), { ...t });
|
|
733
|
+
this._newPromiseGroups.push(s);
|
|
734
|
+
const o = performance.now();
|
|
735
|
+
return s.ready.finally(() => {
|
|
736
|
+
const r = this._newPromiseGroups.indexOf(s);
|
|
737
|
+
r >= 0 && (this._newPromiseGroups.splice(r, 1), ct() && performance.measure("LODsManager:awaitLoading", {
|
|
738
|
+
start: o,
|
|
739
|
+
detail: { id: e, name: t == null ? void 0 : t.name, awaited: s.awaitedCount, resolved: s.resolvedCount }
|
|
740
|
+
}));
|
|
741
|
+
}), s.ready;
|
|
742
|
+
}
|
|
743
|
+
_postprocessPromiseGroups() {
|
|
744
|
+
if (this._newPromiseGroups.length !== 0)
|
|
745
|
+
for (let t = this._newPromiseGroups.length - 1; t >= 0; t--)
|
|
746
|
+
this._newPromiseGroups[t].update(p(this, ee));
|
|
747
|
+
}
|
|
644
748
|
addEventListener(t, e) {
|
|
645
749
|
t === "changed" && this._lodchangedlisteners.push(e);
|
|
646
750
|
}
|
|
647
751
|
removeEventListener(t, e) {
|
|
648
752
|
if (t === "changed") {
|
|
649
|
-
const
|
|
650
|
-
|
|
753
|
+
const s = this._lodchangedlisteners.indexOf(e);
|
|
754
|
+
s >= 0 && this._lodchangedlisteners.splice(s, 1);
|
|
651
755
|
}
|
|
652
756
|
}
|
|
653
757
|
/**
|
|
654
758
|
* Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
|
|
655
759
|
*/
|
|
656
760
|
enable() {
|
|
657
|
-
if (
|
|
761
|
+
if (p(this, H))
|
|
658
762
|
return;
|
|
659
763
|
console.debug("[gltf-progressive] Enabling LODsManager for renderer");
|
|
660
764
|
let t = 0;
|
|
661
765
|
V(this, H, this.renderer.render);
|
|
662
766
|
const e = this;
|
|
663
|
-
Ue(this.renderer), this.renderer.render = function(
|
|
664
|
-
const
|
|
665
|
-
(
|
|
666
|
-
const
|
|
667
|
-
|
|
767
|
+
Ue(this.renderer), this.renderer.render = function(s, o) {
|
|
768
|
+
const r = e.renderer.getRenderTarget();
|
|
769
|
+
(r == null || "isXRRenderTarget" in r && r.isXRRenderTarget) && (t = 0, V(e, ee, p(e, ee) + 1), V(e, ie, p(e, _e).getDelta()), V(e, we, p(e, we) + p(e, ie)), e._fpsBuffer.shift(), e._fpsBuffer.push(1 / p(e, ie)), V(e, j, e._fpsBuffer.reduce((a, l) => a + l) / e._fpsBuffer.length), F && p(e, ee) % 200 === 0 && console.log("FPS", Math.round(p(e, j)), "Interval:", p(e, G)));
|
|
770
|
+
const i = t++;
|
|
771
|
+
p(e, H).call(this, s, o), e.onAfterRender(s, o, i);
|
|
668
772
|
};
|
|
669
773
|
}
|
|
670
774
|
disable() {
|
|
671
|
-
|
|
775
|
+
p(this, H) && (console.debug("[gltf-progressive] Disabling LODsManager for renderer"), this.renderer.render = p(this, H), V(this, H, void 0));
|
|
672
776
|
}
|
|
673
777
|
update(t, e) {
|
|
674
778
|
this.internalUpdate(t, e);
|
|
675
779
|
}
|
|
676
|
-
onAfterRender(t, e,
|
|
780
|
+
onAfterRender(t, e, s) {
|
|
677
781
|
if (this.pause)
|
|
678
782
|
return;
|
|
679
|
-
const
|
|
680
|
-
let
|
|
681
|
-
if (
|
|
682
|
-
const a =
|
|
683
|
-
(a.name === "EffectMaterial" || a.name === "CopyShader") && (
|
|
783
|
+
const r = this.renderer.renderLists.get(t, 0).opaque;
|
|
784
|
+
let i = !0;
|
|
785
|
+
if (r.length === 1) {
|
|
786
|
+
const a = r[0].material;
|
|
787
|
+
(a.name === "EffectMaterial" || a.name === "CopyShader") && (i = !1);
|
|
684
788
|
}
|
|
685
|
-
if ((e.parent && e.parent.type === "CubeCamera" ||
|
|
686
|
-
if (
|
|
789
|
+
if ((e.parent && e.parent.type === "CubeCamera" || s >= 1 && e.type === "OrthographicCamera") && (i = !1), i) {
|
|
790
|
+
if (yt || (this.updateInterval === "auto" ? p(this, j) < 40 && p(this, G) < 10 ? (V(this, G, p(this, G) + 1), F && console.warn("↓ Reducing LOD updates", p(this, G), p(this, j).toFixed(0))) : p(this, j) >= 60 && p(this, G) > 1 && (V(this, G, p(this, G) - 1), F && console.warn("↑ Increasing LOD updates", p(this, G), p(this, j).toFixed(0))) : V(this, G, this.updateInterval), p(this, G) > 0 && p(this, ee) % p(this, G) != 0))
|
|
687
791
|
return;
|
|
688
|
-
this.internalUpdate(t, e);
|
|
792
|
+
this.internalUpdate(t, e), this._postprocessPromiseGroups();
|
|
689
793
|
}
|
|
690
794
|
}
|
|
691
795
|
/**
|
|
692
796
|
* Update LODs in a scene
|
|
693
797
|
*/
|
|
694
798
|
internalUpdate(t, e) {
|
|
695
|
-
var l,
|
|
696
|
-
const
|
|
799
|
+
var l, c;
|
|
800
|
+
const s = this.renderer.renderLists.get(t, 0), o = s.opaque;
|
|
697
801
|
this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix, e.matrixWorldInverse);
|
|
698
|
-
const
|
|
699
|
-
for (const
|
|
700
|
-
if (
|
|
701
|
-
|
|
802
|
+
const r = this.targetTriangleDensity;
|
|
803
|
+
for (const u of o) {
|
|
804
|
+
if (u.material && (((l = u.geometry) == null ? void 0 : l.type) === "BoxGeometry" || ((c = u.geometry) == null ? void 0 : c.type) === "BufferGeometry") && (u.material.name === "SphericalGaussianBlur" || u.material.name == "BackgroundCubeMaterial" || u.material.name === "CubemapFromEquirect" || u.material.name === "EquirectangularToCubeUV")) {
|
|
805
|
+
F && (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)));
|
|
702
806
|
continue;
|
|
703
807
|
}
|
|
704
|
-
switch (
|
|
808
|
+
switch (u.material.type) {
|
|
705
809
|
case "LineBasicMaterial":
|
|
706
810
|
case "LineDashedMaterial":
|
|
707
811
|
case "PointsMaterial":
|
|
@@ -710,39 +814,39 @@ const T = class {
|
|
|
710
814
|
case "MeshDepthMaterial":
|
|
711
815
|
continue;
|
|
712
816
|
}
|
|
713
|
-
if (
|
|
714
|
-
|
|
715
|
-
const g = Math.random() * 16777215,
|
|
716
|
-
|
|
817
|
+
if (F === "color" && u.material && !u.object.progressive_debug_color) {
|
|
818
|
+
u.object.progressive_debug_color = !0;
|
|
819
|
+
const g = Math.random() * 16777215, _ = new Qe({ color: g });
|
|
820
|
+
u.object.material = _;
|
|
717
821
|
}
|
|
718
|
-
const h =
|
|
719
|
-
(h instanceof
|
|
822
|
+
const h = u.object;
|
|
823
|
+
(h instanceof se || h.isMesh) && this.updateLODs(t, e, h, r);
|
|
720
824
|
}
|
|
721
|
-
const
|
|
722
|
-
for (const
|
|
723
|
-
const h =
|
|
724
|
-
(h instanceof
|
|
825
|
+
const i = s.transparent;
|
|
826
|
+
for (const u of i) {
|
|
827
|
+
const h = u.object;
|
|
828
|
+
(h instanceof se || h.isMesh) && this.updateLODs(t, e, h, r);
|
|
725
829
|
}
|
|
726
|
-
const a =
|
|
727
|
-
for (const
|
|
728
|
-
const h =
|
|
729
|
-
(h instanceof
|
|
830
|
+
const a = s.transmissive;
|
|
831
|
+
for (const u of a) {
|
|
832
|
+
const h = u.object;
|
|
833
|
+
(h instanceof se || h.isMesh) && this.updateLODs(t, e, h, r);
|
|
730
834
|
}
|
|
731
835
|
}
|
|
732
836
|
/** Update the LOD levels for the renderer. */
|
|
733
|
-
updateLODs(t, e,
|
|
837
|
+
updateLODs(t, e, s, o) {
|
|
734
838
|
var a, l;
|
|
735
|
-
|
|
736
|
-
let
|
|
737
|
-
if (
|
|
839
|
+
s.userData || (s.userData = {});
|
|
840
|
+
let r = s[Se];
|
|
841
|
+
if (r || (r = new xt(), s[Se] = r), r.frames++ < 2)
|
|
738
842
|
return;
|
|
739
|
-
for (const
|
|
740
|
-
(a =
|
|
741
|
-
const
|
|
742
|
-
|
|
743
|
-
for (const
|
|
744
|
-
(l =
|
|
745
|
-
|
|
843
|
+
for (const c of Z)
|
|
844
|
+
(a = c.onBeforeUpdateLOD) == null || a.call(c, this.renderer, t, e, s);
|
|
845
|
+
const i = P.overrideGlobalLodLevel !== void 0 ? P.overrideGlobalLodLevel : te;
|
|
846
|
+
i >= 0 ? (E.mesh_lod = i, E.texture_lod = i) : (this.calculateLodLevel(e, s, r, o, E), E.mesh_lod = Math.round(E.mesh_lod), E.texture_lod = Math.round(E.texture_lod)), E.mesh_lod >= 0 && this.loadProgressiveMeshes(s, E.mesh_lod), s.material && E.texture_lod >= 0 && this.loadProgressiveTextures(s.material, E.texture_lod), y && s.material && !s.isGizmo && Ve(s.material);
|
|
847
|
+
for (const c of Z)
|
|
848
|
+
(l = c.onAfterUpdatedLOD) == null || l.call(c, this.renderer, t, e, s, E);
|
|
849
|
+
r.lastLodLevel_Mesh = E.mesh_lod, r.lastLodLevel_Texture = E.texture_lod;
|
|
746
850
|
}
|
|
747
851
|
/** Load progressive textures for the given material
|
|
748
852
|
* @param material the material to load the textures for
|
|
@@ -753,16 +857,20 @@ const T = class {
|
|
|
753
857
|
if (!t)
|
|
754
858
|
return;
|
|
755
859
|
if (Array.isArray(t)) {
|
|
756
|
-
for (const
|
|
757
|
-
this.loadProgressiveTextures(
|
|
860
|
+
for (const r of t)
|
|
861
|
+
this.loadProgressiveTextures(r, e);
|
|
758
862
|
return;
|
|
759
863
|
}
|
|
760
|
-
let
|
|
761
|
-
(t[Q] === void 0 || e < t[Q]) && (
|
|
762
|
-
const
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
864
|
+
let s = !1;
|
|
865
|
+
(t[Q] === void 0 || e < t[Q]) && (s = !0);
|
|
866
|
+
const o = t["DEBUG:LOD"];
|
|
867
|
+
if (o != null && (s = t[Q] != o, e = o), s) {
|
|
868
|
+
t[Q] = e;
|
|
869
|
+
const r = T.assignTextureLOD(t, e).then((i) => {
|
|
870
|
+
this._lodchangedlisteners.forEach((a) => a({ type: "texture", level: e, object: t }));
|
|
871
|
+
});
|
|
872
|
+
ye.addPromise("texture", t, r, this._newPromiseGroups);
|
|
873
|
+
}
|
|
766
874
|
}
|
|
767
875
|
/** Load progressive meshes for the given mesh
|
|
768
876
|
* @param mesh the mesh to load the LOD for
|
|
@@ -773,121 +881,121 @@ const T = class {
|
|
|
773
881
|
loadProgressiveMeshes(t, e) {
|
|
774
882
|
if (!t)
|
|
775
883
|
return Promise.resolve(null);
|
|
776
|
-
let
|
|
777
|
-
const
|
|
778
|
-
if (
|
|
884
|
+
let s = t[Q] !== e;
|
|
885
|
+
const o = t["DEBUG:LOD"];
|
|
886
|
+
if (o != null && (s = t[Q] != o, e = o), s) {
|
|
779
887
|
t[Q] = e;
|
|
780
|
-
const
|
|
781
|
-
return
|
|
888
|
+
const r = t.geometry, i = T.assignMeshLOD(t, e).then((a) => (a && t[Q] == e && r != t.geometry && this._lodchangedlisteners.forEach((l) => l({ type: "mesh", level: e, object: t })), a));
|
|
889
|
+
return ye.addPromise("mesh", t, i, this._newPromiseGroups), i;
|
|
782
890
|
}
|
|
783
891
|
return Promise.resolve(null);
|
|
784
892
|
}
|
|
785
893
|
static isInside(t, e) {
|
|
786
|
-
const
|
|
787
|
-
return this._tempPtInside.set(
|
|
894
|
+
const s = t.min, o = t.max, r = (s.x + o.x) * 0.5, i = (s.y + o.y) * 0.5;
|
|
895
|
+
return this._tempPtInside.set(r, i, s.z).applyMatrix4(e).z < 0;
|
|
788
896
|
}
|
|
789
|
-
calculateLodLevel(t, e,
|
|
790
|
-
var N, X,
|
|
897
|
+
calculateLodLevel(t, e, s, o, r) {
|
|
898
|
+
var N, X, w;
|
|
791
899
|
if (!e) {
|
|
792
|
-
|
|
900
|
+
r.mesh_lod = -1, r.texture_lod = -1;
|
|
793
901
|
return;
|
|
794
902
|
}
|
|
795
903
|
if (!t) {
|
|
796
|
-
|
|
904
|
+
r.mesh_lod = -1, r.texture_lod = -1;
|
|
797
905
|
return;
|
|
798
906
|
}
|
|
799
907
|
let a = 10 + 1, l = !1;
|
|
800
|
-
if (
|
|
908
|
+
if (F && e["DEBUG:LOD"] != null)
|
|
801
909
|
return e["DEBUG:LOD"];
|
|
802
|
-
const
|
|
803
|
-
if (!h && !
|
|
804
|
-
|
|
910
|
+
const c = (N = T.getMeshLODExtension(e.geometry)) == null ? void 0 : N.lods, u = T.getPrimitiveIndex(e.geometry), h = c && c.length > 0, g = T.getMaterialMinMaxLODsCount(e.material), _ = (g == null ? void 0 : g.min_count) != 1 / 0 && g.min_count > 0 && g.max_count > 0;
|
|
911
|
+
if (!h && !_) {
|
|
912
|
+
r.mesh_lod = 0, r.texture_lod = 0;
|
|
805
913
|
return;
|
|
806
914
|
}
|
|
807
915
|
h || (l = !0, a = 0);
|
|
808
|
-
const
|
|
809
|
-
let
|
|
916
|
+
const M = this.renderer.domElement.clientHeight || this.renderer.domElement.height;
|
|
917
|
+
let L = e.geometry.boundingBox;
|
|
810
918
|
if (e.type === "SkinnedMesh") {
|
|
811
|
-
const
|
|
812
|
-
if (!
|
|
813
|
-
|
|
814
|
-
else if (this.skinnedMeshAutoUpdateBoundsInterval > 0 &&
|
|
815
|
-
const
|
|
816
|
-
|
|
919
|
+
const D = e;
|
|
920
|
+
if (!D.boundingBox)
|
|
921
|
+
D.computeBoundingBox();
|
|
922
|
+
else if (this.skinnedMeshAutoUpdateBoundsInterval > 0 && s.frames % this.skinnedMeshAutoUpdateBoundsInterval === 0) {
|
|
923
|
+
const m = ce(D), q = D.geometry;
|
|
924
|
+
m && (D.geometry = m), D.computeBoundingBox(), D.geometry = q;
|
|
817
925
|
}
|
|
818
|
-
|
|
926
|
+
L = D.boundingBox;
|
|
819
927
|
}
|
|
820
|
-
if (
|
|
821
|
-
const
|
|
928
|
+
if (L) {
|
|
929
|
+
const D = t;
|
|
822
930
|
if (e.geometry.attributes.color && e.geometry.attributes.color.count < 100 && e.geometry.boundingSphere) {
|
|
823
931
|
this._sphere.copy(e.geometry.boundingSphere), this._sphere.applyMatrix4(e.matrixWorld);
|
|
824
|
-
const
|
|
825
|
-
if (this._sphere.containsPoint(
|
|
826
|
-
|
|
932
|
+
const x = t.getWorldPosition(this._tempWorldPosition);
|
|
933
|
+
if (this._sphere.containsPoint(x)) {
|
|
934
|
+
r.mesh_lod = 0, r.texture_lod = 0;
|
|
827
935
|
return;
|
|
828
936
|
}
|
|
829
937
|
}
|
|
830
|
-
if (this._tempBox.copy(
|
|
831
|
-
|
|
938
|
+
if (this._tempBox.copy(L), this._tempBox.applyMatrix4(e.matrixWorld), D.isPerspectiveCamera && P.isInside(this._tempBox, this.projectionScreenMatrix)) {
|
|
939
|
+
r.mesh_lod = 0, r.texture_lod = 0;
|
|
832
940
|
return;
|
|
833
941
|
}
|
|
834
|
-
if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled &&
|
|
835
|
-
const
|
|
836
|
-
let C =
|
|
837
|
-
const fe = 2,
|
|
838
|
-
C = (C - he) * fe + he, $ = ($ - ge) * fe + ge, z = (z - he) * fe + he,
|
|
839
|
-
const
|
|
840
|
-
|
|
942
|
+
if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && D.isPerspectiveCamera && D.fov > 70) {
|
|
943
|
+
const x = this._tempBox.min, v = this._tempBox.max;
|
|
944
|
+
let C = x.x, $ = x.y, z = v.x, oe = v.y;
|
|
945
|
+
const fe = 2, ve = 1.5, he = (x.x + v.x) * 0.5, ge = (x.y + v.y) * 0.5;
|
|
946
|
+
C = (C - he) * fe + he, $ = ($ - ge) * fe + ge, z = (z - he) * fe + he, oe = (oe - ge) * fe + ge;
|
|
947
|
+
const qe = C < 0 && z > 0 ? 0 : Math.min(Math.abs(x.x), Math.abs(v.x)), Ke = $ < 0 && oe > 0 ? 0 : Math.min(Math.abs(x.y), Math.abs(v.y)), De = Math.max(qe, Ke);
|
|
948
|
+
s.lastCentrality = (ve - De) * (ve - De) * (ve - De);
|
|
841
949
|
} else
|
|
842
|
-
|
|
843
|
-
const
|
|
844
|
-
|
|
845
|
-
const q = t.matrixWorldInverse,
|
|
846
|
-
|
|
847
|
-
const
|
|
848
|
-
if (Math.max(
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
const v =
|
|
950
|
+
s.lastCentrality = 1;
|
|
951
|
+
const m = this._tempBox.getSize(this._tempBoxSize);
|
|
952
|
+
m.multiplyScalar(0.5), screen.availHeight > 0 && M > 0 && m.multiplyScalar(M / screen.availHeight), t.isPerspectiveCamera ? m.x *= t.aspect : t.isOrthographicCamera;
|
|
953
|
+
const q = t.matrixWorldInverse, A = this._tempBox2;
|
|
954
|
+
A.copy(L), A.applyMatrix4(e.matrixWorld), A.applyMatrix4(q);
|
|
955
|
+
const k = A.getSize(this._tempBox2Size), R = Math.max(k.x, k.y);
|
|
956
|
+
if (Math.max(m.x, m.y) != 0 && R != 0 && (m.z = k.z / Math.max(k.x, k.y) * Math.max(m.x, m.y)), s.lastScreenCoverage = Math.max(m.x, m.y, m.z), s.lastScreenspaceVolume.copy(m), s.lastScreenCoverage *= s.lastCentrality, F && P.debugDrawLine) {
|
|
957
|
+
const x = this.tempMatrix.copy(this.projectionScreenMatrix);
|
|
958
|
+
x.invert();
|
|
959
|
+
const v = P.corner0, C = P.corner1, $ = P.corner2, z = P.corner3;
|
|
852
960
|
v.copy(this._tempBox.min), C.copy(this._tempBox.max), C.x = v.x, $.copy(this._tempBox.max), $.y = v.y, z.copy(this._tempBox.max);
|
|
853
|
-
const
|
|
854
|
-
v.z = C.z = $.z = z.z =
|
|
961
|
+
const oe = (v.z + z.z) * 0.5;
|
|
962
|
+
v.z = C.z = $.z = z.z = oe, v.applyMatrix4(x), C.applyMatrix4(x), $.applyMatrix4(x), z.applyMatrix4(x), P.debugDrawLine(v, C, 255), P.debugDrawLine(v, $, 255), P.debugDrawLine(C, z, 255), P.debugDrawLine($, z, 255);
|
|
855
963
|
}
|
|
856
964
|
let f = 999;
|
|
857
|
-
if (
|
|
858
|
-
for (let
|
|
859
|
-
const v =
|
|
860
|
-
if ((((X = v.densities) == null ? void 0 : X[
|
|
861
|
-
f =
|
|
965
|
+
if (c && s.lastScreenCoverage > 0)
|
|
966
|
+
for (let x = 0; x < c.length; x++) {
|
|
967
|
+
const v = c[x];
|
|
968
|
+
if ((((X = v.densities) == null ? void 0 : X[u]) || v.density || 1e-5) / s.lastScreenCoverage < o) {
|
|
969
|
+
f = x;
|
|
862
970
|
break;
|
|
863
971
|
}
|
|
864
972
|
}
|
|
865
973
|
f < a && (a = f, l = !0);
|
|
866
974
|
}
|
|
867
|
-
if (l ?
|
|
868
|
-
const
|
|
869
|
-
|
|
975
|
+
if (l ? r.mesh_lod = a : r.mesh_lod = s.lastLodLevel_Mesh, F && r.mesh_lod != s.lastLodLevel_Mesh) {
|
|
976
|
+
const m = c == null ? void 0 : c[r.mesh_lod];
|
|
977
|
+
m && console.log(`Mesh LOD changed: ${s.lastLodLevel_Mesh} → ${r.mesh_lod} (${m.density.toFixed(0)}) - ${e.name}`);
|
|
870
978
|
}
|
|
871
|
-
if (
|
|
872
|
-
const
|
|
873
|
-
if (
|
|
874
|
-
if (
|
|
875
|
-
const
|
|
876
|
-
|
|
979
|
+
if (_) {
|
|
980
|
+
const D = "saveData" in globalThis.navigator && globalThis.navigator.saveData === !0;
|
|
981
|
+
if (s.lastLodLevel_Texture < 0) {
|
|
982
|
+
if (r.texture_lod = g.max_count - 1, F) {
|
|
983
|
+
const m = g.lods[g.max_count - 1];
|
|
984
|
+
F && console.log(`First Texture LOD ${r.texture_lod} (${m.max_height}px) - ${e.name}`);
|
|
877
985
|
}
|
|
878
986
|
} else {
|
|
879
|
-
const
|
|
880
|
-
let q =
|
|
881
|
-
((
|
|
882
|
-
const
|
|
883
|
-
let
|
|
987
|
+
const m = s.lastScreenspaceVolume.x + s.lastScreenspaceVolume.y + s.lastScreenspaceVolume.z;
|
|
988
|
+
let q = s.lastScreenCoverage * 4;
|
|
989
|
+
((w = this.context) == null ? void 0 : w.engine) === "model-viewer" && (q *= 1.5);
|
|
990
|
+
const k = M / window.devicePixelRatio * q;
|
|
991
|
+
let R = !1;
|
|
884
992
|
for (let O = g.lods.length - 1; O >= 0; O--) {
|
|
885
993
|
const f = g.lods[O];
|
|
886
|
-
if (!(
|
|
887
|
-
if (
|
|
994
|
+
if (!(D && f.max_height >= 2048) && !(ut() && f.max_height > 4096) && (f.max_height > k || !R && O === 0)) {
|
|
995
|
+
if (R = !0, r.texture_lod = O, r.texture_lod < s.lastLodLevel_Texture) {
|
|
888
996
|
const S = f.max_height;
|
|
889
|
-
|
|
890
|
-
Screensize: ${
|
|
997
|
+
F && console.log(`Texture LOD changed: ${s.lastLodLevel_Texture} → ${r.texture_lod} = ${S}px
|
|
998
|
+
Screensize: ${k.toFixed(0)}px, Coverage: ${(100 * s.lastScreenCoverage).toFixed(2)}%, Volume ${m.toFixed(1)}
|
|
891
999
|
${e.name}`);
|
|
892
1000
|
}
|
|
893
1001
|
break;
|
|
@@ -895,18 +1003,18 @@ ${e.name}`);
|
|
|
895
1003
|
}
|
|
896
1004
|
}
|
|
897
1005
|
} else
|
|
898
|
-
|
|
1006
|
+
r.texture_lod = 0;
|
|
899
1007
|
}
|
|
900
1008
|
};
|
|
901
|
-
let I =
|
|
902
|
-
|
|
1009
|
+
let I = P;
|
|
1010
|
+
G = new WeakMap(), H = new WeakMap(), _e = new WeakMap(), ee = new WeakMap(), ie = new WeakMap(), we = new WeakMap(), j = new WeakMap(), /**
|
|
903
1011
|
* 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.
|
|
904
1012
|
*/
|
|
905
1013
|
d(I, "debugDrawLine"), /**
|
|
906
1014
|
* Force override the LOD level for all objects in the scene
|
|
907
1015
|
*/
|
|
908
1016
|
d(I, "overrideGlobalLodLevel"), d(I, "corner0", new K()), d(I, "corner1", new K()), d(I, "corner2", new K()), d(I, "corner3", new K()), d(I, "_tempPtInside", new K());
|
|
909
|
-
class
|
|
1017
|
+
class xt {
|
|
910
1018
|
constructor() {
|
|
911
1019
|
d(this, "frames", 0);
|
|
912
1020
|
d(this, "lastLodLevel_Mesh", -1);
|
|
@@ -916,79 +1024,79 @@ class yt {
|
|
|
916
1024
|
d(this, "lastCentrality", 0);
|
|
917
1025
|
}
|
|
918
1026
|
}
|
|
919
|
-
const
|
|
920
|
-
let
|
|
921
|
-
function
|
|
922
|
-
const n =
|
|
1027
|
+
const Be = Symbol("NEEDLE_mesh_lod"), pe = Symbol("NEEDLE_texture_lod");
|
|
1028
|
+
let de = null;
|
|
1029
|
+
function We() {
|
|
1030
|
+
const n = Lt();
|
|
923
1031
|
n && (n.mapURLs(function(t) {
|
|
924
1032
|
return Re(), t;
|
|
925
|
-
}), Re(),
|
|
1033
|
+
}), Re(), de == null || de.disconnect(), de = new MutationObserver((t) => {
|
|
926
1034
|
t.forEach((e) => {
|
|
927
|
-
e.addedNodes.forEach((
|
|
928
|
-
|
|
1035
|
+
e.addedNodes.forEach((s) => {
|
|
1036
|
+
s instanceof HTMLElement && s.tagName.toLowerCase() === "model-viewer" && Xe(s);
|
|
929
1037
|
});
|
|
930
1038
|
});
|
|
931
|
-
}),
|
|
1039
|
+
}), de.observe(document, { childList: !0, subtree: !0 }));
|
|
932
1040
|
}
|
|
933
|
-
function
|
|
1041
|
+
function Lt() {
|
|
934
1042
|
if (typeof customElements > "u")
|
|
935
1043
|
return null;
|
|
936
1044
|
const n = customElements.get("model-viewer");
|
|
937
1045
|
return n || (customElements.whenDefined("model-viewer").then(() => {
|
|
938
|
-
console.debug("[gltf-progressive] model-viewer defined"),
|
|
1046
|
+
console.debug("[gltf-progressive] model-viewer defined"), We();
|
|
939
1047
|
}), null);
|
|
940
1048
|
}
|
|
941
1049
|
function Re() {
|
|
942
1050
|
if (typeof document > "u")
|
|
943
1051
|
return;
|
|
944
1052
|
document.querySelectorAll("model-viewer").forEach((t) => {
|
|
945
|
-
|
|
1053
|
+
Xe(t);
|
|
946
1054
|
});
|
|
947
1055
|
}
|
|
948
1056
|
const ke = /* @__PURE__ */ new WeakSet();
|
|
949
|
-
let
|
|
950
|
-
function
|
|
1057
|
+
let _t = 0;
|
|
1058
|
+
function Xe(n) {
|
|
951
1059
|
if (!n || ke.has(n))
|
|
952
1060
|
return null;
|
|
953
|
-
ke.add(n), console.debug("[gltf-progressive] found new model-viewer..." + ++
|
|
1061
|
+
ke.add(n), console.debug("[gltf-progressive] found new model-viewer..." + ++_t + `
|
|
954
1062
|
`, n.getAttribute("src"));
|
|
955
|
-
let t = null, e = null,
|
|
956
|
-
for (let
|
|
957
|
-
const
|
|
958
|
-
!t &&
|
|
1063
|
+
let t = null, e = null, s = null;
|
|
1064
|
+
for (let o = n; o != null; o = Object.getPrototypeOf(o)) {
|
|
1065
|
+
const r = Object.getOwnPropertySymbols(o), i = r.find((c) => c.toString() == "Symbol(renderer)"), a = r.find((c) => c.toString() == "Symbol(scene)"), l = r.find((c) => c.toString() == "Symbol(needsRender)");
|
|
1066
|
+
!t && i != null && (t = n[i].threeRenderer), !e && a != null && (e = n[a]), !s && l != null && (s = n[l]);
|
|
959
1067
|
}
|
|
960
1068
|
if (t && e) {
|
|
961
|
-
let
|
|
962
|
-
if (
|
|
963
|
-
let
|
|
964
|
-
if (
|
|
1069
|
+
let o = function() {
|
|
1070
|
+
if (s) {
|
|
1071
|
+
let i = 0, a = setInterval(() => {
|
|
1072
|
+
if (i++ > 5) {
|
|
965
1073
|
clearInterval(a);
|
|
966
1074
|
return;
|
|
967
1075
|
}
|
|
968
|
-
|
|
1076
|
+
s == null || s.call(n);
|
|
969
1077
|
}, 300);
|
|
970
1078
|
}
|
|
971
1079
|
};
|
|
972
1080
|
console.debug("[gltf-progressive] setup model-viewer");
|
|
973
|
-
const
|
|
974
|
-
return I.addPlugin(new
|
|
975
|
-
|
|
976
|
-
}), n.addEventListener("model-visibility", (
|
|
977
|
-
|
|
1081
|
+
const r = I.get(t, { engine: "model-viewer" });
|
|
1082
|
+
return I.addPlugin(new wt()), r.enable(), r.addEventListener("changed", () => {
|
|
1083
|
+
s == null || s.call(n);
|
|
1084
|
+
}), n.addEventListener("model-visibility", (i) => {
|
|
1085
|
+
i.detail.visible && (s == null || s.call(n));
|
|
978
1086
|
}), n.addEventListener("load", () => {
|
|
979
|
-
|
|
1087
|
+
o();
|
|
980
1088
|
}), () => {
|
|
981
|
-
|
|
1089
|
+
r.disable();
|
|
982
1090
|
};
|
|
983
1091
|
}
|
|
984
1092
|
return null;
|
|
985
1093
|
}
|
|
986
|
-
class
|
|
1094
|
+
class wt {
|
|
987
1095
|
constructor() {
|
|
988
1096
|
d(this, "_didWarnAboutMissingUrl", !1);
|
|
989
1097
|
}
|
|
990
|
-
onBeforeUpdateLOD(t, e,
|
|
991
|
-
this.tryParseMeshLOD(e,
|
|
1098
|
+
onBeforeUpdateLOD(t, e, s, o) {
|
|
1099
|
+
this.tryParseMeshLOD(e, o), this.tryParseTextureLOD(e, o);
|
|
992
1100
|
}
|
|
993
1101
|
getUrl(t) {
|
|
994
1102
|
if (!t)
|
|
@@ -1006,28 +1114,28 @@ class xt {
|
|
|
1006
1114
|
if (e[pe] == !0)
|
|
1007
1115
|
return;
|
|
1008
1116
|
e[pe] = !0;
|
|
1009
|
-
const
|
|
1010
|
-
if (
|
|
1011
|
-
let
|
|
1012
|
-
var
|
|
1117
|
+
const s = this.tryGetCurrentGLTF(t), o = this.tryGetCurrentModelViewer(t), r = this.getUrl(o);
|
|
1118
|
+
if (r && s && e.material) {
|
|
1119
|
+
let i = function(l) {
|
|
1120
|
+
var u, h, g;
|
|
1013
1121
|
if (l[pe] == !0)
|
|
1014
1122
|
return;
|
|
1015
1123
|
l[pe] = !0, l.userData && (l.userData.LOD = -1);
|
|
1016
|
-
const
|
|
1017
|
-
for (let
|
|
1018
|
-
const
|
|
1019
|
-
if ((
|
|
1020
|
-
const N = (h = (
|
|
1124
|
+
const c = Object.keys(l);
|
|
1125
|
+
for (let _ = 0; _ < c.length; _++) {
|
|
1126
|
+
const M = c[_], L = l[M];
|
|
1127
|
+
if ((L == null ? void 0 : L.isTexture) === !0) {
|
|
1128
|
+
const N = (h = (u = L.userData) == null ? void 0 : u.associations) == null ? void 0 : h.textures;
|
|
1021
1129
|
if (N == null)
|
|
1022
1130
|
continue;
|
|
1023
|
-
const X =
|
|
1131
|
+
const X = s.parser.json.textures[N];
|
|
1024
1132
|
if (!X) {
|
|
1025
1133
|
console.warn("Texture data not found for texture index " + N);
|
|
1026
1134
|
continue;
|
|
1027
1135
|
}
|
|
1028
1136
|
if ((g = X == null ? void 0 : X.extensions) != null && g[Y]) {
|
|
1029
|
-
const
|
|
1030
|
-
|
|
1137
|
+
const w = X.extensions[Y];
|
|
1138
|
+
w && r && T.registerTexture(r, L, w.lods.length, N, w);
|
|
1031
1139
|
}
|
|
1032
1140
|
}
|
|
1033
1141
|
}
|
|
@@ -1035,43 +1143,43 @@ class xt {
|
|
|
1035
1143
|
const a = e.material;
|
|
1036
1144
|
if (Array.isArray(a))
|
|
1037
1145
|
for (const l of a)
|
|
1038
|
-
|
|
1146
|
+
i(l);
|
|
1039
1147
|
else
|
|
1040
|
-
|
|
1148
|
+
i(a);
|
|
1041
1149
|
}
|
|
1042
1150
|
}
|
|
1043
1151
|
tryParseMeshLOD(t, e) {
|
|
1044
|
-
var
|
|
1045
|
-
if (e[
|
|
1152
|
+
var i, a;
|
|
1153
|
+
if (e[Be] == !0)
|
|
1046
1154
|
return;
|
|
1047
|
-
e[
|
|
1048
|
-
const
|
|
1049
|
-
if (!
|
|
1155
|
+
e[Be] = !0;
|
|
1156
|
+
const s = this.tryGetCurrentModelViewer(t), o = this.getUrl(s);
|
|
1157
|
+
if (!o)
|
|
1050
1158
|
return;
|
|
1051
|
-
const
|
|
1052
|
-
if (
|
|
1159
|
+
const r = (a = (i = e.userData) == null ? void 0 : i.gltfExtensions) == null ? void 0 : a[Y];
|
|
1160
|
+
if (r && o) {
|
|
1053
1161
|
const l = e.uuid;
|
|
1054
|
-
|
|
1162
|
+
T.registerMesh(o, l, e, 0, r.lods.length, r);
|
|
1055
1163
|
}
|
|
1056
1164
|
}
|
|
1057
1165
|
}
|
|
1058
|
-
function
|
|
1059
|
-
Ue(t),
|
|
1166
|
+
function vt(n, t, e, s) {
|
|
1167
|
+
Ue(t), Ne(e), ze(e, {
|
|
1060
1168
|
progressive: !0,
|
|
1061
|
-
...
|
|
1062
|
-
}), e.register((
|
|
1063
|
-
const
|
|
1064
|
-
return (
|
|
1169
|
+
...s == null ? void 0 : s.hints
|
|
1170
|
+
}), e.register((r) => new T(r, n));
|
|
1171
|
+
const o = I.get(t);
|
|
1172
|
+
return (s == null ? void 0 : s.enableLODsManager) !== !1 && o.enable(), o;
|
|
1065
1173
|
}
|
|
1066
|
-
|
|
1067
|
-
if (!
|
|
1174
|
+
We();
|
|
1175
|
+
if (!ft) {
|
|
1068
1176
|
const n = {
|
|
1069
1177
|
gltfProgressive: {
|
|
1070
|
-
useNeedleProgressive:
|
|
1178
|
+
useNeedleProgressive: vt,
|
|
1071
1179
|
LODsManager: I,
|
|
1072
|
-
configureLoader:
|
|
1073
|
-
getRaycastMesh:
|
|
1074
|
-
useRaycastMeshes:
|
|
1180
|
+
configureLoader: ze,
|
|
1181
|
+
getRaycastMesh: ce,
|
|
1182
|
+
useRaycastMeshes: gt
|
|
1075
1183
|
}
|
|
1076
1184
|
};
|
|
1077
1185
|
if (!globalThis.Needle)
|
|
@@ -1083,16 +1191,16 @@ if (!ut) {
|
|
|
1083
1191
|
export {
|
|
1084
1192
|
Y as EXTENSION_NAME,
|
|
1085
1193
|
I as LODsManager,
|
|
1086
|
-
|
|
1194
|
+
T as NEEDLE_progressive,
|
|
1087
1195
|
rt as VERSION,
|
|
1088
|
-
|
|
1089
|
-
|
|
1196
|
+
Ne as addDracoAndKTX2Loaders,
|
|
1197
|
+
ze as configureLoader,
|
|
1090
1198
|
Ue as createLoaders,
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1199
|
+
ce as getRaycastMesh,
|
|
1200
|
+
We as patchModelViewer,
|
|
1201
|
+
ht as registerRaycastMesh,
|
|
1202
|
+
nt as setDracoDecoderLocation,
|
|
1203
|
+
at as setKTX2TranscoderLocation,
|
|
1204
|
+
vt as useNeedleProgressive,
|
|
1205
|
+
gt as useRaycastMeshes
|
|
1098
1206
|
};
|