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