@needle-tools/gltf-progressive 1.0.0-alpha.18 → 1.0.0-alpha.19
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 +3 -0
- package/gltf-progressive.js +26 -22
- package/gltf-progressive.min.js +1 -1
- package/gltf-progressive.umd.cjs +2 -2
- package/lib/lods_manager.d.ts +2 -0
- package/lib/lods_manager.js +2 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,9 @@ 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.0.0-alpha.19] - 2023-05-31
|
|
8
|
+
- add `LODsManager.plugins` getter
|
|
9
|
+
|
|
7
10
|
## [1.0.0-alpha.18] - 2023-05-30
|
|
8
11
|
- update README
|
|
9
12
|
|
package/gltf-progressive.js
CHANGED
|
@@ -46,7 +46,7 @@ function xe(a) {
|
|
|
46
46
|
function we(a, e) {
|
|
47
47
|
(a.type === "Mesh" || a.type === "SkinnedMesh") && (a.userData || (a.userData = {}), a.userData["needle:raycast-mesh"] = e);
|
|
48
48
|
}
|
|
49
|
-
const
|
|
49
|
+
const E = new Array(), I = "NEEDLE_progressive", v = ee("debugprogressive"), H = Symbol("needle-progressive-texture"), N = /* @__PURE__ */ new Map(), Z = /* @__PURE__ */ new Set();
|
|
50
50
|
if (v) {
|
|
51
51
|
let a = function() {
|
|
52
52
|
e += 1, console.log("Toggle LOD level", e, N), N.forEach((i, n) => {
|
|
@@ -84,7 +84,7 @@ const O = class {
|
|
|
84
84
|
}
|
|
85
85
|
/** The name of the extension */
|
|
86
86
|
get name() {
|
|
87
|
-
return
|
|
87
|
+
return I;
|
|
88
88
|
}
|
|
89
89
|
static getMeshLODInformation(e) {
|
|
90
90
|
const t = this.getAssignedLODInformation(e);
|
|
@@ -141,7 +141,7 @@ const O = class {
|
|
|
141
141
|
const i = e.geometry, n = this.getAssignedLODInformation(i);
|
|
142
142
|
if (!n)
|
|
143
143
|
return Promise.resolve(null);
|
|
144
|
-
for (const s of
|
|
144
|
+
for (const s of E)
|
|
145
145
|
(r = s.onBeforeGetLODMesh) == null || r.call(s, e, t);
|
|
146
146
|
return e["LOD:requested level"] = t, O.getOrLoadLOD(i, t).then((s) => {
|
|
147
147
|
if (e["LOD:requested level"] === t) {
|
|
@@ -220,7 +220,7 @@ const O = class {
|
|
|
220
220
|
var t, r;
|
|
221
221
|
return v && console.log("AFTER", this.url, e), (t = this.parser.json.textures) == null || t.forEach((i, n) => {
|
|
222
222
|
if (i != null && i.extensions) {
|
|
223
|
-
const s = i == null ? void 0 : i.extensions[
|
|
223
|
+
const s = i == null ? void 0 : i.extensions[I];
|
|
224
224
|
if (s) {
|
|
225
225
|
let o = !1;
|
|
226
226
|
for (const l of this.parser.associations.keys())
|
|
@@ -232,7 +232,7 @@ const O = class {
|
|
|
232
232
|
}
|
|
233
233
|
}), (r = this.parser.json.meshes) == null || r.forEach((i, n) => {
|
|
234
234
|
if (i != null && i.extensions) {
|
|
235
|
-
const s = i == null ? void 0 : i.extensions[
|
|
235
|
+
const s = i == null ? void 0 : i.extensions[I];
|
|
236
236
|
if (s && s.lods) {
|
|
237
237
|
for (const o of this.parser.associations.keys())
|
|
238
238
|
if (o.isMesh) {
|
|
@@ -295,7 +295,7 @@ const O = class {
|
|
|
295
295
|
let m = !1;
|
|
296
296
|
for (const d of y.parser.json.textures) {
|
|
297
297
|
if (d != null && d.extensions) {
|
|
298
|
-
const M = d == null ? void 0 : d.extensions[
|
|
298
|
+
const M = d == null ? void 0 : d.extensions[I];
|
|
299
299
|
if (M != null && M.guid && M.guid === L.guid) {
|
|
300
300
|
m = !0;
|
|
301
301
|
break;
|
|
@@ -313,7 +313,7 @@ const O = class {
|
|
|
313
313
|
let m = !1;
|
|
314
314
|
for (const d of y.parser.json.meshes) {
|
|
315
315
|
if (d != null && d.extensions) {
|
|
316
|
-
const M = d == null ? void 0 : d.extensions[
|
|
316
|
+
const M = d == null ? void 0 : d.extensions[I];
|
|
317
317
|
if (M != null && M.guid && M.guid === L.guid) {
|
|
318
318
|
m = !0;
|
|
319
319
|
break;
|
|
@@ -329,9 +329,9 @@ const O = class {
|
|
|
329
329
|
} else {
|
|
330
330
|
const _ = new Array();
|
|
331
331
|
for (let B = 0; B < d.children.length; B++) {
|
|
332
|
-
const
|
|
333
|
-
if (
|
|
334
|
-
const $ =
|
|
332
|
+
const G = d.children[B];
|
|
333
|
+
if (G instanceof X) {
|
|
334
|
+
const $ = G.geometry;
|
|
335
335
|
O.assignLODInformation(i.url, $, n, t, B, M.density), _.push($);
|
|
336
336
|
}
|
|
337
337
|
}
|
|
@@ -385,7 +385,7 @@ u(S, "registerMesh", (e, t, r, i, n, s) => {
|
|
|
385
385
|
o.userData || (o.userData = {}), O.assignLODInformation(e, o, t, i, n, s.density), O.lodInfos.set(t, s);
|
|
386
386
|
let l = O.lowresCache.get(t);
|
|
387
387
|
l ? l.push(r.geometry) : l = [r.geometry], O.lowresCache.set(t, l), i > 0 && !xe(r) && we(r, o);
|
|
388
|
-
for (const f of
|
|
388
|
+
for (const f of E)
|
|
389
389
|
(g = f.onRegisteredNewMesh) == null || g.call(f, r, s);
|
|
390
390
|
}), /** A map of key = asset uuid and value = LOD information */
|
|
391
391
|
u(S, "lodInfos", /* @__PURE__ */ new Map()), /** cache of already loaded mesh lods */
|
|
@@ -441,11 +441,11 @@ const J = ee("debugprogressive"), Me = ee("noprogressive"), ie = Symbol("Needle:
|
|
|
441
441
|
return (t = e.userData) == null ? void 0 : t.LOD_state;
|
|
442
442
|
}
|
|
443
443
|
static addPlugin(e) {
|
|
444
|
-
|
|
444
|
+
E.push(e);
|
|
445
445
|
}
|
|
446
446
|
static removePlugin(e) {
|
|
447
|
-
const t =
|
|
448
|
-
t >= 0 &&
|
|
447
|
+
const t = E.indexOf(e);
|
|
448
|
+
t >= 0 && E.splice(t, 1);
|
|
449
449
|
}
|
|
450
450
|
/**
|
|
451
451
|
* Gets the LODsManager for the given renderer. If the LODsManager does not exist yet, it will be created.
|
|
@@ -455,6 +455,10 @@ const J = ee("debugprogressive"), Me = ee("noprogressive"), ie = Symbol("Needle:
|
|
|
455
455
|
static get(e) {
|
|
456
456
|
return e[ie] ? e[ie] : new P(e);
|
|
457
457
|
}
|
|
458
|
+
/** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
|
|
459
|
+
get plugins() {
|
|
460
|
+
return E;
|
|
461
|
+
}
|
|
458
462
|
/**
|
|
459
463
|
* Enable the LODsManager. This will replace the render method of the renderer with a method that updates the LODs.
|
|
460
464
|
*/
|
|
@@ -517,7 +521,7 @@ const J = ee("debugprogressive"), Me = ee("noprogressive"), ie = Symbol("Needle:
|
|
|
517
521
|
/** Update the LOD levels for the renderer. */
|
|
518
522
|
updateLODs(e, t, r, i) {
|
|
519
523
|
var l, g;
|
|
520
|
-
for (const f of
|
|
524
|
+
for (const f of E)
|
|
521
525
|
(l = f.onBeforeUpdateLOD) == null || l.call(f, this.renderer, e, t, r);
|
|
522
526
|
let n = r.userData.LOD_state;
|
|
523
527
|
n || (n = new ve(), r.userData.LOD_state = n);
|
|
@@ -532,7 +536,7 @@ const J = ee("debugprogressive"), Me = ee("noprogressive"), ie = Symbol("Needle:
|
|
|
532
536
|
else
|
|
533
537
|
this.loadProgressiveTextures(r.material, o);
|
|
534
538
|
}
|
|
535
|
-
for (const f of
|
|
539
|
+
for (const f of E)
|
|
536
540
|
(g = f.onAfterUpdatedLOD) == null || g.call(f, this.renderer, e, t, r, s);
|
|
537
541
|
n.lastLodLevel = s;
|
|
538
542
|
}
|
|
@@ -591,8 +595,8 @@ const J = ee("debugprogressive"), Me = ee("noprogressive"), ie = Symbol("Needle:
|
|
|
591
595
|
if (this._tempBox.applyMatrix4(this.projectionScreenMatrix), this.renderer.xr.enabled && p.fov > 70) {
|
|
592
596
|
const D = this._tempBox.min, y = this._tempBox.max;
|
|
593
597
|
let T = D.x, w = D.y, m = y.x, d = y.y;
|
|
594
|
-
const M = 2, _ = 1.5, B = (D.x + y.x) * 0.5,
|
|
595
|
-
T = (T - B) * M + B, w = (w -
|
|
598
|
+
const M = 2, _ = 1.5, B = (D.x + y.x) * 0.5, G = (D.y + y.y) * 0.5;
|
|
599
|
+
T = (T - B) * M + B, w = (w - G) * M + G, m = (m - B) * M + B, d = (d - G) * M + G;
|
|
596
600
|
const $ = T < 0 && m > 0 ? 0 : Math.min(Math.abs(D.x), Math.abs(y.x)), le = w < 0 && d > 0 ? 0 : Math.min(Math.abs(D.y), Math.abs(y.y)), V = Math.max($, le);
|
|
597
601
|
r.lastCentrality = (_ - V) * (_ - V) * (_ - V);
|
|
598
602
|
} else
|
|
@@ -694,8 +698,8 @@ class Te {
|
|
|
694
698
|
console.warn("Texture data not found for texture index " + A);
|
|
695
699
|
continue;
|
|
696
700
|
}
|
|
697
|
-
if ((p = C == null ? void 0 : C.extensions) != null && p[
|
|
698
|
-
const x = C.extensions[
|
|
701
|
+
if ((p = C == null ? void 0 : C.extensions) != null && p[I]) {
|
|
702
|
+
const x = C.extensions[I];
|
|
699
703
|
x && i && S.registerTexture(i, L, x.lods.length, x);
|
|
700
704
|
}
|
|
701
705
|
}
|
|
@@ -717,7 +721,7 @@ class Te {
|
|
|
717
721
|
const r = this.getUrl();
|
|
718
722
|
if (!r)
|
|
719
723
|
return;
|
|
720
|
-
const i = (s = (n = t.userData) == null ? void 0 : n.gltfExtensions) == null ? void 0 : s[
|
|
724
|
+
const i = (s = (n = t.userData) == null ? void 0 : n.gltfExtensions) == null ? void 0 : s[I];
|
|
721
725
|
if (i && r) {
|
|
722
726
|
const o = t.uuid;
|
|
723
727
|
S.registerMesh(r, o, t, 0, i.lods.length, i);
|
|
@@ -733,7 +737,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
733
737
|
Se(document.querySelector("model-viewer"));
|
|
734
738
|
});
|
|
735
739
|
export {
|
|
736
|
-
|
|
740
|
+
I as EXTENSION_NAME,
|
|
737
741
|
b as LODsManager,
|
|
738
742
|
S as NEEDLE_progressive,
|
|
739
743
|
ae as addDracoAndKTX2Loaders,
|
package/gltf-progressive.min.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
var le=Object.defineProperty,ue=(t,e,r)=>e in t?le(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,c=(t,e,r)=>(ue(t,typeof e!="symbol"?e+"":e,r),r);import{MeshoptDecoder as ce}from"three/examples/jsm/libs/meshopt_decoder.module.js";import{DRACOLoader as de}from"three/examples/jsm/loaders/DRACOLoader.js";import{KTX2Loader as he}from"three/examples/jsm/loaders/KTX2Loader.js";import{BufferGeometry as z,Mesh as U,Material as fe,Texture as k,TextureLoader as ge,Matrix4 as ee,Frustum as me,Sphere as pe,Box3 as te,Vector3 as B}from"three";import{GLTFLoader as ye}from"three/examples/jsm/loaders/GLTFLoader.js";let $="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",V="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch($+"draco_decoder.js",{method:"head"}).catch(t=>{$="./include/draco/",V="./include/ktx2/"});function De(t){$=t}function xe(t){V=t}let G,X,N;function K(t){G||(G=new de,G.setDecoderPath($),G.setDecoderConfig({type:"js"})),N||(N=new he,N.setTranscoderPath(V)),X||(X=ce),t?N.detectSupport(t):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function H(t){t.dracoLoader||t.setDRACOLoader(G),t.ktx2Loader||t.setKTX2Loader(N),t.meshoptDecoder||t.setMeshoptDecoder(X)}function Y(t){const e=new URL(window.location.href).searchParams.get(t);return e==null||e==="0"||e==="false"?!1:e===""?!0:e}function Le(t,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||t===void 0)return e;const r=t.lastIndexOf("/");if(r>=0){const n=t.substring(0,r+1);for(;n.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return n+e}return e}function re(t){var e;return((e=t.userData)==null?void 0:e["needle:raycast-mesh"])instanceof z?t.userData["needle:raycast-mesh"]:null}function se(t,e){(t.type==="Mesh"||t.type==="SkinnedMesh")&&(t.userData||(t.userData={}),t.userData["needle:raycast-mesh"]=e)}const R=new Array,I="NEEDLE_progressive",v=Y("debugprogressive"),J=Symbol("needle-progressive-texture"),F=new Map,Q=new Set;if(v){let t=function(){e+=1,console.log("Toggle LOD level",e,F),F.forEach((o,s)=>{for(const a of o.keys){const i=s[a];if(i.isBufferGeometry===!0){const l=O.getMeshLODInformation(i),d=l?Math.min(e,l.lods.length):0;s["DEBUG:LOD"]=e,O.assignMeshLOD(s,d),l&&(r=Math.max(r,l.lods.length-1))}else if(s.isMaterial===!0){s["DEBUG:LOD"]=e,O.assignTextureLOD(s,e);break}}}),e>=r&&(e=-1)},e=-1,r=2,n=!1;window.addEventListener("keyup",o=>{o.key==="p"&&t(),o.key==="w"&&(n=!n,Q&&Q.forEach(s=>{s.name!="BackgroundCubeMaterial"&&"wireframe"in s&&(s.wireframe=n)}))})}function ne(t,e,r){var n;if(!v)return;F.has(t)||F.set(t,{keys:[],sourceId:r});const o=F.get(t);((n=o?.keys)==null?void 0:n.includes(e))==!1&&o.keys.push(e)}const M=class{constructor(t,e){c(this,"parser"),c(this,"url"),v&&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 hasLODLevelAvailable(t,e){var r;if(t.isMaterial===!0){for(const s of Object.keys(t)){const a=t[s];if(a.isTexture&&this.hasLODLevelAvailable(a,e))return!0}return!1}else if(t.isGroup===!0){for(const s of t.children)if(s.isMesh===!0&&this.hasLODLevelAvailable(s,e))return!0}let n,o;if(t.isMesh?n=t.geometry:(t.isBufferGeometry||t.isTexture)&&(n=t),n&&(r=n?.userData)!=null&&r.LODS){const s=n.userData.LODS;if(o=this.lodInfos.get(s.key),e===void 0)return o!=null;if(o)return Array.isArray(o.lods)?e<o.lods.length:e===0}return!1}static assignMeshLOD(t,e){var r;if(!t)return Promise.resolve(null);if(t instanceof U||t.isMesh===!0){const n=t.geometry,o=this.getAssignedLODInformation(n);if(!o)return Promise.resolve(null);for(const s of R)(r=s.onBeforeGetLODMesh)==null||r.call(s,t,e);return t["LOD:requested level"]=e,M.getOrLoadLOD(n,e).then(s=>{if(t["LOD:requested level"]===e){if(delete t["LOD:requested level"],Array.isArray(s)){const a=o.index||0;s=s[a]}s&&n!=s&&s instanceof z&&(t.geometry=s,v&&ne(t,"geometry",o.url))}return s}).catch(s=>(console.error("Error loading mesh LOD",t,s),null))}else v&&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 fe||t.isMaterial===!0){const r=t,n=[],o=new Array;if(v&&Q.add(r),r.uniforms&&r.isRawShaderMaterial||r.isShaderMaterial===!0){const s=r;for(const a of Object.keys(s.uniforms)){const i=s.uniforms[a].value;if(i?.isTexture===!0){const l=this.assignTextureLODForSlot(i,e,r,a);n.push(l),o.push(a)}}}else for(const s of Object.keys(r)){const a=r[s];if(a?.isTexture===!0){const i=this.assignTextureLODForSlot(a,e,r,s);n.push(i),o.push(s)}}return Promise.all(n).then(s=>{const a=new Array;for(let i=0;i<s.length;i++){const l=s[i],d=o[i];l&&l.isTexture===!0?a.push({material:r,slot:d,texture:l,level:e}):a.push({material:r,slot:d,texture:null,level:e})}return a})}if(t instanceof k||t.isTexture===!0){const r=t;return this.assignTextureLODForSlot(r,e,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(t,e,r,n){return t?.isTexture!==!0?Promise.resolve(null):M.getOrLoadLOD(t,e).then(o=>{if(Array.isArray(o))return null;if(o?.isTexture===!0){if(o!=t&&(r&&n&&(r[n]=o),v&&n&&r)){const s=this.getAssignedLODInformation(t);s&&ne(r,n,s.url)}return o}else v=="verbose"&&console.warn("No LOD found for",t,e);return null}).catch(o=>(console.error("Error loading LOD",t,o),null))}afterRoot(t){var e,r;return v&&console.log("AFTER",this.url,t),(e=this.parser.json.textures)==null||e.forEach((n,o)=>{if(n!=null&&n.extensions){const s=n?.extensions[I];if(s){let a=!1;for(const i of this.parser.associations.keys())i.isTexture===!0&&this.parser.associations.get(i).textures===o&&(a=!0,M.registerTexture(this.url,i,o,s));a||this.parser.getDependency("texture",o).then(i=>{i&&M.registerTexture(this.url,i,o,s)})}}}),(r=this.parser.json.meshes)==null||r.forEach((n,o)=>{if(n!=null&&n.extensions){const s=n?.extensions[I];if(s&&s.lods){for(const a of this.parser.associations.keys())if(a.isMesh){const i=this.parser.associations.get(a);i.meshes===o&&M.registerMesh(this.url,s.guid,a,s.lods.length,i.primitives,s)}}}}),null}static async getOrLoadLOD(t,e){var r,n,o;const s=v=="verbose",a=t.userData.LODS;if(!a)return null;const i=a?.key;let l;if(t.isTexture===!0){const d=t;d.source&&d.source[J]&&(l=d.source[J])}if(l||(l=M.lodInfos.get(i)),l){if(e>0){let u=!1;const p=Array.isArray(l.lods);if(p&&e>=l.lods.length?u=!0:p||(u=!0),u)return this.lowresCache.get(i)}const d=Array.isArray(l.lods)?l.lods[e].path:l.lods;if(!d)return v&&!l["missing:uri"]&&(l["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+e,l)),null;const h=Le(a.url,d);if(h.endsWith(".glb")||h.endsWith(".gltf")){if(!l.guid)return console.warn("missing pointer for glb/gltf texture",l),null;const u=h+"_"+l.guid,p=this.previouslyLoaded.get(u);if(p!==void 0){s&&console.log(`LOD ${e} was already loading/loaded: ${u}`);let y=await p.catch(m=>(console.error(`Error loading LOD ${e} from ${h}
|
|
2
2
|
`,m),null)),g=!1;if(y==null||(y instanceof k&&t instanceof k?(r=y.image)!=null&&r.data||(n=y.source)!=null&&n.data?y=this.copySettings(t,y):(g=!0,this.previouslyLoaded.delete(u)):y instanceof z&&t instanceof z&&((o=y.attributes.position)!=null&&o.array||(g=!0,this.previouslyLoaded.delete(u)))),!g)return y}const D=l,P=new Promise(async(y,g)=>{const m=new ye;H(m),v&&(await new Promise(L=>setTimeout(L,1e3)),s&&console.warn("Start loading (delayed) "+h,D.guid));let b=h;if(D&&Array.isArray(D.lods)){const L=D.lods[e];L.hash&&(b+="?v="+L.hash)}const x=await m.loadAsync(b).catch(L=>(console.error(`Error loading LOD ${e} from ${h}
|
|
3
|
-
`,L),null));if(!x)return null;const S=x.parser;s&&console.log("Loading finished "+h,D.guid);let _=0;if(x.parser.json.textures){let L=!1;for(const f of x.parser.json.textures){if(f!=null&&f.extensions){const w=f?.extensions[I];if(w!=null&&w.guid&&w.guid===D.guid){L=!0;break}}_++}if(L){let f=await S.getDependency("texture",_);return f&&M.assignLODInformation(a.url,f,i,e,void 0,void 0),s&&console.log('change "'+t.name+'" \u2192 "'+f.name+'"',h,_,f,u),t instanceof k&&(f=this.copySettings(t,f)),f&&(f.guid=D.guid),y(f)}else v&&console.warn("Could not find texture with guid",D.guid)}if(_=0,x.parser.json.meshes){let L=!1;for(const f of x.parser.json.meshes){if(f!=null&&f.extensions){const w=f?.extensions[I];if(w!=null&&w.guid&&w.guid===D.guid){L=!0;break}}_++}if(L){const f=await S.getDependency("mesh",_),w=D;if(s&&console.log(`Loaded Mesh "${f.name}"`,h,_,f,u),f.isMesh===!0){const E=f.geometry;return M.assignLODInformation(a.url,E,i,e,void 0,w.density),y(E)}else{const E=new Array;for(let C=0;C<f.children.length;C++){const W=f.children[C];if(W instanceof U){const j=W.geometry;M.assignLODInformation(a.url,j,i,e,C,w.density),E.push(j)}}return y(E)}}}return y(null)});return this.previouslyLoaded.set(u,P),await P}else if(t instanceof k){s&&console.log("Load texture from uri: "+h);const u=await new ge().loadAsync(h);return u?(u.guid=l.guid,u.flipY=!1,u.needsUpdate=!0,u.colorSpace=t.colorSpace,s&&console.log(l,u)):v&&console.warn("failed loading",h),u}}else v&&console.warn(`Can not load LOD ${e}: no LOD info found for "${i}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,n,o,s){if(!e)return;e.userData||(e.userData={});const a=new ve(t,r,n,o,s);e.userData.LODS=a,e.userData.LOD=n}static getAssignedLODInformation(t){var e;return((e=t?.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return this._copiedTextures.get(t)||(e=e.clone(),this._copiedTextures.set(t,e),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.generateMipmaps=t.generateMipmaps,e)}};let O=M;c(O,"registerTexture",(t,e,r,n)=>{v&&console.log("> Progressive: register texture",r,e.name,e.uuid,e,n),e.source&&(e.source[J]=n);const o=n.guid;M.assignLODInformation(t,e,o,0,0,void 0),M.lodInfos.set(o,n),M.lowresCache.set(o,e)}),c(O,"registerMesh",(t,e,r,n,o,s)=>{var a;v&&console.log("> Progressive: register mesh",o,r.name,s,r.uuid,r);const i=r.geometry;i.userData||(i.userData={}),M.assignLODInformation(t,i,e,n,o,s.density),M.lodInfos.set(e,s);let l=M.lowresCache.get(e);l?l.push(r.geometry):l=[r.geometry],M.lowresCache.set(e,l),n>0&&!re(r)&&se(r,i);for(const d of R)(a=d.onRegisteredNewMesh)==null||a.call(d,r,s)}),c(O,"lodInfos",new Map),c(O,"previouslyLoaded",new Map),c(O,"lowresCache",new Map),c(O,"_copiedTextures",new Map);class ve{constructor(e,r,n,o,s){c(this,"url"),c(this,"key"),c(this,"level"),c(this,"index"),c(this,"density"),this.url=e,this.key=r,this.level=n,o!=null&&(this.index=o),s!=null&&(this.density=s)}}const Z=Y("debugprogressive"),Me=Y("noprogressive"),oe=Symbol("Needle:LODSManager"),T=class{constructor(t){c(this,"renderer"),c(this,"projectionScreenMatrix",new ee),c(this,"cameraFrustrum",new me),c(this,"targetTriangleDensity",2e5),c(this,"updateInterval",0),c(this,"pause",!1),c(this,"_frame",0),c(this,"_originalRender"),c(this,"_sphere",new pe),c(this,"_tempBox",new te),c(this,"_tempBox2",new te),c(this,"tempMatrix",new ee),c(this,"_tempWorldPosition",new B),c(this,"_tempBoxSize",new B),c(this,"_tempBox2Size",new B),this.renderer=t}static getObjectLODState(t){var e;return(e=t.userData)==null?void 0:e.LOD_state}static addPlugin(t){R.push(t)}static removePlugin(t){const e=R.indexOf(t);e>=0&&R.splice(e,1)}static get(t){return t[oe]?t[oe]:new T(t)}enable(){if(this._originalRender)return;let t=0;this._originalRender=this.renderer.render;const e=this;K(this.renderer),this.renderer.render=function(r,n){e.renderer.getRenderTarget()==null&&(t=0,e._frame+=1);const o=e._frame,s=t++;e.onBeforeRender(r,n,s,o),e._originalRender.call(this,r,n),e.onAfterRender(r,n,s,o)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(t,e,r,n){}onAfterRender(t,e,r,n){var o,s;if(this.pause)return;const a=this.renderer.renderLists.get(t,0),i=a.opaque;let l=!0;if(i.length===1){const d=i[0].material;(d.name==="EffectMaterial"||d.name==="CopyShader")&&(l=!1)}if(l){if(Me||this.updateInterval>0&&n%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const d=this.targetTriangleDensity;for(const u of i){if(u.material&&(((o=u.geometry)==null?void 0:o.type)==="BoxGeometry"||((s=u.geometry)==null?void 0:s.type)==="BufferGeometry")&&(u.material.name==="SphericalGaussianBlur"||u.material.name=="BackgroundCubeMaterial"||u.material.name==="CubemapFromEquirect"||u.material.name==="EquirectangularToCubeUV")){Z&&(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 p=u.object;(p instanceof U||p.isMesh)&&this.updateLODs(t,e,p,d)}const h=a.transparent;for(const u of h){const p=u.object;(p instanceof U||p.isMesh)&&this.updateLODs(t,e,p,d)}}}updateLODs(t,e,r,n){var o,s;for(const d of R)(o=d.onBeforeUpdateLOD)==null||o.call(d,this.renderer,t,e,r);let a=r.userData.LOD_state;a||(a=new Oe,r.userData.LOD_state=a);let i=this.calculateLodLevel(e,r,a,n);i=Math.round(i),i>=0&&this.loadProgressiveMeshes(r,i);let l=0;if(r.material){const d=r["DEBUG:LOD"];if(d!=null&&(l=d),Array.isArray(r.material))for(const h of r.material)this.loadProgressiveTextures(h,l);else this.loadProgressiveTextures(r.material,l)}for(const d of R)(s=d.onAfterUpdatedLOD)==null||s.call(d,this.renderer,t,e,r,i);a.lastLodLevel=i}loadProgressiveTextures(t,e){return t&&t.userData&&t.userData.LOD!==e?(t.userData.LOD=e,O.assignTextureLOD(t,e)):Promise.resolve(null)}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t.userData||(t.userData={}),t.userData.LOD!==e){t.userData.LOD=e;const r=t.geometry;return O.assignMeshLOD(t,e).then(n=>(n&&t.userData.LOD==e&&r!=t.geometry,n))}return Promise.resolve(null)}static isInside(t,e){const r=t.min,n=t.max,o=(r.x+n.x)*.5,s=(r.y+n.y)*.5;return this._tempPtInside.set(o,s,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,n){var o;if(!e)return-1;let s=10+1;if(t){if(Z&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const a=O.getMeshLODInformation(e.geometry),i=a?.lods;if(!i||i.length<=0)return 0;if(!((o=this.cameraFrustrum)!=null&&o.intersectsObject(e)))return 99;const l=e.geometry.boundingBox;if(l&&t.isPerspectiveCamera){const d=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 g=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(g))return 0}if(this._tempBox.copy(l),this._tempBox.applyMatrix4(e.matrixWorld),T.isInside(this._tempBox,this.projectionScreenMatrix))return 0;if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&d.fov>70){const g=this._tempBox.min,m=this._tempBox.max;let b=g.x,x=g.y,S=m.x,_=m.y;const L=2,f=1.5,w=(g.x+m.x)*.5,E=(g.y+m.y)*.5;b=(b-w)*L+w,x=(x-E)*L+E,S=(S-w)*L+w,_=(_-E)*L+E;const C=b<0&&S>0?0:Math.min(Math.abs(g.x),Math.abs(m.x)),W=x<0&&_>0?0:Math.min(Math.abs(g.y),Math.abs(m.y)),j=Math.max(C,W);r.lastCentrality=(f-j)*(f-j)*(f-j)}else r.lastCentrality=1;const h=this._tempBox.getSize(this._tempBoxSize);h.multiplyScalar(.5),screen.availHeight>0&&h.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),h.x*=d.aspect;const u=t.matrixWorldInverse,p=this._tempBox2;p.copy(l),p.applyMatrix4(e.matrixWorld),p.applyMatrix4(u);const D=p.getSize(this._tempBox2Size),P=Math.max(D.x,D.y);if(Math.max(h.x,h.y)!=0&&P!=0&&(h.z=D.z/Math.max(D.x,D.y)*Math.max(h.x,h.y)),r.lastScreenCoverage=Math.max(h.x,h.y,h.z),r.lastScreenspaceVolume.copy(h),r.lastScreenCoverage*=r.lastCentrality,Z&&T.debugDrawLine){const g=this.tempMatrix.copy(this.projectionScreenMatrix);g.invert();const m=T.corner0,b=T.corner1,x=T.corner2,S=T.corner3;m.copy(this._tempBox.min),b.copy(this._tempBox.max),b.x=m.x,x.copy(this._tempBox.max),x.y=m.y,S.copy(this._tempBox.max);const _=(m.z+S.z)*.5;m.z=b.z=x.z=S.z=_,m.applyMatrix4(g),b.applyMatrix4(g),x.applyMatrix4(g),S.applyMatrix4(g),T.debugDrawLine(m,b,255),T.debugDrawLine(m,x,255),T.debugDrawLine(b,S,255),T.debugDrawLine(x,S,255)}let y=999;if(i&&r.lastScreenCoverage>0){for(let g=0;g<i.length;g++)if(i[g].density/r.lastScreenCoverage<n){y=g;break}}y<s&&(s=y)}}return s}};let A=T;c(A,"debugDrawLine"),c(A,"corner0",new B),c(A,"corner1",new B),c(A,"corner2",new B),c(A,"corner3",new B),c(A,"_tempPtInside",new B);class Oe{constructor(){c(this,"lastLodLevel",0),c(this,"lastScreenCoverage",0),c(this,"lastScreenspaceVolume",new B),c(this,"lastCentrality",0)}}const ie=Symbol("NEEDLE_mesh_lod"),q=Symbol("NEEDLE_texture_lod");function ae(t){if(!t)return null;let e=null,r=null;for(let n=t;n!=null;n=Object.getPrototypeOf(n)){const o=Object.getOwnPropertySymbols(n),s=o.find(i=>i.toString()=="Symbol(renderer)"),a=o.find(i=>i.toString()=="Symbol(scene)");!e&&s!=null&&(e=t[s].threeRenderer),!r&&a!=null&&(r=t[a])}if(e){console.log("Adding Needle LODs to modelviewer");const n=A.get(e);if(A.addPlugin(new we(t)),n.enable(),r){const o=r.camera||r.traverse(s=>s.type=="PerspectiveCamera")[0];o&&e.render(r,o)}return()=>{n.disable()}}return null}class we{constructor(e){c(this,"modelviewer"),c(this,"_didWarnAboutMissingUrl",!1),this.modelviewer=e}onBeforeUpdateLOD(e,r,n,o){this.tryParseMeshLOD(r,o),this.tryParseTextureLOD(r,o)}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[q]==!0)return;r[q]=!0;const n=this.tryGetCurrentGLTF(e),o=this.getUrl();if(o&&n&&r.material){let s=function(i){var l,d,h;if(i[q]==!0)return;i[q]=!0,i.userData&&(i.userData.LOD=-1);const u=Object.keys(i);for(let p=0;p<u.length;p++){const D=u[p],P=i[D];if(P?.isTexture===!0){const y=(d=(l=P.userData)==null?void 0:l.associations)==null?void 0:d.textures,g=n.parser.json.textures[y];if(!g){console.warn("Texture data not found for texture index "+y);continue}if((h=g?.extensions)!=null&&h[I]){const m=g.extensions[I];m&&o&&O.registerTexture(o,P,m.lods.length,m)}}}};const a=r.material;if(Array.isArray(a))for(const i of a)s(i);else s(a)}}tryParseMeshLOD(e,r){var n,o;if(r[ie]==!0)return;r[ie]=!0;const s=this.getUrl();if(!s)return;const a=(o=(n=r.userData)==null?void 0:n.gltfExtensions)==null?void 0:o[I];if(a&&s){const i=r.uuid;O.registerMesh(s,i,r,0,a.lods.length,a)}}}function be(t,e,r,n){K(e),H(r),r.register(s=>new O(s,t));const o=A.get(e);return n?.enableLODsManager!==!1&&o.enable(),o}document.addEventListener("DOMContentLoaded",()=>{ae(document.querySelector("model-viewer"))});export{I as EXTENSION_NAME,A as LODsManager,O as NEEDLE_progressive,H as addDracoAndKTX2Loaders,K as createLoaders,re as getRaycastMesh,ae as patchModelViewer,De as setDracoDecoderLocation,xe as setKTX2TranscoderLocation,se as setRaycastMesh,be as useNeedleProgressive};
|
|
3
|
+
`,L),null));if(!x)return null;const S=x.parser;s&&console.log("Loading finished "+h,D.guid);let _=0;if(x.parser.json.textures){let L=!1;for(const f of x.parser.json.textures){if(f!=null&&f.extensions){const w=f?.extensions[I];if(w!=null&&w.guid&&w.guid===D.guid){L=!0;break}}_++}if(L){let f=await S.getDependency("texture",_);return f&&M.assignLODInformation(a.url,f,i,e,void 0,void 0),s&&console.log('change "'+t.name+'" \u2192 "'+f.name+'"',h,_,f,u),t instanceof k&&(f=this.copySettings(t,f)),f&&(f.guid=D.guid),y(f)}else v&&console.warn("Could not find texture with guid",D.guid)}if(_=0,x.parser.json.meshes){let L=!1;for(const f of x.parser.json.meshes){if(f!=null&&f.extensions){const w=f?.extensions[I];if(w!=null&&w.guid&&w.guid===D.guid){L=!0;break}}_++}if(L){const f=await S.getDependency("mesh",_),w=D;if(s&&console.log(`Loaded Mesh "${f.name}"`,h,_,f,u),f.isMesh===!0){const E=f.geometry;return M.assignLODInformation(a.url,E,i,e,void 0,w.density),y(E)}else{const E=new Array;for(let C=0;C<f.children.length;C++){const W=f.children[C];if(W instanceof U){const j=W.geometry;M.assignLODInformation(a.url,j,i,e,C,w.density),E.push(j)}}return y(E)}}}return y(null)});return this.previouslyLoaded.set(u,P),await P}else if(t instanceof k){s&&console.log("Load texture from uri: "+h);const u=await new ge().loadAsync(h);return u?(u.guid=l.guid,u.flipY=!1,u.needsUpdate=!0,u.colorSpace=t.colorSpace,s&&console.log(l,u)):v&&console.warn("failed loading",h),u}}else v&&console.warn(`Can not load LOD ${e}: no LOD info found for "${i}" ${t.name}`,t.type);return null}static assignLODInformation(t,e,r,n,o,s){if(!e)return;e.userData||(e.userData={});const a=new ve(t,r,n,o,s);e.userData.LODS=a,e.userData.LOD=n}static getAssignedLODInformation(t){var e;return((e=t?.userData)==null?void 0:e.LODS)||null}static copySettings(t,e){return this._copiedTextures.get(t)||(e=e.clone(),this._copiedTextures.set(t,e),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.generateMipmaps=t.generateMipmaps,e)}};let O=M;c(O,"registerTexture",(t,e,r,n)=>{v&&console.log("> Progressive: register texture",r,e.name,e.uuid,e,n),e.source&&(e.source[J]=n);const o=n.guid;M.assignLODInformation(t,e,o,0,0,void 0),M.lodInfos.set(o,n),M.lowresCache.set(o,e)}),c(O,"registerMesh",(t,e,r,n,o,s)=>{var a;v&&console.log("> Progressive: register mesh",o,r.name,s,r.uuid,r);const i=r.geometry;i.userData||(i.userData={}),M.assignLODInformation(t,i,e,n,o,s.density),M.lodInfos.set(e,s);let l=M.lowresCache.get(e);l?l.push(r.geometry):l=[r.geometry],M.lowresCache.set(e,l),n>0&&!re(r)&&se(r,i);for(const d of R)(a=d.onRegisteredNewMesh)==null||a.call(d,r,s)}),c(O,"lodInfos",new Map),c(O,"previouslyLoaded",new Map),c(O,"lowresCache",new Map),c(O,"_copiedTextures",new Map);class ve{constructor(e,r,n,o,s){c(this,"url"),c(this,"key"),c(this,"level"),c(this,"index"),c(this,"density"),this.url=e,this.key=r,this.level=n,o!=null&&(this.index=o),s!=null&&(this.density=s)}}const Z=Y("debugprogressive"),Me=Y("noprogressive"),oe=Symbol("Needle:LODSManager"),T=class{constructor(t){c(this,"renderer"),c(this,"projectionScreenMatrix",new ee),c(this,"cameraFrustrum",new me),c(this,"targetTriangleDensity",2e5),c(this,"updateInterval",0),c(this,"pause",!1),c(this,"_frame",0),c(this,"_originalRender"),c(this,"_sphere",new pe),c(this,"_tempBox",new te),c(this,"_tempBox2",new te),c(this,"tempMatrix",new ee),c(this,"_tempWorldPosition",new B),c(this,"_tempBoxSize",new B),c(this,"_tempBox2Size",new B),this.renderer=t}static getObjectLODState(t){var e;return(e=t.userData)==null?void 0:e.LOD_state}static addPlugin(t){R.push(t)}static removePlugin(t){const e=R.indexOf(t);e>=0&&R.splice(e,1)}static get(t){return t[oe]?t[oe]:new T(t)}get plugins(){return R}enable(){if(this._originalRender)return;let t=0;this._originalRender=this.renderer.render;const e=this;K(this.renderer),this.renderer.render=function(r,n){e.renderer.getRenderTarget()==null&&(t=0,e._frame+=1);const o=e._frame,s=t++;e.onBeforeRender(r,n,s,o),e._originalRender.call(this,r,n),e.onAfterRender(r,n,s,o)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(t,e,r,n){}onAfterRender(t,e,r,n){var o,s;if(this.pause)return;const a=this.renderer.renderLists.get(t,0),i=a.opaque;let l=!0;if(i.length===1){const d=i[0].material;(d.name==="EffectMaterial"||d.name==="CopyShader")&&(l=!1)}if(l){if(Me||this.updateInterval>0&&n%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const d=this.targetTriangleDensity;for(const u of i){if(u.material&&(((o=u.geometry)==null?void 0:o.type)==="BoxGeometry"||((s=u.geometry)==null?void 0:s.type)==="BufferGeometry")&&(u.material.name==="SphericalGaussianBlur"||u.material.name=="BackgroundCubeMaterial"||u.material.name==="CubemapFromEquirect"||u.material.name==="EquirectangularToCubeUV")){Z&&(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 p=u.object;(p instanceof U||p.isMesh)&&this.updateLODs(t,e,p,d)}const h=a.transparent;for(const u of h){const p=u.object;(p instanceof U||p.isMesh)&&this.updateLODs(t,e,p,d)}}}updateLODs(t,e,r,n){var o,s;for(const d of R)(o=d.onBeforeUpdateLOD)==null||o.call(d,this.renderer,t,e,r);let a=r.userData.LOD_state;a||(a=new Oe,r.userData.LOD_state=a);let i=this.calculateLodLevel(e,r,a,n);i=Math.round(i),i>=0&&this.loadProgressiveMeshes(r,i);let l=0;if(r.material){const d=r["DEBUG:LOD"];if(d!=null&&(l=d),Array.isArray(r.material))for(const h of r.material)this.loadProgressiveTextures(h,l);else this.loadProgressiveTextures(r.material,l)}for(const d of R)(s=d.onAfterUpdatedLOD)==null||s.call(d,this.renderer,t,e,r,i);a.lastLodLevel=i}loadProgressiveTextures(t,e){return t&&t.userData&&t.userData.LOD!==e?(t.userData.LOD=e,O.assignTextureLOD(t,e)):Promise.resolve(null)}loadProgressiveMeshes(t,e){if(!t)return Promise.resolve(null);if(t.userData||(t.userData={}),t.userData.LOD!==e){t.userData.LOD=e;const r=t.geometry;return O.assignMeshLOD(t,e).then(n=>(n&&t.userData.LOD==e&&r!=t.geometry,n))}return Promise.resolve(null)}static isInside(t,e){const r=t.min,n=t.max,o=(r.x+n.x)*.5,s=(r.y+n.y)*.5;return this._tempPtInside.set(o,s,r.z).applyMatrix4(e).z<0}calculateLodLevel(t,e,r,n){var o;if(!e)return-1;let s=10+1;if(t){if(Z&&e["DEBUG:LOD"]!=null)return e["DEBUG:LOD"];const a=O.getMeshLODInformation(e.geometry),i=a?.lods;if(!i||i.length<=0)return 0;if(!((o=this.cameraFrustrum)!=null&&o.intersectsObject(e)))return 99;const l=e.geometry.boundingBox;if(l&&t.isPerspectiveCamera){const d=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 g=t.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(g))return 0}if(this._tempBox.copy(l),this._tempBox.applyMatrix4(e.matrixWorld),T.isInside(this._tempBox,this.projectionScreenMatrix))return 0;if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&d.fov>70){const g=this._tempBox.min,m=this._tempBox.max;let b=g.x,x=g.y,S=m.x,_=m.y;const L=2,f=1.5,w=(g.x+m.x)*.5,E=(g.y+m.y)*.5;b=(b-w)*L+w,x=(x-E)*L+E,S=(S-w)*L+w,_=(_-E)*L+E;const C=b<0&&S>0?0:Math.min(Math.abs(g.x),Math.abs(m.x)),W=x<0&&_>0?0:Math.min(Math.abs(g.y),Math.abs(m.y)),j=Math.max(C,W);r.lastCentrality=(f-j)*(f-j)*(f-j)}else r.lastCentrality=1;const h=this._tempBox.getSize(this._tempBoxSize);h.multiplyScalar(.5),screen.availHeight>0&&h.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),h.x*=d.aspect;const u=t.matrixWorldInverse,p=this._tempBox2;p.copy(l),p.applyMatrix4(e.matrixWorld),p.applyMatrix4(u);const D=p.getSize(this._tempBox2Size),P=Math.max(D.x,D.y);if(Math.max(h.x,h.y)!=0&&P!=0&&(h.z=D.z/Math.max(D.x,D.y)*Math.max(h.x,h.y)),r.lastScreenCoverage=Math.max(h.x,h.y,h.z),r.lastScreenspaceVolume.copy(h),r.lastScreenCoverage*=r.lastCentrality,Z&&T.debugDrawLine){const g=this.tempMatrix.copy(this.projectionScreenMatrix);g.invert();const m=T.corner0,b=T.corner1,x=T.corner2,S=T.corner3;m.copy(this._tempBox.min),b.copy(this._tempBox.max),b.x=m.x,x.copy(this._tempBox.max),x.y=m.y,S.copy(this._tempBox.max);const _=(m.z+S.z)*.5;m.z=b.z=x.z=S.z=_,m.applyMatrix4(g),b.applyMatrix4(g),x.applyMatrix4(g),S.applyMatrix4(g),T.debugDrawLine(m,b,255),T.debugDrawLine(m,x,255),T.debugDrawLine(b,S,255),T.debugDrawLine(x,S,255)}let y=999;if(i&&r.lastScreenCoverage>0){for(let g=0;g<i.length;g++)if(i[g].density/r.lastScreenCoverage<n){y=g;break}}y<s&&(s=y)}}return s}};let A=T;c(A,"debugDrawLine"),c(A,"corner0",new B),c(A,"corner1",new B),c(A,"corner2",new B),c(A,"corner3",new B),c(A,"_tempPtInside",new B);class Oe{constructor(){c(this,"lastLodLevel",0),c(this,"lastScreenCoverage",0),c(this,"lastScreenspaceVolume",new B),c(this,"lastCentrality",0)}}const ie=Symbol("NEEDLE_mesh_lod"),q=Symbol("NEEDLE_texture_lod");function ae(t){if(!t)return null;let e=null,r=null;for(let n=t;n!=null;n=Object.getPrototypeOf(n)){const o=Object.getOwnPropertySymbols(n),s=o.find(i=>i.toString()=="Symbol(renderer)"),a=o.find(i=>i.toString()=="Symbol(scene)");!e&&s!=null&&(e=t[s].threeRenderer),!r&&a!=null&&(r=t[a])}if(e){console.log("Adding Needle LODs to modelviewer");const n=A.get(e);if(A.addPlugin(new we(t)),n.enable(),r){const o=r.camera||r.traverse(s=>s.type=="PerspectiveCamera")[0];o&&e.render(r,o)}return()=>{n.disable()}}return null}class we{constructor(e){c(this,"modelviewer"),c(this,"_didWarnAboutMissingUrl",!1),this.modelviewer=e}onBeforeUpdateLOD(e,r,n,o){this.tryParseMeshLOD(r,o),this.tryParseTextureLOD(r,o)}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[q]==!0)return;r[q]=!0;const n=this.tryGetCurrentGLTF(e),o=this.getUrl();if(o&&n&&r.material){let s=function(i){var l,d,h;if(i[q]==!0)return;i[q]=!0,i.userData&&(i.userData.LOD=-1);const u=Object.keys(i);for(let p=0;p<u.length;p++){const D=u[p],P=i[D];if(P?.isTexture===!0){const y=(d=(l=P.userData)==null?void 0:l.associations)==null?void 0:d.textures,g=n.parser.json.textures[y];if(!g){console.warn("Texture data not found for texture index "+y);continue}if((h=g?.extensions)!=null&&h[I]){const m=g.extensions[I];m&&o&&O.registerTexture(o,P,m.lods.length,m)}}}};const a=r.material;if(Array.isArray(a))for(const i of a)s(i);else s(a)}}tryParseMeshLOD(e,r){var n,o;if(r[ie]==!0)return;r[ie]=!0;const s=this.getUrl();if(!s)return;const a=(o=(n=r.userData)==null?void 0:n.gltfExtensions)==null?void 0:o[I];if(a&&s){const i=r.uuid;O.registerMesh(s,i,r,0,a.lods.length,a)}}}function be(t,e,r,n){K(e),H(r),r.register(s=>new O(s,t));const o=A.get(e);return n?.enableLODsManager!==!1&&o.enable(),o}document.addEventListener("DOMContentLoaded",()=>{ae(document.querySelector("model-viewer"))});export{I as EXTENSION_NAME,A as LODsManager,O as NEEDLE_progressive,H as addDracoAndKTX2Loaders,K as createLoaders,re as getRaycastMesh,ae as patchModelViewer,De as setDracoDecoderLocation,xe as setKTX2TranscoderLocation,se as setRaycastMesh,be as useNeedleProgressive};
|
package/gltf-progressive.umd.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var ae=Object.defineProperty;var le=(a,e,t)=>e in a?ae(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var u=(a,e,t)=>(le(a,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ce=require("three/examples/jsm/libs/meshopt_decoder.module.js"),ue=require("three/examples/jsm/loaders/DRACOLoader.js"),fe=require("three/examples/jsm/loaders/KTX2Loader.js"),g=require("three"),de=require("three/examples/jsm/loaders/GLTFLoader.js");let q="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",J="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(q+"draco_decoder.js",{method:"head"}).catch(a=>{q="./include/draco/",J="./include/ktx2/"});function ge(a){q=a}function he(a){J=a}let N,Y,U;function Q(a){N||(N=new ue.DRACOLoader,N.setDecoderPath(q),N.setDecoderConfig({type:"js"})),U||(U=new fe.KTX2Loader,U.setTranscoderPath(J)),Y||(Y=ce.MeshoptDecoder),a?U.detectSupport(a):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function Z(a){a.dracoLoader||a.setDRACOLoader(N),a.ktx2Loader||a.setKTX2Loader(U),a.meshoptDecoder||a.setMeshoptDecoder(Y)}function j(a){const t=new URL(window.location.href).searchParams.get(a);return t==null||t==="0"||t==="false"?!1:t===""?!0:t}function pe(a,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||a===void 0)return e;const t=a.lastIndexOf("/");if(t>=0){const r=a.substring(0,t+1);for(;r.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return r+e}return e}function se(a){var e;return((e=a.userData)==null?void 0:e["needle:raycast-mesh"])instanceof g.BufferGeometry?a.userData["needle:raycast-mesh"]:null}function ie(a,e){(a.type==="Mesh"||a.type==="SkinnedMesh")&&(a.userData||(a.userData={}),a.userData["needle:raycast-mesh"]=e)}const
|
|
1
|
+
"use strict";var ae=Object.defineProperty;var le=(a,e,t)=>e in a?ae(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var u=(a,e,t)=>(le(a,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ce=require("three/examples/jsm/libs/meshopt_decoder.module.js"),ue=require("three/examples/jsm/loaders/DRACOLoader.js"),fe=require("three/examples/jsm/loaders/KTX2Loader.js"),g=require("three"),de=require("three/examples/jsm/loaders/GLTFLoader.js");let q="https://www.gstatic.com/draco/versioned/decoders/1.4.1/",J="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/";fetch(q+"draco_decoder.js",{method:"head"}).catch(a=>{q="./include/draco/",J="./include/ktx2/"});function ge(a){q=a}function he(a){J=a}let N,Y,U;function Q(a){N||(N=new ue.DRACOLoader,N.setDecoderPath(q),N.setDecoderConfig({type:"js"})),U||(U=new fe.KTX2Loader,U.setTranscoderPath(J)),Y||(Y=ce.MeshoptDecoder),a?U.detectSupport(a):console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures will probably fail")}function Z(a){a.dracoLoader||a.setDRACOLoader(N),a.ktx2Loader||a.setKTX2Loader(U),a.meshoptDecoder||a.setMeshoptDecoder(Y)}function j(a){const t=new URL(window.location.href).searchParams.get(a);return t==null||t==="0"||t==="false"?!1:t===""?!0:t}function pe(a,e){if(e===void 0||e.startsWith("./")||e.startsWith("http")||a===void 0)return e;const t=a.lastIndexOf("/");if(t>=0){const r=a.substring(0,t+1);for(;r.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return r+e}return e}function se(a){var e;return((e=a.userData)==null?void 0:e["needle:raycast-mesh"])instanceof g.BufferGeometry?a.userData["needle:raycast-mesh"]:null}function ie(a,e){(a.type==="Mesh"||a.type==="SkinnedMesh")&&(a.userData||(a.userData={}),a.userData["needle:raycast-mesh"]=e)}const G=new Array,R="NEEDLE_progressive",T=j("debugprogressive"),$=Symbol("needle-progressive-texture"),z=new Map,H=new Set;if(T){let a=function(){e+=1,console.log("Toggle LOD level",e,z),z.forEach((i,n)=>{for(const s of i.keys){const o=n[s];if(o.isBufferGeometry===!0){const l=v.getMeshLODInformation(o),h=l?Math.min(e,l.lods.length):0;n["DEBUG:LOD"]=e,v.assignMeshLOD(n,h),l&&(t=Math.max(t,l.lods.length-1))}else if(n.isMaterial===!0){n["DEBUG:LOD"]=e,v.assignTextureLOD(n,e);break}}}),e>=t&&(e=-1)},e=-1,t=2,r=!1;window.addEventListener("keyup",i=>{i.key==="p"&&a(),i.key==="w"&&(r=!r,H&&H.forEach(n=>{n.name!="BackgroundCubeMaterial"&&"wireframe"in n&&(n.wireframe=r)}))})}function ee(a,e,t){var i;if(!T)return;z.has(a)||z.set(a,{keys:[],sourceId:t});const r=z.get(a);((i=r==null?void 0:r.keys)==null?void 0:i.includes(e))==!1&&r.keys.push(e)}const O=class{constructor(e,t){u(this,"parser");u(this,"url");T&&console.log("Progressive extension registered for",t),this.parser=e,this.url=t}get name(){return R}static getMeshLODInformation(e){const t=this.getAssignedLODInformation(e);return t!=null&&t.key?this.lodInfos.get(t.key):null}static hasLODLevelAvailable(e,t){var n;if(e.isMaterial===!0){for(const s of Object.keys(e)){const o=e[s];if(o.isTexture&&this.hasLODLevelAvailable(o,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&&(n=r==null?void 0:r.userData)!=null&&n.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 g.Mesh||e.isMesh===!0){const i=e.geometry,n=this.getAssignedLODInformation(i);if(!n)return Promise.resolve(null);for(const s of G)(r=s.onBeforeGetLODMesh)==null||r.call(s,e,t);return e["LOD:requested level"]=t,O.getOrLoadLOD(i,t).then(s=>{if(e["LOD:requested level"]===t){if(delete e["LOD:requested level"],Array.isArray(s)){const o=n.index||0;s=s[o]}s&&i!=s&&s instanceof g.BufferGeometry&&(e.geometry=s,T&&ee(e,"geometry",n.url))}return s}).catch(s=>(console.error("Error loading mesh LOD",e,s),null))}else T&&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 g.Material||e.isMaterial===!0){const r=e,i=[],n=new Array;if(T&&H.add(r),r.uniforms&&r.isRawShaderMaterial||r.isShaderMaterial===!0){const s=r;for(const o of Object.keys(s.uniforms)){const l=s.uniforms[o].value;if((l==null?void 0:l.isTexture)===!0){const h=this.assignTextureLODForSlot(l,t,r,o);i.push(h),n.push(o)}}}else for(const s of Object.keys(r)){const o=r[s];if((o==null?void 0:o.isTexture)===!0){const l=this.assignTextureLODForSlot(o,t,r,s);i.push(l),n.push(s)}}return Promise.all(i).then(s=>{const o=new Array;for(let l=0;l<s.length;l++){const h=s[l],f=n[l];h&&h.isTexture===!0?o.push({material:r,slot:f,texture:h,level:t}):o.push({material:r,slot:f,texture:null,level:t})}return o})}if(e instanceof g.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):O.getOrLoadLOD(e,t).then(n=>{if(Array.isArray(n))return null;if((n==null?void 0:n.isTexture)===!0){if(n!=e&&(r&&i&&(r[i]=n),T&&i&&r)){const s=this.getAssignedLODInformation(e);s&&ee(r,i,s.url)}return n}else T=="verbose"&&console.warn("No LOD found for",e,t);return null}).catch(n=>(console.error("Error loading LOD",e,n),null))}afterRoot(e){var t,r;return T&&console.log("AFTER",this.url,e),(t=this.parser.json.textures)==null||t.forEach((i,n)=>{if(i!=null&&i.extensions){const s=i==null?void 0:i.extensions[R];if(s){let o=!1;for(const l of this.parser.associations.keys())l.isTexture===!0&&this.parser.associations.get(l).textures===n&&(o=!0,O.registerTexture(this.url,l,n,s));o||this.parser.getDependency("texture",n).then(l=>{l&&O.registerTexture(this.url,l,n,s)})}}}),(r=this.parser.json.meshes)==null||r.forEach((i,n)=>{if(i!=null&&i.extensions){const s=i==null?void 0:i.extensions[R];if(s&&s.lods){for(const o of this.parser.associations.keys())if(o.isMesh){const l=this.parser.associations.get(o);l.meshes===n&&O.registerMesh(this.url,s.guid,o,s.lods.length,l.primitives,s)}}}}),null}static async getOrLoadLOD(e,t){var o,l,h;const r=T=="verbose",i=e.userData.LODS;if(!i)return null;const n=i==null?void 0:i.key;let s;if(e.isTexture===!0){const f=e;f.source&&f.source[$]&&(s=f.source[$])}if(s||(s=O.lodInfos.get(n)),s){if(t>0){let c=!1;const p=Array.isArray(s.lods);if(p&&t>=s.lods.length?c=!0:p||(c=!0),c)return this.lowresCache.get(n)}const f=Array.isArray(s.lods)?s.lods[t].path:s.lods;if(!f)return T&&!s["missing:uri"]&&(s["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+t,s)),null;const y=pe(i.url,f);if(y.endsWith(".glb")||y.endsWith(".gltf")){if(!s.guid)return console.warn("missing pointer for glb/gltf texture",s),null;const c=y+"_"+s.guid,p=this.previouslyLoaded.get(c);if(p!==void 0){r&&console.log(`LOD ${t} was already loading/loaded: ${c}`);let M=await p.catch(F=>(console.error(`Error loading LOD ${t} from ${y}
|
|
2
2
|
`,F),null)),k=!1;if(M==null||(M instanceof g.Texture&&e instanceof g.Texture?(o=M.image)!=null&&o.data||(l=M.source)!=null&&l.data?M=this.copySettings(e,M):(k=!0,this.previouslyLoaded.delete(c)):M instanceof g.BufferGeometry&&e instanceof g.BufferGeometry&&((h=M.attributes.position)!=null&&h.array||(k=!0,this.previouslyLoaded.delete(c)))),!k)return M}const D=s,b=new Promise(async(M,k)=>{const F=new de.GLTFLoader;Z(F),T&&(await new Promise(L=>setTimeout(L,1e3)),r&&console.warn("Start loading (delayed) "+y,D.guid));let x=y;if(D&&Array.isArray(D.lods)){const L=D.lods[t];L.hash&&(x+="?v="+L.hash)}const m=await F.loadAsync(x).catch(L=>(console.error(`Error loading LOD ${t} from ${y}
|
|
3
|
-
`,L),null));if(!m)return null;const P=m.parser;r&&console.log("Loading finished "+y,D.guid);let w=0;if(m.parser.json.textures){let L=!1;for(const d of m.parser.json.textures){if(d!=null&&d.extensions){const S=d==null?void 0:d.extensions[R];if(S!=null&&S.guid&&S.guid===D.guid){L=!0;break}}w++}if(L){let d=await P.getDependency("texture",w);return d&&O.assignLODInformation(i.url,d,n,t,void 0,void 0),r&&console.log('change "'+e.name+'" → "'+d.name+'"',y,w,d,c),e instanceof g.Texture&&(d=this.copySettings(e,d)),d&&(d.guid=D.guid),M(d)}else T&&console.warn("Could not find texture with guid",D.guid)}if(w=0,m.parser.json.meshes){let L=!1;for(const d of m.parser.json.meshes){if(d!=null&&d.extensions){const S=d==null?void 0:d.extensions[R];if(S!=null&&S.guid&&S.guid===D.guid){L=!0;break}}w++}if(L){const d=await P.getDependency("mesh",w),S=D;if(r&&console.log(`Loaded Mesh "${d.name}"`,y,w,d,c),d.isMesh===!0){const B=d.geometry;return O.assignLODInformation(i.url,B,n,t,void 0,S.density),M(B)}else{const B=new Array;for(let E=0;E<d.children.length;E++){const G=d.children[E];if(G instanceof g.Mesh){const W=G.geometry;O.assignLODInformation(i.url,W,n,t,E,S.density),B.push(W)}}return M(B)}}}return M(null)});return this.previouslyLoaded.set(c,b),await b}else if(e instanceof g.Texture){r&&console.log("Load texture from uri: "+y);const p=await new g.TextureLoader().loadAsync(y);return p?(p.guid=s.guid,p.flipY=!1,p.needsUpdate=!0,p.colorSpace=e.colorSpace,r&&console.log(s,p)):T&&console.warn("failed loading",y),p}}else T&&console.warn(`Can not load LOD ${t}: no LOD info found for "${n}" ${e.name}`,e.type);return null}static assignLODInformation(e,t,r,i,n,s){if(!t)return;t.userData||(t.userData={});const o=new ye(e,r,i,n,s);t.userData.LODS=o,t.userData.LOD=i}static getAssignedLODInformation(e){var t;return((t=e==null?void 0:e.userData)==null?void 0:t.LODS)||null}static copySettings(e,t){const r=this._copiedTextures.get(e);return r||(t=t.clone(),this._copiedTextures.set(e,t),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.generateMipmaps=e.generateMipmaps,t)}};let v=O;u(v,"registerTexture",(e,t,r,i)=>{T&&console.log("> Progressive: register texture",r,t.name,t.uuid,t,i),t.source&&(t.source[$]=i);const n=i.guid;O.assignLODInformation(e,t,n,0,0,void 0),O.lodInfos.set(n,i),O.lowresCache.set(n,t)}),u(v,"registerMesh",(e,t,r,i,n,s)=>{var h;T&&console.log("> Progressive: register mesh",n,r.name,s,r.uuid,r);const o=r.geometry;o.userData||(o.userData={}),O.assignLODInformation(e,o,t,i,n,s.density),O.lodInfos.set(t,s);let l=O.lowresCache.get(t);l?l.push(r.geometry):l=[r.geometry],O.lowresCache.set(t,l),i>0&&!se(r)&&ie(r,o);for(const f of I)(h=f.onRegisteredNewMesh)==null||h.call(f,r,s)}),u(v,"lodInfos",new Map),u(v,"previouslyLoaded",new Map),u(v,"lowresCache",new Map),u(v,"_copiedTextures",new Map);class ye{constructor(e,t,r,i,n){u(this,"url");u(this,"key");u(this,"level");u(this,"index");u(this,"density");this.url=e,this.key=t,this.level=r,i!=null&&(this.index=i),n!=null&&(this.density=n)}}const K=j("debugprogressive"),me=j("noprogressive"),te=Symbol("Needle:LODSManager"),A=class{constructor(e){u(this,"renderer");u(this,"projectionScreenMatrix",new g.Matrix4);u(this,"cameraFrustrum",new g.Frustum);u(this,"targetTriangleDensity",2e5);u(this,"updateInterval",0);u(this,"pause",!1);u(this,"_frame",0);u(this,"_originalRender");u(this,"_sphere",new g.Sphere);u(this,"_tempBox",new g.Box3);u(this,"_tempBox2",new g.Box3);u(this,"tempMatrix",new g.Matrix4);u(this,"_tempWorldPosition",new g.Vector3);u(this,"_tempBoxSize",new g.Vector3);u(this,"_tempBox2Size",new g.Vector3);this.renderer=e}static getObjectLODState(e){var t;return(t=e.userData)==null?void 0:t.LOD_state}static addPlugin(e){I.push(e)}static removePlugin(e){const t=I.indexOf(e);t>=0&&I.splice(t,1)}static get(e){return e[te]?e[te]:new A(e)}enable(){if(this._originalRender)return;let e=0;this._originalRender=this.renderer.render;const t=this;Q(this.renderer),this.renderer.render=function(r,i){t.renderer.getRenderTarget()==null&&(e=0,t._frame+=1);const s=t._frame,o=e++;t.onBeforeRender(r,i,o,s),t._originalRender.call(this,r,i),t.onAfterRender(r,i,o,s)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(e,t,r,i){}onAfterRender(e,t,r,i){var l,h;if(this.pause)return;const n=this.renderer.renderLists.get(e,0),s=n.opaque;let o=!0;if(s.length===1){const f=s[0].material;(f.name==="EffectMaterial"||f.name==="CopyShader")&&(o=!1)}if(o){if(me||this.updateInterval>0&&i%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const f=this.targetTriangleDensity;for(const c of s){if(c.material&&(((l=c.geometry)==null?void 0:l.type)==="BoxGeometry"||((h=c.geometry)==null?void 0:h.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){K&&(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 p=c.object;(p instanceof g.Mesh||p.isMesh)&&this.updateLODs(e,t,p,f)}const y=n.transparent;for(const c of y){const p=c.object;(p instanceof g.Mesh||p.isMesh)&&this.updateLODs(e,t,p,f)}}}updateLODs(e,t,r,i){var l,h;for(const f of I)(l=f.onBeforeUpdateLOD)==null||l.call(f,this.renderer,e,t,r);let n=r.userData.LOD_state;n||(n=new Le,r.userData.LOD_state=n);let s=this.calculateLodLevel(t,r,n,i);s=Math.round(s),s>=0&&this.loadProgressiveMeshes(r,s);let o=0;if(r.material){const f=r["DEBUG:LOD"];if(f!=null&&(o=f),Array.isArray(r.material))for(const y of r.material)this.loadProgressiveTextures(y,o);else this.loadProgressiveTextures(r.material,o)}for(const f of I)(h=f.onAfterUpdatedLOD)==null||h.call(f,this.renderer,e,t,r,s);n.lastLodLevel=s}loadProgressiveTextures(e,t){return e&&e.userData&&e.userData.LOD!==t?(e.userData.LOD=t,v.assignTextureLOD(e,t)):Promise.resolve(null)}loadProgressiveMeshes(e,t){if(!e)return Promise.resolve(null);if(e.userData||(e.userData={}),e.userData.LOD!==t){e.userData.LOD=t;const r=e.geometry;return v.assignMeshLOD(e,t).then(i=>(i&&e.userData.LOD==t&&r!=e.geometry,i))}return Promise.resolve(null)}static isInside(e,t){const r=e.min,i=e.max,n=(r.x+i.x)*.5,s=(r.y+i.y)*.5;return this._tempPtInside.set(n,s,r.z).applyMatrix4(t).z<0}calculateLodLevel(e,t,r,i){var o;if(!t)return-1;let s=10+1;if(e){if(K&&t["DEBUG:LOD"]!=null)return t["DEBUG:LOD"];const l=v.getMeshLODInformation(t.geometry),h=l==null?void 0:l.lods;if(!h||h.length<=0)return 0;if(!((o=this.cameraFrustrum)!=null&&o.intersectsObject(t)))return 99;const f=t.geometry.boundingBox;if(f&&e.isPerspectiveCamera){const y=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 x=e.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(x))return 0}if(this._tempBox.copy(f),this._tempBox.applyMatrix4(t.matrixWorld),A.isInside(this._tempBox,this.projectionScreenMatrix))return 0;if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&y.fov>70){const x=this._tempBox.min,m=this._tempBox.max;let P=x.x,w=x.y,L=m.x,d=m.y;const S=2,B=1.5,E=(x.x+m.x)*.5,G=(x.y+m.y)*.5;P=(P-E)*S+E,w=(w-G)*S+G,L=(L-E)*S+E,d=(d-G)*S+G;const W=P<0&&L>0?0:Math.min(Math.abs(x.x),Math.abs(m.x)),oe=w<0&&d>0?0:Math.min(Math.abs(x.y),Math.abs(m.y)),X=Math.max(W,oe);r.lastCentrality=(B-X)*(B-X)*(B-X)}else r.lastCentrality=1;const c=this._tempBox.getSize(this._tempBoxSize);c.multiplyScalar(.5),screen.availHeight>0&&c.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),c.x*=y.aspect;const p=e.matrixWorldInverse,D=this._tempBox2;D.copy(f),D.applyMatrix4(t.matrixWorld),D.applyMatrix4(p);const b=D.getSize(this._tempBox2Size),C=Math.max(b.x,b.y);if(Math.max(c.x,c.y)!=0&&C!=0&&(c.z=b.z/Math.max(b.x,b.y)*Math.max(c.x,c.y)),r.lastScreenCoverage=Math.max(c.x,c.y,c.z),r.lastScreenspaceVolume.copy(c),r.lastScreenCoverage*=r.lastCentrality,K&&A.debugDrawLine){const x=this.tempMatrix.copy(this.projectionScreenMatrix);x.invert();const m=A.corner0,P=A.corner1,w=A.corner2,L=A.corner3;m.copy(this._tempBox.min),P.copy(this._tempBox.max),P.x=m.x,w.copy(this._tempBox.max),w.y=m.y,L.copy(this._tempBox.max);const d=(m.z+L.z)*.5;m.z=P.z=w.z=L.z=d,m.applyMatrix4(x),P.applyMatrix4(x),w.applyMatrix4(x),L.applyMatrix4(x),A.debugDrawLine(m,P,255),A.debugDrawLine(m,w,255),A.debugDrawLine(P,L,255),A.debugDrawLine(w,L,255)}let k=999;if(h&&r.lastScreenCoverage>0){for(let x=0;x<h.length;x++)if(h[x].density/r.lastScreenCoverage<i){k=x;break}}k<s&&(s=k)}}return s}};let _=A;u(_,"debugDrawLine"),u(_,"corner0",new g.Vector3),u(_,"corner1",new g.Vector3),u(_,"corner2",new g.Vector3),u(_,"corner3",new g.Vector3),u(_,"_tempPtInside",new g.Vector3);class Le{constructor(){u(this,"lastLodLevel",0);u(this,"lastScreenCoverage",0);u(this,"lastScreenspaceVolume",new g.Vector3);u(this,"lastCentrality",0)}}const re=Symbol("NEEDLE_mesh_lod"),V=Symbol("NEEDLE_texture_lod");function ne(a){if(!a)return null;let e=null,t=null;for(let r=a;r!=null;r=Object.getPrototypeOf(r)){const i=Object.getOwnPropertySymbols(r),n=i.find(o=>o.toString()=="Symbol(renderer)"),s=i.find(o=>o.toString()=="Symbol(scene)");!e&&n!=null&&(e=a[n].threeRenderer),!t&&s!=null&&(t=a[s])}if(e){console.log("Adding Needle LODs to modelviewer");const r=_.get(e);if(_.addPlugin(new De(a)),r.enable(),t){const i=t.camera||t.traverse(n=>n.type=="PerspectiveCamera")[0];i&&e.render(t,i)}return()=>{r.disable()}}return null}class De{constructor(e){u(this,"modelviewer");u(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[V]==!0)return;t[V]=!0;const r=this.tryGetCurrentGLTF(e),i=this.getUrl();if(i&&r&&t.material){let n=function(o){var h,f,y;if(o[V]==!0)return;o[V]=!0,o.userData&&(o.userData.LOD=-1);const l=Object.keys(o);for(let c=0;c<l.length;c++){const p=l[c],D=o[p];if((D==null?void 0:D.isTexture)===!0){const b=(f=(h=D.userData)==null?void 0:h.associations)==null?void 0:f.textures,C=r.parser.json.textures[b];if(!C){console.warn("Texture data not found for texture index "+b);continue}if((y=C==null?void 0:C.extensions)!=null&&y[R]){const M=C.extensions[R];M&&i&&v.registerTexture(i,D,M.lods.length,M)}}}};const s=t.material;if(Array.isArray(s))for(const o of s)n(o);else n(s)}}tryParseMeshLOD(e,t){var n,s;if(t[re]==!0)return;t[re]=!0;const r=this.getUrl();if(!r)return;const i=(s=(n=t.userData)==null?void 0:n.gltfExtensions)==null?void 0:s[R];if(i&&r){const o=t.uuid;v.registerMesh(r,o,t,0,i.lods.length,i)}}}function xe(a,e,t,r){Q(e),Z(t),t.register(n=>new v(n,a));const i=_.get(e);return(r==null?void 0:r.enableLODsManager)!==!1&&i.enable(),i}document.addEventListener("DOMContentLoaded",()=>{ne(document.querySelector("model-viewer"))});exports.EXTENSION_NAME=R;exports.LODsManager=_;exports.NEEDLE_progressive=v;exports.addDracoAndKTX2Loaders=Z;exports.createLoaders=Q;exports.getRaycastMesh=se;exports.patchModelViewer=ne;exports.setDracoDecoderLocation=ge;exports.setKTX2TranscoderLocation=he;exports.setRaycastMesh=ie;exports.useNeedleProgressive=xe;
|
|
3
|
+
`,L),null));if(!m)return null;const P=m.parser;r&&console.log("Loading finished "+y,D.guid);let w=0;if(m.parser.json.textures){let L=!1;for(const d of m.parser.json.textures){if(d!=null&&d.extensions){const S=d==null?void 0:d.extensions[R];if(S!=null&&S.guid&&S.guid===D.guid){L=!0;break}}w++}if(L){let d=await P.getDependency("texture",w);return d&&O.assignLODInformation(i.url,d,n,t,void 0,void 0),r&&console.log('change "'+e.name+'" → "'+d.name+'"',y,w,d,c),e instanceof g.Texture&&(d=this.copySettings(e,d)),d&&(d.guid=D.guid),M(d)}else T&&console.warn("Could not find texture with guid",D.guid)}if(w=0,m.parser.json.meshes){let L=!1;for(const d of m.parser.json.meshes){if(d!=null&&d.extensions){const S=d==null?void 0:d.extensions[R];if(S!=null&&S.guid&&S.guid===D.guid){L=!0;break}}w++}if(L){const d=await P.getDependency("mesh",w),S=D;if(r&&console.log(`Loaded Mesh "${d.name}"`,y,w,d,c),d.isMesh===!0){const B=d.geometry;return O.assignLODInformation(i.url,B,n,t,void 0,S.density),M(B)}else{const B=new Array;for(let E=0;E<d.children.length;E++){const I=d.children[E];if(I instanceof g.Mesh){const W=I.geometry;O.assignLODInformation(i.url,W,n,t,E,S.density),B.push(W)}}return M(B)}}}return M(null)});return this.previouslyLoaded.set(c,b),await b}else if(e instanceof g.Texture){r&&console.log("Load texture from uri: "+y);const p=await new g.TextureLoader().loadAsync(y);return p?(p.guid=s.guid,p.flipY=!1,p.needsUpdate=!0,p.colorSpace=e.colorSpace,r&&console.log(s,p)):T&&console.warn("failed loading",y),p}}else T&&console.warn(`Can not load LOD ${t}: no LOD info found for "${n}" ${e.name}`,e.type);return null}static assignLODInformation(e,t,r,i,n,s){if(!t)return;t.userData||(t.userData={});const o=new ye(e,r,i,n,s);t.userData.LODS=o,t.userData.LOD=i}static getAssignedLODInformation(e){var t;return((t=e==null?void 0:e.userData)==null?void 0:t.LODS)||null}static copySettings(e,t){const r=this._copiedTextures.get(e);return r||(t=t.clone(),this._copiedTextures.set(e,t),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.generateMipmaps=e.generateMipmaps,t)}};let v=O;u(v,"registerTexture",(e,t,r,i)=>{T&&console.log("> Progressive: register texture",r,t.name,t.uuid,t,i),t.source&&(t.source[$]=i);const n=i.guid;O.assignLODInformation(e,t,n,0,0,void 0),O.lodInfos.set(n,i),O.lowresCache.set(n,t)}),u(v,"registerMesh",(e,t,r,i,n,s)=>{var h;T&&console.log("> Progressive: register mesh",n,r.name,s,r.uuid,r);const o=r.geometry;o.userData||(o.userData={}),O.assignLODInformation(e,o,t,i,n,s.density),O.lodInfos.set(t,s);let l=O.lowresCache.get(t);l?l.push(r.geometry):l=[r.geometry],O.lowresCache.set(t,l),i>0&&!se(r)&&ie(r,o);for(const f of G)(h=f.onRegisteredNewMesh)==null||h.call(f,r,s)}),u(v,"lodInfos",new Map),u(v,"previouslyLoaded",new Map),u(v,"lowresCache",new Map),u(v,"_copiedTextures",new Map);class ye{constructor(e,t,r,i,n){u(this,"url");u(this,"key");u(this,"level");u(this,"index");u(this,"density");this.url=e,this.key=t,this.level=r,i!=null&&(this.index=i),n!=null&&(this.density=n)}}const K=j("debugprogressive"),me=j("noprogressive"),te=Symbol("Needle:LODSManager"),A=class{constructor(e){u(this,"renderer");u(this,"projectionScreenMatrix",new g.Matrix4);u(this,"cameraFrustrum",new g.Frustum);u(this,"targetTriangleDensity",2e5);u(this,"updateInterval",0);u(this,"pause",!1);u(this,"_frame",0);u(this,"_originalRender");u(this,"_sphere",new g.Sphere);u(this,"_tempBox",new g.Box3);u(this,"_tempBox2",new g.Box3);u(this,"tempMatrix",new g.Matrix4);u(this,"_tempWorldPosition",new g.Vector3);u(this,"_tempBoxSize",new g.Vector3);u(this,"_tempBox2Size",new g.Vector3);this.renderer=e}static getObjectLODState(e){var t;return(t=e.userData)==null?void 0:t.LOD_state}static addPlugin(e){G.push(e)}static removePlugin(e){const t=G.indexOf(e);t>=0&&G.splice(t,1)}static get(e){return e[te]?e[te]:new A(e)}get plugins(){return G}enable(){if(this._originalRender)return;let e=0;this._originalRender=this.renderer.render;const t=this;Q(this.renderer),this.renderer.render=function(r,i){t.renderer.getRenderTarget()==null&&(e=0,t._frame+=1);const s=t._frame,o=e++;t.onBeforeRender(r,i,o,s),t._originalRender.call(this,r,i),t.onAfterRender(r,i,o,s)}}disable(){this._originalRender&&(this.renderer.render=this._originalRender,this._originalRender=void 0)}onBeforeRender(e,t,r,i){}onAfterRender(e,t,r,i){var l,h;if(this.pause)return;const n=this.renderer.renderLists.get(e,0),s=n.opaque;let o=!0;if(s.length===1){const f=s[0].material;(f.name==="EffectMaterial"||f.name==="CopyShader")&&(o=!1)}if(o){if(me||this.updateInterval>0&&i%this.updateInterval!=0)return;this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),this.cameraFrustrum.setFromProjectionMatrix(this.projectionScreenMatrix,this.renderer.coordinateSystem);const f=this.targetTriangleDensity;for(const c of s){if(c.material&&(((l=c.geometry)==null?void 0:l.type)==="BoxGeometry"||((h=c.geometry)==null?void 0:h.type)==="BufferGeometry")&&(c.material.name==="SphericalGaussianBlur"||c.material.name=="BackgroundCubeMaterial"||c.material.name==="CubemapFromEquirect"||c.material.name==="EquirectangularToCubeUV")){K&&(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 p=c.object;(p instanceof g.Mesh||p.isMesh)&&this.updateLODs(e,t,p,f)}const y=n.transparent;for(const c of y){const p=c.object;(p instanceof g.Mesh||p.isMesh)&&this.updateLODs(e,t,p,f)}}}updateLODs(e,t,r,i){var l,h;for(const f of G)(l=f.onBeforeUpdateLOD)==null||l.call(f,this.renderer,e,t,r);let n=r.userData.LOD_state;n||(n=new Le,r.userData.LOD_state=n);let s=this.calculateLodLevel(t,r,n,i);s=Math.round(s),s>=0&&this.loadProgressiveMeshes(r,s);let o=0;if(r.material){const f=r["DEBUG:LOD"];if(f!=null&&(o=f),Array.isArray(r.material))for(const y of r.material)this.loadProgressiveTextures(y,o);else this.loadProgressiveTextures(r.material,o)}for(const f of G)(h=f.onAfterUpdatedLOD)==null||h.call(f,this.renderer,e,t,r,s);n.lastLodLevel=s}loadProgressiveTextures(e,t){return e&&e.userData&&e.userData.LOD!==t?(e.userData.LOD=t,v.assignTextureLOD(e,t)):Promise.resolve(null)}loadProgressiveMeshes(e,t){if(!e)return Promise.resolve(null);if(e.userData||(e.userData={}),e.userData.LOD!==t){e.userData.LOD=t;const r=e.geometry;return v.assignMeshLOD(e,t).then(i=>(i&&e.userData.LOD==t&&r!=e.geometry,i))}return Promise.resolve(null)}static isInside(e,t){const r=e.min,i=e.max,n=(r.x+i.x)*.5,s=(r.y+i.y)*.5;return this._tempPtInside.set(n,s,r.z).applyMatrix4(t).z<0}calculateLodLevel(e,t,r,i){var o;if(!t)return-1;let s=10+1;if(e){if(K&&t["DEBUG:LOD"]!=null)return t["DEBUG:LOD"];const l=v.getMeshLODInformation(t.geometry),h=l==null?void 0:l.lods;if(!h||h.length<=0)return 0;if(!((o=this.cameraFrustrum)!=null&&o.intersectsObject(t)))return 99;const f=t.geometry.boundingBox;if(f&&e.isPerspectiveCamera){const y=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 x=e.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(x))return 0}if(this._tempBox.copy(f),this._tempBox.applyMatrix4(t.matrixWorld),A.isInside(this._tempBox,this.projectionScreenMatrix))return 0;if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&y.fov>70){const x=this._tempBox.min,m=this._tempBox.max;let P=x.x,w=x.y,L=m.x,d=m.y;const S=2,B=1.5,E=(x.x+m.x)*.5,I=(x.y+m.y)*.5;P=(P-E)*S+E,w=(w-I)*S+I,L=(L-E)*S+E,d=(d-I)*S+I;const W=P<0&&L>0?0:Math.min(Math.abs(x.x),Math.abs(m.x)),oe=w<0&&d>0?0:Math.min(Math.abs(x.y),Math.abs(m.y)),X=Math.max(W,oe);r.lastCentrality=(B-X)*(B-X)*(B-X)}else r.lastCentrality=1;const c=this._tempBox.getSize(this._tempBoxSize);c.multiplyScalar(.5),screen.availHeight>0&&c.multiplyScalar(this.renderer.domElement.clientHeight/screen.availHeight),c.x*=y.aspect;const p=e.matrixWorldInverse,D=this._tempBox2;D.copy(f),D.applyMatrix4(t.matrixWorld),D.applyMatrix4(p);const b=D.getSize(this._tempBox2Size),C=Math.max(b.x,b.y);if(Math.max(c.x,c.y)!=0&&C!=0&&(c.z=b.z/Math.max(b.x,b.y)*Math.max(c.x,c.y)),r.lastScreenCoverage=Math.max(c.x,c.y,c.z),r.lastScreenspaceVolume.copy(c),r.lastScreenCoverage*=r.lastCentrality,K&&A.debugDrawLine){const x=this.tempMatrix.copy(this.projectionScreenMatrix);x.invert();const m=A.corner0,P=A.corner1,w=A.corner2,L=A.corner3;m.copy(this._tempBox.min),P.copy(this._tempBox.max),P.x=m.x,w.copy(this._tempBox.max),w.y=m.y,L.copy(this._tempBox.max);const d=(m.z+L.z)*.5;m.z=P.z=w.z=L.z=d,m.applyMatrix4(x),P.applyMatrix4(x),w.applyMatrix4(x),L.applyMatrix4(x),A.debugDrawLine(m,P,255),A.debugDrawLine(m,w,255),A.debugDrawLine(P,L,255),A.debugDrawLine(w,L,255)}let k=999;if(h&&r.lastScreenCoverage>0){for(let x=0;x<h.length;x++)if(h[x].density/r.lastScreenCoverage<i){k=x;break}}k<s&&(s=k)}}return s}};let _=A;u(_,"debugDrawLine"),u(_,"corner0",new g.Vector3),u(_,"corner1",new g.Vector3),u(_,"corner2",new g.Vector3),u(_,"corner3",new g.Vector3),u(_,"_tempPtInside",new g.Vector3);class Le{constructor(){u(this,"lastLodLevel",0);u(this,"lastScreenCoverage",0);u(this,"lastScreenspaceVolume",new g.Vector3);u(this,"lastCentrality",0)}}const re=Symbol("NEEDLE_mesh_lod"),V=Symbol("NEEDLE_texture_lod");function ne(a){if(!a)return null;let e=null,t=null;for(let r=a;r!=null;r=Object.getPrototypeOf(r)){const i=Object.getOwnPropertySymbols(r),n=i.find(o=>o.toString()=="Symbol(renderer)"),s=i.find(o=>o.toString()=="Symbol(scene)");!e&&n!=null&&(e=a[n].threeRenderer),!t&&s!=null&&(t=a[s])}if(e){console.log("Adding Needle LODs to modelviewer");const r=_.get(e);if(_.addPlugin(new De(a)),r.enable(),t){const i=t.camera||t.traverse(n=>n.type=="PerspectiveCamera")[0];i&&e.render(t,i)}return()=>{r.disable()}}return null}class De{constructor(e){u(this,"modelviewer");u(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[V]==!0)return;t[V]=!0;const r=this.tryGetCurrentGLTF(e),i=this.getUrl();if(i&&r&&t.material){let n=function(o){var h,f,y;if(o[V]==!0)return;o[V]=!0,o.userData&&(o.userData.LOD=-1);const l=Object.keys(o);for(let c=0;c<l.length;c++){const p=l[c],D=o[p];if((D==null?void 0:D.isTexture)===!0){const b=(f=(h=D.userData)==null?void 0:h.associations)==null?void 0:f.textures,C=r.parser.json.textures[b];if(!C){console.warn("Texture data not found for texture index "+b);continue}if((y=C==null?void 0:C.extensions)!=null&&y[R]){const M=C.extensions[R];M&&i&&v.registerTexture(i,D,M.lods.length,M)}}}};const s=t.material;if(Array.isArray(s))for(const o of s)n(o);else n(s)}}tryParseMeshLOD(e,t){var n,s;if(t[re]==!0)return;t[re]=!0;const r=this.getUrl();if(!r)return;const i=(s=(n=t.userData)==null?void 0:n.gltfExtensions)==null?void 0:s[R];if(i&&r){const o=t.uuid;v.registerMesh(r,o,t,0,i.lods.length,i)}}}function xe(a,e,t,r){Q(e),Z(t),t.register(n=>new v(n,a));const i=_.get(e);return(r==null?void 0:r.enableLODsManager)!==!1&&i.enable(),i}document.addEventListener("DOMContentLoaded",()=>{ne(document.querySelector("model-viewer"))});exports.EXTENSION_NAME=R;exports.LODsManager=_;exports.NEEDLE_progressive=v;exports.addDracoAndKTX2Loaders=Z;exports.createLoaders=Q;exports.getRaycastMesh=se;exports.patchModelViewer=ne;exports.setDracoDecoderLocation=ge;exports.setKTX2TranscoderLocation=he;exports.setRaycastMesh=ie;exports.useNeedleProgressive=xe;
|
package/lib/lods_manager.d.ts
CHANGED
|
@@ -46,6 +46,8 @@ export declare class LODsManager {
|
|
|
46
46
|
readonly renderer: WebGLRenderer;
|
|
47
47
|
readonly projectionScreenMatrix: Matrix4;
|
|
48
48
|
readonly cameraFrustrum: Frustum;
|
|
49
|
+
/** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
|
|
50
|
+
get plugins(): NEEDLE_progressive_plugin[];
|
|
49
51
|
/**
|
|
50
52
|
* The target triangle density is the desired max amount of triangles on screen when the mesh is filling the screen.
|
|
51
53
|
* @default 200_000
|
package/lib/lods_manager.js
CHANGED
|
@@ -66,6 +66,8 @@ export class LODsManager {
|
|
|
66
66
|
renderer;
|
|
67
67
|
projectionScreenMatrix = new Matrix4();
|
|
68
68
|
cameraFrustrum = new Frustum();
|
|
69
|
+
/** @deprecated use static `LODsManager.addPlugin()` method. This getter will be removed in later versions */
|
|
70
|
+
get plugins() { return plugins; }
|
|
69
71
|
/**
|
|
70
72
|
* The target triangle density is the desired max amount of triangles on screen when the mesh is filling the screen.
|
|
71
73
|
* @default 200_000
|
package/package.json
CHANGED