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