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