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