@needle-tools/gltf-progressive 1.2.1-alpha.2 → 1.2.1-alpha.4
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 +6 -0
- package/README.md +3 -2
- package/gltf-progressive.js +51 -51
- package/gltf-progressive.min.js +4 -4
- package/gltf-progressive.umd.cjs +4 -4
- package/lib/lods_manager.js +3 -9
- package/lib/utils.internal.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to this package will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [1.2.1-alpha.4] - 2023-06-19
|
|
8
|
+
- Fix: SkinnedMesh bounds calculation
|
|
9
|
+
|
|
10
|
+
## [1.2.1-alpha.3] - 2023-06-15
|
|
11
|
+
- update the README
|
|
12
|
+
|
|
7
13
|
## [1.2.1-alpha.2] - 2023-06-15
|
|
8
14
|
- fix: Ortographic camera causing LODs being falsely updated
|
|
9
15
|
- fix: regression introduced in 1.2.1-alpha
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Support for loading of glTF or GLB files with progressive mesh or texture data f
|
|
|
6
6
|
- Automatic loading of mesh and texture LODs.
|
|
7
7
|
- High quality LOD levels are loaded on demand based on screen density.
|
|
8
8
|
- Use low-poly LOD meshes for raycasting which allows the usage of high-poly meshes with smooth interaction
|
|
9
|
-
|
|
9
|
+
- Use [cloud.needle.tools](https://cloud.needle.tools) for processing glTF, GLB & VRM assets
|
|
10
10
|
|
|
11
11
|
## Examples
|
|
12
12
|
|
|
@@ -15,7 +15,8 @@ Examples are in the `/examples` directory. Live versions can be found in the lin
|
|
|
15
15
|
- [Vanilla three.js](https://engine.needle.tools/demos/gltf-progressive/threejs/) - multiple models and animations
|
|
16
16
|
- [\<model-viewer\>](https://engine.needle.tools/demos/gltf-progressive/modelviewer)
|
|
17
17
|
- [React Three Fiber](https://engine.needle.tools/demos/gltf-progressive/r3f/)
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
[Interactive Examples: Stackblitz ⚡️](https://stackblitz.com/@marwie/collections/gltf-progressive)
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
<br/>
|
package/gltf-progressive.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var De = Object.defineProperty;
|
|
2
2
|
var we = (l, e, t) => e in l ? De(l, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[e] = t;
|
|
3
3
|
var d = (l, e, t) => (we(l, typeof e != "symbol" ? e + "" : e, t), t);
|
|
4
|
-
import { BufferGeometry as ee, Mesh as
|
|
4
|
+
import { BufferGeometry as ee, Mesh as W, Material as _e, Texture as K, TextureLoader as Oe, Matrix4 as de, Frustum as ve, Sphere as Se, Box3 as he, Vector3 as k } from "three";
|
|
5
5
|
import { GLTFLoader as Te } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
6
6
|
import { MeshoptDecoder as be } from "three/examples/jsm/libs/meshopt_decoder.module.js";
|
|
7
7
|
import { DRACOLoader as Ae } from "three/examples/jsm/loaders/DRACOLoader.js";
|
|
@@ -41,15 +41,15 @@ function Ce(l, e) {
|
|
|
41
41
|
}
|
|
42
42
|
let q;
|
|
43
43
|
function Be() {
|
|
44
|
-
return q !== void 0 || (q = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), re("debugprogressive") && console.log("isMobileDevice", q)), q;
|
|
44
|
+
return q !== void 0 || (q = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent), re("debugprogressive") && console.log("[glTF Progressive]: isMobileDevice", q)), q;
|
|
45
45
|
}
|
|
46
46
|
const le = Symbol("needle:raycast-mesh");
|
|
47
47
|
function fe(l) {
|
|
48
48
|
return (l == null ? void 0 : l[le]) instanceof ee ? l[le] : null;
|
|
49
49
|
}
|
|
50
|
-
function
|
|
50
|
+
function Re(l, e) {
|
|
51
51
|
if ((l.type === "Mesh" || l.type === "SkinnedMesh") && !fe(l)) {
|
|
52
|
-
const r =
|
|
52
|
+
const r = ke(e);
|
|
53
53
|
r.userData = { isRaycastMesh: !0 }, l[le] = r;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -57,8 +57,8 @@ function Ve(l = !0) {
|
|
|
57
57
|
if (l) {
|
|
58
58
|
if (X)
|
|
59
59
|
return;
|
|
60
|
-
const e = X =
|
|
61
|
-
|
|
60
|
+
const e = X = W.prototype.raycast;
|
|
61
|
+
W.prototype.raycast = function(t, r) {
|
|
62
62
|
const i = this, o = fe(i);
|
|
63
63
|
let s;
|
|
64
64
|
o && i.isMesh && (s = i.geometry, i.geometry = o), e.call(this, t, r), s && (i.geometry = s);
|
|
@@ -66,17 +66,17 @@ function Ve(l = !0) {
|
|
|
66
66
|
} else {
|
|
67
67
|
if (!X)
|
|
68
68
|
return;
|
|
69
|
-
|
|
69
|
+
W.prototype.raycast = X, X = null;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
let X = null;
|
|
73
|
-
function
|
|
73
|
+
function ke(l) {
|
|
74
74
|
const e = new ee();
|
|
75
75
|
for (const t in l.attributes)
|
|
76
76
|
e.setAttribute(t, l.getAttribute(t));
|
|
77
77
|
return e.setIndex(l.getIndex()), e;
|
|
78
78
|
}
|
|
79
|
-
const
|
|
79
|
+
const F = new Array(), E = "NEEDLE_progressive", y = re("debugprogressive"), oe = Symbol("needle-progressive-texture"), H = /* @__PURE__ */ new Map(), ce = /* @__PURE__ */ new Set();
|
|
80
80
|
if (y) {
|
|
81
81
|
let l = function() {
|
|
82
82
|
e += 1, console.log("Toggle LOD level", e, H), H.forEach((i, o) => {
|
|
@@ -225,11 +225,11 @@ const O = class {
|
|
|
225
225
|
var r;
|
|
226
226
|
if (!e)
|
|
227
227
|
return Promise.resolve(null);
|
|
228
|
-
if (e instanceof
|
|
228
|
+
if (e instanceof W || e.isMesh === !0) {
|
|
229
229
|
const i = e.geometry, o = this.getAssignedLODInformation(i);
|
|
230
230
|
if (!o)
|
|
231
231
|
return Promise.resolve(null);
|
|
232
|
-
for (const s of
|
|
232
|
+
for (const s of F)
|
|
233
233
|
(r = s.onBeforeGetLODMesh) == null || r.call(s, e, t);
|
|
234
234
|
return e["LOD:requested level"] = t, O.getOrLoadLOD(i, t).then((s) => {
|
|
235
235
|
if (e["LOD:requested level"] === t) {
|
|
@@ -389,16 +389,16 @@ const O = class {
|
|
|
389
389
|
const g = w.lods[t];
|
|
390
390
|
g.hash && (J += "?v=" + g.hash);
|
|
391
391
|
}
|
|
392
|
-
const
|
|
392
|
+
const R = await A.loadAsync(J).catch((g) => (console.error(`Error loading LOD ${t} from ${u}
|
|
393
393
|
`, g), null));
|
|
394
|
-
if (!
|
|
394
|
+
if (!R)
|
|
395
395
|
return null;
|
|
396
|
-
const U =
|
|
396
|
+
const U = R.parser;
|
|
397
397
|
r && console.log("Loading finished " + u, w.guid);
|
|
398
398
|
let I = 0;
|
|
399
|
-
if (
|
|
399
|
+
if (R.parser.json.textures) {
|
|
400
400
|
let g = !1;
|
|
401
|
-
for (const f of
|
|
401
|
+
for (const f of R.parser.json.textures) {
|
|
402
402
|
if (f != null && f.extensions) {
|
|
403
403
|
const L = f == null ? void 0 : f.extensions[E];
|
|
404
404
|
if (L != null && L.guid && L.guid === w.guid) {
|
|
@@ -412,11 +412,11 @@ const O = class {
|
|
|
412
412
|
let f = await U.getDependency("texture", I);
|
|
413
413
|
return f && O.assignLODInformation(i.url, f, o, t, void 0, void 0), r && console.log('change "' + e.name + '" → "' + f.name + '"', u, I, f, p), e instanceof K && (f = this.copySettings(e, f)), f && (f.guid = w.guid), _(f);
|
|
414
414
|
} else
|
|
415
|
-
y && console.warn("Could not find texture with guid", w.guid,
|
|
415
|
+
y && console.warn("Could not find texture with guid", w.guid, R.parser.json);
|
|
416
416
|
}
|
|
417
|
-
if (I = 0,
|
|
417
|
+
if (I = 0, R.parser.json.meshes) {
|
|
418
418
|
let g = !1;
|
|
419
|
-
for (const f of
|
|
419
|
+
for (const f of R.parser.json.meshes) {
|
|
420
420
|
if (f != null && f.extensions) {
|
|
421
421
|
const L = f == null ? void 0 : f.extensions[E];
|
|
422
422
|
if (L != null && L.guid && L.guid === w.guid) {
|
|
@@ -436,14 +436,14 @@ const O = class {
|
|
|
436
436
|
for (let T = 0; T < f.children.length; T++) {
|
|
437
437
|
const G = f.children[T];
|
|
438
438
|
if (G.isMesh === !0) {
|
|
439
|
-
const
|
|
440
|
-
O.assignLODInformation(i.url,
|
|
439
|
+
const $ = G.geometry;
|
|
440
|
+
O.assignLODInformation(i.url, $, o, t, T, L.density), S.push($);
|
|
441
441
|
}
|
|
442
442
|
}
|
|
443
443
|
return _(S);
|
|
444
444
|
}
|
|
445
445
|
} else
|
|
446
|
-
y && console.warn("Could not find mesh with guid", w.guid,
|
|
446
|
+
y && console.warn("Could not find mesh with guid", w.guid, R.parser.json);
|
|
447
447
|
}
|
|
448
448
|
return _(null);
|
|
449
449
|
});
|
|
@@ -500,8 +500,8 @@ d(v, "registerMesh", (e, t, r, i, o, s) => {
|
|
|
500
500
|
}
|
|
501
501
|
n.userData || (n.userData = {}), O.assignLODInformation(e, n, t, i, o, s.density), O.lodInfos.set(t, s);
|
|
502
502
|
let a = O.lowresCache.get(t);
|
|
503
|
-
a ? a.push(r.geometry) : a = [r.geometry], O.lowresCache.set(t, a), i > 0 && !fe(r) &&
|
|
504
|
-
for (const c of
|
|
503
|
+
a ? a.push(r.geometry) : a = [r.geometry], O.lowresCache.set(t, a), i > 0 && !fe(r) && Re(r, n);
|
|
504
|
+
for (const c of F)
|
|
505
505
|
(h = c.onRegisteredNewMesh) == null || h.call(c, r, s);
|
|
506
506
|
}), /** A map of key = asset uuid and value = LOD information */
|
|
507
507
|
d(v, "lodInfos", /* @__PURE__ */ new Map()), /** cache of already loaded mesh lods */
|
|
@@ -520,7 +520,7 @@ class Ee {
|
|
|
520
520
|
this.url = e, this.key = t, this.level = r, i != null && (this.index = i), o != null && (this.density = o);
|
|
521
521
|
}
|
|
522
522
|
}
|
|
523
|
-
const z = re("debugprogressive"), Ie = re("noprogressive"), pe = Symbol("Needle:LODSManager"), ne = Symbol("Needle:LODState"),
|
|
523
|
+
const z = re("debugprogressive"), Ie = re("noprogressive"), pe = Symbol("Needle:LODSManager"), ne = Symbol("Needle:LODState"), N = Symbol("Needle:CurrentLOD"), C = { mesh_lod: -1, texture_lod: -1 }, P = class {
|
|
524
524
|
// readonly plugins: NEEDLE_progressive_plugin[] = [];
|
|
525
525
|
constructor(e) {
|
|
526
526
|
d(this, "renderer");
|
|
@@ -546,9 +546,9 @@ const z = re("debugprogressive"), Ie = re("noprogressive"), pe = Symbol("Needle:
|
|
|
546
546
|
d(this, "_tempBox", new he());
|
|
547
547
|
d(this, "_tempBox2", new he());
|
|
548
548
|
d(this, "tempMatrix", new de());
|
|
549
|
-
d(this, "_tempWorldPosition", new
|
|
550
|
-
d(this, "_tempBoxSize", new
|
|
551
|
-
d(this, "_tempBox2Size", new
|
|
549
|
+
d(this, "_tempWorldPosition", new k());
|
|
550
|
+
d(this, "_tempBoxSize", new k());
|
|
551
|
+
d(this, "_tempBox2Size", new k());
|
|
552
552
|
this.renderer = e;
|
|
553
553
|
}
|
|
554
554
|
/** @internal */
|
|
@@ -556,11 +556,11 @@ const z = re("debugprogressive"), Ie = re("noprogressive"), pe = Symbol("Needle:
|
|
|
556
556
|
return e[ne];
|
|
557
557
|
}
|
|
558
558
|
static addPlugin(e) {
|
|
559
|
-
|
|
559
|
+
F.push(e);
|
|
560
560
|
}
|
|
561
561
|
static removePlugin(e) {
|
|
562
|
-
const t =
|
|
563
|
-
t >= 0 &&
|
|
562
|
+
const t = F.indexOf(e);
|
|
563
|
+
t >= 0 && F.splice(t, 1);
|
|
564
564
|
}
|
|
565
565
|
/**
|
|
566
566
|
* Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
|
|
@@ -572,7 +572,7 @@ const z = re("debugprogressive"), Ie = re("noprogressive"), pe = Symbol("Needle:
|
|
|
572
572
|
}
|
|
573
573
|
/** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
|
|
574
574
|
get plugins() {
|
|
575
|
-
return
|
|
575
|
+
return F;
|
|
576
576
|
}
|
|
577
577
|
/**
|
|
578
578
|
* Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
|
|
@@ -624,12 +624,12 @@ const z = re("debugprogressive"), Ie = re("noprogressive"), pe = Symbol("Needle:
|
|
|
624
624
|
continue;
|
|
625
625
|
}
|
|
626
626
|
const p = u.object;
|
|
627
|
-
(p instanceof
|
|
627
|
+
(p instanceof W || p.isMesh) && this.updateLODs(e, t, p, c, i);
|
|
628
628
|
}
|
|
629
629
|
const m = o.transparent;
|
|
630
630
|
for (const u of m) {
|
|
631
631
|
const p = u.object;
|
|
632
|
-
(p instanceof
|
|
632
|
+
(p instanceof W || p.isMesh) && this.updateLODs(e, t, p, c, i);
|
|
633
633
|
}
|
|
634
634
|
}
|
|
635
635
|
}
|
|
@@ -640,7 +640,7 @@ const z = re("debugprogressive"), Ie = re("noprogressive"), pe = Symbol("Needle:
|
|
|
640
640
|
let s = r[ne];
|
|
641
641
|
if (s || (s = new Ge(), r[ne] = s), s.frames++ < 2)
|
|
642
642
|
return;
|
|
643
|
-
for (const c of
|
|
643
|
+
for (const c of F)
|
|
644
644
|
(a = c.onBeforeUpdateLOD) == null || a.call(c, this.renderer, e, t, r);
|
|
645
645
|
this.calculateLodLevel(t, r, s, i, C), C.mesh_lod = Math.round(C.mesh_lod), C.texture_lod = Math.round(C.texture_lod), C.mesh_lod >= 0 && this.loadProgressiveMeshes(r, C.mesh_lod);
|
|
646
646
|
let n = C.texture_lod;
|
|
@@ -648,7 +648,7 @@ const z = re("debugprogressive"), Ie = re("noprogressive"), pe = Symbol("Needle:
|
|
|
648
648
|
const c = r["DEBUG:LOD"];
|
|
649
649
|
c != null && (n = c), this.loadProgressiveTextures(r.material, n);
|
|
650
650
|
}
|
|
651
|
-
for (const c of
|
|
651
|
+
for (const c of F)
|
|
652
652
|
(h = c.onAfterUpdatedLOD) == null || h.call(c, this.renderer, e, t, r, C);
|
|
653
653
|
s.lastLodLevel_Mesh = C.mesh_lod, s.lastLodLevel_Texture = C.texture_lod;
|
|
654
654
|
}
|
|
@@ -666,7 +666,7 @@ const z = re("debugprogressive"), Ie = re("noprogressive"), pe = Symbol("Needle:
|
|
|
666
666
|
return;
|
|
667
667
|
}
|
|
668
668
|
let r = !1;
|
|
669
|
-
(e[
|
|
669
|
+
(e[N] === void 0 || t < e[N]) && (r = !0), r && (e[N] = t, v.assignTextureLOD(e, t));
|
|
670
670
|
}
|
|
671
671
|
/** Load progressive meshes for the given mesh
|
|
672
672
|
* @param mesh the mesh to load the LOD for
|
|
@@ -677,10 +677,10 @@ const z = re("debugprogressive"), Ie = re("noprogressive"), pe = Symbol("Needle:
|
|
|
677
677
|
loadProgressiveMeshes(e, t) {
|
|
678
678
|
if (!e)
|
|
679
679
|
return Promise.resolve(null);
|
|
680
|
-
if (e[
|
|
681
|
-
e[
|
|
680
|
+
if (e[N] !== t) {
|
|
681
|
+
e[N] = t;
|
|
682
682
|
const r = e.geometry;
|
|
683
|
-
return v.assignMeshLOD(e, t).then((i) => (i && e[
|
|
683
|
+
return v.assignMeshLOD(e, t).then((i) => (i && e[N] == t && r != e.geometry, i));
|
|
684
684
|
}
|
|
685
685
|
return Promise.resolve(null);
|
|
686
686
|
}
|
|
@@ -725,15 +725,15 @@ const z = re("debugprogressive"), Ie = re("noprogressive"), pe = Symbol("Needle:
|
|
|
725
725
|
return;
|
|
726
726
|
}
|
|
727
727
|
}
|
|
728
|
-
if (this._tempBox.copy(x),
|
|
728
|
+
if (this._tempBox.copy(x), this._tempBox.applyMatrix4(t.matrixWorld), P.isInside(this._tempBox, this.projectionScreenMatrix)) {
|
|
729
729
|
o.mesh_lod = 0, o.texture_lod = 0;
|
|
730
730
|
return;
|
|
731
731
|
}
|
|
732
732
|
if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && D.fov > 70) {
|
|
733
733
|
const g = this._tempBox.min, f = this._tempBox.max;
|
|
734
734
|
let L = g.x, S = g.y, T = f.x, G = f.y;
|
|
735
|
-
const
|
|
736
|
-
L = (L - Q) *
|
|
735
|
+
const $ = 2, se = 1.5, Q = (g.x + f.x) * 0.5, Z = (g.y + f.y) * 0.5;
|
|
736
|
+
L = (L - Q) * $ + Q, S = (S - Z) * $ + Z, T = (T - Q) * $ + Q, G = (G - Z) * $ + Z;
|
|
737
737
|
const Le = L < 0 && T > 0 ? 0 : Math.min(Math.abs(g.x), Math.abs(f.x)), Me = S < 0 && G > 0 ? 0 : Math.min(Math.abs(g.y), Math.abs(f.y)), ie = Math.max(Le, Me);
|
|
738
738
|
r.lastCentrality = (se - ie) * (se - ie) * (se - ie);
|
|
739
739
|
} else
|
|
@@ -788,19 +788,19 @@ const z = re("debugprogressive"), Ie = re("noprogressive"), pe = Symbol("Needle:
|
|
|
788
788
|
let B = P;
|
|
789
789
|
/** 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.
|
|
790
790
|
*/
|
|
791
|
-
d(B, "debugDrawLine"), d(B, "corner0", new
|
|
791
|
+
d(B, "debugDrawLine"), d(B, "corner0", new k()), d(B, "corner1", new k()), d(B, "corner2", new k()), d(B, "corner3", new k()), d(B, "_tempPtInside", new k());
|
|
792
792
|
class Ge {
|
|
793
793
|
constructor() {
|
|
794
794
|
d(this, "frames", 0);
|
|
795
795
|
d(this, "lastLodLevel_Mesh", -1);
|
|
796
796
|
d(this, "lastLodLevel_Texture", -1);
|
|
797
797
|
d(this, "lastScreenCoverage", 0);
|
|
798
|
-
d(this, "lastScreenspaceVolume", new
|
|
798
|
+
d(this, "lastScreenspaceVolume", new k());
|
|
799
799
|
d(this, "lastCentrality", 0);
|
|
800
800
|
}
|
|
801
801
|
}
|
|
802
802
|
const ye = Symbol("NEEDLE_mesh_lod"), j = Symbol("NEEDLE_texture_lod");
|
|
803
|
-
function
|
|
803
|
+
function Fe(l) {
|
|
804
804
|
if (!l)
|
|
805
805
|
return null;
|
|
806
806
|
let e = null, t = null;
|
|
@@ -810,7 +810,7 @@ function $e(l) {
|
|
|
810
810
|
}
|
|
811
811
|
if (e) {
|
|
812
812
|
const r = B.get(e);
|
|
813
|
-
if (B.addPlugin(new
|
|
813
|
+
if (B.addPlugin(new $e(l)), r.enable(), t) {
|
|
814
814
|
const i = t.camera || t.traverse((o) => o.type == "PerspectiveCamera")[0];
|
|
815
815
|
i && e.render(t, i);
|
|
816
816
|
}
|
|
@@ -820,7 +820,7 @@ function $e(l) {
|
|
|
820
820
|
}
|
|
821
821
|
return null;
|
|
822
822
|
}
|
|
823
|
-
class
|
|
823
|
+
class $e {
|
|
824
824
|
constructor(e) {
|
|
825
825
|
d(this, "modelviewer");
|
|
826
826
|
d(this, "_didWarnAboutMissingUrl", !1);
|
|
@@ -887,7 +887,7 @@ class Fe {
|
|
|
887
887
|
}
|
|
888
888
|
}
|
|
889
889
|
document.addEventListener("DOMContentLoaded", () => {
|
|
890
|
-
|
|
890
|
+
Fe(document.querySelector("model-viewer"));
|
|
891
891
|
});
|
|
892
892
|
function He(l, e, t, r) {
|
|
893
893
|
me(e), xe(t), t.register((o) => new v(o, l));
|
|
@@ -901,10 +901,10 @@ export {
|
|
|
901
901
|
xe as addDracoAndKTX2Loaders,
|
|
902
902
|
me as createLoaders,
|
|
903
903
|
fe as getRaycastMesh,
|
|
904
|
-
|
|
904
|
+
Fe as patchModelViewer,
|
|
905
905
|
Xe as setDracoDecoderLocation,
|
|
906
906
|
Ye as setKTX2TranscoderLocation,
|
|
907
|
-
|
|
907
|
+
Re as setRaycastMesh,
|
|
908
908
|
He as useNeedleProgressive,
|
|
909
909
|
Ve as useRaycastMeshes
|
|
910
910
|
};
|
package/gltf-progressive.min.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var ve=Object.defineProperty,Le=(t,e,r)=>e in t?ve(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,d=(t,e,r)=>(Le(t,typeof e!="symbol"?e+"":e,r),r);import{BufferGeometry as K,Mesh as $,Material as
|
|
2
|
-
`,
|
|
3
|
-
`,v),null));if(!S)return null;const
|
|
1
|
+
var ve=Object.defineProperty,Le=(t,e,r)=>e in t?ve(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,d=(t,e,r)=>(Le(t,typeof e!="symbol"?e+"":e,r),r);import{BufferGeometry as K,Mesh as $,Material as De,Texture as W,TextureLoader as Me,Matrix4 as ce,Frustum as _e,Sphere as we,Box3 as de,Vector3 as R}from"three";import{GLTFLoader as Oe}from"three/examples/jsm/loaders/GLTFLoader.js";import{MeshoptDecoder as be}from"three/examples/jsm/libs/meshopt_decoder.module.js";import{DRACOLoader as Se}from"three/examples/jsm/loaders/DRACOLoader.js";import{KTX2Loader as Te}from"three/examples/jsm/loaders/KTX2Loader.js";let Y="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",re="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(Y+"draco_decoder.js",{method:"head"}).catch(t=>{Y="./include/draco/",re="./include/ktx2/"});function Ae(t){Y=t}function Pe(t){re=t}let U,se,z;function ne(t){U||(U=new Se,U.setDecoderPath(Y),U.setDecoderConfig({type:"js"})),z||(z=new Te,z.setTranscoderPath(re)),se||(se=be),t?z.detectSupport(t):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function oe(t){t.dracoLoader||t.setDRACOLoader(U),t.ktx2Loader||t.setKTX2Loader(z),t.meshoptDecoder||t.setMeshoptDecoder(se)}function J(t){const e=new URL(window.location.href).searchParams.get(t);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function Ee(t,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||t===void 0)return e;const r=t.lastIndexOf("/");if(r>=0){const o=t.substring(0,r+1);for(;o.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return o+e}return e}let Q;function Ie(){return Q!==void 0||(Q=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),J("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",Q)),Q}const ie=Symbol("needle:raycast-mesh");function Z(t){return t?.[ie]instanceof K?t[ie]:null}function he(t,e){if((t.type==="Mesh"||t.type==="SkinnedMesh")&&!Z(t)){const r=Ce(e);r.userData={isRaycastMesh:!0},t[ie]=r}}function Be(t=!0){if(t){if(q)return;const e=q=$.prototype.raycast;$.prototype.raycast=function(r,o){const s=this,n=Z(s);let i;n&&s.isMesh&&(i=s.geometry,s.geometry=n),e.call(this,r,o),i&&(s.geometry=i)}}else{if(!q)return;$.prototype.raycast=q,q=null}}let q=null;function Ce(t){const e=new K;for(const r in t.attributes)e.setAttribute(r,t.getAttribute(r));return e.setIndex(t.getIndex()),e}const k=new Array,I="NEEDLE_progressive",p=J("debugprogressive"),ae=Symbol("needle-progressive-texture"),V=new Map,le=new Set;if(p){let t=function(){e+=1,console.log("Toggle LOD level",e,V),V.forEach((s,n)=>{for(const i of s.keys){const a=n[i];if(a!=null){if(a.isBufferGeometry===!0){const u=O.getMeshLODInformation(a),l=u?Math.min(e,u.lods.length):0;n["DEBUG:LOD"]=e,O.assignMeshLOD(n,l),u&&(r=Math.max(r,u.lods.length-1))}else if(n.isMaterial===!0){n["DEBUG:LOD"]=e,O.assignTextureLOD(n,e);break}}}}),e>=r&&(e=-1)},e=-1,r=2,o=!1;window.addEventListener("keyup",s=>{s.key==="p"&&t(),s.key==="w"&&(o=!o,le&&le.forEach(n=>{n.name!="BackgroundCubeMaterial"&&n.glyphMap==null&&"wireframe"in n&&(n.wireframe=o)}))})}function fe(t,e,r){var o;if(!p)return;V.has(t)||V.set(t,{keys:[],sourceId:r});const s=V.get(t);((o=s?.keys)==null?void 0:o.includes(e))==!1&&s.keys.push(e)}const _=class{constructor(t,e){d(this,"parser"),d(this,"url"),d(this,"_isLoadingMesh"),d(this,"loadMesh",r=>{var o,s;if(this._isLoadingMesh)return null;const n=(s=(o=this.parser.json.meshes[r])==null?void 0:o.extensions)==null?void 0:s[I];return n?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",r).then(i=>{var a;return this._isLoadingMesh=!1,i&&_.registerMesh(this.url,n.guid,i,(a=n.lods)==null?void 0:a.length,void 0,n),i})):null}),p&&console.log("Progressive extension registered for",e),this.parser=t,this.url=e}get name(){return I}static getMeshLODInformation(t){const e=this.getAssignedLODInformation(t);return e!=null&&e.key?this.lodInfos.get(e.key):null}static getMaterialMinMaxLODsCount(t,e){const r=this,o="LODS:minmax",s=t[o];if(s!=null)return s;if(e||(e={min_count:1/0,max_count:0,lods:[]}),Array.isArray(t)){for(const i of t)this.getMaterialMinMaxLODsCount(i,e);return t[o]=e,e}if(p==="verbose"&&console.log("getMaterialMinMaxLODsCount",t),t.type==="ShaderMaterial"||t.type==="RawShaderMaterial"){const i=t;for(const a of Object.keys(i.uniforms)){const u=i.uniforms[a].value;u?.isTexture===!0&&n(u,e)}}else if(t.isMaterial)for(const i of Object.keys(t)){const a=t[i];a?.isTexture===!0&&n(a,e)}return t[o]=e,e;function n(i,a){const u=r.getAssignedLODInformation(i);if(u){const l=r.lodInfos.get(u.key);if(l&&l.lods){a.min_count=Math.min(a.min_count,l.lods.length),a.max_count=Math.max(a.max_count,l.lods.length);for(let x=0;x<l.lods.length;x++){const c=l.lods[x];c.width&&(a.lods[x]=a.lods[x]||{min_height:1/0,max_height:0},a.lods[x].min_height=Math.min(a.lods[x].min_height,c.height),a.lods[x].max_height=Math.max(a.lods[x].max_height,c.height))}}}}}static hasLODLevelAvailable(t,e){var r;if(Array.isArray(t)){for(const n of t)if(this.hasLODLevelAvailable(n,e))return!0;return!1}if(t.isMaterial===!0){for(const n of Object.keys(t)){const i=t[n];if(i&&i.isTexture&&this.hasLODLevelAvailable(i,e))return!0}return!1}else if(t.isGroup===!0){for(const n of t.children)if(n.isMesh===!0&&this.hasLODLevelAvailable(n,e))return!0}let o,s;if(t.isMesh?o=t.geometry:(t.isBufferGeometry||t.isTexture)&&(o=t),o&&(r=o?.userData)!=null&&r.LODS){const n=o.userData.LODS;if(s=this.lodInfos.get(n.key),e===void 0)return s!=null;if(s)return Array.isArray(s.lods)?e<s.lods.length:e===0}return!1}static assignMeshLOD(t,e){var r;if(!t)return Promise.resolve(null);if(t instanceof $||t.isMesh===!0){const o=t.geometry,s=this.getAssignedLODInformation(o);if(!s)return Promise.resolve(null);for(const n of k)(r=n.onBeforeGetLODMesh)==null||r.call(n,t,e);return t["LOD:requested level"]=e,_.getOrLoadLOD(o,e).then(n=>{if(t["LOD:requested level"]===e){if(delete t["LOD:requested level"],Array.isArray(n)){const i=s.index||0;n=n[i]}n&&o!=n&&(n?.isBufferGeometry?(t.geometry=n,p&&fe(t,"geometry",s.url)):p&&console.error("Invalid LOD geometry",n))}return n}).catch(n=>(console.error("Error loading mesh LOD",t,n),null))}else p&&console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh",t);return Promise.resolve(null)}static assignTextureLOD(t,e=0){if(!t)return Promise.resolve(null);if(t instanceof De||t.isMaterial===!0){const r=t,o=[],s=new Array;if(p&&le.add(r),r.uniforms&&r.isRawShaderMaterial||r.isShaderMaterial===!0){const n=r;for(const i of Object.keys(n.uniforms)){const a=n.uniforms[i].value;if(a?.isTexture===!0){const u=this.assignTextureLODForSlot(a,e,r,i);o.push(u),s.push(i)}}}else for(const n of Object.keys(r)){const i=r[n];if(i?.isTexture===!0){const a=this.assignTextureLODForSlot(i,e,r,n);o.push(a),s.push(n)}}return Promise.all(o).then(n=>{const i=new Array;for(let a=0;a<n.length;a++){const u=n[a],l=s[a];u&&u.isTexture===!0?i.push({material:r,slot:l,texture:u,level:e}):i.push({material:r,slot:l,texture:null,level:e})}return i})}if(t instanceof W||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,o){return t?.isTexture!==!0?Promise.resolve(null):o==="glyphMap"?Promise.resolve(t):_.getOrLoadLOD(t,e).then(s=>{if(Array.isArray(s))return null;if(s?.isTexture===!0){if(s!=t){if(r&&o){const n=r[o];if(n){const i=this.getAssignedLODInformation(n);if(i&&i?.level<e)return p==="verbose"&&console.warn("Assigned texture level is already higher: ",i.level,e,r,n,s),null}r[o]=s}if(p&&o&&r){const n=this.getAssignedLODInformation(t);n&&fe(r,o,n.url)}}return s}else p=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(s=>(console.error("Error loading LOD",t,s),null))}afterRoot(t){var e,r;return p&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((o,s)=>{var n;if(o!=null&&o.extensions){const i=o?.extensions[I];if(i){if(!i.lods){p&&console.warn("Texture has no LODs",i);return}let a=!1;for(const u of this.parser.associations.keys())u.isTexture===!0&&this.parser.associations.get(u).textures===s&&(a=!0,_.registerTexture(this.url,u,(n=i.lods)==null?void 0:n.length,s,i));a||this.parser.getDependency("texture",s).then(u=>{var l;u&&_.registerTexture(this.url,u,(l=i.lods)==null?void 0:l.length,s,i)})}}}),(r=this.parser.json.meshes)==null||r.forEach((o,s)=>{if(o!=null&&o.extensions){const n=o?.extensions[I];if(n&&n.lods){for(const i of this.parser.associations.keys())if(i.isMesh){const a=this.parser.associations.get(i);a.meshes===s&&_.registerMesh(this.url,n.guid,i,n.lods.length,a.primitives,n)}}}}),null}static async getOrLoadLOD(t,e){var r,o,s,n;const i=p=="verbose",a=t.userData.LODS;if(!a)return null;const u=a?.key;let l;if(t.isTexture===!0){const x=t;x.source&&x.source[ae]&&(l=x.source[ae])}if(l||(l=_.lodInfos.get(u)),l){if(e>0){let f=!1;const b=Array.isArray(l.lods);if(b&&e>=l.lods.length?f=!0:b||(f=!0),f)return this.lowresCache.get(u)}const x=Array.isArray(l.lods)?(r=l.lods[e])==null?void 0:r.path:l.lods;if(!x)return p&&!l["missing:uri"]&&(l["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,l)),null;const c=Ee(a.url,x);if(c.endsWith(".glb")||c.endsWith(".gltf")){if(!l.guid)return console.warn("missing pointer for glb/gltf texture",l),null;const f=c+"_"+l.guid,b=this.previouslyLoaded.get(f);if(b!==void 0){i&&console.log(`LOD ${e} was already loading/loaded: ${f}`);let m=await b.catch(E=>(console.error(`Error loading LOD ${e} from ${c}
|
|
2
|
+
`,E),null)),w=!1;if(m==null||(m instanceof W&&t instanceof W?(o=m.image)!=null&&o.data||(s=m.source)!=null&&s.data?m=this.copySettings(t,m):(w=!0,this.previouslyLoaded.delete(f)):m instanceof K&&t instanceof K&&((n=m.attributes.position)!=null&&n.array||(w=!0,this.previouslyLoaded.delete(f)))),!w)return m}const g=l,L=new Promise(async(m,w)=>{const E=new Oe;oe(E),p&&(await new Promise(v=>setTimeout(v,1e3)),i&&console.warn("Start loading (delayed) "+c,g.guid));let X=c;if(g&&Array.isArray(g.lods)){const v=g.lods[e];v.hash&&(X+="?v="+v.hash)}const S=await E.loadAsync(X).catch(v=>(console.error(`Error loading LOD ${e} from ${c}
|
|
3
|
+
`,v),null));if(!S)return null;const D=S.parser;i&&console.log("Loading finished "+c,g.guid);let y=0;if(S.parser.json.textures){let v=!1;for(const h of S.parser.json.textures){if(h!=null&&h.extensions){const M=h?.extensions[I];if(M!=null&&M.guid&&M.guid===g.guid){v=!0;break}}y++}if(v){let h=await D.getDependency("texture",y);return h&&_.assignLODInformation(a.url,h,u,e,void 0,void 0),i&&console.log('change "'+t.name+'" \u2192 "'+h.name+'"',c,y,h,f),t instanceof W&&(h=this.copySettings(t,h)),h&&(h.guid=g.guid),m(h)}else p&&console.warn("Could not find texture with guid",g.guid,S.parser.json)}if(y=0,S.parser.json.meshes){let v=!1;for(const h of S.parser.json.meshes){if(h!=null&&h.extensions){const M=h?.extensions[I];if(M!=null&&M.guid&&M.guid===g.guid){v=!0;break}}y++}if(v){const h=await D.getDependency("mesh",y),M=g;if(i&&console.log(`Loaded Mesh "${h.name}"`,c,y,h,f),h.isMesh===!0){const A=h.geometry;return _.assignLODInformation(a.url,A,u,e,void 0,M.density),m(A)}else{const A=new Array;for(let C=0;C<h.children.length;C++){const F=h.children[C];if(F.isMesh===!0){const j=F.geometry;_.assignLODInformation(a.url,j,u,e,C,M.density),A.push(j)}}return m(A)}}else p&&console.warn("Could not find mesh with guid",g.guid,S.parser.json)}return m(null)});return this.previouslyLoaded.set(f,L),await L}else if(t instanceof W){i&&console.log("Load texture from uri: "+c);const f=await new Me().loadAsync(c);return f?(f.guid=l.guid,f.flipY=!1,f.needsUpdate=!0,f.colorSpace=t.colorSpace,i&&console.log(l,f)):p&&console.warn("failed loading",c),f}}else p&&console.warn(`Can not load LOD ${e}: no LOD info found for "${u}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,o,s,n){if(!e)return;e.userData||(e.userData={});const i=new Re(t,r,o,s,n);e.userData.LODS=i}static getAssignedLODInformation(t){var e;return((e=t?.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return e=e.clone(),p&&console.warn(`Copying texture settings
|
|
4
4
|
`,t.uuid,`
|
|
5
|
-
`,e.uuid),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}};let O=_;d(O,"registerTexture",(t,e,r,o,s)=>{if(p&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,s),!e){p&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[ae]=s);const n=s.guid;_.assignLODInformation(t,e,n,r,o,void 0),_.lodInfos.set(n,s),_.lowresCache.set(n,e)}),d(O,"registerMesh",(t,e,r,o,s,n)=>{var i;p&&console.log("> Progressive: register mesh",s,r.name,n,r.uuid,r);const a=r.geometry;if(!a){p&&console.warn("gltf-progressive: Register mesh without geometry");return}a.userData||(a.userData={}),_.assignLODInformation(t,a,e,o,s,n.density),_.lodInfos.set(e,n);let u=_.lowresCache.get(e);u?u.push(r.geometry):u=[r.geometry],_.lowresCache.set(e,u),o>0&&!Z(r)&&he(r,a);for(const l of k)(i=l.onRegisteredNewMesh)==null||i.call(l,r,n)}),d(O,"lodInfos",new Map),d(O,"previouslyLoaded",new Map),d(O,"lowresCache",new Map);class Re{constructor(e,r,o,s,n){d(this,"url"),d(this,"key"),d(this,"level"),d(this,"index"),d(this,"density"),this.url=e,this.key=r,this.level=o,s!=null&&(this.index=s),n!=null&&(this.density=n)}}const G=J("debugprogressive"),ke=J("noprogressive"),ge=Symbol("Needle:LODSManager"),ue=Symbol("Needle:LODState"),N=Symbol("Needle:CurrentLOD"),E={mesh_lod:-1,texture_lod:-1},T=class{constructor(t){d(this,"renderer"),d(this,"projectionScreenMatrix",new ce),d(this,"cameraFrustrum",new _e),d(this,"targetTriangleDensity",2e5),d(this,"updateInterval",0),d(this,"pause",!1),d(this,"_frame",0),d(this,"_originalRender"),d(this,"_sphere",new we),d(this,"_tempBox",new de),d(this,"_tempBox2",new de),d(this,"tempMatrix",new ce),d(this,"_tempWorldPosition",new R),d(this,"_tempBoxSize",new R),d(this,"_tempBox2Size",new R),this.renderer=t}static getObjectLODState(t){return t[ue]}static addPlugin(t){k.push(t)}static removePlugin(t){const e=k.indexOf(t);e>=0&&k.splice(e,1)}static get(t){return t[ge]?t[ge]:new T(t)}get plugins(){return k}enable(){if(this._originalRender)return;let t=0;this._originalRender=this.renderer.render;const e=this;ne(this.renderer),this.renderer.render=function(r,o){e.renderer.getRenderTarget()==null&&(t=0,e._frame+=1);const s=e._frame,n=t++;e.onBeforeRender(r,o,n,s),e._originalRender.call(this,r,o),e.onAfterRender(r,o,n,s)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(t,e,r,o){}onAfterRender(t,e,r,o){var s,n;if(this.pause)return;const i=this.renderer.renderLists.get(t,0),a=i.opaque;let u=!0;if(a.length===1){const l=a[0].material;(l.name==="EffectMaterial"||l.name==="CopyShader")&&(u=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(u=!1),u){if(ke||this.updateInterval>0&&o%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const l=this.targetTriangleDensity;for(const c of a){if(c.material&&(((s=c.geometry)==null?void 0:s.type)==="BoxGeometry"||((n=c.geometry)==null?void 0:n.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){G&&(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",c,c.material.name,c.material.type)));continue}switch(c.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}const f=c.object;(f instanceof $||f.isMesh)&&this.updateLODs(t,e,f,l,o)}const x=i.transparent;for(const c of x){const f=c.object;(f instanceof $||f.isMesh)&&this.updateLODs(t,e,f,l,o)}}}updateLODs(t,e,r,o,s){var n,i;r.userData||(r.userData={});let a=r[ue];if(a||(a=new je,r[ue]=a),a.frames++<2)return;for(const l of k)(n=l.onBeforeUpdateLOD)==null||n.call(l,this.renderer,t,e,r);this.calculateLodLevel(e,r,a,o,E),E.mesh_lod=Math.round(E.mesh_lod),E.texture_lod=Math.round(E.texture_lod),E.mesh_lod>=0&&this.loadProgressiveMeshes(r,E.mesh_lod);let u=E.texture_lod;if(r.material&&u>=0){const l=r["DEBUG:LOD"];l!=null&&(u=l),this.loadProgressiveTextures(r.material,u)}for(const l of k)(i=l.onAfterUpdatedLOD)==null||i.call(l,this.renderer,t,e,r,E);a.lastLodLevel_Mesh=E.mesh_lod,a.lastLodLevel_Texture=E.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}let r=!1;(t[N]===void 0||e<t[N])&&(r=!0),r&&(t[N]=e,O.assignTextureLOD(t,e))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t[N]!==e){t[N]=e;const r=t.geometry;return O.assignMeshLOD(t,e).then(o=>(o&&t[N]==e&&r!=t.geometry,o))}return Promise.resolve(null)}static isInside(t,e){const r=t.min,o=t.max,s=(r.x+o.x)*.5,n=(r.y+o.y)*.5;return this._tempPtInside.set(s,n,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,o,s){var n;if(!e){s.mesh_lod=-1,s.texture_lod=-1;return}if(!t){s.mesh_lod=-1,s.texture_lod=-1;return}let i=10+1,a=!1;if(G&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=O.getMeshLODInformation(e.geometry),l=u?.lods,x=l&&l.length>0,c=O.getMaterialMinMaxLODsCount(e.material),f=c?.min_count!=1/0&&c.min_count>0&&c.max_count>0;if(!x&&!f){s.mesh_lod=0,s.texture_lod=0;return}if(x||(a=!0,i=0),!((n=this.cameraFrustrum)!=null&&n.intersectsObject(e))){s.mesh_lod=99,s.texture_lod=99;return}let b=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const g=e;g.boundingBox||g.computeBoundingBox(),b=g.boundingBox}if(b&&t.isPerspectiveCamera){const g=t;if(e.geometry.attributes.color&&e.geometry.attributes.color.count<100&&e.geometry.boundingSphere){this._sphere.copy(e.geometry.boundingSphere),this._sphere.applyMatrix4(e.matrixWorld);const M=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(M)){s.mesh_lod=0,s.texture_lod=0;return}}if(this._tempBox.copy(b),e.type==="SkinnedMesh"?e.parent&&this._tempBox.applyMatrix4(e.parent.matrixWorld):this._tempBox.applyMatrix4(e.matrixWorld),T.isInside(this._tempBox,this.projectionScreenMatrix)){s.mesh_lod=0,s.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&g.fov>70){const M=this._tempBox.min,y=this._tempBox.max;let v=M.x,h=M.y,D=y.x,A=y.y;const C=2,F=1.5,j=(M.x+y.x)*.5,H=(M.y+y.y)*.5;v=(v-j)*C+j,h=(h-H)*C+H,D=(D-j)*C+j,A=(A-H)*C+H;const xe=v<0&&D>0?0:Math.min(Math.abs(M.x),Math.abs(y.x)),ye=h<0&&A>0?0:Math.min(Math.abs(M.y),Math.abs(y.y)),te=Math.max(xe,ye);r.lastCentrality=(F-te)*(F-te)*(F-te)}else r.lastCentrality=1;const L=this._tempBox.getSize(this._tempBoxSize);L.multiplyScalar(.5),screen.availHeight>0&&L.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),L.x*=g.aspect;const m=t.matrixWorldInverse,w=this._tempBox2;w.copy(b),w.applyMatrix4(e.matrixWorld),w.applyMatrix4(m);const P=w.getSize(this._tempBox2Size),X=Math.max(P.x,P.y);if(Math.max(L.x,L.y)!=0&&X!=0&&(L.z=P.z/Math.max(P.x,P.y)*Math.max(L.x,L.y)),r.lastScreenCoverage=Math.max(L.x,L.y,L.z),r.lastScreenspaceVolume.copy(L),r.lastScreenCoverage*=r.lastCentrality,G&&T.debugDrawLine){const M=this.tempMatrix.copy(this.projectionScreenMatrix);M.invert();const y=T.corner0,v=T.corner1,h=T.corner2,D=T.corner3;y.copy(this._tempBox.min),v.copy(this._tempBox.max),v.x=y.x,h.copy(this._tempBox.max),h.y=y.y,D.copy(this._tempBox.max);const A=(y.z+D.z)*.5;y.z=v.z=h.z=D.z=A,y.applyMatrix4(M),v.applyMatrix4(M),h.applyMatrix4(M),D.applyMatrix4(M),T.debugDrawLine(y,v,255),T.debugDrawLine(y,h,255),T.debugDrawLine(v,D,255),T.debugDrawLine(h,D,255)}let S=999;if(l&&r.lastScreenCoverage>0){for(let M=0;M<l.length;M++)if(l[M].density/r.lastScreenCoverage<o){S=M;break}}S<i&&(i=S,a=!0)}if(a?s.mesh_lod=i:s.mesh_lod=r.lastLodLevel_Mesh,G&&s.mesh_lod!=r.lastLodLevel_Mesh){const g=l?.[s.mesh_lod];g&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} \u2192 ${s.mesh_lod} (${g.density.toFixed(0)}) - ${e.name}`)}if(f)if(r.lastLodLevel_Texture<0){if(s.texture_lod=c.max_count-1,G){const g=c.lods[c.max_count-1];G&&console.log(`First Texture LOD ${s.texture_lod} (${g.max_height}px) - ${e.name}`)}}else{const g=r.lastScreenCoverage*1.5,L=this.renderer.domElement.clientHeight/window.devicePixelRatio*g;for(let m=c.lods.length-1;m>=0;m--){const w=c.lods[m];if(!(Ie()&&w.max_height>4096)&&w.max_height>L){s.texture_lod=m,s.texture_lod<r.lastLodLevel_Texture&&G&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} \u2192 ${s.texture_lod} (${w.max_height}px: ${(100*r.lastScreenCoverage).toFixed(2)} % = ${L.toFixed(0)}px) - ${e.name}`);break}}}else s.texture_lod=0}};let B=T;d(B,"debugDrawLine"),d(B,"corner0",new R),d(B,"corner1",new R),d(B,"corner2",new R),d(B,"corner3",new R),d(B,"_tempPtInside",new R);class je{constructor(){d(this,"frames",0),d(this,"lastLodLevel_Mesh",-1),d(this,"lastLodLevel_Texture",-1),d(this,"lastScreenCoverage",0),d(this,"lastScreenspaceVolume",new R),d(this,"lastCentrality",0)}}const me=Symbol("NEEDLE_mesh_lod"),ee=Symbol("NEEDLE_texture_lod");function pe(t){if(!t)return null;let e=null,r=null;for(let o=t;o!=null;o=Object.getPrototypeOf(o)){const s=Object.getOwnPropertySymbols(o),n=s.find(a=>a.toString()=="Symbol(renderer)"),i=s.find(a=>a.toString()=="Symbol(scene)");!e&&n!=null&&(e=t[n].threeRenderer),!r&&i!=null&&(r=t[i])}if(e){const o=B.get(e);if(B.addPlugin(new Ge(t)),o.enable(),r){const s=r.camera||r.traverse(n=>n.type=="PerspectiveCamera")[0];s&&e.render(r,s)}return()=>{o.disable()}}return null}class Ge{constructor(e){d(this,"modelviewer"),d(this,"_didWarnAboutMissingUrl",!1),this.modelviewer=e}onBeforeUpdateLOD(e,r,o,s){this.tryParseMeshLOD(r,s),this.tryParseTextureLOD(r,s)}getUrl(){let e=this.modelviewer.getAttribute("src");return e||(e=this.modelviewer.src),e||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",this.modelviewer),this._didWarnAboutMissingUrl=!0),e}tryGetCurrentGLTF(e){return e._currentGLTF}tryParseTextureLOD(e,r){if(r[ee]==!0)return;r[ee]=!0;const o=this.tryGetCurrentGLTF(e),s=this.getUrl();if(s&&o&&r.material){let n=function(a){var u,l,x;if(a[ee]==!0)return;a[ee]=!0,a.userData&&(a.userData.LOD=-1);const c=Object.keys(a);for(let f=0;f<c.length;f++){const b=c[f],g=a[b];if(g?.isTexture===!0){const L=(l=(u=g.userData)==null?void 0:u.associations)==null?void 0:l.textures,m=o.parser.json.textures[L];if(!m){console.warn("Texture data not found for texture index "+L);continue}if((x=m?.extensions)!=null&&x[I]){const w=m.extensions[I];w&&s&&O.registerTexture(s,g,w.lods.length,L,w)}}}};const i=r.material;if(Array.isArray(i))for(const a of i)n(a);else n(i)}}tryParseMeshLOD(e,r){var o,s;if(r[me]==!0)return;r[me]=!0;const n=this.getUrl();if(!n)return;const i=(s=(o=r.userData)==null?void 0:o.gltfExtensions)==null?void 0:s[I];if(i&&n){const a=r.uuid;O.registerMesh(n,a,r,0,i.lods.length,i)}}}document.addEventListener("DOMContentLoaded",()=>{pe(document.querySelector("model-viewer"))});function Fe(t,e,r,o){ne(e),oe(r),r.register(n=>new O(n,t));const s=B.get(e);return o?.enableLODsManager!==!1&&s.enable(),s}export{I as EXTENSION_NAME,B as LODsManager,O as NEEDLE_progressive,oe as addDracoAndKTX2Loaders,ne as createLoaders,Z as getRaycastMesh,pe as patchModelViewer,Ae as setDracoDecoderLocation,Ee as setKTX2TranscoderLocation,he as setRaycastMesh,Fe as useNeedleProgressive,Be as useRaycastMeshes};
|
|
5
|
+
`,e.uuid),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}};let O=_;d(O,"registerTexture",(t,e,r,o,s)=>{if(p&&console.log("> Progressive: register texture",o,e.name,e.uuid,e,s),!e){p&&console.error("gltf-progressive: Register texture without texture");return}e.source&&(e.source[ae]=s);const n=s.guid;_.assignLODInformation(t,e,n,r,o,void 0),_.lodInfos.set(n,s),_.lowresCache.set(n,e)}),d(O,"registerMesh",(t,e,r,o,s,n)=>{var i;p&&console.log("> Progressive: register mesh",s,r.name,n,r.uuid,r);const a=r.geometry;if(!a){p&&console.warn("gltf-progressive: Register mesh without geometry");return}a.userData||(a.userData={}),_.assignLODInformation(t,a,e,o,s,n.density),_.lodInfos.set(e,n);let u=_.lowresCache.get(e);u?u.push(r.geometry):u=[r.geometry],_.lowresCache.set(e,u),o>0&&!Z(r)&&he(r,a);for(const l of k)(i=l.onRegisteredNewMesh)==null||i.call(l,r,n)}),d(O,"lodInfos",new Map),d(O,"previouslyLoaded",new Map),d(O,"lowresCache",new Map);class Re{constructor(e,r,o,s,n){d(this,"url"),d(this,"key"),d(this,"level"),d(this,"index"),d(this,"density"),this.url=e,this.key=r,this.level=o,s!=null&&(this.index=s),n!=null&&(this.density=n)}}const G=J("debugprogressive"),ke=J("noprogressive"),ge=Symbol("Needle:LODSManager"),ue=Symbol("Needle:LODState"),N=Symbol("Needle:CurrentLOD"),P={mesh_lod:-1,texture_lod:-1},T=class{constructor(t){d(this,"renderer"),d(this,"projectionScreenMatrix",new ce),d(this,"cameraFrustrum",new _e),d(this,"targetTriangleDensity",2e5),d(this,"updateInterval",0),d(this,"pause",!1),d(this,"_frame",0),d(this,"_originalRender"),d(this,"_sphere",new we),d(this,"_tempBox",new de),d(this,"_tempBox2",new de),d(this,"tempMatrix",new ce),d(this,"_tempWorldPosition",new R),d(this,"_tempBoxSize",new R),d(this,"_tempBox2Size",new R),this.renderer=t}static getObjectLODState(t){return t[ue]}static addPlugin(t){k.push(t)}static removePlugin(t){const e=k.indexOf(t);e>=0&&k.splice(e,1)}static get(t){return t[ge]?t[ge]:new T(t)}get plugins(){return k}enable(){if(this._originalRender)return;let t=0;this._originalRender=this.renderer.render;const e=this;ne(this.renderer),this.renderer.render=function(r,o){e.renderer.getRenderTarget()==null&&(t=0,e._frame+=1);const s=e._frame,n=t++;e.onBeforeRender(r,o,n,s),e._originalRender.call(this,r,o),e.onAfterRender(r,o,n,s)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(t,e,r,o){}onAfterRender(t,e,r,o){var s,n;if(this.pause)return;const i=this.renderer.renderLists.get(t,0),a=i.opaque;let u=!0;if(a.length===1){const l=a[0].material;(l.name==="EffectMaterial"||l.name==="CopyShader")&&(u=!1)}if((e.parent&&e.parent.type==="CubeCamera"||r>=1&&e.type==="OrthographicCamera")&&(u=!1),u){if(ke||this.updateInterval>0&&o%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const l=this.targetTriangleDensity;for(const c of a){if(c.material&&(((s=c.geometry)==null?void 0:s.type)==="BoxGeometry"||((n=c.geometry)==null?void 0:n.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){G&&(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(c.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",c,c.material.name,c.material.type)));continue}switch(c.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}const f=c.object;(f instanceof $||f.isMesh)&&this.updateLODs(t,e,f,l,o)}const x=i.transparent;for(const c of x){const f=c.object;(f instanceof $||f.isMesh)&&this.updateLODs(t,e,f,l,o)}}}updateLODs(t,e,r,o,s){var n,i;r.userData||(r.userData={});let a=r[ue];if(a||(a=new je,r[ue]=a),a.frames++<2)return;for(const l of k)(n=l.onBeforeUpdateLOD)==null||n.call(l,this.renderer,t,e,r);this.calculateLodLevel(e,r,a,o,P),P.mesh_lod=Math.round(P.mesh_lod),P.texture_lod=Math.round(P.texture_lod),P.mesh_lod>=0&&this.loadProgressiveMeshes(r,P.mesh_lod);let u=P.texture_lod;if(r.material&&u>=0){const l=r["DEBUG:LOD"];l!=null&&(u=l),this.loadProgressiveTextures(r.material,u)}for(const l of k)(i=l.onAfterUpdatedLOD)==null||i.call(l,this.renderer,t,e,r,P);a.lastLodLevel_Mesh=P.mesh_lod,a.lastLodLevel_Texture=P.texture_lod}loadProgressiveTextures(t,e){if(!t)return;if(Array.isArray(t)){for(const o of t)this.loadProgressiveTextures(o,e);return}let r=!1;(t[N]===void 0||e<t[N])&&(r=!0),r&&(t[N]=e,O.assignTextureLOD(t,e))}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t[N]!==e){t[N]=e;const r=t.geometry;return O.assignMeshLOD(t,e).then(o=>(o&&t[N]==e&&r!=t.geometry,o))}return Promise.resolve(null)}static isInside(t,e){const r=t.min,o=t.max,s=(r.x+o.x)*.5,n=(r.y+o.y)*.5;return this._tempPtInside.set(s,n,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,o,s){var n;if(!e){s.mesh_lod=-1,s.texture_lod=-1;return}if(!t){s.mesh_lod=-1,s.texture_lod=-1;return}let i=10+1,a=!1;if(G&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const u=O.getMeshLODInformation(e.geometry),l=u?.lods,x=l&&l.length>0,c=O.getMaterialMinMaxLODsCount(e.material),f=c?.min_count!=1/0&&c.min_count>0&&c.max_count>0;if(!x&&!f){s.mesh_lod=0,s.texture_lod=0;return}if(x||(a=!0,i=0),!((n=this.cameraFrustrum)!=null&&n.intersectsObject(e))){s.mesh_lod=99,s.texture_lod=99;return}let b=e.geometry.boundingBox;if(e.type==="SkinnedMesh"){const g=e;g.boundingBox||g.computeBoundingBox(),b=g.boundingBox}if(b&&t.isPerspectiveCamera){const g=t;if(e.geometry.attributes.color&&e.geometry.attributes.color.count<100&&e.geometry.boundingSphere){this._sphere.copy(e.geometry.boundingSphere),this._sphere.applyMatrix4(e.matrixWorld);const D=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(D)){s.mesh_lod=0,s.texture_lod=0;return}}if(this._tempBox.copy(b),this._tempBox.applyMatrix4(e.matrixWorld),T.isInside(this._tempBox,this.projectionScreenMatrix)){s.mesh_lod=0,s.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&g.fov>70){const D=this._tempBox.min,y=this._tempBox.max;let v=D.x,h=D.y,M=y.x,A=y.y;const C=2,F=1.5,j=(D.x+y.x)*.5,H=(D.y+y.y)*.5;v=(v-j)*C+j,h=(h-H)*C+H,M=(M-j)*C+j,A=(A-H)*C+H;const xe=v<0&&M>0?0:Math.min(Math.abs(D.x),Math.abs(y.x)),ye=h<0&&A>0?0:Math.min(Math.abs(D.y),Math.abs(y.y)),te=Math.max(xe,ye);r.lastCentrality=(F-te)*(F-te)*(F-te)}else r.lastCentrality=1;const L=this._tempBox.getSize(this._tempBoxSize);L.multiplyScalar(.5),screen.availHeight>0&&L.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),L.x*=g.aspect;const m=t.matrixWorldInverse,w=this._tempBox2;w.copy(b),w.applyMatrix4(e.matrixWorld),w.applyMatrix4(m);const E=w.getSize(this._tempBox2Size),X=Math.max(E.x,E.y);if(Math.max(L.x,L.y)!=0&&X!=0&&(L.z=E.z/Math.max(E.x,E.y)*Math.max(L.x,L.y)),r.lastScreenCoverage=Math.max(L.x,L.y,L.z),r.lastScreenspaceVolume.copy(L),r.lastScreenCoverage*=r.lastCentrality,G&&T.debugDrawLine){const D=this.tempMatrix.copy(this.projectionScreenMatrix);D.invert();const y=T.corner0,v=T.corner1,h=T.corner2,M=T.corner3;y.copy(this._tempBox.min),v.copy(this._tempBox.max),v.x=y.x,h.copy(this._tempBox.max),h.y=y.y,M.copy(this._tempBox.max);const A=(y.z+M.z)*.5;y.z=v.z=h.z=M.z=A,y.applyMatrix4(D),v.applyMatrix4(D),h.applyMatrix4(D),M.applyMatrix4(D),T.debugDrawLine(y,v,255),T.debugDrawLine(y,h,255),T.debugDrawLine(v,M,255),T.debugDrawLine(h,M,255)}let S=999;if(l&&r.lastScreenCoverage>0){for(let D=0;D<l.length;D++)if(l[D].density/r.lastScreenCoverage<o){S=D;break}}S<i&&(i=S,a=!0)}if(a?s.mesh_lod=i:s.mesh_lod=r.lastLodLevel_Mesh,G&&s.mesh_lod!=r.lastLodLevel_Mesh){const g=l?.[s.mesh_lod];g&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} \u2192 ${s.mesh_lod} (${g.density.toFixed(0)}) - ${e.name}`)}if(f)if(r.lastLodLevel_Texture<0){if(s.texture_lod=c.max_count-1,G){const g=c.lods[c.max_count-1];G&&console.log(`First Texture LOD ${s.texture_lod} (${g.max_height}px) - ${e.name}`)}}else{const g=r.lastScreenCoverage*1.5,L=this.renderer.domElement.clientHeight/window.devicePixelRatio*g;for(let m=c.lods.length-1;m>=0;m--){const w=c.lods[m];if(!(Ie()&&w.max_height>4096)&&w.max_height>L){s.texture_lod=m,s.texture_lod<r.lastLodLevel_Texture&&G&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} \u2192 ${s.texture_lod} (${w.max_height}px: ${(100*r.lastScreenCoverage).toFixed(2)} % = ${L.toFixed(0)}px) - ${e.name}`);break}}}else s.texture_lod=0}};let B=T;d(B,"debugDrawLine"),d(B,"corner0",new R),d(B,"corner1",new R),d(B,"corner2",new R),d(B,"corner3",new R),d(B,"_tempPtInside",new R);class je{constructor(){d(this,"frames",0),d(this,"lastLodLevel_Mesh",-1),d(this,"lastLodLevel_Texture",-1),d(this,"lastScreenCoverage",0),d(this,"lastScreenspaceVolume",new R),d(this,"lastCentrality",0)}}const me=Symbol("NEEDLE_mesh_lod"),ee=Symbol("NEEDLE_texture_lod");function pe(t){if(!t)return null;let e=null,r=null;for(let o=t;o!=null;o=Object.getPrototypeOf(o)){const s=Object.getOwnPropertySymbols(o),n=s.find(a=>a.toString()=="Symbol(renderer)"),i=s.find(a=>a.toString()=="Symbol(scene)");!e&&n!=null&&(e=t[n].threeRenderer),!r&&i!=null&&(r=t[i])}if(e){const o=B.get(e);if(B.addPlugin(new Ge(t)),o.enable(),r){const s=r.camera||r.traverse(n=>n.type=="PerspectiveCamera")[0];s&&e.render(r,s)}return()=>{o.disable()}}return null}class Ge{constructor(e){d(this,"modelviewer"),d(this,"_didWarnAboutMissingUrl",!1),this.modelviewer=e}onBeforeUpdateLOD(e,r,o,s){this.tryParseMeshLOD(r,s),this.tryParseTextureLOD(r,s)}getUrl(){let e=this.modelviewer.getAttribute("src");return e||(e=this.modelviewer.src),e||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",this.modelviewer),this._didWarnAboutMissingUrl=!0),e}tryGetCurrentGLTF(e){return e._currentGLTF}tryParseTextureLOD(e,r){if(r[ee]==!0)return;r[ee]=!0;const o=this.tryGetCurrentGLTF(e),s=this.getUrl();if(s&&o&&r.material){let n=function(a){var u,l,x;if(a[ee]==!0)return;a[ee]=!0,a.userData&&(a.userData.LOD=-1);const c=Object.keys(a);for(let f=0;f<c.length;f++){const b=c[f],g=a[b];if(g?.isTexture===!0){const L=(l=(u=g.userData)==null?void 0:u.associations)==null?void 0:l.textures,m=o.parser.json.textures[L];if(!m){console.warn("Texture data not found for texture index "+L);continue}if((x=m?.extensions)!=null&&x[I]){const w=m.extensions[I];w&&s&&O.registerTexture(s,g,w.lods.length,L,w)}}}};const i=r.material;if(Array.isArray(i))for(const a of i)n(a);else n(i)}}tryParseMeshLOD(e,r){var o,s;if(r[me]==!0)return;r[me]=!0;const n=this.getUrl();if(!n)return;const i=(s=(o=r.userData)==null?void 0:o.gltfExtensions)==null?void 0:s[I];if(i&&n){const a=r.uuid;O.registerMesh(n,a,r,0,i.lods.length,i)}}}document.addEventListener("DOMContentLoaded",()=>{pe(document.querySelector("model-viewer"))});function Fe(t,e,r,o){ne(e),oe(r),r.register(n=>new O(n,t));const s=B.get(e);return o?.enableLODsManager!==!1&&s.enable(),s}export{I as EXTENSION_NAME,B as LODsManager,O as NEEDLE_progressive,oe as addDracoAndKTX2Loaders,ne as createLoaders,Z as getRaycastMesh,pe as patchModelViewer,Ae as setDracoDecoderLocation,Pe as setKTX2TranscoderLocation,he as setRaycastMesh,Fe as useNeedleProgressive,Be as useRaycastMeshes};
|
package/gltf-progressive.umd.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`,P),null)),A=!1;if(O==null||(O instanceof p.Texture&&e instanceof p.Texture?(a=O.image)!=null&&a.data||(h=O.source)!=null&&h.data?O=this.copySettings(e,O):(A=!0,this.previouslyLoaded.delete(y)):O instanceof p.BufferGeometry&&e instanceof p.BufferGeometry&&((c=O.attributes.position)!=null&&c.array||(A=!0,this.previouslyLoaded.delete(y)))),!A)return O}const
|
|
3
|
-
`,g),null));if(!k)return null;const z=k.parser;r&&console.log("Loading finished "+u,
|
|
1
|
+
"use strict";var me=Object.defineProperty;var Le=(l,e,t)=>e in l?me(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t;var d=(l,e,t)=>(Le(l,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("three"),Me=require("three/examples/jsm/loaders/GLTFLoader.js"),De=require("three/examples/jsm/libs/meshopt_decoder.module.js"),we=require("three/examples/jsm/loaders/DRACOLoader.js"),_e=require("three/examples/jsm/loaders/KTX2Loader.js");let Z="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",le="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(Z+"draco_decoder.js",{method:"head"}).catch(l=>{Z="./include/draco/",le="./include/ktx2/"});function Oe(l){Z=l}function ve(l){le=l}let q,oe,K;function ce(l){q||(q=new we.DRACOLoader,q.setDecoderPath(Z),q.setDecoderConfig({type:"js"})),K||(K=new _e.KTX2Loader,K.setTranscoderPath(le)),oe||(oe=De.MeshoptDecoder),l?K.detectSupport(l):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function ue(l){l.dracoLoader||l.setDRACOLoader(q),l.ktx2Loader||l.setKTX2Loader(K),l.meshoptDecoder||l.setMeshoptDecoder(oe)}function j(l){const t=new URL(window.location.href).searchParams.get(l);return t==null||t==="0"||t==="false"?!1:t===""?!0:t}function Se(l,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||l===void 0)return e;const t=l.lastIndexOf("/");if(t>=0){const r=l.substring(0,t+1);for(;r.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return r+e}return e}let W;function Te(){return W!==void 0||(W=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),j("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",W)),W}const ne=Symbol("needle:raycast-mesh");function ee(l){return(l==null?void 0:l[ne])instanceof p.BufferGeometry?l[ne]:null}function ge(l,e){if((l.type==="Mesh"||l.type==="SkinnedMesh")&&!ee(l)){const r=Ae(e);r.userData={isRaycastMesh:!0},l[ne]=r}}function be(l=!0){if(l){if(V)return;const e=V=p.Mesh.prototype.raycast;p.Mesh.prototype.raycast=function(t,r){const i=this,o=ee(i);let s;o&&i.isMesh&&(s=i.geometry,i.geometry=o),e.call(this,t,r),s&&(i.geometry=s)}}else{if(!V)return;p.Mesh.prototype.raycast=V,V=null}}let V=null;function Ae(l){const e=new p.BufferGeometry;for(const t in l.attributes)e.setAttribute(t,l.getAttribute(t));return e.setIndex(l.getIndex()),e}const F=new Array,E="NEEDLE_progressive",x=j("debugprogressive"),se=Symbol("needle-progressive-texture"),X=new Map,ae=new Set;if(x){let l=function(){e+=1,console.log("Toggle LOD level",e,X),X.forEach((i,o)=>{for(const s of i.keys){const n=o[s];if(n!=null){if(n.isBufferGeometry===!0){const a=S.getMeshLODInformation(n),h=a?Math.min(e,a.lods.length):0;o["DEBUG:LOD"]=e,S.assignMeshLOD(o,h),a&&(t=Math.max(t,a.lods.length-1))}else if(o.isMaterial===!0){o["DEBUG:LOD"]=e,S.assignTextureLOD(o,e);break}}}}),e>=t&&(e=-1)},e=-1,t=2,r=!1;window.addEventListener("keyup",i=>{i.key==="p"&&l(),i.key==="w"&&(r=!r,ae&&ae.forEach(o=>{o.name!="BackgroundCubeMaterial"&&o.glyphMap==null&&"wireframe"in o&&(o.wireframe=r)}))})}function fe(l,e,t){var i;if(!x)return;X.has(l)||X.set(l,{keys:[],sourceId:t});const r=X.get(l);((i=r==null?void 0:r.keys)==null?void 0:i.includes(e))==!1&&r.keys.push(e)}const v=class{constructor(e,t){d(this,"parser");d(this,"url");d(this,"_isLoadingMesh");d(this,"loadMesh",e=>{var r,i;if(this._isLoadingMesh)return null;const t=(i=(r=this.parser.json.meshes[e])==null?void 0:r.extensions)==null?void 0:i[E];return t?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",e).then(o=>{var s;return this._isLoadingMesh=!1,o&&v.registerMesh(this.url,t.guid,o,(s=t.lods)==null?void 0:s.length,void 0,t),o})):null});x&&console.log("Progressive extension registered for",t),this.parser=e,this.url=t}get name(){return E}static getMeshLODInformation(e){const t=this.getAssignedLODInformation(e);return t!=null&&t.key?this.lodInfos.get(t.key):null}static getMaterialMinMaxLODsCount(e,t){const r=this,i="LODS:minmax",o=e[i];if(o!=null)return o;if(t||(t={min_count:1/0,max_count:0,lods:[]}),Array.isArray(e)){for(const n of e)this.getMaterialMinMaxLODsCount(n,t);return e[i]=t,t}if(x==="verbose"&&console.log("getMaterialMinMaxLODsCount",e),e.type==="ShaderMaterial"||e.type==="RawShaderMaterial"){const n=e;for(const a of Object.keys(n.uniforms)){const h=n.uniforms[a].value;(h==null?void 0:h.isTexture)===!0&&s(h,t)}}else if(e.isMaterial)for(const n of Object.keys(e)){const a=e[n];(a==null?void 0:a.isTexture)===!0&&s(a,t)}return e[i]=t,t;function s(n,a){const h=r.getAssignedLODInformation(n);if(h){const c=r.lodInfos.get(h.key);if(c&&c.lods){a.min_count=Math.min(a.min_count,c.lods.length),a.max_count=Math.max(a.max_count,c.lods.length);for(let m=0;m<c.lods.length;m++){const u=c.lods[m];u.width&&(a.lods[m]=a.lods[m]||{min_height:1/0,max_height:0},a.lods[m].min_height=Math.min(a.lods[m].min_height,u.height),a.lods[m].max_height=Math.max(a.lods[m].max_height,u.height))}}}}}static hasLODLevelAvailable(e,t){var o;if(Array.isArray(e)){for(const s of e)if(this.hasLODLevelAvailable(s,t))return!0;return!1}if(e.isMaterial===!0){for(const s of Object.keys(e)){const n=e[s];if(n&&n.isTexture&&this.hasLODLevelAvailable(n,t))return!0}return!1}else if(e.isGroup===!0){for(const s of e.children)if(s.isMesh===!0&&this.hasLODLevelAvailable(s,t))return!0}let r,i;if(e.isMesh?r=e.geometry:(e.isBufferGeometry||e.isTexture)&&(r=e),r&&(o=r==null?void 0:r.userData)!=null&&o.LODS){const s=r.userData.LODS;if(i=this.lodInfos.get(s.key),t===void 0)return i!=null;if(i)return Array.isArray(i.lods)?t<i.lods.length:t===0}return!1}static assignMeshLOD(e,t){var r;if(!e)return Promise.resolve(null);if(e instanceof p.Mesh||e.isMesh===!0){const i=e.geometry,o=this.getAssignedLODInformation(i);if(!o)return Promise.resolve(null);for(const s of F)(r=s.onBeforeGetLODMesh)==null||r.call(s,e,t);return e["LOD:requested level"]=t,v.getOrLoadLOD(i,t).then(s=>{if(e["LOD:requested level"]===t){if(delete e["LOD:requested level"],Array.isArray(s)){const n=o.index||0;s=s[n]}s&&i!=s&&((s==null?void 0:s.isBufferGeometry)?(e.geometry=s,x&&fe(e,"geometry",o.url)):x&&console.error("Invalid LOD geometry",s))}return s}).catch(s=>(console.error("Error loading mesh LOD",e,s),null))}else x&&console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh",e);return Promise.resolve(null)}static assignTextureLOD(e,t=0){if(!e)return Promise.resolve(null);if(e instanceof p.Material||e.isMaterial===!0){const r=e,i=[],o=new Array;if(x&&ae.add(r),r.uniforms&&r.isRawShaderMaterial||r.isShaderMaterial===!0){const s=r;for(const n of Object.keys(s.uniforms)){const a=s.uniforms[n].value;if((a==null?void 0:a.isTexture)===!0){const h=this.assignTextureLODForSlot(a,t,r,n);i.push(h),o.push(n)}}}else for(const s of Object.keys(r)){const n=r[s];if((n==null?void 0:n.isTexture)===!0){const a=this.assignTextureLODForSlot(n,t,r,s);i.push(a),o.push(s)}}return Promise.all(i).then(s=>{const n=new Array;for(let a=0;a<s.length;a++){const h=s[a],c=o[a];h&&h.isTexture===!0?n.push({material:r,slot:c,texture:h,level:t}):n.push({material:r,slot:c,texture:null,level:t})}return n})}if(e instanceof p.Texture||e.isTexture===!0){const r=e;return this.assignTextureLODForSlot(r,t,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(e,t,r,i){return(e==null?void 0:e.isTexture)!==!0?Promise.resolve(null):i==="glyphMap"?Promise.resolve(e):v.getOrLoadLOD(e,t).then(o=>{if(Array.isArray(o))return null;if((o==null?void 0:o.isTexture)===!0){if(o!=e){if(r&&i){const s=r[i];if(s){const n=this.getAssignedLODInformation(s);if(n&&(n==null?void 0:n.level)<t)return x==="verbose"&&console.warn("Assigned texture level is already higher: ",n.level,t,r,s,o),null}r[i]=o}if(x&&i&&r){const s=this.getAssignedLODInformation(e);s&&fe(r,i,s.url)}}return o}else x=="verbose"&&console.warn("No LOD found for",e,t);return null}).catch(o=>(console.error("Error loading LOD",e,o),null))}afterRoot(e){var t,r;return x&&console.log("AFTER",this.url,e),(t=this.parser.json.textures)==null||t.forEach((i,o)=>{var s;if(i!=null&&i.extensions){const n=i==null?void 0:i.extensions[E];if(n){if(!n.lods){x&&console.warn("Texture has no LODs",n);return}let a=!1;for(const h of this.parser.associations.keys())h.isTexture===!0&&this.parser.associations.get(h).textures===o&&(a=!0,v.registerTexture(this.url,h,(s=n.lods)==null?void 0:s.length,o,n));a||this.parser.getDependency("texture",o).then(h=>{var c;h&&v.registerTexture(this.url,h,(c=n.lods)==null?void 0:c.length,o,n)})}}}),(r=this.parser.json.meshes)==null||r.forEach((i,o)=>{if(i!=null&&i.extensions){const s=i==null?void 0:i.extensions[E];if(s&&s.lods){for(const n of this.parser.associations.keys())if(n.isMesh){const a=this.parser.associations.get(n);a.meshes===o&&v.registerMesh(this.url,s.guid,n,s.lods.length,a.primitives,s)}}}}),null}static async getOrLoadLOD(e,t){var n,a,h,c;const r=x=="verbose",i=e.userData.LODS;if(!i)return null;const o=i==null?void 0:i.key;let s;if(e.isTexture===!0){const m=e;m.source&&m.source[se]&&(s=m.source[se])}if(s||(s=v.lodInfos.get(o)),s){if(t>0){let y=!1;const L=Array.isArray(s.lods);if(L&&t>=s.lods.length?y=!0:L||(y=!0),y)return this.lowresCache.get(o)}const m=Array.isArray(s.lods)?(n=s.lods[t])==null?void 0:n.path:s.lods;if(!m)return x&&!s["missing:uri"]&&(s["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+t,s)),null;const u=Se(i.url,m);if(u.endsWith(".glb")||u.endsWith(".gltf")){if(!s.guid)return console.warn("missing pointer for glb/gltf texture",s),null;const y=u+"_"+s.guid,L=this.previouslyLoaded.get(y);if(L!==void 0){r&&console.log(`LOD ${t} was already loading/loaded: ${y}`);let O=await L.catch(P=>(console.error(`Error loading LOD ${t} from ${u}
|
|
2
|
+
`,P),null)),A=!1;if(O==null||(O instanceof p.Texture&&e instanceof p.Texture?(a=O.image)!=null&&a.data||(h=O.source)!=null&&h.data?O=this.copySettings(e,O):(A=!0,this.previouslyLoaded.delete(y)):O instanceof p.BufferGeometry&&e instanceof p.BufferGeometry&&((c=O.attributes.position)!=null&&c.array||(A=!0,this.previouslyLoaded.delete(y)))),!A)return O}const _=s,w=new Promise(async(O,A)=>{const P=new Me.GLTFLoader;ue(P),x&&(await new Promise(g=>setTimeout(g,1e3)),r&&console.warn("Start loading (delayed) "+u,_.guid));let Y=u;if(_&&Array.isArray(_.lods)){const g=_.lods[t];g.hash&&(Y+="?v="+g.hash)}const k=await P.loadAsync(Y).catch(g=>(console.error(`Error loading LOD ${t} from ${u}
|
|
3
|
+
`,g),null));if(!k)return null;const z=k.parser;r&&console.log("Loading finished "+u,_.guid);let I=0;if(k.parser.json.textures){let g=!1;for(const f of k.parser.json.textures){if(f!=null&&f.extensions){const M=f==null?void 0:f.extensions[E];if(M!=null&&M.guid&&M.guid===_.guid){g=!0;break}}I++}if(g){let f=await z.getDependency("texture",I);return f&&v.assignLODInformation(i.url,f,o,t,void 0,void 0),r&&console.log('change "'+e.name+'" → "'+f.name+'"',u,I,f,y),e instanceof p.Texture&&(f=this.copySettings(e,f)),f&&(f.guid=_.guid),O(f)}else x&&console.warn("Could not find texture with guid",_.guid,k.parser.json)}if(I=0,k.parser.json.meshes){let g=!1;for(const f of k.parser.json.meshes){if(f!=null&&f.extensions){const M=f==null?void 0:f.extensions[E];if(M!=null&&M.guid&&M.guid===_.guid){g=!0;break}}I++}if(g){const f=await z.getDependency("mesh",I),M=_;if(r&&console.log(`Loaded Mesh "${f.name}"`,u,I,f,y),f.isMesh===!0){const T=f.geometry;return v.assignLODInformation(i.url,T,o,t,void 0,M.density),O(T)}else{const T=new Array;for(let b=0;b<f.children.length;b++){const G=f.children[b];if(G.isMesh===!0){const $=G.geometry;v.assignLODInformation(i.url,$,o,t,b,M.density),T.push($)}}return O(T)}}else x&&console.warn("Could not find mesh with guid",_.guid,k.parser.json)}return O(null)});return this.previouslyLoaded.set(y,w),await w}else if(e instanceof p.Texture){r&&console.log("Load texture from uri: "+u);const L=await new p.TextureLoader().loadAsync(u);return L?(L.guid=s.guid,L.flipY=!1,L.needsUpdate=!0,L.colorSpace=e.colorSpace,r&&console.log(s,L)):x&&console.warn("failed loading",u),L}}else x&&console.warn(`Can not load LOD ${t}: no LOD info found for "${o}" ${e.name}`,e.type);return null}static assignLODInformation(e,t,r,i,o,s){if(!t)return;t.userData||(t.userData={});const n=new Pe(e,r,i,o,s);t.userData.LODS=n}static getAssignedLODInformation(e){var t;return((t=e==null?void 0:e.userData)==null?void 0:t.LODS)||null}static copySettings(e,t){return t=t.clone(),x&&console.warn(`Copying texture settings
|
|
4
4
|
`,e.uuid,`
|
|
5
|
-
`,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}};let S=v;d(S,"registerTexture",(e,t,r,i,o)=>{if(x&&console.log("> Progressive: register texture",i,t.name,t.uuid,t,o),!t){x&&console.error("gltf-progressive: Register texture without texture");return}t.source&&(t.source[se]=o);const s=o.guid;v.assignLODInformation(e,t,s,r,i,void 0),v.lodInfos.set(s,o),v.lowresCache.set(s,t)}),d(S,"registerMesh",(e,t,r,i,o,s)=>{var h;x&&console.log("> Progressive: register mesh",o,r.name,s,r.uuid,r);const n=r.geometry;if(!n){x&&console.warn("gltf-progressive: Register mesh without geometry");return}n.userData||(n.userData={}),v.assignLODInformation(e,n,t,i,o,s.density),v.lodInfos.set(t,s);let a=v.lowresCache.get(t);a?a.push(r.geometry):a=[r.geometry],v.lowresCache.set(t,a),i>0&&!ee(r)&&ge(r,n);for(const c of F)(h=c.onRegisteredNewMesh)==null||h.call(c,r,s)}),d(S,"lodInfos",new Map),d(S,"previouslyLoaded",new Map),d(S,"lowresCache",new Map);class Pe{constructor(e,t,r,i,o){d(this,"url");d(this,"key");d(this,"level");d(this,"index");d(this,"density");this.url=e,this.key=t,this.level=r,i!=null&&(this.index=i),o!=null&&(this.density=o)}}const N=j("debugprogressive"),Be=j("noprogressive"),de=Symbol("Needle:LODSManager"),ie=Symbol("Needle:LODState"),U=Symbol("Needle:CurrentLOD"),R={mesh_lod:-1,texture_lod:-1},B=class{constructor(e){d(this,"renderer");d(this,"projectionScreenMatrix",new p.Matrix4);d(this,"cameraFrustrum",new p.Frustum);d(this,"targetTriangleDensity",2e5);d(this,"updateInterval",0);d(this,"pause",!1);d(this,"_frame",0);d(this,"_originalRender");d(this,"_sphere",new p.Sphere);d(this,"_tempBox",new p.Box3);d(this,"_tempBox2",new p.Box3);d(this,"tempMatrix",new p.Matrix4);d(this,"_tempWorldPosition",new p.Vector3);d(this,"_tempBoxSize",new p.Vector3);d(this,"_tempBox2Size",new p.Vector3);this.renderer=e}static getObjectLODState(e){return e[ie]}static addPlugin(e){F.push(e)}static removePlugin(e){const t=F.indexOf(e);t>=0&&F.splice(t,1)}static get(e){return e[de]?e[de]:new B(e)}get plugins(){return F}enable(){if(this._originalRender)return;let e=0;this._originalRender=this.renderer.render;const t=this;ce(this.renderer),this.renderer.render=function(r,i){t.renderer.getRenderTarget()==null&&(e=0,t._frame+=1);const s=t._frame,n=e++;t.onBeforeRender(r,i,n,s),t._originalRender.call(this,r,i),t.onAfterRender(r,i,n,s)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(e,t,r,i){}onAfterRender(e,t,r,i){var a,h;if(this.pause)return;const o=this.renderer.renderLists.get(e,0),s=o.opaque;let n=!0;if(s.length===1){const c=s[0].material;(c.name==="EffectMaterial"||c.name==="CopyShader")&&(n=!1)}if((t.parent&&t.parent.type==="CubeCamera"||r>=1&&t.type==="OrthographicCamera")&&(n=!1),n){if(Be||this.updateInterval>0&&i%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const c=this.targetTriangleDensity;for(const u of s){if(u.material&&(((a=u.geometry)==null?void 0:a.type)==="BoxGeometry"||((h=u.geometry)==null?void 0:h.type)==="BufferGeometry")&&(u.material.name==="SphericalGaussianBlur"||u.material.name=="BackgroundCubeMaterial"||u.material.name==="CubemapFromEquirect"||u.material.name==="EquirectangularToCubeUV")){N&&(u.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(u.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",u,u.material.name,u.material.type)));continue}switch(u.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}const y=u.object;(y instanceof p.Mesh||y.isMesh)&&this.updateLODs(e,t,y,c,i)}const L=o.transparent;for(const u of L){const y=u.object;(y instanceof p.Mesh||y.isMesh)&&this.updateLODs(e,t,y,c,i)}}}updateLODs(e,t,r,i,o){var a,h;r.userData||(r.userData={});let s=r[ie];if(s||(s=new Ce,r[ie]=s),s.frames++<2)return;for(const c of F)(a=c.onBeforeUpdateLOD)==null||a.call(c,this.renderer,e,t,r);this.calculateLodLevel(t,r,s,i,R),R.mesh_lod=Math.round(R.mesh_lod),R.texture_lod=Math.round(R.texture_lod),R.mesh_lod>=0&&this.loadProgressiveMeshes(r,R.mesh_lod);let n=R.texture_lod;if(r.material&&n>=0){const c=r["DEBUG:LOD"];c!=null&&(n=c),this.loadProgressiveTextures(r.material,n)}for(const c of F)(h=c.onAfterUpdatedLOD)==null||h.call(c,this.renderer,e,t,r,R);s.lastLodLevel_Mesh=R.mesh_lod,s.lastLodLevel_Texture=R.texture_lod}loadProgressiveTextures(e,t){if(!e)return;if(Array.isArray(e)){for(const i of e)this.loadProgressiveTextures(i,t);return}let r=!1;(e[U]===void 0||t<e[U])&&(r=!0),r&&(e[U]=t,S.assignTextureLOD(e,t))}loadProgressiveMeshes(e,t){if(!e)return Promise.resolve(null);if(e[U]!==t){e[U]=t;const r=e.geometry;return S.assignMeshLOD(e,t).then(i=>(i&&e[U]==t&&r!=e.geometry,i))}return Promise.resolve(null)}static isInside(e,t){const r=e.min,i=e.max,o=(r.x+i.x)*.5,s=(r.y+i.y)*.5;return this._tempPtInside.set(o,s,r.z).applyMatrix4(t).z<0}calculateLodLevel(e,t,r,i,o){var w;if(!t){o.mesh_lod=-1,o.texture_lod=-1;return}if(!e){o.mesh_lod=-1,o.texture_lod=-1;return}let n=10+1,a=!1;if(N&&t["DEBUG:LOD"]!=null)return t["DEBUG:LOD"];const h=S.getMeshLODInformation(t.geometry),c=h==null?void 0:h.lods,L=c&&c.length>0,u=S.getMaterialMinMaxLODsCount(t.material),y=(u==null?void 0:u.min_count)!=1/0&&u.min_count>0&&u.max_count>0;if(!L&&!y){o.mesh_lod=0,o.texture_lod=0;return}if(L||(a=!0,n=0),!((w=this.cameraFrustrum)!=null&&w.intersectsObject(t))){o.mesh_lod=99,o.texture_lod=99;return}let m=t.geometry.boundingBox;if(t.type==="SkinnedMesh"){const _=t;_.boundingBox||_.computeBoundingBox(),m=_.boundingBox}if(m&&e.isPerspectiveCamera){const _=e;if(t.geometry.attributes.color&&t.geometry.attributes.color.count<100&&t.geometry.boundingSphere){this._sphere.copy(t.geometry.boundingSphere),this._sphere.applyMatrix4(t.matrixWorld);const g=e.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(g)){o.mesh_lod=0,o.texture_lod=0;return}}if(this._tempBox.copy(m),t.type==="SkinnedMesh"?t.parent&&this._tempBox.applyMatrix4(t.parent.matrixWorld):this._tempBox.applyMatrix4(t.matrixWorld),B.isInside(this._tempBox,this.projectionScreenMatrix)){o.mesh_lod=0,o.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&_.fov>70){const g=this._tempBox.min,f=this._tempBox.max;let M=g.x,T=g.y,b=f.x,G=f.y;const $=2,te=1.5,H=(g.x+f.x)*.5,J=(g.y+f.y)*.5;M=(M-H)*$+H,T=(T-J)*$+J,b=(b-H)*$+H,G=(G-J)*$+J;const ye=M<0&&b>0?0:Math.min(Math.abs(g.x),Math.abs(f.x)),xe=T<0&&G>0?0:Math.min(Math.abs(g.y),Math.abs(f.y)),re=Math.max(ye,xe);r.lastCentrality=(te-re)*(te-re)*(te-re)}else r.lastCentrality=1;const D=this._tempBox.getSize(this._tempBoxSize);D.multiplyScalar(.5),screen.availHeight>0&&D.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),D.x*=_.aspect;const O=e.matrixWorldInverse,A=this._tempBox2;A.copy(m),A.applyMatrix4(t.matrixWorld),A.applyMatrix4(O);const P=A.getSize(this._tempBox2Size),Y=Math.max(P.x,P.y);if(Math.max(D.x,D.y)!=0&&Y!=0&&(D.z=P.z/Math.max(P.x,P.y)*Math.max(D.x,D.y)),r.lastScreenCoverage=Math.max(D.x,D.y,D.z),r.lastScreenspaceVolume.copy(D),r.lastScreenCoverage*=r.lastCentrality,N&&B.debugDrawLine){const g=this.tempMatrix.copy(this.projectionScreenMatrix);g.invert();const f=B.corner0,M=B.corner1,T=B.corner2,b=B.corner3;f.copy(this._tempBox.min),M.copy(this._tempBox.max),M.x=f.x,T.copy(this._tempBox.max),T.y=f.y,b.copy(this._tempBox.max);const G=(f.z+b.z)*.5;f.z=M.z=T.z=b.z=G,f.applyMatrix4(g),M.applyMatrix4(g),T.applyMatrix4(g),b.applyMatrix4(g),B.debugDrawLine(f,M,255),B.debugDrawLine(f,T,255),B.debugDrawLine(M,b,255),B.debugDrawLine(T,b,255)}let z=999;if(c&&r.lastScreenCoverage>0){for(let g=0;g<c.length;g++)if(c[g].density/r.lastScreenCoverage<i){z=g;break}}z<n&&(n=z,a=!0)}if(a?o.mesh_lod=n:o.mesh_lod=r.lastLodLevel_Mesh,N&&o.mesh_lod!=r.lastLodLevel_Mesh){const D=c==null?void 0:c[o.mesh_lod];D&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${o.mesh_lod} (${D.density.toFixed(0)}) - ${t.name}`)}if(y)if(r.lastLodLevel_Texture<0){if(o.texture_lod=u.max_count-1,N){const _=u.lods[u.max_count-1];N&&console.log(`First Texture LOD ${o.texture_lod} (${_.max_height}px) - ${t.name}`)}}else{const _=r.lastScreenCoverage*1.5,O=this.renderer.domElement.clientHeight/window.devicePixelRatio*_;for(let A=u.lods.length-1;A>=0;A--){const P=u.lods[A];if(!(Te()&&P.max_height>4096)&&P.max_height>O){o.texture_lod=A,o.texture_lod<r.lastLodLevel_Texture&&N&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${o.texture_lod} (${P.max_height}px: ${(100*r.lastScreenCoverage).toFixed(2)} % = ${O.toFixed(0)}px) - ${t.name}`);break}}}else o.texture_lod=0}};let C=B;d(C,"debugDrawLine"),d(C,"corner0",new p.Vector3),d(C,"corner1",new p.Vector3),d(C,"corner2",new p.Vector3),d(C,"corner3",new p.Vector3),d(C,"_tempPtInside",new p.Vector3);class Ce{constructor(){d(this,"frames",0);d(this,"lastLodLevel_Mesh",-1);d(this,"lastLodLevel_Texture",-1);d(this,"lastScreenCoverage",0);d(this,"lastScreenspaceVolume",new p.Vector3);d(this,"lastCentrality",0)}}const he=Symbol("NEEDLE_mesh_lod"),Q=Symbol("NEEDLE_texture_lod");function pe(l){if(!l)return null;let e=null,t=null;for(let r=l;r!=null;r=Object.getPrototypeOf(r)){const i=Object.getOwnPropertySymbols(r),o=i.find(n=>n.toString()=="Symbol(renderer)"),s=i.find(n=>n.toString()=="Symbol(scene)");!e&&o!=null&&(e=l[o].threeRenderer),!t&&s!=null&&(t=l[s])}if(e){const r=C.get(e);if(C.addPlugin(new Re(l)),r.enable(),t){const i=t.camera||t.traverse(o=>o.type=="PerspectiveCamera")[0];i&&e.render(t,i)}return()=>{r.disable()}}return null}class Re{constructor(e){d(this,"modelviewer");d(this,"_didWarnAboutMissingUrl",!1);this.modelviewer=e}onBeforeUpdateLOD(e,t,r,i){this.tryParseMeshLOD(t,i),this.tryParseTextureLOD(t,i)}getUrl(){let e=this.modelviewer.getAttribute("src");return e||(e=this.modelviewer.src),e||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",this.modelviewer),this._didWarnAboutMissingUrl=!0),e}tryGetCurrentGLTF(e){return e._currentGLTF}tryParseTextureLOD(e,t){if(t[Q]==!0)return;t[Q]=!0;const r=this.tryGetCurrentGLTF(e),i=this.getUrl();if(i&&r&&t.material){let o=function(n){var h,c,L;if(n[Q]==!0)return;n[Q]=!0,n.userData&&(n.userData.LOD=-1);const a=Object.keys(n);for(let u=0;u<a.length;u++){const y=a[u],m=n[y];if((m==null?void 0:m.isTexture)===!0){const w=(c=(h=m.userData)==null?void 0:h.associations)==null?void 0:c.textures,_=r.parser.json.textures[w];if(!_){console.warn("Texture data not found for texture index "+w);continue}if((L=_==null?void 0:_.extensions)!=null&&L[E]){const D=_.extensions[E];D&&i&&S.registerTexture(i,m,D.lods.length,w,D)}}}};const s=t.material;if(Array.isArray(s))for(const n of s)o(n);else o(s)}}tryParseMeshLOD(e,t){var o,s;if(t[he]==!0)return;t[he]=!0;const r=this.getUrl();if(!r)return;const i=(s=(o=t.userData)==null?void 0:o.gltfExtensions)==null?void 0:s[E];if(i&&r){const n=t.uuid;S.registerMesh(r,n,t,0,i.lods.length,i)}}}document.addEventListener("DOMContentLoaded",()=>{pe(document.querySelector("model-viewer"))});function Ee(l,e,t,r){ce(e),ue(t),t.register(o=>new S(o,l));const i=C.get(e);return(r==null?void 0:r.enableLODsManager)!==!1&&i.enable(),i}exports.EXTENSION_NAME=E;exports.LODsManager=C;exports.NEEDLE_progressive=S;exports.addDracoAndKTX2Loaders=ue;exports.createLoaders=ce;exports.getRaycastMesh=ee;exports.patchModelViewer=pe;exports.setDracoDecoderLocation=Oe;exports.setKTX2TranscoderLocation=ve;exports.setRaycastMesh=ge;exports.useNeedleProgressive=Ee;exports.useRaycastMeshes=be;
|
|
5
|
+
`,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}};let S=v;d(S,"registerTexture",(e,t,r,i,o)=>{if(x&&console.log("> Progressive: register texture",i,t.name,t.uuid,t,o),!t){x&&console.error("gltf-progressive: Register texture without texture");return}t.source&&(t.source[se]=o);const s=o.guid;v.assignLODInformation(e,t,s,r,i,void 0),v.lodInfos.set(s,o),v.lowresCache.set(s,t)}),d(S,"registerMesh",(e,t,r,i,o,s)=>{var h;x&&console.log("> Progressive: register mesh",o,r.name,s,r.uuid,r);const n=r.geometry;if(!n){x&&console.warn("gltf-progressive: Register mesh without geometry");return}n.userData||(n.userData={}),v.assignLODInformation(e,n,t,i,o,s.density),v.lodInfos.set(t,s);let a=v.lowresCache.get(t);a?a.push(r.geometry):a=[r.geometry],v.lowresCache.set(t,a),i>0&&!ee(r)&&ge(r,n);for(const c of F)(h=c.onRegisteredNewMesh)==null||h.call(c,r,s)}),d(S,"lodInfos",new Map),d(S,"previouslyLoaded",new Map),d(S,"lowresCache",new Map);class Pe{constructor(e,t,r,i,o){d(this,"url");d(this,"key");d(this,"level");d(this,"index");d(this,"density");this.url=e,this.key=t,this.level=r,i!=null&&(this.index=i),o!=null&&(this.density=o)}}const N=j("debugprogressive"),Be=j("noprogressive"),de=Symbol("Needle:LODSManager"),ie=Symbol("Needle:LODState"),U=Symbol("Needle:CurrentLOD"),R={mesh_lod:-1,texture_lod:-1},B=class{constructor(e){d(this,"renderer");d(this,"projectionScreenMatrix",new p.Matrix4);d(this,"cameraFrustrum",new p.Frustum);d(this,"targetTriangleDensity",2e5);d(this,"updateInterval",0);d(this,"pause",!1);d(this,"_frame",0);d(this,"_originalRender");d(this,"_sphere",new p.Sphere);d(this,"_tempBox",new p.Box3);d(this,"_tempBox2",new p.Box3);d(this,"tempMatrix",new p.Matrix4);d(this,"_tempWorldPosition",new p.Vector3);d(this,"_tempBoxSize",new p.Vector3);d(this,"_tempBox2Size",new p.Vector3);this.renderer=e}static getObjectLODState(e){return e[ie]}static addPlugin(e){F.push(e)}static removePlugin(e){const t=F.indexOf(e);t>=0&&F.splice(t,1)}static get(e){return e[de]?e[de]:new B(e)}get plugins(){return F}enable(){if(this._originalRender)return;let e=0;this._originalRender=this.renderer.render;const t=this;ce(this.renderer),this.renderer.render=function(r,i){t.renderer.getRenderTarget()==null&&(e=0,t._frame+=1);const s=t._frame,n=e++;t.onBeforeRender(r,i,n,s),t._originalRender.call(this,r,i),t.onAfterRender(r,i,n,s)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(e,t,r,i){}onAfterRender(e,t,r,i){var a,h;if(this.pause)return;const o=this.renderer.renderLists.get(e,0),s=o.opaque;let n=!0;if(s.length===1){const c=s[0].material;(c.name==="EffectMaterial"||c.name==="CopyShader")&&(n=!1)}if((t.parent&&t.parent.type==="CubeCamera"||r>=1&&t.type==="OrthographicCamera")&&(n=!1),n){if(Be||this.updateInterval>0&&i%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const c=this.targetTriangleDensity;for(const u of s){if(u.material&&(((a=u.geometry)==null?void 0:a.type)==="BoxGeometry"||((h=u.geometry)==null?void 0:h.type)==="BufferGeometry")&&(u.material.name==="SphericalGaussianBlur"||u.material.name=="BackgroundCubeMaterial"||u.material.name==="CubemapFromEquirect"||u.material.name==="EquirectangularToCubeUV")){N&&(u.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(u.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",u,u.material.name,u.material.type)));continue}switch(u.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}const y=u.object;(y instanceof p.Mesh||y.isMesh)&&this.updateLODs(e,t,y,c,i)}const m=o.transparent;for(const u of m){const y=u.object;(y instanceof p.Mesh||y.isMesh)&&this.updateLODs(e,t,y,c,i)}}}updateLODs(e,t,r,i,o){var a,h;r.userData||(r.userData={});let s=r[ie];if(s||(s=new Ce,r[ie]=s),s.frames++<2)return;for(const c of F)(a=c.onBeforeUpdateLOD)==null||a.call(c,this.renderer,e,t,r);this.calculateLodLevel(t,r,s,i,R),R.mesh_lod=Math.round(R.mesh_lod),R.texture_lod=Math.round(R.texture_lod),R.mesh_lod>=0&&this.loadProgressiveMeshes(r,R.mesh_lod);let n=R.texture_lod;if(r.material&&n>=0){const c=r["DEBUG:LOD"];c!=null&&(n=c),this.loadProgressiveTextures(r.material,n)}for(const c of F)(h=c.onAfterUpdatedLOD)==null||h.call(c,this.renderer,e,t,r,R);s.lastLodLevel_Mesh=R.mesh_lod,s.lastLodLevel_Texture=R.texture_lod}loadProgressiveTextures(e,t){if(!e)return;if(Array.isArray(e)){for(const i of e)this.loadProgressiveTextures(i,t);return}let r=!1;(e[U]===void 0||t<e[U])&&(r=!0),r&&(e[U]=t,S.assignTextureLOD(e,t))}loadProgressiveMeshes(e,t){if(!e)return Promise.resolve(null);if(e[U]!==t){e[U]=t;const r=e.geometry;return S.assignMeshLOD(e,t).then(i=>(i&&e[U]==t&&r!=e.geometry,i))}return Promise.resolve(null)}static isInside(e,t){const r=e.min,i=e.max,o=(r.x+i.x)*.5,s=(r.y+i.y)*.5;return this._tempPtInside.set(o,s,r.z).applyMatrix4(t).z<0}calculateLodLevel(e,t,r,i,o){var _;if(!t){o.mesh_lod=-1,o.texture_lod=-1;return}if(!e){o.mesh_lod=-1,o.texture_lod=-1;return}let n=10+1,a=!1;if(N&&t["DEBUG:LOD"]!=null)return t["DEBUG:LOD"];const h=S.getMeshLODInformation(t.geometry),c=h==null?void 0:h.lods,m=c&&c.length>0,u=S.getMaterialMinMaxLODsCount(t.material),y=(u==null?void 0:u.min_count)!=1/0&&u.min_count>0&&u.max_count>0;if(!m&&!y){o.mesh_lod=0,o.texture_lod=0;return}if(m||(a=!0,n=0),!((_=this.cameraFrustrum)!=null&&_.intersectsObject(t))){o.mesh_lod=99,o.texture_lod=99;return}let L=t.geometry.boundingBox;if(t.type==="SkinnedMesh"){const w=t;w.boundingBox||w.computeBoundingBox(),L=w.boundingBox}if(L&&e.isPerspectiveCamera){const w=e;if(t.geometry.attributes.color&&t.geometry.attributes.color.count<100&&t.geometry.boundingSphere){this._sphere.copy(t.geometry.boundingSphere),this._sphere.applyMatrix4(t.matrixWorld);const g=e.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(g)){o.mesh_lod=0,o.texture_lod=0;return}}if(this._tempBox.copy(L),this._tempBox.applyMatrix4(t.matrixWorld),B.isInside(this._tempBox,this.projectionScreenMatrix)){o.mesh_lod=0,o.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&w.fov>70){const g=this._tempBox.min,f=this._tempBox.max;let M=g.x,T=g.y,b=f.x,G=f.y;const $=2,te=1.5,H=(g.x+f.x)*.5,J=(g.y+f.y)*.5;M=(M-H)*$+H,T=(T-J)*$+J,b=(b-H)*$+H,G=(G-J)*$+J;const ye=M<0&&b>0?0:Math.min(Math.abs(g.x),Math.abs(f.x)),xe=T<0&&G>0?0:Math.min(Math.abs(g.y),Math.abs(f.y)),re=Math.max(ye,xe);r.lastCentrality=(te-re)*(te-re)*(te-re)}else r.lastCentrality=1;const D=this._tempBox.getSize(this._tempBoxSize);D.multiplyScalar(.5),screen.availHeight>0&&D.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),D.x*=w.aspect;const O=e.matrixWorldInverse,A=this._tempBox2;A.copy(L),A.applyMatrix4(t.matrixWorld),A.applyMatrix4(O);const P=A.getSize(this._tempBox2Size),Y=Math.max(P.x,P.y);if(Math.max(D.x,D.y)!=0&&Y!=0&&(D.z=P.z/Math.max(P.x,P.y)*Math.max(D.x,D.y)),r.lastScreenCoverage=Math.max(D.x,D.y,D.z),r.lastScreenspaceVolume.copy(D),r.lastScreenCoverage*=r.lastCentrality,N&&B.debugDrawLine){const g=this.tempMatrix.copy(this.projectionScreenMatrix);g.invert();const f=B.corner0,M=B.corner1,T=B.corner2,b=B.corner3;f.copy(this._tempBox.min),M.copy(this._tempBox.max),M.x=f.x,T.copy(this._tempBox.max),T.y=f.y,b.copy(this._tempBox.max);const G=(f.z+b.z)*.5;f.z=M.z=T.z=b.z=G,f.applyMatrix4(g),M.applyMatrix4(g),T.applyMatrix4(g),b.applyMatrix4(g),B.debugDrawLine(f,M,255),B.debugDrawLine(f,T,255),B.debugDrawLine(M,b,255),B.debugDrawLine(T,b,255)}let z=999;if(c&&r.lastScreenCoverage>0){for(let g=0;g<c.length;g++)if(c[g].density/r.lastScreenCoverage<i){z=g;break}}z<n&&(n=z,a=!0)}if(a?o.mesh_lod=n:o.mesh_lod=r.lastLodLevel_Mesh,N&&o.mesh_lod!=r.lastLodLevel_Mesh){const D=c==null?void 0:c[o.mesh_lod];D&&console.log(`Mesh LOD changed: ${r.lastLodLevel_Mesh} → ${o.mesh_lod} (${D.density.toFixed(0)}) - ${t.name}`)}if(y)if(r.lastLodLevel_Texture<0){if(o.texture_lod=u.max_count-1,N){const w=u.lods[u.max_count-1];N&&console.log(`First Texture LOD ${o.texture_lod} (${w.max_height}px) - ${t.name}`)}}else{const w=r.lastScreenCoverage*1.5,O=this.renderer.domElement.clientHeight/window.devicePixelRatio*w;for(let A=u.lods.length-1;A>=0;A--){const P=u.lods[A];if(!(Te()&&P.max_height>4096)&&P.max_height>O){o.texture_lod=A,o.texture_lod<r.lastLodLevel_Texture&&N&&console.log(`Texture LOD changed: ${r.lastLodLevel_Texture} → ${o.texture_lod} (${P.max_height}px: ${(100*r.lastScreenCoverage).toFixed(2)} % = ${O.toFixed(0)}px) - ${t.name}`);break}}}else o.texture_lod=0}};let C=B;d(C,"debugDrawLine"),d(C,"corner0",new p.Vector3),d(C,"corner1",new p.Vector3),d(C,"corner2",new p.Vector3),d(C,"corner3",new p.Vector3),d(C,"_tempPtInside",new p.Vector3);class Ce{constructor(){d(this,"frames",0);d(this,"lastLodLevel_Mesh",-1);d(this,"lastLodLevel_Texture",-1);d(this,"lastScreenCoverage",0);d(this,"lastScreenspaceVolume",new p.Vector3);d(this,"lastCentrality",0)}}const he=Symbol("NEEDLE_mesh_lod"),Q=Symbol("NEEDLE_texture_lod");function pe(l){if(!l)return null;let e=null,t=null;for(let r=l;r!=null;r=Object.getPrototypeOf(r)){const i=Object.getOwnPropertySymbols(r),o=i.find(n=>n.toString()=="Symbol(renderer)"),s=i.find(n=>n.toString()=="Symbol(scene)");!e&&o!=null&&(e=l[o].threeRenderer),!t&&s!=null&&(t=l[s])}if(e){const r=C.get(e);if(C.addPlugin(new Re(l)),r.enable(),t){const i=t.camera||t.traverse(o=>o.type=="PerspectiveCamera")[0];i&&e.render(t,i)}return()=>{r.disable()}}return null}class Re{constructor(e){d(this,"modelviewer");d(this,"_didWarnAboutMissingUrl",!1);this.modelviewer=e}onBeforeUpdateLOD(e,t,r,i){this.tryParseMeshLOD(t,i),this.tryParseTextureLOD(t,i)}getUrl(){let e=this.modelviewer.getAttribute("src");return e||(e=this.modelviewer.src),e||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",this.modelviewer),this._didWarnAboutMissingUrl=!0),e}tryGetCurrentGLTF(e){return e._currentGLTF}tryParseTextureLOD(e,t){if(t[Q]==!0)return;t[Q]=!0;const r=this.tryGetCurrentGLTF(e),i=this.getUrl();if(i&&r&&t.material){let o=function(n){var h,c,m;if(n[Q]==!0)return;n[Q]=!0,n.userData&&(n.userData.LOD=-1);const a=Object.keys(n);for(let u=0;u<a.length;u++){const y=a[u],L=n[y];if((L==null?void 0:L.isTexture)===!0){const _=(c=(h=L.userData)==null?void 0:h.associations)==null?void 0:c.textures,w=r.parser.json.textures[_];if(!w){console.warn("Texture data not found for texture index "+_);continue}if((m=w==null?void 0:w.extensions)!=null&&m[E]){const D=w.extensions[E];D&&i&&S.registerTexture(i,L,D.lods.length,_,D)}}}};const s=t.material;if(Array.isArray(s))for(const n of s)o(n);else o(s)}}tryParseMeshLOD(e,t){var o,s;if(t[he]==!0)return;t[he]=!0;const r=this.getUrl();if(!r)return;const i=(s=(o=t.userData)==null?void 0:o.gltfExtensions)==null?void 0:s[E];if(i&&r){const n=t.uuid;S.registerMesh(r,n,t,0,i.lods.length,i)}}}document.addEventListener("DOMContentLoaded",()=>{pe(document.querySelector("model-viewer"))});function Ee(l,e,t,r){ce(e),ue(t),t.register(o=>new S(o,l));const i=C.get(e);return(r==null?void 0:r.enableLODsManager)!==!1&&i.enable(),i}exports.EXTENSION_NAME=E;exports.LODsManager=C;exports.NEEDLE_progressive=S;exports.addDracoAndKTX2Loaders=ue;exports.createLoaders=ce;exports.getRaycastMesh=ee;exports.patchModelViewer=pe;exports.setDracoDecoderLocation=Oe;exports.setKTX2TranscoderLocation=ve;exports.setRaycastMesh=ge;exports.useNeedleProgressive=Ee;exports.useRaycastMeshes=be;
|
package/lib/lods_manager.js
CHANGED
|
@@ -367,8 +367,9 @@ export class LODsManager {
|
|
|
367
367
|
let boundingBox = mesh.geometry.boundingBox;
|
|
368
368
|
if (mesh.type === "SkinnedMesh") {
|
|
369
369
|
const skinnedMesh = mesh;
|
|
370
|
-
if (!skinnedMesh.boundingBox)
|
|
370
|
+
if (!skinnedMesh.boundingBox) {
|
|
371
371
|
skinnedMesh.computeBoundingBox();
|
|
372
|
+
}
|
|
372
373
|
boundingBox = skinnedMesh.boundingBox;
|
|
373
374
|
}
|
|
374
375
|
if (boundingBox && camera.isPerspectiveCamera) {
|
|
@@ -388,14 +389,7 @@ export class LODsManager {
|
|
|
388
389
|
}
|
|
389
390
|
// calculate size on screen
|
|
390
391
|
this._tempBox.copy(boundingBox);
|
|
391
|
-
|
|
392
|
-
if (mesh.type === "SkinnedMesh") {
|
|
393
|
-
if (mesh.parent)
|
|
394
|
-
this._tempBox.applyMatrix4(mesh.parent.matrixWorld);
|
|
395
|
-
}
|
|
396
|
-
else {
|
|
397
|
-
this._tempBox.applyMatrix4(mesh.matrixWorld);
|
|
398
|
-
}
|
|
392
|
+
this._tempBox.applyMatrix4(mesh.matrixWorld);
|
|
399
393
|
// Converting into projection space has the disadvantage that objects further to the side
|
|
400
394
|
// will have a much larger coverage, especially with high-field-of-view situations like in VR.
|
|
401
395
|
// Alternatively, we could attempt to calculate angular coverage (some kind of polar coordinates maybe?)
|
package/lib/utils.internal.js
CHANGED
|
@@ -41,6 +41,6 @@ export function isMobileDevice() {
|
|
|
41
41
|
return _ismobile;
|
|
42
42
|
_ismobile = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent);
|
|
43
43
|
if (getParam("debugprogressive"))
|
|
44
|
-
console.log("isMobileDevice", _ismobile);
|
|
44
|
+
console.log("[glTF Progressive]: isMobileDevice", _ismobile);
|
|
45
45
|
return _ismobile;
|
|
46
46
|
}
|
package/package.json
CHANGED