gaussian-splats-3d.module.min.js 190 KB

12
  1. import*as e from"three";import{Ray as t,Plane as n,MathUtils as s,EventDispatcher as r,Vector3 as i,MOUSE as o,TOUCH as a,Quaternion as l,Spherical as c,Vector2 as h}from"three";class d{static idGen=0;constructor(e,t){let n,s;this.promise=new Promise(((e,t)=>{n=e.bind(this),s=t.bind(this)}));e(((...e)=>{n(...e)}).bind(this),(e=>{s(e)}).bind(this)),this.abortHandler=t,this.id=d.idGen++}then(e){return new d(((t,n)=>{this.promise=this.promise.then(((...n)=>{const s=e(...n);s instanceof Promise||s instanceof d?s.then(((...e)=>{t(...e)})):t(s)})).catch((e=>{n(e)}))}),this.abortHandler)}catch(e){return new d((t=>{this.promise=this.promise.then(((...e)=>{t(...e)})).catch(e)}),this.abortHandler)}abort(){this.abortHandler&&this.abortHandler()}}class p extends Error{constructor(e){super(e)}}!function(){const e=new Float32Array(1),t=new Int32Array(e.buffer)}();const u=function(){const e=new Float32Array(1),t=new Int32Array(e.buffer);return function(n){return e[0]=n,t[0]}}(),m=function(e,t,n=!0){const s=new AbortController,r=s.signal;let i=!1,o=null;return new d(((s,a)=>{o=a,fetch(e,{signal:r}).then((async e=>{const r=e.body.getReader();let o=0,l=e.headers.get("Content-Length"),c=l?parseInt(l):void 0;const h=[];for(;!i;)try{const{value:e,done:i}=await r.read();if(i){if(t&&t(100,"100%",e,c),n){const e=new Blob(h).arrayBuffer();s(e)}else s();break}let a,l;if(o+=e.length,void 0!==c&&(a=o/c*100,l=`${a.toFixed(2)}%`),n&&h.push(e),t){t(a,l,e,c)&&(n=!1)}}catch(e){a(e);break}}))}),(()=>{s.abort(),o(new p("Fetch aborted.")),i=!0}))},f=function(e,t,n){return Math.max(Math.min(e,n),t)},g=function(){return performance.now()/1e3},S=e=>{if(e.geometry&&(e.geometry.dispose(),e.geometry=null),e.material&&(e.material.dispose(),e.material=null),e.children)for(let t of e.children)S(t)},y=(e,t)=>new Promise((n=>{window.setTimeout((()=>{n(e())}),t?1:50)})),C=(e=0)=>{switch(e){case 1:return 9;case 2:return 24}return 0};class A{static OFFSET={X:0,Y:1,Z:2,SCALE0:3,SCALE1:4,SCALE2:5,ROTATION0:6,ROTATION1:7,ROTATION2:8,ROTATION3:9,FDC0:10,FDC1:11,FDC2:12,OPACITY:13,FRC0:14,FRC1:15,FRC2:16,FRC3:17,FRC4:18,FRC5:19,FRC6:20,FRC7:21,FRC8:22,FRC9:23,FRC10:24,FRC11:25,FRC12:26,FRC13:27,FRC14:28,FRC15:29,FRC16:30,FRC17:31,FRC18:32,FRC19:33,FRC20:34,FRC21:35,FRC22:36,FRC23:37};constructor(e=0){this.sphericalHarmonicsDegree=e,this.sphericalHarmonicsCount=C(this.sphericalHarmonicsDegree),this.componentCount=this.sphericalHarmonicsCount+14,this.defaultSphericalHarmonics=new Array(this.sphericalHarmonicsCount).fill(0),this.splats=[],this.splatCount=0}static createSplat(e=0){const t=[0,0,0,1,1,1,1,0,0,0,0,0,0,0];let n=C(e);for(let e=0;e<n;e++)t.push(0);return t}addSplat(e){this.splats.push(e),this.splatCount++}getSplat(e){return this.splats[e]}addDefaultSplat(){const e=A.createSplat(this.sphericalHarmonicsDegree);return this.addSplat(e),e}addSplatFromComonents(e,t,n,s,r,i,o,a,l,c,h,d,p,u,...m){const f=[e,t,n,s,r,i,o,a,l,c,h,d,p,u,...this.defaultSphericalHarmonics];for(let e=0;e<m.length&&e<this.sphericalHarmonicsCount;e++)f[e]=m[e];return this.addSplat(f),f}addSplatFromArray(e,t){const n=e.splats[t],s=A.createSplat(this.sphericalHarmonicsDegree);for(let e=0;e<this.componentCount&&e<n.length;e++)s[e]=n[e];this.addSplat(s)}}const x=e.DataUtils.toHalfFloat.bind(e.DataUtils),v=e=>Math.floor(128*e)+128,w=e.DataUtils.fromHalfFloat.bind(e.DataUtils),b=e=>Math.floor(128*w(e))+128,T=(t,n,s=!1)=>0===n?t:1===n||2===n&&!s?e.DataUtils.fromHalfFloat(t):2===n?t/255*2-1:void 0,F=(e,t,n,s=!1)=>0===n?e.getFloat32(4*t,!0):1===n||2===n&&!s?e.getUint16(2*t,!0):e.getUint8(t,!0);class M{static CurrentMajorVersion=0;static CurrentMinorVersion=1;static CenterComponentCount=3;static ScaleComponentCount=3;static RotationComponentCount=4;static ColorComponentCount=4;static CovarianceComponentCount=6;static SplatScaleOffsetFloat=3;static SplatRotationOffsetFloat=6;static CompressionLevels={0:{BytesPerCenter:12,BytesPerScale:12,BytesPerRotation:16,BytesPerColor:4,ScaleOffsetBytes:12,RotationffsetBytes:24,ColorOffsetBytes:40,SphericalHarmonicsOffsetBytes:44,ScaleRange:1,BytesPerSphericalHarmonicsComponent:4,SphericalHarmonicsOffsetFloat:11,SphericalHarmonicsDegrees:{0:{BytesPerSplat:44},1:{BytesPerSplat:80},2:{BytesPerSplat:140}}},1:{BytesPerCenter:6,BytesPerScale:6,BytesPerRotation:8,BytesPerColor:4,ScaleOffsetBytes:6,RotationffsetBytes:12,ColorOffsetBytes:20,SphericalHarmonicsOffsetBytes:24,ScaleRange:32767,BytesPerSphericalHarmonicsComponent:2,SphericalHarmonicsOffsetFloat:12,SphericalHarmonicsDegrees:{0:{BytesPerSplat:24},1:{BytesPerSplat:42},2:{BytesPerSplat:72}}},2:{BytesPerCenter:6,BytesPerScale:6,BytesPerRotation:8,BytesPerColor:4,ScaleOffsetBytes:6,RotationffsetBytes:12,ColorOffsetBytes:20,SphericalHarmonicsOffsetBytes:24,ScaleRange:32767,BytesPerSphericalHarmonicsComponent:1,SphericalHarmonicsOffsetFloat:12,SphericalHarmonicsDegrees:{0:{BytesPerSplat:24},1:{BytesPerSplat:33},2:{BytesPerSplat:48}}}};static CovarianceSizeFloats=6;static HeaderSizeBytes=4096;static SectionHeaderSizeBytes=1024;static BucketStorageSizeBytes=12;static BucketStorageSizeFloats=3;static BucketBlockSize=5;static BucketSize=256;constructor(e,t=!0){this.constructFromBuffer(e,t)}getSplatCount(){return this.splatCount}getMaxSplatCount(){return this.maxSplatCount}getMinSphericalHarmonicsDegree(){let e=0;for(let t=0;t<this.sections.length;t++){const n=this.sections[t];(0===t||n.sphericalHarmonicsDegree<e)&&(e=n.sphericalHarmonicsDegree)}return e}getBucketIndex(e,t){let n;const s=e.fullBucketCount*e.bucketSize;if(t<s)n=Math.floor(t/e.bucketSize);else{let r=s;n=e.fullBucketCount;let i=0;for(;r<e.splatCount;){let s=e.partiallyFilledBucketLengths[i];if(t>=r&&t<r+s)break;r+=s,n++,i++}}return n}getSplatCenter(e,t,n){const s=this.globalSplatIndexToSectionMap[e],r=this.sections[s],i=e-r.splatCountOffset,o=r.bytesPerSplat*i,a=new DataView(this.bufferData,r.dataBase+o),l=F(a,0,this.compressionLevel),c=F(a,1,this.compressionLevel),h=F(a,2,this.compressionLevel);if(this.compressionLevel>=1){const e=this.getBucketIndex(r,i)*M.BucketStorageSizeFloats,n=r.compressionScaleFactor,s=r.compressionScaleRange;t.x=(l-s)*n+r.bucketArray[e],t.y=(c-s)*n+r.bucketArray[e+1],t.z=(h-s)*n+r.bucketArray[e+2]}else t.x=l,t.y=c,t.z=h;n&&t.applyMatrix4(n)}getSplatScaleAndRotation=function(){const t=new e.Matrix4,n=new e.Matrix4,s=new e.Matrix4,r=new e.Vector3,i=new e.Vector3,o=new e.Quaternion;return function(e,a,l,c){const h=this.globalSplatIndexToSectionMap[e],d=this.sections[h],p=e-d.splatCountOffset,u=d.bytesPerSplat*p+M.CompressionLevels[this.compressionLevel].ScaleOffsetBytes,m=new DataView(this.bufferData,d.dataBase+u);i.set(T(F(m,0,this.compressionLevel),this.compressionLevel),T(F(m,1,this.compressionLevel),this.compressionLevel),T(F(m,2,this.compressionLevel),this.compressionLevel)),o.set(T(F(m,4,this.compressionLevel),this.compressionLevel),T(F(m,5,this.compressionLevel),this.compressionLevel),T(F(m,6,this.compressionLevel),this.compressionLevel),T(F(m,3,this.compressionLevel),this.compressionLevel)),c?(t.makeScale(i.x,i.y,i.z),n.makeRotationFromQuaternion(o),s.copy(t).multiply(n).multiply(c),s.decompose(r,l,a)):(a.copy(i),l.copy(o))}}();getSplatColor(e,t){const n=this.globalSplatIndexToSectionMap[e],s=this.sections[n],r=e-s.splatCountOffset,i=s.bytesPerSplat*r+M.CompressionLevels[this.compressionLevel].ColorOffsetBytes,o=new Uint8Array(this.bufferData,s.dataBase+i,4);t.set(o[0],o[1],o[2],o[3])}fillSplatCenterArray(t,n,s,r,i){const o=this.splatCount;s=s||0,r=r||o-1,void 0===i&&(i=s);const a=new e.Vector3;for(let e=s;e<=r;e++){const r=this.globalSplatIndexToSectionMap[e],o=this.sections[r],l=e-o.splatCountOffset,c=(e-s+i)*M.CenterComponentCount,h=o.bytesPerSplat*l,d=new DataView(this.bufferData,o.dataBase+h),p=F(d,0,this.compressionLevel),u=F(d,1,this.compressionLevel),m=F(d,2,this.compressionLevel);if(this.compressionLevel>=1){const e=this.getBucketIndex(o,l)*M.BucketStorageSizeFloats,t=o.compressionScaleFactor,n=o.compressionScaleRange;a.x=(p-n)*t+o.bucketArray[e],a.y=(u-n)*t+o.bucketArray[e+1],a.z=(m-n)*t+o.bucketArray[e+2]}else a.x=p,a.y=u,a.z=m;n&&a.applyMatrix4(n),t[c]=a.x,t[c+1]=a.y,t[c+2]=a.z}}static computeCovariance=function(){const t=new e.Matrix4,n=new e.Matrix3,s=new e.Matrix3,r=new e.Matrix3,i=new e.Matrix3,o=new e.Matrix3,a=new e.Matrix3;return function(e,l,c,h,d=0,p){t.makeScale(e.x,e.y,e.z),n.setFromMatrix4(t),t.makeRotationFromQuaternion(l),s.setFromMatrix4(t),r.copy(s).multiply(n),i.copy(r).transpose().premultiply(r),c&&(o.setFromMatrix4(c),a.copy(o).transpose(),i.multiply(a),i.premultiply(o)),p>=1?(h[d]=x(i.elements[0]),h[d+1]=x(i.elements[3]),h[d+2]=x(i.elements[6]),h[d+3]=x(i.elements[4]),h[d+4]=x(i.elements[7]),h[d+5]=x(i.elements[8])):(h[d]=i.elements[0],h[d+1]=i.elements[3],h[d+2]=i.elements[6],h[d+3]=i.elements[4],h[d+4]=i.elements[7],h[d+5]=i.elements[8])}}();fillSplatCovarianceArray(t,n,s,r,i,o){const a=this.splatCount,l=new e.Vector3,c=new e.Quaternion;s=s||0,r=r||a-1,void 0===i&&(i=s);for(let e=s;e<=r;e++){const r=this.globalSplatIndexToSectionMap[e],a=this.sections[r],h=e-a.splatCountOffset,d=(e-s+i)*M.CovarianceComponentCount,p=a.bytesPerSplat*h+M.CompressionLevels[this.compressionLevel].ScaleOffsetBytes,u=new DataView(this.bufferData,a.dataBase+p);l.set(T(F(u,0,this.compressionLevel),this.compressionLevel),T(F(u,1,this.compressionLevel),this.compressionLevel),T(F(u,2,this.compressionLevel),this.compressionLevel)),c.set(T(F(u,4,this.compressionLevel),this.compressionLevel),T(F(u,5,this.compressionLevel),this.compressionLevel),T(F(u,6,this.compressionLevel),this.compressionLevel),T(F(u,3,this.compressionLevel),this.compressionLevel)),M.computeCovariance(l,c,n,t,d,o)}}fillSplatColorArray(e,t,n,s,r){const i=this.splatCount;n=n||0,s=s||i-1,void 0===r&&(r=n);for(let i=n;i<=s;i++){const s=this.globalSplatIndexToSectionMap[i],o=this.sections[s],a=i-o.splatCountOffset,l=(i-n+r)*M.ColorComponentCount,c=o.bytesPerSplat*a+M.CompressionLevels[this.compressionLevel].ColorOffsetBytes,h=new Uint8Array(this.bufferData,o.dataBase+c);let d=h[3];d=d>=t?d:0,e[l]=h[0],e[l+1]=h[1],e[l+2]=h[2],e[l+3]=d}}fillSphericalHarmonicsArray=function(){const t=[];for(let n=0;n<15;n++)t[n]=new e.Vector3;const n=new e.Matrix3,s=[],r=[],i=[],o=[],a=[],l=[],c=[],h=[],d=[],p=[],u=[],m=[],f=[],g=[],S=[],y=[],A=[],B=[],E=e=>e,D=(e,t,n,s)=>{e[0]=t,e[1]=n,e[2]=s},P=(e,t,n,s,r)=>{e[0]=F(t,s,r,!0),e[1]=F(t,s+n,r,!0),e[2]=F(t,s+n+n,r,!0)},R=(e,t)=>{t[0]=e[0],t[1]=e[1],t[2]=e[2]},I=(e,t,n,s)=>{t[n]=s(e[0]),t[n+1]=s(e[1]),t[n+2]=s(e[2])},k=(e,t,n)=>(t[0]=T(e[0],n,!0),t[1]=T(e[1],n,!0),t[2]=T(e[2],n,!0),t);return function(e,t,T,F,O,L,z){const H=this.splatCount;F=F||0,O=O||H-1,void 0===L&&(L=F),T&&t>=1&&(n.setFromMatrix4(T),D(s,n.elements[4],-n.elements[7],n.elements[1]),D(r,-n.elements[5],n.elements[8],-n.elements[2]),D(i,n.elements[3],-n.elements[6],n.elements[0]));for(let n=F;n<=O;n++){const D=this.globalSplatIndexToSectionMap[n],O=this.sections[D];t=Math.min(t,O.sphericalHarmonicsDegree);const H=C(t),_=n-O.splatCountOffset,U=O.bytesPerSplat*_+M.CompressionLevels[this.compressionLevel].SphericalHarmonicsOffsetBytes,V=new DataView(this.bufferData,O.dataBase+U),N=(n-F+L)*H;let W=T?0:this.compressionLevel,j=E;W!==z&&(1===W?0===z?j=w:2==z&&(j=b):0===W&&(1===z?j=x:2==z&&(j=v))),t>=1&&(P(d,V,3,0,this.compressionLevel),P(p,V,3,1,this.compressionLevel),P(u,V,3,2,this.compressionLevel),T?(k(d,d,this.compressionLevel),k(p,p,this.compressionLevel),k(u,u,this.compressionLevel),M.rotateSphericalHarmonics3(d,p,u,s,r,i,g,S,y)):(R(d,g),R(p,S),R(u,y)),I(g,e,N,j),I(S,e,N+3,j),I(y,e,N+6,j),t>=2&&(P(d,V,5,9,this.compressionLevel),P(p,V,5,10,this.compressionLevel),P(u,V,5,11,this.compressionLevel),P(m,V,5,12,this.compressionLevel),P(f,V,5,13,this.compressionLevel),T?(k(d,d,this.compressionLevel),k(p,p,this.compressionLevel),k(u,u,this.compressionLevel),k(m,m,this.compressionLevel),k(f,f,this.compressionLevel),M.rotateSphericalHarmonics5(d,p,u,m,f,s,r,i,o,a,l,c,h,g,S,y,A,B)):(R(d,g),R(p,S),R(u,y),R(m,A),R(f,B)),I(g,e,N+9,j),I(S,e,N+12,j),I(y,e,N+15,j),I(A,e,N+18,j),I(B,e,N+21,j)))}}}();static dot3=(e,t,n,s,r)=>{r[0]=r[1]=r[2]=0;const i=s[0],o=s[1],a=s[2];M.addInto3(e[0]*i,e[1]*i,e[2]*i,r),M.addInto3(t[0]*o,t[1]*o,t[2]*o,r),M.addInto3(n[0]*a,n[1]*a,n[2]*a,r)};static addInto3=(e,t,n,s)=>{s[0]=s[0]+e,s[1]=s[1]+t,s[2]=s[2]+n};static dot5=(e,t,n,s,r,i,o)=>{o[0]=o[1]=o[2]=0;const a=i[0],l=i[1],c=i[2],h=i[3],d=i[4];M.addInto3(e[0]*a,e[1]*a,e[2]*a,o),M.addInto3(t[0]*l,t[1]*l,t[2]*l,o),M.addInto3(n[0]*c,n[1]*c,n[2]*c,o),M.addInto3(s[0]*h,s[1]*h,s[2]*h,o),M.addInto3(r[0]*d,r[1]*d,r[2]*d,o)};static rotateSphericalHarmonics3=(e,t,n,s,r,i,o,a,l)=>{M.dot3(e,t,n,s,o),M.dot3(e,t,n,r,a),M.dot3(e,t,n,i,l)};static rotateSphericalHarmonics5=(e,t,n,s,r,i,o,a,l,c,h,d,p,u,m,f,g,S)=>{const y=Math.sqrt(1/4),C=Math.sqrt(3/4),A=Math.sqrt(1/3),x=Math.sqrt(4/3),v=Math.sqrt(1/12);l[0]=y*(a[2]*i[0]+a[0]*i[2]+(i[2]*a[0]+i[0]*a[2])),l[1]=a[1]*i[0]+i[1]*a[0],l[2]=C*(a[1]*i[1]+i[1]*a[1]),l[3]=a[1]*i[2]+i[1]*a[2],l[4]=y*(a[2]*i[2]-a[0]*i[0]+(i[2]*a[2]-i[0]*a[0])),M.dot5(e,t,n,s,r,l,u),c[0]=y*(o[2]*i[0]+o[0]*i[2]+(i[2]*o[0]+i[0]*o[2])),c[1]=o[1]*i[0]+i[1]*o[0],c[2]=C*(o[1]*i[1]+i[1]*o[1]),c[3]=o[1]*i[2]+i[1]*o[2],c[4]=y*(o[2]*i[2]-o[0]*i[0]+(i[2]*o[2]-i[0]*o[0])),M.dot5(e,t,n,s,r,c,m),h[0]=A*(o[2]*o[0]+o[0]*o[2])+-v*(a[2]*a[0]+a[0]*a[2]+(i[2]*i[0]+i[0]*i[2])),h[1]=x*o[1]*o[0]+-A*(a[1]*a[0]+i[1]*i[0]),h[2]=o[1]*o[1]+-y*(a[1]*a[1]+i[1]*i[1]),h[3]=x*o[1]*o[2]+-A*(a[1]*a[2]+i[1]*i[2]),h[4]=A*(o[2]*o[2]-o[0]*o[0])+-v*(a[2]*a[2]-a[0]*a[0]+(i[2]*i[2]-i[0]*i[0])),M.dot5(e,t,n,s,r,h,f),d[0]=y*(o[2]*a[0]+o[0]*a[2]+(a[2]*o[0]+a[0]*o[2])),d[1]=o[1]*a[0]+a[1]*o[0],d[2]=C*(o[1]*a[1]+a[1]*o[1]),d[3]=o[1]*a[2]+a[1]*o[2],d[4]=y*(o[2]*a[2]-o[0]*a[0]+(a[2]*o[2]-a[0]*o[0])),M.dot5(e,t,n,s,r,d,g),p[0]=y*(a[2]*a[0]+a[0]*a[2]-(i[2]*i[0]+i[0]*i[2])),p[1]=a[1]*a[0]-i[1]*i[0],p[2]=C*(a[1]*a[1]-i[1]*i[1]),p[3]=a[1]*a[2]-i[1]*i[2],p[4]=y*(a[2]*a[2]-a[0]*a[0]-(i[2]*i[2]-i[0]*i[0])),M.dot5(e,t,n,s,r,p,S)};static parseHeader(t){const n=new Uint8Array(t,0,M.HeaderSizeBytes),s=new Uint16Array(t,0,M.HeaderSizeBytes/2),r=new Uint32Array(t,0,M.HeaderSizeBytes/4),i=new Float32Array(t,0,M.HeaderSizeBytes/4);return{versionMajor:n[0],versionMinor:n[1],maxSectionCount:r[1],sectionCount:r[2],maxSplatCount:r[3],splatCount:r[4],compressionLevel:s[10],sceneCenter:new e.Vector3(i[6],i[7],i[8])}}static writeHeaderCountsToBuffer(e,t,n){const s=new Uint32Array(n,0,M.HeaderSizeBytes/4);s[2]=e,s[4]=t}static writeHeaderToBuffer(e,t){const n=new Uint8Array(t,0,M.HeaderSizeBytes),s=new Uint16Array(t,0,M.HeaderSizeBytes/2),r=new Uint32Array(t,0,M.HeaderSizeBytes/4),i=new Float32Array(t,0,M.HeaderSizeBytes/4);n[0]=e.versionMajor,n[1]=e.versionMinor,n[2]=0,n[3]=0,r[1]=e.maxSectionCount,r[2]=e.sectionCount,r[3]=e.maxSplatCount,r[4]=e.splatCount,s[10]=e.compressionLevel,i[6]=e.sceneCenter.x,i[7]=e.sceneCenter.y,i[8]=e.sceneCenter.z}static parseSectionHeaders(e,t,n=0,s){const r=e.compressionLevel,i=e.maxSectionCount,o=new Uint16Array(t,n,i*M.SectionHeaderSizeBytes/2),a=new Uint32Array(t,n,i*M.SectionHeaderSizeBytes/4),l=new Float32Array(t,n,i*M.SectionHeaderSizeBytes/4),c=[];let h=0,d=h/2,p=h/4,u=M.HeaderSizeBytes+e.maxSectionCount*M.SectionHeaderSizeBytes,m=0;for(let e=0;e<i;e++){const t=a[p+1],n=a[p+2],i=a[p+3],f=l[p+4],g=f/2,S=o[d+10],y=a[p+6]||M.CompressionLevels[r].ScaleRange,C=a[p+8],A=a[p+9],x=4*A,v=S*i+x,w=o[d+20],{bytesPerSplat:b}=M.calculateComponentStorage(r,w),T=b*t,F=T+v,B={bytesPerSplat:b,splatCountOffset:m,splatCount:s?t:0,maxSplatCount:t,bucketSize:n,bucketCount:i,bucketBlockSize:f,halfBucketBlockSize:g,bucketStorageSizeBytes:S,bucketsStorageSizeBytes:v,splatDataStorageSizeBytes:T,storageSizeBytes:F,compressionScaleRange:y,compressionScaleFactor:g/y,base:u,bucketsBase:u+x,dataBase:u+v,fullBucketCount:C,partiallyFilledBucketCount:A,sphericalHarmonicsDegree:w};c[e]=B,u+=F,h+=M.SectionHeaderSizeBytes,d=h/2,p=h/4,m+=t}return c}static writeSectionHeaderToBuffer(e,t,n,s=0){const r=new Uint16Array(n,s,M.SectionHeaderSizeBytes/2),i=new Uint32Array(n,s,M.SectionHeaderSizeBytes/4),o=new Float32Array(n,s,M.SectionHeaderSizeBytes/4);i[0]=e.splatCount,i[1]=e.maxSplatCount,i[2]=t>=1?e.bucketSize:0,i[3]=t>=1?e.bucketCount:0,o[4]=t>=1?e.bucketBlockSize:0,r[10]=t>=1?M.BucketStorageSizeBytes:0,i[6]=t>=1?e.compressionScaleRange:0,i[7]=e.storageSizeBytes,i[8]=t>=1?e.fullBucketCount:0,i[9]=t>=1?e.partiallyFilledBucketCount:0,r[20]=e.sphericalHarmonicsDegree}static writeSectionHeaderSplatCountToBuffer(e,t,n=0){new Uint32Array(t,n,M.SectionHeaderSizeBytes/4)[0]=e}constructFromBuffer(t,n){this.bufferData=t,this.globalSplatIndexToLocalSplatIndexMap=[],this.globalSplatIndexToSectionMap=[];const s=M.parseHeader(this.bufferData);this.versionMajor=s.versionMajor,this.versionMinor=s.versionMinor,this.maxSectionCount=s.maxSectionCount,this.sectionCount=n?s.maxSectionCount:0,this.maxSplatCount=s.maxSplatCount,this.splatCount=n?s.maxSplatCount:0,this.compressionLevel=s.compressionLevel,this.sceneCenter=(new e.Vector3).copy(s.sceneCenter),this.sections=M.parseSectionHeaders(s,this.bufferData,M.HeaderSizeBytes,n),this.linkBufferArrays(),this.buildMaps()}static calculateComponentStorage(e,t){const n=M.CompressionLevels[e].BytesPerCenter,s=M.CompressionLevels[e].BytesPerScale,r=M.CompressionLevels[e].BytesPerRotation,i=M.CompressionLevels[e].BytesPerColor,o=C(t),a=M.CompressionLevels[e].BytesPerSphericalHarmonicsComponent*o;return{bytesPerCenter:n,bytesPerScale:s,bytesPerRotation:r,bytesPerColor:i,sphericalHarmonicsComponentsPerSplat:o,sphericalHarmonicsBytesPerSplat:a,bytesPerSplat:n+s+r+i+a}}linkBufferArrays(){for(let e=0;e<this.maxSectionCount;e++){const t=this.sections[e];t.bucketArray=new Float32Array(this.bufferData,t.bucketsBase,t.bucketCount*M.BucketStorageSizeFloats),t.partiallyFilledBucketCount>0&&(t.partiallyFilledBucketLengths=new Uint32Array(this.bufferData,t.base,t.partiallyFilledBucketCount))}}buildMaps(){let e=0;for(let t=0;t<this.maxSectionCount;t++){const n=this.sections[t];for(let s=0;s<n.maxSplatCount;s++){const n=e+s;this.globalSplatIndexToLocalSplatIndexMap[n]=s,this.globalSplatIndexToSectionMap[n]=t}e+=n.maxSplatCount}}updateLoadedCounts(e,t){M.writeHeaderCountsToBuffer(e,t,this.bufferData),this.sectionCount=e,this.splatCount=t}updateSectionLoadedCounts(e,t){const n=M.HeaderSizeBytes+M.SectionHeaderSizeBytes*e;M.writeSectionHeaderSplatCountToBuffer(t,this.bufferData,n),this.sections[e].splatCount=t}static generateFromUncompressedSplatArrays(t,n,s,r,i,o,a=[]){const l=(e,t,n,s,r=0)=>{const i=new Uint8Array(e,t),o=new Uint8Array(n,s);for(let e=0;e<r;e++)o[e]=i[e]};let c=0;for(let e=0;e<t.length;e++){const n=t[e];if(0===e||n.sphericalHarmonicsDegree<c){if(e>0&&n.sphericalHarmonicsDegree!==c){throw new Error("SplatBuffer::generateFromUncompressedSplatArrays() -> all splat arrays must have the same spherical harmonics degree.")}c=n.sphericalHarmonicsDegree}}const{bytesPerCenter:h,bytesPerScale:d,bytesPerRotation:p,bytesPerColor:u,sphericalHarmonicsComponentsPerSplat:m,sphericalHarmonicsBytesPerSplat:g,bytesPerSplat:S}=M.calculateComponentStorage(s,c),y=M.CompressionLevels[s].ScaleRange,C=[],w=[];let b=0;const T=new e.Quaternion;for(let r=0;r<t.length;r++){const F=t[r],B=a[r]||{},E=(B.blockSizeFactor||1)*(i||M.BucketBlockSize),D=Math.ceil((B.bucketSizeFactor||1)*(o||M.BucketSize)),P=new A(c);for(let e=0;e<F.splatCount;e++){const t=F.splats[e];let s;s=t[A.OFFSET.OPACITY]?t[A.OFFSET.OPACITY]:255,s>=n&&P.addSplat(t)}const R=M.computeBucketsForUncompressedSplatArray(P,E,D),I=R.fullBuckets.length,k=R.partiallyFullBuckets.map((e=>e.splats.length)),O=k.length,L=[...R.fullBuckets,...R.partiallyFullBuckets],z=P.splats.length*S,H=4*O,_=s>=1?L.length*M.BucketStorageSizeBytes+H:0,U=z+_,V=new ArrayBuffer(U),N=y/(E/2),W=2*y+1,j=new ArrayBuffer(h),G=new ArrayBuffer(d),Q=new ArrayBuffer(p),X=new ArrayBuffer(u),Y=new ArrayBuffer(g),q=new e.Vector3,K=new e.Vector3;let Z=0;for(let e=0;e<L.length;e++){const t=L[e];q.fromArray(t.center);for(let e=0;e<t.splats.length;e++){let n=t.splats[e];const r=P.splats[n],i=_+Z*S,o=i+h,a=o+d,g=a+p,C=g+u;if(0===s){const e=new Float32Array(V,i,M.CenterComponentCount),t=new Float32Array(V,a,M.RotationComponentCount),n=new Float32Array(V,o,M.ScaleComponentCount);if(void 0!==r[A.OFFSET.SCALE0]?(T.set(r[A.OFFSET.ROTATION0],r[A.OFFSET.ROTATION1],r[A.OFFSET.ROTATION2],r[A.OFFSET.ROTATION3]),T.normalize(),t.set([T.x,T.y,T.z,T.w]),n.set([r[A.OFFSET.SCALE0],r[A.OFFSET.SCALE1],r[A.OFFSET.SCALE2]])):(t.set([1,0,0,0]),n.set([.01,.01,.01])),e.set([r[A.OFFSET.X],r[A.OFFSET.Y],r[A.OFFSET.Z]]),c>0){const e=new Float32Array(V,C,m);if(c>=1){for(let t=0;t<9;t++)e[t]=r[A.OFFSET.FRC0+t];if(c>=2)for(let t=0;t<15;t++)e[t+9]=r[A.OFFSET.FRC9+t]}}}else{const e=new Uint16Array(j,0,M.CenterComponentCount),t=new Uint16Array(Q,0,M.RotationComponentCount),n=new Uint16Array(G,0,M.ScaleComponentCount);if(void 0!==r[A.OFFSET.SCALE0]?(T.set(r[A.OFFSET.ROTATION0],r[A.OFFSET.ROTATION1],r[A.OFFSET.ROTATION2],r[A.OFFSET.ROTATION3]),T.normalize(),t.set([x(T.x),x(T.y),x(T.z),x(T.w)]),n.set([x(r[A.OFFSET.SCALE0]),x(r[A.OFFSET.SCALE1]),x(r[A.OFFSET.SCALE2])])):(t.set([x(1),0,0,0]),n.set([x(.01),x(.01),x(.01)])),K.set(r[A.OFFSET.X],r[A.OFFSET.Y],r[A.OFFSET.Z]).sub(q),K.x=Math.round(K.x*N)+y,K.x=f(K.x,0,W),K.y=Math.round(K.y*N)+y,K.y=f(K.y,0,W),K.z=Math.round(K.z*N)+y,K.z=f(K.z,0,W),e.set([K.x,K.y,K.z]),c>0){const e=1===s?2:1,t=new(1===s?Uint16Array:Uint8Array)(Y,0,m);if(c>=1){for(let e=0;e<9;e++){const n=r[A.OFFSET.FRC0+e];t[e]=1===s?x(n):v(n)}const n=9*e;if(l(t.buffer,0,V,C,n),c>=2){for(let e=0;e<15;e++){const n=r[A.OFFSET.FRC9+e];t[e+9]=1===s?x(n):v(n)}const i=15*e;l(t.buffer,n,V,C+n,i)}}}l(e.buffer,0,V,i,6),l(n.buffer,0,V,o,6),l(t.buffer,0,V,a,8)}const w=new Uint8ClampedArray(X,0,4);void 0!==r[A.OFFSET.FDC0]?w.set([r[A.OFFSET.FDC0],r[A.OFFSET.FDC1],r[A.OFFSET.FDC2]]):w.set([255,0,0]),void 0!==r[A.OFFSET.OPACITY]?w[3]=r[A.OFFSET.OPACITY]:w[3]=255,l(w.buffer,0,V,g,4),Z++}}if(b+=Z,s>=1){const e=new Uint32Array(V,0,4*k.length);for(let t=0;t<k.length;t++)e[t]=k[t];const t=new Float32Array(V,H,L.length*M.BucketStorageSizeFloats);for(let e=0;e<L.length;e++){const n=L[e],s=3*e;t[s]=n.center[0],t[s+1]=n.center[1],t[s+2]=n.center[2]}}C.push(V);const $=new ArrayBuffer(M.SectionHeaderSizeBytes);M.writeSectionHeaderToBuffer({maxSplatCount:Z,splatCount:Z,bucketSize:D,bucketCount:L.length,bucketBlockSize:E,compressionScaleRange:y,storageSizeBytes:U,fullBucketCount:I,partiallyFilledBucketCount:O,sphericalHarmonicsDegree:c},s,$,0),w.push($)}let F=0;for(let e of C)F+=e.byteLength;const B=M.HeaderSizeBytes+M.SectionHeaderSizeBytes*C.length+F,E=new ArrayBuffer(B);M.writeHeaderToBuffer({versionMajor:0,versionMinor:1,maxSectionCount:C.length,sectionCount:C.length,maxSplatCount:b,splatCount:b,compressionLevel:s,sceneCenter:r},E);let D=M.HeaderSizeBytes;for(let e of w)new Uint8Array(E,D,M.SectionHeaderSizeBytes).set(new Uint8Array(e)),D+=M.SectionHeaderSizeBytes;for(let e of C)new Uint8Array(E,D,e.byteLength).set(new Uint8Array(e)),D+=e.byteLength;return new M(E)}static computeBucketsForUncompressedSplatArray(t,n,s){let r=t.splatCount;const i=n/2,o=new e.Vector3,a=new e.Vector3;for(let e=0;e<r;e++){const n=t.splats[e],s=[n[A.OFFSET.X],n[A.OFFSET.Y],n[A.OFFSET.Z]];(0===e||s[0]<o.x)&&(o.x=s[0]),(0===e||s[0]>a.x)&&(a.x=s[0]),(0===e||s[1]<o.y)&&(o.y=s[1]),(0===e||s[1]>a.y)&&(a.y=s[1]),(0===e||s[2]<o.z)&&(o.z=s[2]),(0===e||s[2]>a.z)&&(a.z=s[2])}const l=(new e.Vector3).copy(a).sub(o),c=Math.ceil(l.y/n),h=Math.ceil(l.z/n),d=new e.Vector3,p=[],u={};for(let e=0;e<r;e++){const r=t.splats[e],a=[r[A.OFFSET.X],r[A.OFFSET.Y],r[A.OFFSET.Z]],l=Math.floor((a[0]-o.x)/n),m=Math.floor((a[1]-o.y)/n),f=Math.floor((a[2]-o.z)/n);d.x=l*n+o.x+i,d.y=m*n+o.y+i,d.z=f*n+o.z+i;const g=l*(c*h)+m*h+f;let S=u[g];S||(u[g]=S={splats:[],center:d.toArray()}),S.splats.push(e),S.splats.length>=s&&(p.push(S),u[g]=null)}const m=[];for(let e in u)if(u.hasOwnProperty(e)){const t=u[e];t&&m.push(t)}return{fullBuckets:p,partiallyFullBuckets:m}}}const B=new Uint8Array([112,108,121,10]),E=new Uint8Array([10,101,110,100,95,104,101,97,100,101,114,10]),D="end_header",P=new Map([["char",Int8Array],["uchar",Uint8Array],["short",Int16Array],["ushort",Uint16Array],["int",Int32Array],["uint",Uint32Array],["float",Float32Array],["double",Float64Array]]),R=(e,t)=>{const n=(1<<t)-1;return(e&n)/n},I=(e,t)=>{e.x=R(t>>>21,11),e.y=R(t>>>11,10),e.z=R(t,11)},k=(e,t,n)=>e*(1-n)+t*n,O=(e,t)=>e.properties.find((e=>e.name===t&&e.storage))?.storage;class L{static decodeHeaderText(e){let t,n,s;const r=e.split("\n").filter((e=>!e.startsWith("comment ")));let i=0,o=!1;for(let e=1;e<r.length;++e){const a=r[e].split(" ");switch(a[0]){case"format":if("binary_little_endian"!==a[1])throw new Error("Unsupported ply format");break;case"element":t={name:a[1],count:parseInt(a[2],10),properties:[],storageSizeBytes:0},"chunk"===t.name?n=t:"vertex"===t.name&&(s=t);break;case"property":{if(!P.has(a[1]))throw new Error(`Unrecognized property data type '${a[1]}' in ply header`);const e=P.get(a[1]),n=e.BYTES_PER_ELEMENT*t.count;"vertex"===t.name&&(i+=e.BYTES_PER_ELEMENT),t.properties.push({type:a[1],name:a[2],storage:null,byteSize:e.BYTES_PER_ELEMENT,storageSizeByes:n}),t.storageSizeBytes+=n;break}case D:o=!0;break;default:throw new Error(`Unrecognized header value '${a[0]}' in ply header`)}if(o)break}return{chunkElement:n,vertexElement:s,bytesPerSplat:i,headerSizeBytes:e.indexOf(D)+10+1}}static decodeHeader(e){let t,n=new Uint8Array(e);if(n.length>=B.length&&!((e,t)=>{if(e.length<t.length)return!1;for(let n=0;n<t.length;++n)if(e[n]!==t[n])return!1;return!0})(n,B))throw new Error("Invalid PLY header");if(t=((e,t)=>{const n=e.length-t.length;let s,r;for(s=0;s<=n;++s){for(r=0;r<t.length&&e[s+r]===t[r];++r);if(r===t.length)return s}return-1})(n,E),-1===t)throw new Error("End of PLY header not found");const s=new TextDecoder("ascii").decode(n.slice(0,t)),{chunkElement:r,vertexElement:i,bytesPerSplat:o}=L.decodeHeaderText(s);return{headerSizeBytes:t+E.length,bytesPerSplat:o,chunkElement:r,vertexElement:i}}static readElementData(e,t,n,s,r,i=null){let o=t instanceof DataView?t:new DataView(t);s=s||0,r=r||e.count-1;for(let t=s;t<=r;++t)for(let s=0;s<e.properties.length;++s){const r=e.properties[s],a=P.get(r.type),l=a.BYTES_PER_ELEMENT*e.count;if(r.storage&&!(r.storage.byteLength<l)||i&&!i(r.name)||(r.storage=new a(e.count)),r.storage)switch(r.type){case"char":r.storage[t]=o.getInt8(n);break;case"uchar":r.storage[t]=o.getUint8(n);break;case"short":r.storage[t]=o.getInt16(n,!0);break;case"ushort":r.storage[t]=o.getUint16(n,!0);break;case"int":r.storage[t]=o.getInt32(n,!0);break;case"uint":r.storage[t]=o.getUint32(n,!0);break;case"float":r.storage[t]=o.getFloat32(n,!0);break;case"double":r.storage[t]=o.getFloat64(n,!0)}n+=r.byteSize}return n}static readPly(e,t=null){const n=L.decodeHeader(e);let s=L.readElementData(n.chunkElement,e,n.headerSizeBytes,null,null,t);return L.readElementData(n.vertexElement,e,s,null,null,t),{chunkElement:n.chunkElement,vertexElement:n.vertexElement}}static getElementStorageArrays(e,t){const n=O(e,"min_x"),s=O(e,"min_y"),r=O(e,"min_z"),i=O(e,"max_x"),o=O(e,"max_y"),a=O(e,"max_z"),l=O(e,"min_scale_x"),c=O(e,"min_scale_y"),h=O(e,"min_scale_z");return{positionExtremes:{minX:n,maxX:i,minY:s,maxY:o,minZ:r,maxZ:a},scaleExtremes:{minScaleX:l,maxScaleX:O(e,"max_scale_x"),minScaleY:c,maxScaleY:O(e,"max_scale_y"),minScaleZ:h,maxScaleZ:O(e,"max_scale_z")},position:O(t,"packed_position"),rotation:O(t,"packed_rotation"),scale:O(t,"packed_scale"),color:O(t,"packed_color")}}static decompressSplat=function(){const t=new e.Vector3,n=new e.Quaternion,s=new e.Vector3,r=new e.Vector4,i=A.OFFSET;return function(e,o,a,l,c,h,d,p,u){u=u||A.createSplat();const m=Math.floor((o+e)/256);var g,S;return I(t,a[e]),((e,t)=>{const n=1/(.5*Math.sqrt(2)),s=(R(t>>>20,10)-.5)*n,r=(R(t>>>10,10)-.5)*n,i=(R(t,10)-.5)*n,o=Math.sqrt(1-(s*s+r*r+i*i));switch(t>>>30){case 0:e.set(o,s,r,i);break;case 1:e.set(s,o,r,i);break;case 2:e.set(s,r,o,i);break;case 3:e.set(s,r,i,o)}})(n,d[e]),I(s,c[e]),g=r,S=p[e],g.x=R(S>>>24,8),g.y=R(S>>>16,8),g.z=R(S>>>8,8),g.w=R(S,8),u[i.X]=k(l.minX[m],l.maxX[m],t.x),u[i.Y]=k(l.minY[m],l.maxY[m],t.y),u[i.Z]=k(l.minZ[m],l.maxZ[m],t.z),u[i.ROTATION0]=n.x,u[i.ROTATION1]=n.y,u[i.ROTATION2]=n.z,u[i.ROTATION3]=n.w,u[i.SCALE0]=Math.exp(k(h.minScaleX[m],h.maxScaleX[m],s.x)),u[i.SCALE1]=Math.exp(k(h.minScaleY[m],h.maxScaleY[m],s.y)),u[i.SCALE2]=Math.exp(k(h.minScaleZ[m],h.maxScaleZ[m],s.z)),u[i.FDC0]=f(Math.floor(255*r.x),0,255),u[i.FDC1]=f(Math.floor(255*r.y),0,255),u[i.FDC2]=f(Math.floor(255*r.z),0,255),u[i.OPACITY]=f(Math.floor(255*r.w),0,255),u}}();static parseToUncompressedSplatBufferSection(e,t,n,s,r,i,o,a,l,c=null){L.readElementData(t,i,o,n,s,c);const h=M.CompressionLevels[0].BytesPerCenter,d=M.CompressionLevels[0].BytesPerScale,p=M.CompressionLevels[0].BytesPerRotation,u=M.CompressionLevels[0].SphericalHarmonicsDegrees[0].BytesPerSplat,{positionExtremes:m,scaleExtremes:f,position:g,rotation:S,scale:y,color:C}=L.getElementStorageArrays(e,t),x=A.OFFSET,v=A.createSplat();for(let e=n;e<=s;++e){L.decompressSplat(e,r,g,m,y,f,S,C,v);const t=e*u+l,n=new Float32Array(a,t,3),s=new Float32Array(a,t+h,3),i=new Float32Array(a,t+h+d,4),o=new Uint8Array(a,t+h+d+p,4);n[0]=v[x.X],n[1]=v[x.Y],n[2]=v[x.Z],s[0]=v[x.SCALE0],s[1]=v[x.SCALE1],s[2]=v[x.SCALE2],i[0]=v[x.ROTATION0],i[1]=v[x.ROTATION1],i[2]=v[x.ROTATION2],i[3]=v[x.ROTATION3],o[0]=v[x.FDC0],o[1]=v[x.FDC1],o[2]=v[x.FDC2],o[3]=v[x.OPACITY]}}static parseToUncompressedSplatArray(t){const{chunkElement:n,vertexElement:s}=L.readPly(t),r=new A,{positionExtremes:i,scaleExtremes:o,position:a,rotation:l,scale:c,color:h}=L.getElementStorageArrays(n,s);for(let e=0;e<s.count;++e){r.addDefaultSplat();const t=r.getSplat(r.splatCount-1);L.decompressSplat(e,0,a,i,c,o,l,h,t)}return(new e.Matrix4).identity(),r}}class z{static HeaderEndToken="end_header";static BaseFields=["scale_0","scale_1","scale_2","rot_0","rot_1","rot_2","rot_3","x","y","z","f_dc_0","f_dc_1","f_dc_2","red","green","blue","opacity"];static SphericalHarmonicsFields=Array.from(Array(45)).map(((e,t)=>`f_rest_${t}`));static Fields=[[...z.BaseFields],[...z.BaseFields,...z.SphericalHarmonicsFields]];static checkTextForEndHeader(e){return!!e.includes(z.HeaderEndToken)}static checkBufferForEndHeader(e,t,n,s){const r=new Uint8Array(e,Math.max(0,t-n),n),i=s.decode(r);return z.checkTextForEndHeader(i)}static decodeHeaderText(e){const t=e.split("\n"),n=[];let s=0,r={},i=!1;for(let e=0;e<t.length;e++){const o=t[e].trim();if(n.push(o),o.startsWith("element chunk")||o.match(/[A-Za-z]*packed_[A-Za-z]*/))i=!0;else if(o.startsWith("element vertex")){const e=o.match(/\d+/);e&&(s=parseInt(e[0]))}else if(o.startsWith("property")){const e=o.match(/(\w+)\s+(\w+)\s+(\w+)/);if(e){const t=e[2];r[e[3]]=t}}else if(o===z.HeaderEndToken)break}let o=0,a={};const l={double:8,int:4,uint:4,float:4,short:2,ushort:2,uchar:1},c=[];for(let e in r)if(r.hasOwnProperty(e)){c.push(e);const t=r[e];a[e]=o,o+=l[t]}let h=0,d=0;for(let e of c)e.startsWith("f_rest")&&h++;d=h/3;let p=0;d>=3&&(p=1),d>=8&&(p=2);let u=[];if(p>=1)for(let e=0;e<3;e++)for(let t=0;t<3;t++)u.push("f_rest_"+(t+d*e));let m=[];if(p>=2)for(let e=0;e<3;e++)for(let t=0;t<5;t++)m.push("f_rest_"+(t+d*e+3));return{splatCount:s,propertyTypes:r,compressed:i,headerText:e,headerLines:n,headerSizeBytes:e.indexOf(z.HeaderEndToken)+z.HeaderEndToken.length+1,bytesPerSplat:o,fieldOffsets:a,sphericalHarmonicsDegree:p,sphericalHarmonicsCoefficientsPerChannel:d,sphericalHarmonicsDegree1Fields:u,sphericalHarmonicsDegree2Fields:m}}static decodeHeadeFromBuffer(e){const t=new TextDecoder;let n=0,s="";const r=100;for(;;){if(n+r>=e.byteLength)throw new Error("End of file reached while searching for end of header");const i=new Uint8Array(e,n,r);if(s+=t.decode(i),n+=r,z.checkBufferForEndHeader(e,n,200,t))break}return z.decodeHeaderText(s)}static findVertexData(e,t){return new DataView(e,t.headerSizeBytes)}static readRawVertexFast(e,t,n,s,r,i){let o=i||{};for(let i of s){const s=r[i];"float"===s?o[i]=e.getFloat32(t+n[i],!0):"double"===s?o[i]=e.getFloat64(t+n[i],!0):"uchar"===s&&(o[i]=e.getUint8(t+n[i])/255)}}static parseToUncompressedSplatBufferSection(e,t,n,s,r,i,o,a=0){a=Math.min(a,e.sphericalHarmonicsDegree);const l=M.CompressionLevels[0].BytesPerCenter,c=M.CompressionLevels[0].BytesPerScale,h=M.CompressionLevels[0].BytesPerRotation,d=M.CompressionLevels[0].BytesPerColor,p=M.CompressionLevels[0].SphericalHarmonicsDegrees[a].BytesPerSplat;for(let u=t;u<=n;u++){const t=z.parseToUncompressedSplat(s,u,e,r,a),n=u*p+o,m=new Float32Array(i,n,3),f=new Float32Array(i,n+l,3),g=new Float32Array(i,n+l+c,4),S=new Uint8Array(i,n+l+c+h,4);if(m[0]=t[A.OFFSET.X],m[1]=t[A.OFFSET.Y],m[2]=t[A.OFFSET.Z],f[0]=t[A.OFFSET.SCALE0],f[1]=t[A.OFFSET.SCALE1],f[2]=t[A.OFFSET.SCALE2],g[0]=t[A.OFFSET.ROTATION0],g[1]=t[A.OFFSET.ROTATION1],g[2]=t[A.OFFSET.ROTATION2],g[3]=t[A.OFFSET.ROTATION3],S[0]=t[A.OFFSET.FDC0],S[1]=t[A.OFFSET.FDC1],S[2]=t[A.OFFSET.FDC2],S[3]=t[A.OFFSET.OPACITY],a>=1){const e=new Float32Array(i,n+l+c+h+d,t.sphericalHarmonicsCount);for(let n=0;n<=8;n++)e[n]=t[A.OFFSET.FRC0+n];if(a>=2)for(let n=9;n<=23;n++)e[n]=t[A.OFFSET.FRC0+n]}}}static parseToUncompressedSplat=function(){let t={};const n=new e.Quaternion;return function(e,s,r,i=0,o=0){o=Math.min(o,r.sphericalHarmonicsDegree),z.readRawVertexFast(e,s*r.bytesPerSplat+i,r.fieldOffsets,z.Fields[o>0?1:0],r.propertyTypes,t);const a=A.createSplat(o);if(void 0!==t.scale_0?(a[A.OFFSET.SCALE0]=Math.exp(t.scale_0),a[A.OFFSET.SCALE1]=Math.exp(t.scale_1),a[A.OFFSET.SCALE2]=Math.exp(t.scale_2)):(a[A.OFFSET.SCALE0]=.01,a[A.OFFSET.SCALE1]=.01,a[A.OFFSET.SCALE2]=.01),void 0!==t.f_dc_0){const e=.28209479177387814;a[A.OFFSET.FDC0]=255*(.5+e*t.f_dc_0),a[A.OFFSET.FDC1]=255*(.5+e*t.f_dc_1),a[A.OFFSET.FDC2]=255*(.5+e*t.f_dc_2)}else void 0!==t.red?(a[A.OFFSET.FDC0]=255*t.red,a[A.OFFSET.FDC1]=255*t.green,a[A.OFFSET.FDC2]=255*t.blue):(a[A.OFFSET.FDC0]=0,a[A.OFFSET.FDC1]=0,a[A.OFFSET.FDC2]=0);if(a[A.OFFSET.OPACITY]=void 0!==t.opacity?1/(1+Math.exp(-t.opacity))*255:1,a[A.OFFSET.FDC0]=f(Math.floor(a[A.OFFSET.FDC0]),0,255),a[A.OFFSET.FDC1]=f(Math.floor(a[A.OFFSET.FDC1]),0,255),a[A.OFFSET.FDC2]=f(Math.floor(a[A.OFFSET.FDC2]),0,255),a[A.OFFSET.OPACITY]=f(Math.floor(a[A.OFFSET.OPACITY]),0,255),o>=1)if(void 0!==t.f_rest_0){for(let e=0;e<9;e++)a[A.OFFSET.FRC0+e]=t[r.sphericalHarmonicsDegree1Fields[e]];if(o>=2)for(let e=0;e<15;e++)a[A.OFFSET.FRC9+e]=t[r.sphericalHarmonicsDegree2Fields[e]]}else a[A.OFFSET.FRC0]=0,a[A.OFFSET.FRC1]=0,a[A.OFFSET.FRC2]=0;return null==t.rot_0?n.set(0,0,0,1):(n.set(t.rot_0,t.rot_1,t.rot_2,t.rot_3),n.normalize()),a[A.OFFSET.ROTATION0]=n.x,a[A.OFFSET.ROTATION1]=n.y,a[A.OFFSET.ROTATION2]=n.z,a[A.OFFSET.ROTATION3]=n.w,a[A.OFFSET.X]=t.x,a[A.OFFSET.Y]=t.y,a[A.OFFSET.Z]=t.z,a}}();static parseToUncompressedSplatArray(e,t=0){const n=z.decodeHeadeFromBuffer(e);if(n.compressed)return L.parseToUncompressedSplatArray(e);{const s=n.splatCount,r=z.findVertexData(e,n),i=new A(t);for(let e=0;e<s;e++){const s=z.parseToUncompressedSplat(r,e,n,0,t);i.addSplat(s)}return i}}}class H{constructor(e,t,n,s){this.sectionCount=e,this.sectionFilters=t,this.groupingParameters=n,this.partitionGenerator=s}partitionUncompressedSplatArray(e){let t,n,s;if(this.partitionGenerator){const r=this.partitionGenerator(e);t=r.groupingParameters,n=r.sectionCount,s=r.sectionFilters}else t=this.groupingParameters,n=this.sectionCount,s=this.sectionFilters;const r=[];for(let t=0;t<n;t++){const n=new A(e.sphericalHarmonicsDegree),i=s[t];for(let t=0;t<e.splatCount;t++)i(t)&&n.addSplatFromArray(e,t);r.push(n)}return{splatArrays:r,parameters:t}}static getStandardPartitioner(t=0,n=new e.Vector3,s=M.BucketBlockSize,r=M.BucketSize){return new H(void 0,void 0,void 0,(i=>{t<=0&&(t=i.splatCount);const o=new e.Vector3,a=new e.Vector3,l=.5,c=e=>{e.x=Math.floor(e.x/l)*l,e.y=Math.floor(e.y/l)*l,e.z=Math.floor(e.z/l)*l};i.splats.sort(((e,t)=>{o.set(e[A.OFFSET.X],e[A.OFFSET.Y],e[A.OFFSET.Z]).sub(n),c(o);const s=o.lengthSq();a.set(t[A.OFFSET.X],t[A.OFFSET.Y],t[A.OFFSET.Z]).sub(n),c(a);return s>a.lengthSq()?1:-1}));const h=[],d=[];t=Math.min(i.splatCount,t);const p=Math.ceil(i.splatCount/t);let u=0;for(let e=0;e<p;e++){let e=u;h.push((n=>n>=e&&n<e+t)),d.push({blocksSize:s,bucketSize:r}),u+=t}return{sectionCount:h.length,sectionFilters:h,groupingParameters:d}}))}}class _{constructor(t,n,s,r,i,o,a){this.splatPartitioner=t,this.alphaRemovalThreshold=n,this.compressionLevel=s,this.sectionSize=r,this.sceneCenter=i?(new e.Vector3).copy(i):void 0,this.blockSize=o,this.bucketSize=a}generateFromUncompressedSplatArray(e){const t=this.splatPartitioner.partitionUncompressedSplatArray(e);return M.generateFromUncompressedSplatArrays(t.splatArrays,this.alphaRemovalThreshold,this.compressionLevel,this.sceneCenter,this.blockSize,this.bucketSize,t.parameters)}static getStandardGenerator(t=1,n=1,s=0,r=new e.Vector3,i=M.BucketBlockSize,o=M.BucketSize){const a=H.getStandardPartitioner(s,r,i,o);return new _(a,t,n,s,r,i,o)}}const U=0,V=1,N=2;class W{static DepthMapRange=65536;static MemoryPageSize=65536;static BytesPerFloat=4;static BytesPerInt=4;static MaxScenes=32;static StreamingSectionSize=524288}function j(e,t){let n=0;for(let t of e)n+=t.sizeBytes;(!t||t.byteLength<n)&&(t=new ArrayBuffer(n));let s=0;for(let n of e)new Uint8Array(t,s,n.sizeBytes).set(n.data),s+=n.sizeBytes;return t}class G{static loadFromURL(t,n,s,r,i,o,a=0,l,c,h,d){const p=W.StreamingSectionSize,u=M.HeaderSizeBytes+M.SectionHeaderSizeBytes;let f,g,S,y,C,A=0,x=0,v=!1,w=!1,b=!1,T=new Promise((e=>{C=e})),F=0,B=0,E=0,D="",P=null,R=[];const I=new TextDecoder;return m(t,((t,i,o)=>{const l=t>=100;if(s){if(o&&(R.push({data:o,sizeBytes:o.byteLength,startBytes:E,endBytes:E+o.byteLength}),E+=o.byteLength),v){if(b&&!w){const e=P.headerSizeBytes+P.chunkElement.storageSizeBytes;y=j(R,y),y.byteLength>=e&&(L.readElementData(P.chunkElement,y,P.headerSizeBytes),F=e,B=e,w=!0)}}else if(D+=I.decode(o),z.checkTextForEndHeader(D)){P=z.decodeHeaderText(D),a=Math.min(a,P.sphericalHarmonicsDegree),b=P.compressed,b?(P=L.decodeHeaderText(D),A=P.vertexElement.count):(A=P.splatCount,w=!0);const t=M.CompressionLevels[0].SphericalHarmonicsDegrees[a],n=u+t.BytesPerSplat*A;g=new ArrayBuffer(n),M.writeHeaderToBuffer({versionMajor:M.CurrentMajorVersion,versionMinor:M.CurrentMinorVersion,maxSectionCount:1,sectionCount:1,maxSplatCount:A,splatCount:x,compressionLevel:0,sceneCenter:new e.Vector3},g),F=P.headerSizeBytes,B=P.headerSizeBytes,v=!0}if(v&&w){if(R.length>0){f=j(R,f);if(E-F>p||l){const e=E-B,t=Math.floor(e/P.bytesPerSplat),n=t*P.bytesPerSplat,s=e-n,i=x+t,o=B-R[0].startBytes,c=new DataView(f,o,n),h=M.CompressionLevels[0].SphericalHarmonicsDegrees[a],d=x*h.BytesPerSplat+u;if(b?L.parseToUncompressedSplatBufferSection(P.chunkElement,P.vertexElement,0,t-1,x,c,0,g,d):z.parseToUncompressedSplatBufferSection(P,0,t-1,c,0,g,d,a),x=i,S||(M.writeSectionHeaderToBuffer({maxSplatCount:A,splatCount:x,bucketSize:0,bucketCount:0,bucketBlockSize:0,compressionScaleRange:0,storageSizeBytes:0,fullBucketCount:0,partiallyFilledBucketCount:0,sphericalHarmonicsDegree:a},0,g,M.HeaderSizeBytes),S=new M(g,!1)),S.updateLoadedCounts(1,x),r(S,l),F+=p,B+=n,0===s)R=[];else{let e=[],t=0;for(let n=R.length-1;n>=0;n--){const r=R[n];if(t+=r.sizeBytes,e.unshift(r),t>=s)break}R=e}}}l&&C(S)}}n&&n(t,i,U)}),!s).then((e=>{n&&n(0,"0%",V);return(s?T:G.loadFromFileData(e,i,o,a,l,c,h,d)).then((e=>(n&&n(100,"100%",N),e)))}))}static loadFromFileData(e,t,n,s=0,r,i,o,a){return y((()=>z.parseToUncompressedSplatArray(e,s))).then((e=>_.getStandardGenerator(t,n,r,i,o,a).generateFromUncompressedSplatArray(e)))}}class Q{static RowSizeBytes=32;static CenterSizeBytes=12;static ScaleSizeBytes=12;static RotationSizeBytes=4;static ColorSizeBytes=4;static parseToUncompressedSplatBufferSection(t,n,s,r,i,o){const a=M.CompressionLevels[0].BytesPerCenter,l=M.CompressionLevels[0].BytesPerScale,c=M.CompressionLevels[0].BytesPerRotation,h=M.CompressionLevels[0].SphericalHarmonicsDegrees[0].BytesPerSplat;for(let d=t;d<=n;d++){const t=d*Q.RowSizeBytes+r,n=new Float32Array(s,t,3),p=new Float32Array(s,t+Q.CenterSizeBytes,3),u=new Uint8Array(s,t+Q.CenterSizeBytes+Q.ScaleSizeBytes,4),m=new Uint8Array(s,t+Q.CenterSizeBytes+Q.ScaleSizeBytes+Q.RotationSizeBytes,4),f=new e.Quaternion((m[1]-128)/128,(m[2]-128)/128,(m[3]-128)/128,(m[0]-128)/128);f.normalize();const g=d*h+o,S=new Float32Array(i,g,3),y=new Float32Array(i,g+a,3),C=new Float32Array(i,g+a+l,4),A=new Uint8Array(i,g+a+l+c,4);S[0]=n[0],S[1]=n[1],S[2]=n[2],y[0]=p[0],y[1]=p[1],y[2]=p[2],C[0]=f.w,C[1]=f.x,C[2]=f.y,C[3]=f.z,A[0]=u[0],A[1]=u[1],A[2]=u[2],A[3]=u[3]}}static parseStandardSplatToUncompressedSplatArray(t){const n=t.byteLength/Q.RowSizeBytes,s=new A;for(let r=0;r<n;r++){const n=r*Q.RowSizeBytes,i=new Float32Array(t,n,3),o=new Float32Array(t,n+Q.CenterSizeBytes,3),a=new Uint8Array(t,n+Q.CenterSizeBytes+Q.ScaleSizeBytes,4),l=new Uint8Array(t,n+Q.CenterSizeBytes+Q.ScaleSizeBytes+Q.ColorSizeBytes,4),c=new e.Quaternion((l[1]-128)/128,(l[2]-128)/128,(l[3]-128)/128,(l[0]-128)/128);c.normalize(),s.addSplatFromComonents(i[0],i[1],i[2],o[0],o[1],o[2],c.w,c.x,c.y,c.z,a[0],a[1],a[2],a[3])}return s}}class X{static loadFromURL(t,n,s,r,i,o,a,l,c,h,d){const p=M.HeaderSizeBytes+M.SectionHeaderSizeBytes,u=W.StreamingSectionSize;let f,g,S,y,C=0,A=0,x=new Promise((e=>{y=e})),v=0,w=0,b=[];return m(t,((t,i,o,a)=>{const l=t>=100;if(a||(s=!1),s){if(!f){C=a/Q.RowSizeBytes,f=new ArrayBuffer(a);const t=M.CompressionLevels[0].SphericalHarmonicsDegrees[0].BytesPerSplat;g=new ArrayBuffer(p+t*C),M.writeHeaderToBuffer({versionMajor:M.CurrentMajorVersion,versionMinor:M.CurrentMinorVersion,maxSectionCount:1,sectionCount:1,maxSplatCount:C,splatCount:A,compressionLevel:0,sceneCenter:new e.Vector3},g)}if(o){b.push(o),new Uint8Array(f,w,o.byteLength).set(new Uint8Array(o)),w+=o.byteLength;const e=w-v;if(e>u||l){const t=(l?e:u)/Q.RowSizeBytes,n=A+t;Q.parseToUncompressedSplatBufferSection(A,n-1,f,0,g,p),A=n,S||(M.writeSectionHeaderToBuffer({maxSplatCount:C,splatCount:A,bucketSize:0,bucketCount:0,bucketBlockSize:0,compressionScaleRange:0,storageSizeBytes:0,fullBucketCount:0,partiallyFilledBucketCount:0},0,g,M.HeaderSizeBytes),S=new M(g,!1)),S.updateLoadedCounts(1,A),r(S,l),v+=u}}l&&y(S)}return n&&n(t,i,U),s}),!0).then((e=>{n&&n(0,"0%",V);return(s?x:X.loadFromFileData(e,i,o,a,l,c,h,d)).then((e=>(n&&n(100,"100%",N),e)))}))}static loadFromFileData(t,n,s,r,i,o,a,l){return y((()=>{const c=Q.parseStandardSplatToUncompressedSplatArray(t);if(r){return _.getStandardGenerator(n,s,i,o,a,l).generateFromUncompressedSplatArray(c)}return M.generateFromUncompressedSplatArrays([c],n,0,new e.Vector3)}))}}class Y{static checkVersion(e){const t=M.CurrentMajorVersion,n=M.CurrentMinorVersion,s=M.parseHeader(e);if(s.versionMajor===t&&s.versionMinor>=n||s.versionMajor>t)return!0;throw new Error(`KSplat version not supported: v${s.versionMajor}.${s.versionMinor}. Minimum required: v${t}.${n}`)}static loadFromURL(e,t,n,s){let r,i,o,a,l,c,h=!1,d=!1,p=[],u=!1,f=!1,g=0,S=0,y=W.StreamingSectionSize,C=0,A=!1,x=[],v=new Promise((e=>{c=e}));let w=0;const b=()=>{const e=()=>{f=!0;new Blob(x).arrayBuffer().then((e=>{f=!1,u=!0,l=new ArrayBuffer(a.maxSectionCount*M.SectionHeaderSizeBytes),new Uint8Array(l).set(new Uint8Array(e,M.HeaderSizeBytes,a.maxSectionCount*M.SectionHeaderSizeBytes)),p=M.parseSectionHeaders(a,l,0,!1);let t=0;for(let e=0;e<a.maxSectionCount;e++)t+=p[e].storageSizeBytes;const n=M.HeaderSizeBytes+a.maxSectionCount*M.SectionHeaderSizeBytes+t;if(!r){r=new ArrayBuffer(n);let e=0;for(let t=0;t<x.length;t++){const n=x[t];new Uint8Array(r,e,n.byteLength).set(new Uint8Array(n)),e+=n.byteLength}}C=M.HeaderSizeBytes+M.SectionHeaderSizeBytes*a.maxSectionCount;for(let e=0;e<=p.length&&e<a.maxSectionCount;e++)C+=p[e].storageSizeBytes;0===w&&(w++,window.setTimeout((()=>{w--,T(!0)}),1))}))};!f&&!u&&h&&g>=M.HeaderSizeBytes+M.SectionHeaderSizeBytes*a.maxSectionCount&&e()},T=()=>{if(u){if(A)return;A=g>=C;if(g-S>y||A){S=g,i||(i=new M(r,!1));const e=M.HeaderSizeBytes+M.SectionHeaderSizeBytes*a.maxSectionCount;let t=0,n=0,o=0;for(let s=0;s<a.maxSectionCount;s++){const r=p[s],l=e+(t+4*r.partiallyFilledBucketCount+r.bucketStorageSizeBytes*r.bucketCount);if(!(g>=l))break;{n++;const e=g-l,t=M.CompressionLevels[a.compressionLevel].SphericalHarmonicsDegrees[r.sphericalHarmonicsDegree].BytesPerSplat;let c=Math.floor(e/t);c=Math.min(c,r.maxSplatCount),o+=c,i.updateLoadedCounts(n,o),i.updateSectionLoadedCounts(s,c)}t+=r.storageSizeBytes}s(i,A),A&&c(i)}}};return m(e,((e,s,i)=>{i&&(x.push(i),r&&new Uint8Array(r,g,i.byteLength).set(new Uint8Array(i)),g+=i.byteLength),n&&(!h&&!d&&g>=M.HeaderSizeBytes&&(d=!0,new Blob(x).arrayBuffer().then((e=>{o=new ArrayBuffer(M.HeaderSizeBytes),new Uint8Array(o).set(new Uint8Array(e,0,M.HeaderSizeBytes)),Y.checkVersion(o),d=!1,h=!0,a=M.parseHeader(o),window.setTimeout((()=>{b()}),1)}))),b(),T()),t&&t(e,s,U)}),!n).then((e=>{t&&t(0,"0%",V);return(n?v:Y.loadFromFileData(e)).then((e=>(t&&t(100,"100%",N),e)))}))}static loadFromFileData(e){return y((()=>(Y.checkVersion(e),new M(e))))}static downloadFile=function(){let e;return function(t,n){const s=new Blob([t.bufferData],{type:"application/octet-stream"});e||(e=document.createElement("a"),document.body.appendChild(e)),e.download=n,e.href=URL.createObjectURL(s),e.click()}}()}const q={Splat:0,KSplat:1,Ply:2},K=e=>e.endsWith(".ply")?q.Ply:e.endsWith(".splat")?q.Splat:e.endsWith(".ksplat")?q.KSplat:null;var Z=Object.freeze({__proto__:null,sceneFormatFromPath:K});const $={type:"change"},J={type:"start"},ee={type:"end"},te=new t,ne=new n,se=Math.cos(70*s.DEG2RAD);class re extends r{constructor(e,t){super(),this.object=e,this.domElement=t,this.domElement.style.touchAction="none",this.enabled=!0,this.target=new i,this.minDistance=0,this.maxDistance=1/0,this.minZoom=0,this.maxZoom=1/0,this.minPolarAngle=0,this.maxPolarAngle=Math.PI,this.minAzimuthAngle=-1/0,this.maxAzimuthAngle=1/0,this.enableDamping=!1,this.dampingFactor=.05,this.enableZoom=!0,this.zoomSpeed=1,this.enableRotate=!0,this.rotateSpeed=1,this.enablePan=!0,this.panSpeed=1,this.screenSpacePanning=!0,this.keyPanSpeed=7,this.zoomToCursor=!1,this.autoRotate=!1,this.autoRotateSpeed=2,this.keys={LEFT:"KeyA",UP:"KeyW",RIGHT:"KeyD",BOTTOM:"KeyS"},this.mouseButtons={LEFT:o.ROTATE,MIDDLE:o.DOLLY,RIGHT:o.PAN},this.touches={ONE:a.ROTATE,TWO:a.DOLLY_PAN},this.target0=this.target.clone(),this.position0=this.object.position.clone(),this.zoom0=this.object.zoom,this._domElementKeyEvents=null,this.getPolarAngle=function(){return p.phi},this.getAzimuthalAngle=function(){return p.theta},this.getDistance=function(){return this.object.position.distanceTo(this.target)},this.listenToKeyEvents=function(e){e.addEventListener("keydown",re),this._domElementKeyEvents=e},this.stopListenToKeyEvents=function(){this._domElementKeyEvents.removeEventListener("keydown",re),this._domElementKeyEvents=null},this.saveState=function(){n.target0.copy(n.target),n.position0.copy(n.object.position),n.zoom0=n.object.zoom},this.reset=function(){n.target.copy(n.target0),n.object.position.copy(n.position0),n.object.zoom=n.zoom0,this.clearDampedRotation(),this.clearDampedPan(),n.object.updateProjectionMatrix(),n.dispatchEvent($),n.update(),r=s.NONE},this.clearDampedRotation=function(){u.theta=0,u.phi=0},this.clearDampedPan=function(){f.set(0,0,0)},this.update=function(){const t=new i,o=(new l).setFromUnitVectors(e.up,new i(0,1,0)),a=o.clone().invert(),c=new i,h=new l,g=new i,S=2*Math.PI;return function(){o.setFromUnitVectors(e.up,new i(0,1,0)),a.copy(o).invert();const l=n.object.position;t.copy(l).sub(n.target),t.applyQuaternion(o),p.setFromVector3(t),n.autoRotate&&r===s.NONE&&P(2*Math.PI/60/60*n.autoRotateSpeed),n.enableDamping?(p.theta+=u.theta*n.dampingFactor,p.phi+=u.phi*n.dampingFactor):(p.theta+=u.theta,p.phi+=u.phi);let y=n.minAzimuthAngle,C=n.maxAzimuthAngle;isFinite(y)&&isFinite(C)&&(y<-Math.PI?y+=S:y>Math.PI&&(y-=S),C<-Math.PI?C+=S:C>Math.PI&&(C-=S),p.theta=y<=C?Math.max(y,Math.min(C,p.theta)):p.theta>(y+C)/2?Math.max(y,p.theta):Math.min(C,p.theta)),p.phi=Math.max(n.minPolarAngle,Math.min(n.maxPolarAngle,p.phi)),p.makeSafe(),!0===n.enableDamping?n.target.addScaledVector(f,n.dampingFactor):n.target.add(f),n.zoomToCursor&&M||n.object.isOrthographicCamera?p.radius=_(p.radius):p.radius=_(p.radius*m),t.setFromSpherical(p),t.applyQuaternion(a),l.copy(n.target).add(t),n.object.lookAt(n.target),!0===n.enableDamping?(u.theta*=1-n.dampingFactor,u.phi*=1-n.dampingFactor,f.multiplyScalar(1-n.dampingFactor)):(u.set(0,0,0),f.set(0,0,0));let A=!1;if(n.zoomToCursor&&M){let s=null;if(n.object.isPerspectiveCamera){const e=t.length();s=_(e*m);const r=e-s;n.object.position.addScaledVector(T,r),n.object.updateMatrixWorld()}else if(n.object.isOrthographicCamera){const e=new i(F.x,F.y,0);e.unproject(n.object),n.object.zoom=Math.max(n.minZoom,Math.min(n.maxZoom,n.object.zoom/m)),n.object.updateProjectionMatrix(),A=!0;const r=new i(F.x,F.y,0);r.unproject(n.object),n.object.position.sub(r).add(e),n.object.updateMatrixWorld(),s=t.length()}else console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."),n.zoomToCursor=!1;null!==s&&(this.screenSpacePanning?n.target.set(0,0,-1).transformDirection(n.object.matrix).multiplyScalar(s).add(n.object.position):(te.origin.copy(n.object.position),te.direction.set(0,0,-1).transformDirection(n.object.matrix),Math.abs(n.object.up.dot(te.direction))<se?e.lookAt(n.target):(ne.setFromNormalAndCoplanarPoint(n.object.up,n.target),te.intersectPlane(ne,n.target))))}else n.object.isOrthographicCamera&&(n.object.zoom=Math.max(n.minZoom,Math.min(n.maxZoom,n.object.zoom/m)),n.object.updateProjectionMatrix(),A=!0);return m=1,M=!1,!!(A||c.distanceToSquared(n.object.position)>d||8*(1-h.dot(n.object.quaternion))>d||g.distanceToSquared(n.target)>0)&&(n.dispatchEvent($),c.copy(n.object.position),h.copy(n.object.quaternion),g.copy(n.target),A=!1,!0)}}(),this.dispose=function(){n.domElement.removeEventListener("contextmenu",ie),n.domElement.removeEventListener("pointerdown",Y),n.domElement.removeEventListener("pointercancel",K),n.domElement.removeEventListener("wheel",Z),n.domElement.removeEventListener("pointermove",q),n.domElement.removeEventListener("pointerup",K),null!==n._domElementKeyEvents&&(n._domElementKeyEvents.removeEventListener("keydown",re),n._domElementKeyEvents=null)};const n=this,s={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_PAN:4,TOUCH_DOLLY_PAN:5,TOUCH_DOLLY_ROTATE:6};let r=s.NONE;const d=1e-6,p=new c,u=new c;let m=1;const f=new i,g=new h,S=new h,y=new h,C=new h,A=new h,x=new h,v=new h,w=new h,b=new h,T=new i,F=new h;let M=!1;const B=[],E={};function D(){return Math.pow(.95,n.zoomSpeed)}function P(e){u.theta-=e}function R(e){u.phi-=e}const I=function(){const e=new i;return function(t,n){e.setFromMatrixColumn(n,0),e.multiplyScalar(-t),f.add(e)}}(),k=function(){const e=new i;return function(t,s){!0===n.screenSpacePanning?e.setFromMatrixColumn(s,1):(e.setFromMatrixColumn(s,0),e.crossVectors(n.object.up,e)),e.multiplyScalar(t),f.add(e)}}(),O=function(){const e=new i;return function(t,s){const r=n.domElement;if(n.object.isPerspectiveCamera){const i=n.object.position;e.copy(i).sub(n.target);let o=e.length();o*=Math.tan(n.object.fov/2*Math.PI/180),I(2*t*o/r.clientHeight,n.object.matrix),k(2*s*o/r.clientHeight,n.object.matrix)}else n.object.isOrthographicCamera?(I(t*(n.object.right-n.object.left)/n.object.zoom/r.clientWidth,n.object.matrix),k(s*(n.object.top-n.object.bottom)/n.object.zoom/r.clientHeight,n.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),n.enablePan=!1)}}();function L(e){n.object.isPerspectiveCamera||n.object.isOrthographicCamera?m/=e:(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),n.enableZoom=!1)}function z(e){n.object.isPerspectiveCamera||n.object.isOrthographicCamera?m*=e:(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),n.enableZoom=!1)}function H(t){if(!n.zoomToCursor)return;M=!0;const s=n.domElement.getBoundingClientRect(),r=t.clientX-s.left,i=t.clientY-s.top,o=s.width,a=s.height;F.x=r/o*2-1,F.y=-i/a*2+1,T.set(F.x,F.y,1).unproject(e).sub(e.position).normalize()}function _(e){return Math.max(n.minDistance,Math.min(n.maxDistance,e))}function U(e){g.set(e.clientX,e.clientY)}function V(e){C.set(e.clientX,e.clientY)}function N(){if(1===B.length)g.set(B[0].pageX,B[0].pageY);else{const e=.5*(B[0].pageX+B[1].pageX),t=.5*(B[0].pageY+B[1].pageY);g.set(e,t)}}function W(){if(1===B.length)C.set(B[0].pageX,B[0].pageY);else{const e=.5*(B[0].pageX+B[1].pageX),t=.5*(B[0].pageY+B[1].pageY);C.set(e,t)}}function j(){const e=B[0].pageX-B[1].pageX,t=B[0].pageY-B[1].pageY,n=Math.sqrt(e*e+t*t);v.set(0,n)}function G(e){if(1==B.length)S.set(e.pageX,e.pageY);else{const t=ae(e),n=.5*(e.pageX+t.x),s=.5*(e.pageY+t.y);S.set(n,s)}y.subVectors(S,g).multiplyScalar(n.rotateSpeed);const t=n.domElement;P(2*Math.PI*y.x/t.clientHeight),R(2*Math.PI*y.y/t.clientHeight),g.copy(S)}function Q(e){if(1===B.length)A.set(e.pageX,e.pageY);else{const t=ae(e),n=.5*(e.pageX+t.x),s=.5*(e.pageY+t.y);A.set(n,s)}x.subVectors(A,C).multiplyScalar(n.panSpeed),O(x.x,x.y),C.copy(A)}function X(e){const t=ae(e),s=e.pageX-t.x,r=e.pageY-t.y,i=Math.sqrt(s*s+r*r);w.set(0,i),b.set(0,Math.pow(w.y/v.y,n.zoomSpeed)),L(b.y),v.copy(w)}function Y(e){!1!==n.enabled&&(0===B.length&&(n.domElement.setPointerCapture(e.pointerId),n.domElement.addEventListener("pointermove",q),n.domElement.addEventListener("pointerup",K)),function(e){B.push(e)}(e),"touch"===e.pointerType?function(e){switch(oe(e),B.length){case 1:switch(n.touches.ONE){case a.ROTATE:if(!1===n.enableRotate)return;N(),r=s.TOUCH_ROTATE;break;case a.PAN:if(!1===n.enablePan)return;W(),r=s.TOUCH_PAN;break;default:r=s.NONE}break;case 2:switch(n.touches.TWO){case a.DOLLY_PAN:if(!1===n.enableZoom&&!1===n.enablePan)return;n.enableZoom&&j(),n.enablePan&&W(),r=s.TOUCH_DOLLY_PAN;break;case a.DOLLY_ROTATE:if(!1===n.enableZoom&&!1===n.enableRotate)return;n.enableZoom&&j(),n.enableRotate&&N(),r=s.TOUCH_DOLLY_ROTATE;break;default:r=s.NONE}break;default:r=s.NONE}r!==s.NONE&&n.dispatchEvent(J)}(e):function(e){let t;switch(e.button){case 0:t=n.mouseButtons.LEFT;break;case 1:t=n.mouseButtons.MIDDLE;break;case 2:t=n.mouseButtons.RIGHT;break;default:t=-1}switch(t){case o.DOLLY:if(!1===n.enableZoom)return;!function(e){H(e),v.set(e.clientX,e.clientY)}(e),r=s.DOLLY;break;case o.ROTATE:if(e.ctrlKey||e.metaKey||e.shiftKey){if(!1===n.enablePan)return;V(e),r=s.PAN}else{if(!1===n.enableRotate)return;U(e),r=s.ROTATE}break;case o.PAN:if(e.ctrlKey||e.metaKey||e.shiftKey){if(!1===n.enableRotate)return;U(e),r=s.ROTATE}else{if(!1===n.enablePan)return;V(e),r=s.PAN}break;default:r=s.NONE}r!==s.NONE&&n.dispatchEvent(J)}(e))}function q(e){!1!==n.enabled&&("touch"===e.pointerType?function(e){switch(oe(e),r){case s.TOUCH_ROTATE:if(!1===n.enableRotate)return;G(e),n.update();break;case s.TOUCH_PAN:if(!1===n.enablePan)return;Q(e),n.update();break;case s.TOUCH_DOLLY_PAN:if(!1===n.enableZoom&&!1===n.enablePan)return;!function(e){n.enableZoom&&X(e),n.enablePan&&Q(e)}(e),n.update();break;case s.TOUCH_DOLLY_ROTATE:if(!1===n.enableZoom&&!1===n.enableRotate)return;!function(e){n.enableZoom&&X(e),n.enableRotate&&G(e)}(e),n.update();break;default:r=s.NONE}}(e):function(e){switch(r){case s.ROTATE:if(!1===n.enableRotate)return;!function(e){S.set(e.clientX,e.clientY),y.subVectors(S,g).multiplyScalar(n.rotateSpeed);const t=n.domElement;P(2*Math.PI*y.x/t.clientHeight),R(2*Math.PI*y.y/t.clientHeight),g.copy(S),n.update()}(e);break;case s.DOLLY:if(!1===n.enableZoom)return;!function(e){w.set(e.clientX,e.clientY),b.subVectors(w,v),b.y>0?L(D()):b.y<0&&z(D()),v.copy(w),n.update()}(e);break;case s.PAN:if(!1===n.enablePan)return;!function(e){A.set(e.clientX,e.clientY),x.subVectors(A,C).multiplyScalar(n.panSpeed),O(x.x,x.y),C.copy(A),n.update()}(e)}}(e))}function K(e){!function(e){delete E[e.pointerId];for(let t=0;t<B.length;t++)if(B[t].pointerId==e.pointerId)return void B.splice(t,1)}(e),0===B.length&&(n.domElement.releasePointerCapture(e.pointerId),n.domElement.removeEventListener("pointermove",q),n.domElement.removeEventListener("pointerup",K)),n.dispatchEvent(ee),r=s.NONE}function Z(e){!1!==n.enabled&&!1!==n.enableZoom&&r===s.NONE&&(e.preventDefault(),n.dispatchEvent(J),function(e){H(e),e.deltaY<0?z(D()):e.deltaY>0&&L(D()),n.update()}(e),n.dispatchEvent(ee))}function re(e){!1!==n.enabled&&!1!==n.enablePan&&function(e){let t=!1;switch(e.code){case n.keys.UP:e.ctrlKey||e.metaKey||e.shiftKey?R(2*Math.PI*n.rotateSpeed/n.domElement.clientHeight):O(0,n.keyPanSpeed),t=!0;break;case n.keys.BOTTOM:e.ctrlKey||e.metaKey||e.shiftKey?R(-2*Math.PI*n.rotateSpeed/n.domElement.clientHeight):O(0,-n.keyPanSpeed),t=!0;break;case n.keys.LEFT:e.ctrlKey||e.metaKey||e.shiftKey?P(2*Math.PI*n.rotateSpeed/n.domElement.clientHeight):O(n.keyPanSpeed,0),t=!0;break;case n.keys.RIGHT:e.ctrlKey||e.metaKey||e.shiftKey?P(-2*Math.PI*n.rotateSpeed/n.domElement.clientHeight):O(-n.keyPanSpeed,0),t=!0}t&&(e.preventDefault(),n.update())}(e)}function ie(e){!1!==n.enabled&&e.preventDefault()}function oe(e){let t=E[e.pointerId];void 0===t&&(t=new h,E[e.pointerId]=t),t.set(e.pageX,e.pageY)}function ae(e){const t=e.pointerId===B[0].pointerId?B[1]:B[0];return E[t.pointerId]}n.domElement.addEventListener("contextmenu",ie),n.domElement.addEventListener("pointerdown",Y),n.domElement.addEventListener("pointercancel",K),n.domElement.addEventListener("wheel",Z,{passive:!1}),this.update()}}class ie{static elementIDGen=0;constructor(e,t){this.taskIDGen=0,this.elementID=ie.elementIDGen++,this.tasks=[],this.message=e||"Loading...",this.container=t||document.body,this.spinnerContainerOuter=document.createElement("div"),this.spinnerContainerOuter.className=`spinnerOuterContainer${this.elementID}`,this.spinnerContainerOuter.style.display="none",this.spinnerContainerPrimary=document.createElement("div"),this.spinnerContainerPrimary.className=`spinnerContainerPrimary${this.elementID}`,this.spinnerPrimary=document.createElement("div"),this.spinnerPrimary.classList.add(`spinner${this.elementID}`,`spinnerPrimary${this.elementID}`),this.messageContainerPrimary=document.createElement("div"),this.messageContainerPrimary.classList.add(`messageContainer${this.elementID}`,`messageContainerPrimary${this.elementID}`),this.messageContainerPrimary.innerHTML=this.message,this.spinnerContainerMin=document.createElement("div"),this.spinnerContainerMin.className=`spinnerContainerMin${this.elementID}`,this.spinnerMin=document.createElement("div"),this.spinnerMin.classList.add(`spinner${this.elementID}`,`spinnerMin${this.elementID}`),this.messageContainerMin=document.createElement("div"),this.messageContainerMin.classList.add(`messageContainer${this.elementID}`,`messageContainerMin${this.elementID}`),this.messageContainerMin.innerHTML=this.message,this.spinnerContainerPrimary.appendChild(this.spinnerPrimary),this.spinnerContainerPrimary.appendChild(this.messageContainerPrimary),this.spinnerContainerOuter.appendChild(this.spinnerContainerPrimary),this.spinnerContainerMin.appendChild(this.spinnerMin),this.spinnerContainerMin.appendChild(this.messageContainerMin),this.spinnerContainerOuter.appendChild(this.spinnerContainerMin);const n=document.createElement("style");n.innerHTML=`\n\n .spinnerOuterContainer${this.elementID} {\n width: 100%;\n height: 100%;\n margin: 0;\n top: 0;\n left: 0;\n position: absolute;\n pointer-events: none;\n }\n\n .messageContainer${this.elementID} {\n height: 20px;\n font-family: arial;\n font-size: 12pt;\n color: #ffffff;\n text-align: center;\n vertical-align: middle;\n }\n\n .spinner${this.elementID} {\n padding: 15px;\n background: #07e8d6;\n z-index:99999;\n \n aspect-ratio: 1;\n border-radius: 50%;\n --_m: \n conic-gradient(#0000,#000),\n linear-gradient(#000 0 0) content-box;\n -webkit-mask: var(--_m);\n mask: var(--_m);\n -webkit-mask-composite: source-out;\n mask-composite: subtract;\n box-sizing: border-box;\n animation: load 1s linear infinite;\n }\n\n .spinnerContainerPrimary${this.elementID} {\n z-index:99999;\n background-color: rgba(128, 128, 128, 0.75);\n border: #666666 1px solid;\n border-radius: 5px;\n padding-top: 20px;\n padding-bottom: 10px;\n margin: 0;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-80px, -80px);\n width: 180px;\n pointer-events: auto;\n }\n\n .spinnerPrimary${this.elementID} {\n width: 120px;\n margin-left: 30px;\n }\n\n .messageContainerPrimary${this.elementID} {\n padding-top: 15px;\n }\n\n .spinnerContainerMin${this.elementID} {\n z-index:99999;\n background-color: rgba(128, 128, 128, 0.75);\n border: #666666 1px solid;\n border-radius: 5px;\n padding-top: 20px;\n padding-bottom: 15px;\n margin: 0;\n position: absolute;\n bottom: 50px;\n left: 50%;\n transform: translate(-50%, 0);\n display: flex;\n flex-direction: left;\n pointer-events: auto;\n min-width: 250px;\n }\n\n .messageContainerMin${this.elementID} {\n margin-right: 15px;\n }\n\n .spinnerMin${this.elementID} {\n width: 50px;\n height: 50px;\n margin-left: 15px;\n margin-right: 25px;\n }\n\n .messageContainerMin${this.elementID} {\n padding-top: 15px;\n }\n \n @keyframes load {\n to{transform: rotate(1turn)}\n }\n\n `,this.spinnerContainerOuter.appendChild(n),this.container.appendChild(this.spinnerContainerOuter),this.setMinimized(!1,!0),this.fadeTransitions=[]}addTask(e){const t={message:e,id:this.taskIDGen++};return this.tasks.push(t),this.update(),t.id}removeTask(e){let t=0;for(let n of this.tasks){if(n.id===e){this.tasks.splice(t,1);break}t++}this.update()}removeAllTasks(){this.tasks=[],this.update()}setMessageForTask(e,t){for(let n of this.tasks)if(n.id===e){n.message=t;break}this.update()}update(){this.tasks.length>0?(this.show(),this.setMessage(this.tasks[this.tasks.length-1].message)):this.hide()}show(){this.spinnerContainerOuter.style.display="block",this.visible=!0}hide(){this.spinnerContainerOuter.style.display="none",this.visible=!1}setContainer(e){this.container&&this.container.removeChild(this.spinnerContainerOuter),e&&(this.container=e,this.container.appendChild(this.spinnerContainerOuter),this.spinnerContainerOuter.style.zIndex=this.container.style.zIndex+1)}setMinimized(e,t){const n=(e,t,n,s,r)=>{n?e.style.display=t?s:"none":this.fadeTransitions[r]=((e,t,n,s,r)=>{const i=performance.now();let o="none"===e.style.display?0:parseFloat(e.style.opacity);isNaN(o)&&(o=1);const a=window.setInterval((()=>{const l=performance.now()-i;let c,h=Math.min(l/s,1);h>.999&&(h=1),t?(c=(1-h)*o,c<1e-4&&(c=0)):c=(1-o)*h+o,c>0?(e.style.display=n,e.style.opacity=c):e.style.display="none",h>=1&&(r&&r(),window.clearInterval(a))}),16);return a})(e,!t,s,500,(()=>{this.fadeTransitions[r]=null}))};n(this.spinnerContainerPrimary,!e,t,"block",0),n(this.spinnerContainerMin,e,t,"flex",1),this.minimized=e}setMessage(e){this.messageContainerPrimary.innerHTML=e,this.messageContainerMin.innerHTML=e}}class oe{constructor(e){this.idGen=0,this.tasks=[],this.container=e||document.body,this.progressBarContainerOuter=document.createElement("div"),this.progressBarContainerOuter.className="progressBarOuterContainer",this.progressBarContainerOuter.style.display="none",this.progressBarBox=document.createElement("div"),this.progressBarBox.className="progressBarBox",this.progressBarBackground=document.createElement("div"),this.progressBarBackground.className="progressBarBackground",this.progressBar=document.createElement("div"),this.progressBar.className="progressBar",this.progressBarBackground.appendChild(this.progressBar),this.progressBarBox.appendChild(this.progressBarBackground),this.progressBarContainerOuter.appendChild(this.progressBarBox);const t=document.createElement("style");t.innerHTML="\n\n .progressBarOuterContainer {\n width: 100%;\n height: 100%;\n margin: 0;\n top: 0;\n left: 0;\n position: absolute;\n pointer-events: none;\n }\n\n .progressBarBox {\n z-index:99999;\n padding: 7px 9px 5px 7px;\n background-color: rgba(190, 190, 190, 0.75);\n border: #555555 1px solid;\n border-radius: 15px;\n margin: 0;\n position: absolute;\n bottom: 50px;\n left: 50%;\n transform: translate(-50%, 0);\n width: 180px;\n height: 30px;\n pointer-events: auto;\n }\n\n .progressBarBackground {\n width: 100%;\n height: 25px;\n border-radius:10px;\n background-color: rgba(128, 128, 128, 0.75);\n border: #444444 1px solid;\n box-shadow: inset 0 0 10px #333333;\n }\n\n .progressBar {\n height: 25px;\n width: 0px;\n border-radius:10px;\n background-color: rgba(0, 200, 0, 0.75);\n box-shadow: inset 0 0 10px #003300;\n }\n\n ",this.progressBarContainerOuter.appendChild(t),this.container.appendChild(this.progressBarContainerOuter)}show(){this.progressBarContainerOuter.style.display="block"}hide(){this.progressBarContainerOuter.style.display="none"}setProgress(e){this.progressBar.style.width=e+"%"}setContainer(e){this.container&&this.container.removeChild(this.progressBarContainerOuter),e&&(this.container=e,this.container.appendChild(this.progressBarContainerOuter),this.progressBarContainerOuter.style.zIndex=this.container.style.zIndex+1)}}class ae{constructor(e){this.container=e||document.body,this.infoCells={};const t=[["Camera position","cameraPosition"],["Camera look-at","cameraLookAt"],["Camera up","cameraUp"],["Camera mode","orthographicCamera"],["Cursor position","cursorPosition"],["FPS","fps"],["Rendering:","renderSplatCount"],["Sort time","sortTime"],["Render window","renderWindow"],["Focal adjustment","focalAdjustment"],["Splat scale","splatScale"],["Point cloud mode","pointCloudMode"]];this.infoPanelContainer=document.createElement("div");const n=document.createElement("style");n.innerHTML="\n\n .infoPanel {\n width: 430px;\n padding: 10px;\n background-color: rgba(50, 50, 50, 0.85);\n border: #555555 2px solid;\n color: #dddddd;\n border-radius: 10px;\n z-index: 9999;\n font-family: arial;\n font-size: 11pt;\n text-align: left;\n margin: 0;\n top: 10px;\n left:10px;\n position: absolute;\n pointer-events: auto;\n }\n\n .info-panel-cell {\n margin-bottom: 5px;\n padding-bottom: 2px;\n }\n\n .label-cell {\n font-weight: bold;\n font-size: 12pt;\n width: 140px;\n }\n\n ",this.infoPanelContainer.append(n),this.infoPanel=document.createElement("div"),this.infoPanel.className="infoPanel";const s=document.createElement("div");s.style.display="table";for(let e of t){const t=document.createElement("div");t.style.display="table-row",t.className="info-panel-row";const n=document.createElement("div");n.style.display="table-cell",n.innerHTML=`${e[0]}: `,n.classList.add("info-panel-cell","label-cell");const r=document.createElement("div");r.style.display="table-cell",r.style.width="10px",r.innerHTML=" ",r.className="info-panel-cell";const i=document.createElement("div");i.style.display="table-cell",i.innerHTML="",i.className="info-panel-cell",this.infoCells[e[1]]=i,t.appendChild(n),t.appendChild(r),t.appendChild(i),s.appendChild(t)}this.infoPanel.appendChild(s),this.infoPanelContainer.append(this.infoPanel),this.infoPanelContainer.style.display="none",this.container.appendChild(this.infoPanelContainer),this.visible=!1}update=function(e,t,n,s,r,i,o,a,l,c,h,d,p,u){const m=`${t.x.toFixed(5)}, ${t.y.toFixed(5)}, ${t.z.toFixed(5)}`;if(this.infoCells.cameraPosition.innerHTML!==m&&(this.infoCells.cameraPosition.innerHTML=m),n){const e=n,t=`${e.x.toFixed(5)}, ${e.y.toFixed(5)}, ${e.z.toFixed(5)}`;this.infoCells.cameraLookAt.innerHTML!==t&&(this.infoCells.cameraLookAt.innerHTML=t)}const f=`${s.x.toFixed(5)}, ${s.y.toFixed(5)}, ${s.z.toFixed(5)}`;if(this.infoCells.cameraUp.innerHTML!==f&&(this.infoCells.cameraUp.innerHTML=f),this.infoCells.orthographicCamera.innerHTML=r?"Orthographic":"Perspective",i){const e=i,t=`${e.x.toFixed(5)}, ${e.y.toFixed(5)}, ${e.z.toFixed(5)}`;this.infoCells.cursorPosition.innerHTML=t}else this.infoCells.cursorPosition.innerHTML="N/A";this.infoCells.fps.innerHTML=o,this.infoCells.renderWindow.innerHTML=`${e.x} x ${e.y}`,this.infoCells.renderSplatCount.innerHTML=`${l} splats out of ${a} (${c.toFixed(2)}%)`,this.infoCells.sortTime.innerHTML=`${h.toFixed(3)} ms`,this.infoCells.focalAdjustment.innerHTML=`${d.toFixed(3)}`,this.infoCells.splatScale.innerHTML=`${p.toFixed(3)}`,this.infoCells.pointCloudMode.innerHTML=`${u}`};setContainer(e){this.container&&this.container.removeChild(this.infoPanelContainer),e&&(this.container=e,this.container.appendChild(this.infoPanelContainer),this.infoPanelContainer.style.zIndex=this.container.style.zIndex+1)}show(){this.infoPanelContainer.style.display="block",this.visible=!0}hide(){this.infoPanelContainer.style.display="none",this.visible=!1}}class le extends e.Object3D{constructor(t=new e.Vector3(0,0,1),n=new e.Vector3(0,0,0),s=1,r=.1,i=16776960,o=.2*s,a=.2*o){super(),this.type="ArrowHelper";const l=new e.CylinderGeometry(r,r,s,32);l.translate(0,s/2,0);const c=new e.CylinderGeometry(0,a,o,32);c.translate(0,s,0),this.position.copy(n),this.line=new e.Mesh(l,new e.MeshBasicMaterial({color:i,toneMapped:!1})),this.line.matrixAutoUpdate=!1,this.add(this.line),this.cone=new e.Mesh(c,new e.MeshBasicMaterial({color:i,toneMapped:!1})),this.cone.matrixAutoUpdate=!1,this.add(this.cone),this.setDirection(t)}setDirection(e){if(e.y>.99999)this.quaternion.set(0,0,0,1);else if(e.y<-.99999)this.quaternion.set(1,0,0,0);else{_axis.set(e.z,0,-e.x).normalize();const t=Math.acos(e.y);this.quaternion.setFromAxisAngle(_axis,t)}}setColor(e){this.line.material.color.set(e),this.cone.material.color.set(e)}copy(e){return super.copy(e,!1),this.line.copy(e.line),this.cone.copy(e.cone),this}dispose(){this.line.geometry.dispose(),this.line.material.dispose(),this.cone.geometry.dispose(),this.cone.material.dispose()}}class ce{constructor(e){this.threeScene=e,this.splatRenderTarget=null,this.renderTargetCopyQuad=null,this.renderTargetCopyCamera=null,this.meshCursor=null,this.focusMarker=null,this.controlPlane=null,this.debugRoot=null,this.secondaryDebugRoot=null}updateSplatRenderTargetForRenderDimensions(t,n){this.destroySplatRendertarget(),this.splatRenderTarget=new e.WebGLRenderTarget(t,n,{format:e.RGBAFormat,stencilBuffer:!1,depthBuffer:!0}),this.splatRenderTarget.depthTexture=new e.DepthTexture(t,n),this.splatRenderTarget.depthTexture.format=e.DepthFormat,this.splatRenderTarget.depthTexture.type=e.UnsignedIntType}destroySplatRendertarget(){this.splatRenderTarget&&(this.splatRenderTarget=null)}setupRenderTargetCopyObjects(){const t=new e.ShaderMaterial({vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = vec4( position.xy, 0.0, 1.0 ); \n }\n ",fragmentShader:"\n #include <common>\n #include <packing>\n varying vec2 vUv;\n uniform sampler2D sourceColorTexture;\n uniform sampler2D sourceDepthTexture;\n void main() {\n vec4 color = texture2D(sourceColorTexture, vUv);\n float fragDepth = texture2D(sourceDepthTexture, vUv).x;\n gl_FragDepth = fragDepth;\n gl_FragColor = vec4(color.rgb, color.a * 2.0);\n }\n ",uniforms:{sourceColorTexture:{type:"t",value:null},sourceDepthTexture:{type:"t",value:null}},depthWrite:!1,depthTest:!1,transparent:!0,blending:e.CustomBlending,blendSrc:e.SrcAlphaFactor,blendSrcAlpha:e.SrcAlphaFactor,blendDst:e.OneMinusSrcAlphaFactor,blendDstAlpha:e.OneMinusSrcAlphaFactor});t.extensions.fragDepth=!0,this.renderTargetCopyQuad=new e.Mesh(new e.PlaneGeometry(2,2),t),this.renderTargetCopyCamera=new e.OrthographicCamera(-1,1,1,-1,0,1)}destroyRenderTargetCopyObjects(){this.renderTargetCopyQuad&&(S(this.renderTargetCopyQuad),this.renderTargetCopyQuad=null)}setupMeshCursor(){if(!this.meshCursor){const t=new e.ConeGeometry(.5,1.5,32),n=new e.MeshBasicMaterial({color:16777215}),s=new e.Mesh(t,n);s.rotation.set(0,0,Math.PI),s.position.set(0,1,0);const r=new e.Mesh(t,n);r.position.set(0,-1,0);const i=new e.Mesh(t,n);i.rotation.set(0,0,Math.PI/2),i.position.set(1,0,0);const o=new e.Mesh(t,n);o.rotation.set(0,0,-Math.PI/2),o.position.set(-1,0,0),this.meshCursor=new e.Object3D,this.meshCursor.add(s),this.meshCursor.add(r),this.meshCursor.add(i),this.meshCursor.add(o),this.meshCursor.scale.set(.1,.1,.1),this.threeScene.add(this.meshCursor),this.meshCursor.visible=!1}}destroyMeshCursor(){this.meshCursor&&(S(this.meshCursor),this.threeScene.remove(this.meshCursor),this.meshCursor=null)}setMeshCursorVisibility(e){this.meshCursor.visible=e}getMeschCursorVisibility(){return this.meshCursor.visible}setMeshCursorPosition(e){this.meshCursor.position.copy(e)}positionAndOrientMeshCursor(e,t){this.meshCursor.position.copy(e),this.meshCursor.up.copy(t.up),this.meshCursor.lookAt(t.position)}setupFocusMarker(){if(!this.focusMarker){const t=new e.SphereGeometry(.5,32,32),n=ce.buildFocusMarkerMaterial();n.depthTest=!1,n.depthWrite=!1,n.transparent=!0,this.focusMarker=new e.Mesh(t,n)}}destroyFocusMarker(){this.focusMarker&&(S(this.focusMarker),this.focusMarker=null)}updateFocusMarker=function(){const t=new e.Vector3,n=new e.Matrix4,s=new e.Vector3;return function(e,r,i){n.copy(r.matrixWorld).invert(),t.copy(e).applyMatrix4(n),t.normalize().multiplyScalar(10),t.applyMatrix4(r.matrixWorld),s.copy(r.position).sub(e);const o=s.length();this.focusMarker.position.copy(e),this.focusMarker.scale.set(o,o,o),this.focusMarker.material.uniforms.realFocusPosition.value.copy(e),this.focusMarker.material.uniforms.viewport.value.copy(i),this.focusMarker.material.uniformsNeedUpdate=!0}}();setFocusMarkerVisibility(e){this.focusMarker.visible=e}setFocusMarkerOpacity(e){this.focusMarker.material.uniforms.opacity.value=e,this.focusMarker.material.uniformsNeedUpdate=!0}getFocusMarkerOpacity(){return this.focusMarker.material.uniforms.opacity.value}setupControlPlane(){if(!this.controlPlane){const t=new e.PlaneGeometry(1,1);t.rotateX(-Math.PI/2);const n=new e.MeshBasicMaterial({color:16777215});n.transparent=!0,n.opacity=.6,n.depthTest=!1,n.depthWrite=!1,n.side=e.DoubleSide;const s=new e.Mesh(t,n),r=new e.Vector3(0,1,0);r.normalize();const i=new e.Vector3(0,0,0),o=new le(r,i,.5,.01,56576,.1,.03);this.controlPlane=new e.Object3D,this.controlPlane.add(s),this.controlPlane.add(o)}}destroyControlPlane(){this.controlPlane&&(S(this.controlPlane),this.controlPlane=null)}setControlPlaneVisibility(e){this.controlPlane.visible=e}positionAndOrientControlPlane=function(){const t=new e.Quaternion,n=new e.Vector3(0,1,0);return function(e,s){t.setFromUnitVectors(n,s),this.controlPlane.position.copy(e),this.controlPlane.quaternion.copy(t)}}();addDebugMeshes(){this.debugRoot=this.createDebugMeshes(),this.secondaryDebugRoot=this.createSecondaryDebugMeshes(),this.threeScene.add(this.debugRoot),this.threeScene.add(this.secondaryDebugRoot)}destroyDebugMeshes(){for(let e of[this.debugRoot,this.secondaryDebugRoot])e&&(S(e),this.threeScene.remove(e));this.debugRoot=null,this.secondaryDebugRoot=null}createDebugMeshes(t){const n=new e.SphereGeometry(1,32,32),s=new e.Object3D,r=(r,i)=>{let o=new e.Mesh(n,ce.buildDebugMaterial(r));o.renderOrder=t,s.add(o),o.position.fromArray(i)};return r(16711680,[-50,0,0]),r(16711680,[50,0,0]),r(65280,[0,0,-50]),r(65280,[0,0,50]),r(16755200,[5,0,5]),s}createSecondaryDebugMeshes(t){const n=new e.BoxGeometry(3,3,3),s=new e.Object3D;const r=r=>{let i=new e.Mesh(n,ce.buildDebugMaterial(12303291));i.renderOrder=t,s.add(i),i.position.fromArray(r)};let i=10;return r([-10,0,-10]),r([-10,0,i]),r([i,0,-10]),r([i,0,i]),s}static buildDebugMaterial(t){const n={color:{type:"v3",value:new e.Color(t)}},s=new e.ShaderMaterial({uniforms:n,vertexShader:"\n #include <common>\n varying float ndcDepth;\n\n void main() {\n gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position.xyz, 1.0);\n ndcDepth = gl_Position.z / gl_Position.w;\n gl_Position.x = gl_Position.x / gl_Position.w;\n gl_Position.y = gl_Position.y / gl_Position.w;\n gl_Position.z = 0.0;\n gl_Position.w = 1.0;\n \n }\n ",fragmentShader:"\n #include <common>\n uniform vec3 color;\n varying float ndcDepth;\n void main() {\n gl_FragDepth = (ndcDepth + 1.0) / 2.0;\n gl_FragColor = vec4(color.rgb, 0.0);\n }\n ",transparent:!1,depthTest:!0,depthWrite:!0,side:e.FrontSide});return s.extensions.fragDepth=!0,s}static buildFocusMarkerMaterial(t){const n={color:{type:"v3",value:new e.Color(t)},realFocusPosition:{type:"v3",value:new e.Vector3},viewport:{type:"v2",value:new e.Vector2},opacity:{value:0}};return new e.ShaderMaterial({uniforms:n,vertexShader:"\n #include <common>\n\n uniform vec2 viewport;\n uniform vec3 realFocusPosition;\n\n varying vec4 ndcPosition;\n varying vec4 ndcCenter;\n varying vec4 ndcFocusPosition;\n\n void main() {\n float radius = 0.01;\n\n vec4 viewPosition = modelViewMatrix * vec4(position.xyz, 1.0);\n vec4 viewCenter = modelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0);\n\n vec4 viewFocusPosition = modelViewMatrix * vec4(realFocusPosition, 1.0);\n\n ndcPosition = projectionMatrix * viewPosition;\n ndcPosition = ndcPosition * vec4(1.0 / ndcPosition.w);\n ndcCenter = projectionMatrix * viewCenter;\n ndcCenter = ndcCenter * vec4(1.0 / ndcCenter.w);\n\n ndcFocusPosition = projectionMatrix * viewFocusPosition;\n ndcFocusPosition = ndcFocusPosition * vec4(1.0 / ndcFocusPosition.w);\n\n gl_Position = projectionMatrix * viewPosition;\n\n }\n ",fragmentShader:"\n #include <common>\n uniform vec3 color;\n uniform vec2 viewport;\n uniform float opacity;\n\n varying vec4 ndcPosition;\n varying vec4 ndcCenter;\n varying vec4 ndcFocusPosition;\n\n void main() {\n vec2 screenPosition = vec2(ndcPosition) * viewport;\n vec2 screenCenter = vec2(ndcCenter) * viewport;\n\n vec2 screenVec = screenPosition - screenCenter;\n\n float projectedRadius = length(screenVec);\n\n float lineWidth = 0.0005 * viewport.y;\n float aaRange = 0.0025 * viewport.y;\n float radius = 0.06 * viewport.y;\n float radDiff = abs(projectedRadius - radius) - lineWidth;\n float alpha = 1.0 - clamp(radDiff / 5.0, 0.0, 1.0); \n\n gl_FragColor = vec4(color.rgb, alpha * opacity);\n }\n ",transparent:!0,depthTest:!1,depthWrite:!1,side:e.FrontSide})}dispose(){this.destroyMeshCursor(),this.destroyFocusMarker(),this.destroyDebugMeshes(),this.destroyControlPlane(),this.destroyRenderTargetCopyObjects(),this.destroySplatRendertarget()}}const he=new e.Vector3(1,0,0),de=new e.Vector3(0,1,0),pe=new e.Vector3(0,0,1);class ue{constructor(t=new e.Vector3,n=new e.Vector3){this.origin=new e.Vector3,this.direction=new e.Vector3,this.setParameters(t,n)}setParameters(e,t){this.origin.copy(e),this.direction.copy(t).normalize()}boxContainsPoint(e,t,n){return!(t.x<e.min.x-n||t.x>e.max.x+n||t.y<e.min.y-n||t.y>e.max.y+n||t.z<e.min.z-n||t.z>e.max.z+n)}intersectBox=function(){const t=new e.Vector3,n=[],s=[],r=[];return function(e,i){if(s[0]=this.origin.x,s[1]=this.origin.y,s[2]=this.origin.z,r[0]=this.direction.x,r[1]=this.direction.y,r[2]=this.direction.z,this.boxContainsPoint(e,this.origin,1e-4))return i&&(i.origin.copy(this.origin),i.normal.set(0,0,0),i.distance=-1),!0;for(let o=0;o<3;o++){if(0==r[o])continue;const a=0==o?he:1==o?de:pe,l=r[o]<0?e.max:e.min;let c=-Math.sign(r[o]);n[0]=0==o?l.x:1==o?l.y:l.z;let h=n[0]-s[o];if(h*c<0){const l=(o+1)%3,d=(o+2)%3;if(n[2]=r[l]/r[o]*h+s[l],n[1]=r[d]/r[o]*h+s[d],t.set(n[o],n[d],n[l]),this.boxContainsPoint(e,t,1e-4))return i&&(i.origin.copy(t),i.normal.copy(a).multiplyScalar(c),i.distance=t.sub(this.origin).length()),!0}}return!1}}();intersectSphere=function(){const t=new e.Vector3;return function(e,n,s){t.copy(e).sub(this.origin);const r=t.dot(this.direction),i=r*r,o=t.dot(t)-i,a=n*n;if(o>a)return!1;const l=Math.sqrt(a-o),c=r-l,h=r+l;if(h<0)return!1;let d=c<0?h:c;return s&&(s.origin.copy(this.origin).addScaledVector(this.direction,d),s.normal.copy(s.origin).sub(e).normalize(),s.distance=d),!0}}()}class me{constructor(){this.origin=new e.Vector3,this.normal=new e.Vector3,this.distance=0,this.splatIndex=0}set(e,t,n,s){this.origin.copy(e),this.normal.copy(t),this.distance=n,this.splatIndex=s}clone(){const e=new me;return e.origin.copy(this.origin),e.normal.copy(this.normal),e.distance=this.distance,e.splatIndex=this.splatIndex,e}}class fe{constructor(e,t,n=!1){this.ray=new ue(e,t),this.raycastAgainstTrueSplatEllipsoid=n}setFromCameraAndScreenPosition=function(){const t=new e.Vector2;return function(e,n,s){if(t.x=n.x/s.x*2-1,t.y=(s.y-n.y)/s.y*2-1,e.isPerspectiveCamera)this.ray.origin.setFromMatrixPosition(e.matrixWorld),this.ray.direction.set(t.x,t.y,.5).unproject(e).sub(this.ray.origin).normalize(),this.camera=e;else{if(!e.isOrthographicCamera)throw new Error("Raycaster::setFromCameraAndScreenPosition() -> Unsupported camera type");this.ray.origin.set(t.x,t.y,(e.near+e.far)/(e.near-e.far)).unproject(e),this.ray.direction.set(0,0,-1).transformDirection(e.matrixWorld),this.camera=e}}}();intersectSplatMesh=function(){const t=new e.Matrix4,n=new e.Matrix4,s=new e.Matrix4,r=new ue,i=new e.Vector3;return function(e,o=[]){const a=e.getSplatTree();if(a){for(let l=0;l<a.subTrees.length;l++){const c=a.subTrees[l];n.copy(e.matrixWorld),e.dynamicMode&&(e.getSceneTransform(l,s),n.multiply(s)),t.copy(n).invert(),r.origin.copy(this.ray.origin).applyMatrix4(t),r.direction.copy(this.ray.origin).add(this.ray.direction),r.direction.applyMatrix4(t).sub(r.origin).normalize();const h=[];c.rootNode&&this.castRayAtSplatTreeNode(r,a,c.rootNode,h),h.forEach((e=>{e.origin.applyMatrix4(n),e.normal.applyMatrix4(n).normalize(),e.distance=i.copy(e.origin).sub(this.ray.origin).length()})),o.push(...h)}return o.sort(((e,t)=>e.distance>t.distance?1:-1)),o}}}();castRayAtSplatTreeNode=function(){const t=new e.Vector4,n=new e.Vector3,s=new e.Vector3,r=new e.Quaternion,i=new me,o=1e-7,a=new e.Vector3(0,0,0),l=new e.Matrix4,c=new e.Matrix4,h=new e.Matrix4,d=new e.Matrix4,p=new e.Matrix4,u=new ue;return function(e,m,f,g=[]){if(e.intersectBox(f.boundingBox)){if(f.data&&f.data.indexes&&f.data.indexes.length>0)for(let S=0;S<f.data.indexes.length;S++){const y=f.data.indexes[S];if(m.splatMesh.getSplatColor(y,t),m.splatMesh.getSplatCenter(y,n),m.splatMesh.getSplatScaleAndRotation(y,s,r),!(s.x<=o||s.y<=o||s.z<=o))if(this.raycastAgainstTrueSplatEllipsoid){c.makeScale(s.x,s.y,s.z),h.makeRotationFromQuaternion(r);const o=2*Math.log10(t.w);if(l.makeScale(o,o,o),p.copy(l).multiply(h).multiply(c),d.copy(p).invert(),u.origin.copy(e.origin).sub(n).applyMatrix4(d),u.direction.copy(e.origin).add(e.direction).sub(n),u.direction.applyMatrix4(d).sub(u.origin).normalize(),u.intersectSphere(a,1,i)){const e=i.clone();e.splatIndex=y,e.origin.applyMatrix4(p).add(n),g.push(e)}}else{const t=(s.x+s.y+s.z)/3;if(e.intersectSphere(n,t,i)){const e=i.clone();e.splatIndex=y,g.push(e)}}}if(f.children&&f.children.length>0)for(let t of f.children)this.castRayAtSplatTreeNode(e,m,t,g);return g}}}()}class ge{constructor(t,n=new e.Vector3,s=new e.Quaternion,r=new e.Vector3(1,1,1),i=1){this.splatBuffer=t,this.position=n.clone(),this.quaternion=s.clone(),this.scale=r.clone(),this.transform=new e.Matrix4,this.minimumAlpha=i,this.updateTransform()}copyTransformData(e){this.position.copy(e.position),this.quaternion.copy(e.quaternion),this.scale.copy(e.scale),this.transform.copy(e.transform)}updateTransform(){this.transform.compose(this.position,this.quaternion,this.scale)}}class Se{static idGen=0;constructor(t,n,s,r){this.min=(new e.Vector3).copy(t),this.max=(new e.Vector3).copy(n),this.boundingBox=new e.Box3(this.min,this.max),this.center=(new e.Vector3).copy(this.max).sub(this.min).multiplyScalar(.5).add(this.min),this.depth=s,this.children=[],this.data=null,this.id=r||Se.idGen++}}class ye{constructor(t,n){this.maxDepth=t,this.maxCentersPerNode=n,this.sceneDimensions=new e.Vector3,this.sceneMin=new e.Vector3,this.sceneMax=new e.Vector3,this.rootNode=null,this.nodesWithIndexes=[],this.splatMesh=null}static convertWorkerSubTreeNode(t){const n=(new e.Vector3).fromArray(t.min),s=(new e.Vector3).fromArray(t.max),r=new Se(n,s,t.depth,t.id);if(t.data.indexes){r.data={indexes:[]};for(let e of t.data.indexes)r.data.indexes.push(e)}if(t.children)for(let e of t.children)r.children.push(ye.convertWorkerSubTreeNode(e));return r}static convertWorkerSubTree(t,n){const s=new ye(t.maxDepth,t.maxCentersPerNode);s.sceneMin=(new e.Vector3).fromArray(t.sceneMin),s.sceneMax=(new e.Vector3).fromArray(t.sceneMax),s.splatMesh=n,s.rootNode=ye.convertWorkerSubTreeNode(t.rootNode);const r=(e,t)=>{0===e.children.length&&t(e);for(let n of e.children)r(n,t)};return s.nodesWithIndexes=[],r(s.rootNode,(e=>{e.data&&e.data.indexes&&e.data.indexes.length>0&&s.nodesWithIndexes.push(e)})),s}}function Ce(e){let t=0;class n{constructor(e,t){this.min=[e[0],e[1],e[2]],this.max=[t[0],t[1],t[2]]}containsPoint(e){return e[0]>=this.min[0]&&e[0]<=this.max[0]&&e[1]>=this.min[1]&&e[1]<=this.max[1]&&e[2]>=this.min[2]&&e[2]<=this.max[2]}}class s{constructor(e,t){this.maxDepth=e,this.maxCentersPerNode=t,this.sceneDimensions=[],this.sceneMin=[],this.sceneMax=[],this.rootNode=null,this.addedIndexes={},this.nodesWithIndexes=[],this.splatMesh=null,this.disposed=!1}}class r{constructor(e,n,s,r){this.min=[e[0],e[1],e[2]],this.max=[n[0],n[1],n[2]],this.center=[.5*(n[0]-e[0])+e[0],.5*(n[1]-e[1])+e[1],.5*(n[2]-e[2])+e[2]],this.depth=s,this.children=[],this.data=null,this.id=r||t++}}processSplatTreeNode=function(e,t,s,i){const o=t.data.indexes.length;if(o<e.maxCentersPerNode||t.depth>e.maxDepth){const n=[];for(let s=0;s<t.data.indexes.length;s++)e.addedIndexes[t.data.indexes[s]]||(n.push(t.data.indexes[s]),e.addedIndexes[t.data.indexes[s]]=!0);return t.data.indexes=n,t.data.indexes.sort(((e,t)=>e>t?1:-1)),void e.nodesWithIndexes.push(t)}const a=[t.max[0]-t.min[0],t.max[1]-t.min[1],t.max[2]-t.min[2]],l=[.5*a[0],.5*a[1],.5*a[2]],c=[t.min[0]+l[0],t.min[1]+l[1],t.min[2]+l[2]],h=[new n([c[0]-l[0],c[1],c[2]-l[2]],[c[0],c[1]+l[1],c[2]]),new n([c[0],c[1],c[2]-l[2]],[c[0]+l[0],c[1]+l[1],c[2]]),new n([c[0],c[1],c[2]],[c[0]+l[0],c[1]+l[1],c[2]+l[2]]),new n([c[0]-l[0],c[1],c[2]],[c[0],c[1]+l[1],c[2]+l[2]]),new n([c[0]-l[0],c[1]-l[1],c[2]-l[2]],[c[0],c[1],c[2]]),new n([c[0],c[1]-l[1],c[2]-l[2]],[c[0]+l[0],c[1],c[2]]),new n([c[0],c[1]-l[1],c[2]],[c[0]+l[0],c[1],c[2]+l[2]]),new n([c[0]-l[0],c[1]-l[1],c[2]],[c[0],c[1],c[2]+l[2]])],d=[],p=[];for(let e=0;e<h.length;e++)d[e]=0,p[e]=[];const u=[0,0,0];for(let e=0;e<o;e++){const n=t.data.indexes[e],r=s[n];u[0]=i[r],u[1]=i[r+1],u[2]=i[r+2];for(let e=0;e<h.length;e++)if(h[e].containsPoint(u)){d[e]++,p[e].push(n);break}}for(let e=0;e<h.length;e++){const n=new r(h[e].min,h[e].max,t.depth+1);n.data={indexes:p[e]},t.children.push(n)}t.data={};for(let n of t.children)processSplatTreeNode(e,n,s,i)};const i=(e,t,n)=>{const i=[0,0,0],o=[0,0,0],a=[],l=Math.floor(e.length/4);for(let t=0;t<l;t++){const n=4*t,s=e[n],r=e[n+1],l=e[n+2],c=Math.round(e[n+3]);(0===t||s<i[0])&&(i[0]=s),(0===t||s>o[0])&&(o[0]=s),(0===t||r<i[1])&&(i[1]=r),(0===t||r>o[1])&&(o[1]=r),(0===t||l<i[2])&&(i[2]=l),(0===t||l>o[2])&&(o[2]=l),a.push(c)}const c=new s(t,n);return c.sceneMin=i,c.sceneMax=o,c.rootNode=new r(c.sceneMin,c.sceneMax,0),c.rootNode.data={indexes:a},c};e.onmessage=t=>{t.data.process&&function(t,n,s){const r=[];for(let e of t){const t=Math.floor(e.length/4);for(let n=0;n<t;n++){const t=4*n;r[Math.round(e[t+3])]=t}}const o=[];for(let e of t){const t=i(e,n,s);o.push(t),processSplatTreeNode(t,t.rootNode,r,e)}e.postMessage({subTrees:o})}(t.data.process.centers,t.data.process.maxDepth,t.data.process.maxCentersPerNode)}}class Ae{constructor(e,t){this.maxDepth=e,this.maxCentersPerNode=t,this.subTrees=[],this.splatMesh=null}dispose(){this.diposeSplatTreeWorker(),this.disposed=!0}diposeSplatTreeWorker(){this.splatTreeWorker&&this.splatTreeWorker.terminate(),this.splatTreeWorker=null}processSplatMesh=function(t,n=(()=>!0),s,r){this.splatTreeWorker||(this.splatTreeWorker=new Worker(URL.createObjectURL(new Blob(["(",Ce.toString(),")(self)"],{type:"application/javascript"})))),this.splatMesh=t,this.subTrees=[];const i=new e.Vector3,o=(e,s)=>{const r=new Float32Array(4*s);let o=0;for(let a=0;a<s;a++){const s=a+e;if(n(s)){t.getSplatCenter(s,i);const e=4*o;r[e]=i.x,r[e+1]=i.y,r[e+2]=i.z,r[e+3]=s,o++}}return r};return new Promise((e=>{const n=()=>!!this.disposed&&(this.diposeSplatTreeWorker(),e(),!0);s&&s(!1),y((()=>{if(n())return;const i=[];if(t.dynamicMode){let e=0;for(let n=0;n<t.scenes.length;n++){const s=t.getScene(n).splatBuffer.getSplatCount(),r=o(e,s);i.push(r),e+=s}}else{const e=o(0,t.getSplatCount());i.push(e)}this.splatTreeWorker.onmessage=s=>{n()||s.data.subTrees&&(r&&r(!1),y((()=>{if(!n()){for(let e of s.data.subTrees){const n=ye.convertWorkerSubTree(e,t);this.subTrees.push(n)}this.diposeSplatTreeWorker(),r&&r(!0),y((()=>{e()}))}})))},y((()=>{if(n())return;s&&s(!0);const e=i.map((e=>e.buffer));!function(e,t,n,s,r){e.postMessage({process:{centers:t,maxDepth:s,maxCentersPerNode:r}},n)}(this.splatTreeWorker,i,e,this.maxDepth,this.maxCentersPerNode)}))}))}))};countLeaves(){let e=0;return this.visitLeaves((()=>{e++})),e}visitLeaves(e){const t=(e,n)=>{0===e.children.length&&n(e);for(let s of e.children)t(s,n)};for(let n of this.subTrees)t(n.rootNode,e)}}function xe(e){const t={};function n(n){if(void 0!==t[n])return t[n];let s;switch(n){case"WEBGL_depth_texture":s=e.getExtension("WEBGL_depth_texture")||e.getExtension("MOZ_WEBGL_depth_texture")||e.getExtension("WEBKIT_WEBGL_depth_texture");break;case"EXT_texture_filter_anisotropic":s=e.getExtension("EXT_texture_filter_anisotropic")||e.getExtension("MOZ_EXT_texture_filter_anisotropic")||e.getExtension("WEBKIT_EXT_texture_filter_anisotropic");break;case"WEBGL_compressed_texture_s3tc":s=e.getExtension("WEBGL_compressed_texture_s3tc")||e.getExtension("MOZ_WEBGL_compressed_texture_s3tc")||e.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc");break;case"WEBGL_compressed_texture_pvrtc":s=e.getExtension("WEBGL_compressed_texture_pvrtc")||e.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc");break;default:s=e.getExtension(n)}return t[n]=s,s}return{has:function(e){return null!==n(e)},init:function(e){e.isWebGL2?(n("EXT_color_buffer_float"),n("WEBGL_clip_cull_distance")):(n("WEBGL_depth_texture"),n("OES_texture_float"),n("OES_texture_half_float"),n("OES_texture_half_float_linear"),n("OES_standard_derivatives"),n("OES_element_index_uint"),n("OES_vertex_array_object"),n("ANGLE_instanced_arrays")),n("OES_texture_float_linear"),n("EXT_color_buffer_half_float"),n("WEBGL_multisampled_render_to_texture")},get:function(e){const t=n(e);return null===t&&console.warn("THREE.WebGLRenderer: "+e+" extension not supported."),t}}}function ve(e,t,n){let s;function r(t){if("highp"===t){if(e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_FLOAT).precision>0&&e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).precision>0)return"highp";t="mediump"}return"mediump"===t&&e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).precision>0&&e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).precision>0?"mediump":"lowp"}const i="undefined"!=typeof WebGL2RenderingContext&&"WebGL2RenderingContext"===e.constructor.name;let o=void 0!==n.precision?n.precision:"highp";const a=r(o);a!==o&&(console.warn("THREE.WebGLRenderer:",o,"not supported, using",a,"instead."),o=a);const l=i||t.has("WEBGL_draw_buffers"),c=!0===n.logarithmicDepthBuffer,h=e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS),d=e.getParameter(e.MAX_VERTEX_TEXTURE_IMAGE_UNITS),p=e.getParameter(e.MAX_TEXTURE_SIZE),u=e.getParameter(e.MAX_CUBE_MAP_TEXTURE_SIZE),m=e.getParameter(e.MAX_VERTEX_ATTRIBS),f=e.getParameter(e.MAX_VERTEX_UNIFORM_VECTORS),g=e.getParameter(e.MAX_VARYING_VECTORS),S=e.getParameter(e.MAX_FRAGMENT_UNIFORM_VECTORS),y=d>0,C=i||t.has("OES_texture_float");return{isWebGL2:i,drawBuffers:l,getMaxAnisotropy:function(){if(void 0!==s)return s;if(!0===t.has("EXT_texture_filter_anisotropic")){const n=t.get("EXT_texture_filter_anisotropic");s=e.getParameter(n.MAX_TEXTURE_MAX_ANISOTROPY_EXT)}else s=0;return s},getMaxPrecision:r,precision:o,logarithmicDepthBuffer:c,maxTextures:h,maxVertexTextures:d,maxTextureSize:p,maxCubemapSize:u,maxAttributes:m,maxVertexUniforms:f,maxVaryings:g,maxFragmentUniforms:S,vertexTextures:y,floatFragmentTextures:C,floatVertexTextures:y&&C,maxSamples:i?e.getParameter(e.MAX_SAMPLES):0}}const we={Default:0,Gradual:1,Instant:2},be={None:0,Error:1,Warning:2,Info:3,Debug:4},Te=new e.BufferGeometry,Fe=new e.MeshBasicMaterial;class Me extends e.Mesh{constructor(t=!0,n=!1,s=1,r=!0,i=!1,o=!1,a=2048,l=be.None,c=0){super(Te,Fe),this.renderer=void 0,this.halfPrecisionCovariancesOnGPU=n,this.dynamicMode=t,this.devicePixelRatio=s,this.enableDistancesComputationOnGPU=r,this.integerBasedDistancesComputation=i,this.antialiased=o,this.maxScreenSpaceSplatSize=a,this.logLevel=l,this.sphericalHarmonicsDegree=c,this.minSphericalHarmonicsDegree=0,this.scenes=[],this.splatTree=null,this.baseSplatTree=null,this.splatDataTextures={},this.distancesTransformFeedback={id:null,vertexShader:null,fragmentShader:null,program:null,centersBuffer:null,transformIndexesBuffer:null,outDistancesBuffer:null,centersLoc:-1,modelViewProjLoc:-1,transformIndexesLoc:-1,transformsLocs:[]},this.globalSplatIndexToLocalSplatIndexMap=[],this.globalSplatIndexToSceneIndexMap=[],this.lastBuildSplatCount=0,this.lastBuildScenes=[],this.lastBuildMaxSplatCount=0,this.lastBuildSceneCount=0,this.firstRenderTime=-1,this.finalBuild=!1,this.webGLUtils=null,this.boundingBox=new e.Box3,this.calculatedSceneCenter=new e.Vector3,this.maxSplatDistanceFromSceneCenter=0,this.visibleRegionBufferRadius=0,this.visibleRegionRadius=0,this.visibleRegionFadeStartRadius=0,this.visibleRegionChanging=!1,this.splatScale=1,this.pointCloudModeEnabled=!1,this.disposed=!1,this.lastRenderer=null,this.visible=!1}static buildMaterial(t=!1,n=!1,s=2048,r=1,i=!1,o=0){let a="\n precision highp float;\n #include <common>\n\n attribute uint splatIndex;\n\n uniform highp sampler2D covariancesTexture;\n uniform highp usampler2D centersColorsTexture;\n uniform highp sampler2D sphericalHarmonicsTexture;";t&&(a+=`\n uniform highp usampler2D transformIndexesTexture;\n uniform highp mat4 transforms[${W.MaxScenes}];\n uniform vec2 transformIndexesTextureSize;\n `),a+="\n uniform vec2 focal;\n uniform float orthoZoom;\n uniform int orthographicMode;\n uniform int pointCloudModeEnabled;\n uniform float inverseFocalAdjustment;\n uniform vec2 viewport;\n uniform vec2 basisViewport;\n uniform vec2 covariancesTextureSize;\n uniform vec2 centersColorsTextureSize;\n uniform int sphericalHarmonicsDegree;\n uniform vec2 sphericalHarmonicsTextureSize;\n uniform int sphericalHarmonics8BitMode;\n uniform float visibleRegionRadius;\n uniform float visibleRegionFadeStartRadius;\n uniform float firstRenderTime;\n uniform float currentTime;\n uniform int fadeInComplete;\n uniform vec3 sceneCenter;\n uniform float splatScale;\n\n varying vec4 vColor;\n varying vec2 vUv;\n\n varying vec2 vPosition;\n\n const float sqrt8 = sqrt(8.0);\n const float minAlpha = 1.0 / 255.0;\n\n const vec4 encodeNorm4 = vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);\n const uvec4 mask4 = uvec4(uint(0x000000FF), uint(0x0000FF00), uint(0x00FF0000), uint(0xFF000000));\n const uvec4 shift4 = uvec4(0, 8, 16, 24);\n vec4 uintToRGBAVec (uint u) {\n uvec4 urgba = mask4 & u;\n urgba = urgba >> shift4;\n vec4 rgba = vec4(urgba) * encodeNorm4;\n return rgba;\n }\n\n vec2 getDataUV(in int stride, in int offset, in vec2 dimensions) {\n vec2 samplerUV = vec2(0.0, 0.0);\n float d = float(splatIndex * uint(stride) + uint(offset)) / dimensions.x;\n samplerUV.y = float(floor(d)) / dimensions.y;\n samplerUV.x = fract(d);\n return samplerUV;\n }\n\n vec2 getDataUVF(in uint sIndex, in float stride, in uint offset, in vec2 dimensions) {\n vec2 samplerUV = vec2(0.0, 0.0);\n float d = float(uint(float(sIndex) * stride) + offset) / dimensions.x;\n samplerUV.y = float(floor(d)) / dimensions.y;\n samplerUV.x = fract(d);\n return samplerUV;\n }\n\n const float SH_C1 = 0.4886025119029199f;\n const float[5] SH_C2 = float[](1.0925484, -1.0925484, 0.3153916, -1.0925484, 0.5462742);\n const vec3 vecOnes3 = vec3(1.0, 1.0, 1.0);\n\n void main () {\n\n uint oddOffset = splatIndex & uint(0x00000001);\n uint doubleOddOffset = oddOffset * uint(2);\n bool isEven = oddOffset == uint(0);\n uint nearestEvenIndex = splatIndex - oddOffset;\n float fOddOffset = float(oddOffset);\n\n uvec4 sampledCenterColor = texture(centersColorsTexture, getDataUV(1, 0, centersColorsTextureSize));\n vec3 splatCenter = uintBitsToFloat(uvec3(sampledCenterColor.gba));",a+=t?"\n uint transformIndex = texture(transformIndexesTexture, getDataUV(1, 0, transformIndexesTextureSize)).r;\n mat4 transform = transforms[transformIndex];\n mat4 transformModelViewMatrix = modelViewMatrix * transform;\n ":"mat4 transformModelViewMatrix = modelViewMatrix;",a+="\n vec4 viewCenter = transformModelViewMatrix * vec4(splatCenter, 1.0);\n\n vec4 clipCenter = projectionMatrix * viewCenter;\n\n float clip = 1.2 * clipCenter.w;\n if (clipCenter.z < -clip || clipCenter.x < -clip || clipCenter.x > clip || clipCenter.y < -clip || clipCenter.y > clip) {\n gl_Position = vec4(0.0, 0.0, 2.0, 1.0);\n return;\n }\n\n vPosition = position.xy;\n vColor = uintToRGBAVec(sampledCenterColor.r);\n\n ",o>=1&&(a+=" \n if (sphericalHarmonicsDegree >= 1) {\n ",a+=t?"\n mat4 mTransform = modelMatrix * transform;\n vec3 worldViewDir = normalize(splatCenter - vec3(inverse(mTransform) * vec4(cameraPosition, 1.0)));\n ":"\n vec3 worldViewDir = normalize(splatCenter - cameraPosition);\n ",a+=o>=2?"\n vec4 sampledSH0123 = texture(sphericalHarmonicsTexture, getDataUV(6, 0, sphericalHarmonicsTextureSize));\n vec4 sampledSH4567 = texture(sphericalHarmonicsTexture, getDataUV(6, 1, sphericalHarmonicsTextureSize));\n vec4 sampledSH891011 = texture(sphericalHarmonicsTexture, getDataUV(6, 2, sphericalHarmonicsTextureSize));\n vec3 sh1 = sampledSH0123.rgb;\n vec3 sh2 = vec3(sampledSH0123.a, sampledSH4567.rg);\n vec3 sh3 = vec3(sampledSH4567.ba, sampledSH891011.r);\n ":"\n vec2 shUV = getDataUVF(nearestEvenIndex, 2.5, doubleOddOffset, sphericalHarmonicsTextureSize);\n vec4 sampledSH0123 = texture(sphericalHarmonicsTexture, shUV);\n shUV = getDataUVF(nearestEvenIndex, 2.5, doubleOddOffset + uint(1), sphericalHarmonicsTextureSize);\n vec4 sampledSH4567 = texture(sphericalHarmonicsTexture, shUV);\n shUV = getDataUVF(nearestEvenIndex, 2.5, doubleOddOffset + uint(2), sphericalHarmonicsTextureSize);\n vec4 sampledSH891011 = texture(sphericalHarmonicsTexture, shUV);\n\n vec3 sh1 = vec3(sampledSH0123.rgb) * (1.0 - fOddOffset) + vec3(sampledSH0123.ba, sampledSH4567.r) * fOddOffset;\n vec3 sh2 = vec3(sampledSH0123.a, sampledSH4567.rg) * (1.0 - fOddOffset) + vec3(sampledSH4567.gba) * fOddOffset;\n vec3 sh3 = vec3(sampledSH4567.ba, sampledSH891011.r) * (1.0 - fOddOffset) + vec3(sampledSH891011.rgb) * fOddOffset;\n ",a+="\n if (sphericalHarmonics8BitMode == 1) {\n sh1 = sh1 * 2.0 - vecOnes3;\n sh2 = sh2 * 2.0 - vecOnes3;\n sh3 = sh3 * 2.0 - vecOnes3;\n }\n float x = worldViewDir.x;\n float y = worldViewDir.y;\n float z = worldViewDir.z;\n vColor.rgb += SH_C1 * (-sh1 * y + sh2 * z - sh3 * x);\n ",o>=2&&(a+="\n if (sphericalHarmonicsDegree >= 2) {\n float xx = x * x;\n float yy = y * y;\n float zz = z * z;\n float xy = x * y;\n float yz = y * z;\n float xz = x * z;\n\n vec4 sampledSH12131415 = texture(sphericalHarmonicsTexture, getDataUV(6, 3, sphericalHarmonicsTextureSize));\n vec4 sampledSH16171819 = texture(sphericalHarmonicsTexture, getDataUV(6, 4, sphericalHarmonicsTextureSize));\n vec4 sampledSH20212223 = texture(sphericalHarmonicsTexture, getDataUV(6, 5, sphericalHarmonicsTextureSize));\n\n vec3 sh4 = sampledSH891011.gba;\n vec3 sh5 = sampledSH12131415.rgb;\n vec3 sh6 = vec3(sampledSH12131415.a, sampledSH16171819.rg);\n vec3 sh7 = vec3(sampledSH16171819.ba, sampledSH20212223.r);\n vec3 sh8 = sampledSH20212223.gba;\n\n if (sphericalHarmonics8BitMode == 1) {\n sh4 = sh4 * 2.0 - vecOnes3;\n sh5 = sh5 * 2.0 - vecOnes3;\n sh6 = sh6 * 2.0 - vecOnes3;\n sh7 = sh7 * 2.0 - vecOnes3;\n sh8 = sh8 * 2.0 - vecOnes3;\n }\n\n vColor.rgb +=\n (SH_C2[0] * xy) * sh4 +\n (SH_C2[1] * yz) * sh5 +\n (SH_C2[2] * (2.0 * zz - xx - yy)) * sh6 +\n (SH_C2[3] * xz) * sh7 +\n (SH_C2[4] * (xx - yy)) * sh8;\n }\n "),a+="\n }\n "),a+="\n\n vec4 sampledCovarianceA = texture(covariancesTexture,\n getDataUVF(nearestEvenIndex, 1.5, oddOffset, covariancesTextureSize));\n vec4 sampledCovarianceB = texture(covariancesTexture,\n getDataUVF(nearestEvenIndex, 1.5, oddOffset + uint(1), covariancesTextureSize));\n\n vec3 cov3D_M11_M12_M13 = vec3(sampledCovarianceA.rgb) * (1.0 - fOddOffset) +\n vec3(sampledCovarianceA.ba, sampledCovarianceB.r) * fOddOffset;\n vec3 cov3D_M22_M23_M33 = vec3(sampledCovarianceA.a, sampledCovarianceB.rg) * (1.0 - fOddOffset) +\n vec3(sampledCovarianceB.gba) * fOddOffset;\n\n // Construct the 3D covariance matrix\n mat3 Vrk = mat3(\n cov3D_M11_M12_M13.x, cov3D_M11_M12_M13.y, cov3D_M11_M12_M13.z,\n cov3D_M11_M12_M13.y, cov3D_M22_M23_M33.x, cov3D_M22_M23_M33.y,\n cov3D_M11_M12_M13.z, cov3D_M22_M23_M33.y, cov3D_M22_M23_M33.z\n );\n\n \n // Construct the Jacobian行列式 of the affine仿射 approximation逼近 of the projection matrix. It will be used to transform the\n // 3D covariance matrix instead of using the actual projection matrix because that transformation would\n // require a non-linear component (perspective division) which would yield a non-gaussian result. (This assumes假设\n // the current projection is a perspective projection).\n //翻译结果:构建投影矩阵仿射近似的雅可比矩阵。它将被用来变换3D协方差矩阵,而不是直接使用实际的投影矩阵,因为使用实际投影矩阵进行变换需要包含非线性成分(透视除法),这会导致非高斯的结果。这里假设当前的投影为透视投影。\n //看不懂 https://zhuanlan.zhihu.com/p/661569671\n\n \n mat3 J;\n if (orthographicMode == 1) {\n // Since the projection is linear, we don't need an approximation\n J = transpose(mat3(orthoZoom, 0.0, 0.0,\n 0.0, orthoZoom, 0.0,\n 0.0, 0.0, 0.0));\n } else {\n // Construct the Jacobian of the affine approximation of the projection matrix. It will be used to transform the\n // 3D covariance matrix instead of using the actual projection matrix because that transformation would\n // require a non-linear component (perspective division) which would yield a non-gaussian result.\n float s = 1.0 / (viewCenter.z * viewCenter.z);\n J = mat3(\n focal.x / viewCenter.z, 0., -(focal.x * viewCenter.x) * s,\n 0., focal.y / viewCenter.z, -(focal.y * viewCenter.y) * s,\n 0., 0., 0.\n );\n }\n\n // Concatenate the projection approximation with the model-view transformation\n mat3 W = transpose(mat3(transformModelViewMatrix));\n mat3 T = W * J;\n\n // Transform the 3D covariance matrix (Vrk) to compute the 2D covariance matrix\n mat3 cov2Dm = transpose(T) * Vrk * T;\n ",a+=n?"\n float detOrig = cov2Dm[0][0] * cov2Dm[1][1] - cov2Dm[0][1] * cov2Dm[0][1];\n cov2Dm[0][0] += 0.3;\n cov2Dm[1][1] += 0.3;\n float detBlur = cov2Dm[0][0] * cov2Dm[1][1] - cov2Dm[0][1] * cov2Dm[0][1];\n float compensation = sqrt(max(detOrig / detBlur, 0.0));\n ":"\n cov2Dm[0][0] += 0.3;\n cov2Dm[1][1] += 0.3;\n float compensation = 1.0;\n ",a+=`\n\n vColor.a *= compensation;\n\n if (vColor.a < minAlpha) return;\n\n // We are interested in the upper-left 2x2 portion of the projected 3D covariance matrix because\n // we only care about the X and Y values. We want the X-diagonal, cov2Dm[0][0],\n // the Y-diagonal, cov2Dm[1][1], and the correlation between the two cov2Dm[0][1]. We don't\n // need cov2Dm[1][0] because it is a symetric matrix.\n vec3 cov2Dv = vec3(cov2Dm[0][0], cov2Dm[0][1], cov2Dm[1][1]);\n\n vec3 ndcCenter = clipCenter.xyz / clipCenter.w;\n\n // We now need to solve for the eigen-values and eigen vectors of the 2D covariance matrix\n // so that we can determine the 2D basis for the splat. This is done using the method described\n // here: https://people.math.harvard.edu/~knill/teaching/math21b2004/exhibits/2dmatrices/index.html 公式出处\n // After calculating the eigen-values and eigen-vectors, we calculate the basis for rendering the splat\n // by normalizing the eigen-vectors and then multiplying them by (sqrt(8) * eigen-value), which is\n // equal to scaling them by sqrt(8) standard deviations.\n //\n // This is a different approach than in the original work at INRIA. In that work they compute the\n // max extents of the projected splat in screen space to form a screen-space aligned bounding rectangle\n // which forms the geometry that is actually rasterized. The dimensions of that bounding box are 3.0\n // times the maximum eigen-value, or 3 standard deviations. They then use the inverse 2D covariance\n // matrix (called 'conic') in the CUDA rendering thread to determine fragment opacity by calculating the\n // full gaussian: exp(-0.5 * (X - mean) * conic * (X - mean)) * splat opacity\n float a = cov2Dv.x;\n float d = cov2Dv.z;\n float b = cov2Dv.y;\n float D = a * d - b * b;\n float trace = a + d; //追踪\n float traceOver2 = 0.5 * trace;\n float term2 = sqrt(max(0.1f, traceOver2 * traceOver2 - D));\n float eigenValue1 = traceOver2 + term2; //特征值L1\n float eigenValue2 = traceOver2 - term2; //特征值L1\n\n if (pointCloudModeEnabled == 1) {// each splat is rendered as a filled circle\n eigenValue1 = eigenValue2 = 0.2;\n }\n\n if (eigenValue2 <= 0.0) return;\n\n vec2 eigenVector1 = normalize(vec2(b, eigenValue1 - a));\n // since the eigen vectors are orthogonal, we derive the second one from the first 由于本征向量是正交的,因此我们从第一个导出第二个\n vec2 eigenVector2 = vec2(eigenVector1.y, -eigenVector1.x);\n\n // We use sqrt(8) standard deviations偏差 instead of 3 to eliminate消除 more of the splat with a very low opacity.\n vec2 basisVector1 = eigenVector1 * splatScale * min(sqrt8 * sqrt(eigenValue1), ${parseInt(s)}.0);\n vec2 basisVector2 = eigenVector2 * splatScale * min(sqrt8 * sqrt(eigenValue2), ${parseInt(s)}.0);\n\n if (fadeInComplete == 0) {\n float opacityAdjust = 1.0;\n float centerDist = length(splatCenter - sceneCenter);\n float renderTime = max(currentTime - firstRenderTime, 0.0);\n\n float fadeDistance = 0.75;\n float distanceLoadFadeInFactor = step(visibleRegionFadeStartRadius, centerDist);\n distanceLoadFadeInFactor = (1.0 - distanceLoadFadeInFactor) +\n (1.0 - clamp((centerDist - visibleRegionFadeStartRadius) / fadeDistance, 0.0, 1.0)) *\n distanceLoadFadeInFactor;\n opacityAdjust *= distanceLoadFadeInFactor;\n vColor.a *= opacityAdjust;\n }\n\n vec2 ndcOffset = vec2(vPosition.x * basisVector1 + vPosition.y * basisVector2) *\n basisViewport * 2.0 * inverseFocalAdjustment;\n\n vec4 quadPos = vec4(ndcCenter.xy + ndcOffset, ndcCenter.z , 1.0);\n gl_Position = quadPos; //将整个正方形做一定的拉伸形变,之后在fs中因为只显示中间的圆,所以也就是显示拉伸后的圆。(vs只计算四个顶点的具体位置,其他位置是插值得到的)\n\n // Scale the position data we send to the fragment shader\n vPosition *= sqrt8;\n }`;const l={sceneCenter:{type:"v3",value:new e.Vector3},fadeInComplete:{type:"i",value:0},orthographicMode:{type:"i",value:0},visibleRegionFadeStartRadius:{type:"f",value:0},visibleRegionRadius:{type:"f",value:0},currentTime:{type:"f",value:0},firstRenderTime:{type:"f",value:0},covariancesTexture:{type:"t",value:null},centersColorsTexture:{type:"t",value:null},sphericalHarmonicsTexture:{type:"t",value:null},focal:{type:"v2",value:new e.Vector2},orthoZoom:{type:"f",value:1},inverseFocalAdjustment:{type:"f",value:1},viewport:{type:"v2",value:new e.Vector2},basisViewport:{type:"v2",value:new e.Vector2},debugColor:{type:"v3",value:new e.Color},covariancesTextureSize:{type:"v2",value:new e.Vector2(1024,1024)},centersColorsTextureSize:{type:"v2",value:new e.Vector2(1024,1024)},sphericalHarmonicsDegree:{type:"i",value:o},sphericalHarmonicsTextureSize:{type:"v2",value:new e.Vector2(1024,1024)},sphericalHarmonics8BitMode:{type:"i",value:0},splatScale:{type:"f",value:r},pointCloudModeEnabled:{type:"i",value:i?1:0}};if(t){l.transformIndexesTexture={type:"t",value:null};const t=[];for(let n=0;n<W.MaxScenes;n++)t.push(new e.Matrix4);l.transforms={type:"mat4",value:t},l.transformIndexesTextureSize={type:"v2",value:new e.Vector2(1024,1024)}}return new e.ShaderMaterial({uniforms:l,vertexShader:a,fragmentShader:"\n precision highp float;\n #include <common>\n \n uniform vec3 debugColor;\n\n varying vec4 vColor;\n varying vec2 vUv;\n\n varying vec2 vPosition;\n\n void main () {\n // Compute the positional squared distance from the center of the splat to the current fragment.\n float A = dot(vPosition, vPosition);\n // Since the positional data in vPosition has been scaled by sqrt(8), the squared result will be\n // scaled by a factor of 8. If the squared result is larger than 8, it means it is outside the ellipse\n // defined by the rectangle formed by vPosition. It also means it's farther\n // away than sqrt(8) standard deviations from the mean.\n if (A > 8.0) discard; //position的范围半径为1。指一个rectangle面中的范围。椭圆外的完全透明\n vec3 color = vColor.rgb;\n\n // Since the rendered splat is scaled by sqrt(8), the inverse covariance matrix that is part of\n // the gaussian formula becomes the identity matrix. We're then left with (X - mean) * (X - mean),\n // and since 'mean' is zero, we have X * X, which is the same as A:\n float opacity = exp(-0.5 * A) * vColor.a; //周围的透明度降低\n\n gl_FragColor = vec4(color.rgb, opacity);\n //不知道为何ply转过来的vColor.a是0,(但是在外面访问的opacity并不是0), 导致全是黑色\n }",transparent:!0,alphaTest:1,blending:e.NormalBlending,depthTest:!0,depthWrite:!1,side:e.DoubleSide})}static buildGeomtery(t){const n=new e.BufferGeometry;n.setIndex([0,1,2,0,2,3]);const s=new Float32Array(12),r=new e.BufferAttribute(s,3);n.setAttribute("position",r),r.setXYZ(0,-1,-1,0),r.setXYZ(1,-1,1,0),r.setXYZ(2,1,1,0),r.setXYZ(3,1,-1,0),r.needsUpdate=!0;const i=(new e.InstancedBufferGeometry).copy(n),o=new Uint32Array(t),a=new e.InstancedBufferAttribute(o,1,!1);return a.setUsage(e.DynamicDrawUsage),i.setAttribute("splatIndex",a),i.instanceCount=0,i}static buildScenes(t,n){const s=[];s.length=t.length;for(let r=0;r<t.length;r++){const i=t[r],o=n[r]||{};let a=o.position||[0,0,0],l=o.rotation||[0,0,0,1],c=o.scale||[1,1,1];const h=(new e.Vector3).fromArray(a),d=(new e.Quaternion).fromArray(l),p=(new e.Vector3).fromArray(c);s[r]=Me.createScene(i,h,d,p,o.splatAlphaRemovalThreshold||1)}return s}static createScene(e,t,n,s,r){return new ge(e,t,n,s,r)}static buildSplatIndexMaps(e){const t=[],n=[];let s=0;for(let r=0;r<e.length;r++){const i=e[r].getMaxSplatCount();for(let e=0;e<i;e++)t[s]=e,n[s]=r,s++}return{localSplatIndexMap:t,sceneIndexMap:n}}buildSplatTree=function(t=[],n,s){return new Promise((r=>{this.disposeSplatTree(),this.baseSplatTree=new Ae(8,1e3);const i=performance.now(),o=new e.Vector4;this.baseSplatTree.processSplatMesh(this,(e=>{this.getSplatColor(e,o);const n=this.getSceneIndexForSplat(e),s=t[n]||1;return o.w>=s}),n,s).then((()=>{const e=performance.now()-i;if(this.logLevel>=be.Info&&console.log("SplatTree build: "+e+" ms"),this.disposed)r();else{this.splatTree=this.baseSplatTree,this.baseSplatTree=null;let e=0,t=0,n=0,s=0;this.splatTree.visitLeaves((r=>{const i=r.data.indexes.length;i>0&&(t+=i,n=Math.max(n,i),s++,e++)})),this.logLevel>=be.Info&&(console.log(`SplatTree leaves: ${this.splatTree.countLeaves()}`),console.log(`SplatTree leaves with splats:${e}`),t/=s,console.log(`Avg splat count per node: ${t}`),console.log(`Total splat count: ${this.getSplatCount()}`)),r()}}))}))};build(t,n,s=!0,r=!1,i,o){this.sceneOptions=n,this.finalBuild=r;const a=Me.getTotalMaxSplatCountForSplatBuffers(t),l=Me.buildScenes(t,n);if(s)for(let e=0;e<this.scenes.length&&e<l.length;e++){const t=l[e],n=this.getScene(e);t.copyTransformData(n)}this.scenes=l;let c=3;for(let e of t){const t=e.getMinSphericalHarmonicsDegree();t<c&&(c=t)}this.minSphericalHarmonicsDegree=Math.min(c,this.sphericalHarmonicsDegree);let h=!1;if(t.length!==this.lastBuildScenes.length)h=!0;else for(let e=0;e<t.length;e++){if(t[e]!==this.lastBuildScenes[e].splatBuffer){h=!0;break}}let d=!0;if((1!==this.scenes.length||this.lastBuildSceneCount!==this.scenes.length||this.lastBuildMaxSplatCount!==a||h)&&(d=!1),!d){this.boundingBox=new e.Box3,this.maxSplatDistanceFromSceneCenter=0,this.visibleRegionBufferRadius=0,this.visibleRegionRadius=0,this.visibleRegionFadeStartRadius=0,this.firstRenderTime=-1,this.lastBuildScenes=[],this.lastBuildSplatCount=0,this.lastBuildMaxSplatCount=0,this.disposeMeshData(),this.geometry=Me.buildGeomtery(a),this.material=Me.buildMaterial(this.dynamicMode,this.antialiased,this.maxScreenSpaceSplatSize,this.splatScale,this.pointCloudModeEnabled,this.minSphericalHarmonicsDegree);const n=Me.buildSplatIndexMaps(t);this.globalSplatIndexToLocalSplatIndexMap=n.localSplatIndexMap,this.globalSplatIndexToSceneIndexMap=n.sceneIndexMap}const p=this.getSplatCount();this.enableDistancesComputationOnGPU&&this.setupDistancesComputationTransformFeedback();const u=this.refreshGPUDataFromSplatBuffers(d);for(let e=0;e<this.scenes.length;e++)this.lastBuildScenes[e]=this.scenes[e];return this.lastBuildSplatCount=p,this.lastBuildMaxSplatCount=this.getMaxSplatCount(),this.lastBuildSceneCount=this.scenes.length,r&&this.scenes.length>0&&this.buildSplatTree(n.map((e=>e.splatAlphaRemovalThreshold||1)),i,o).then((()=>{this.onSplatTreeReadyCallback&&this.onSplatTreeReadyCallback(this.splatTree)})),this.visible=this.scenes.length>0,u}dispose(){this.disposeMeshData(),this.disposeTextures(),this.disposeSplatTree(),this.enableDistancesComputationOnGPU&&(this.computeDistancesOnGPUSyncTimeout&&(clearTimeout(this.computeDistancesOnGPUSyncTimeout),this.computeDistancesOnGPUSyncTimeout=null),this.disposeDistancesComputationGPUResources()),this.scenes=[],this.distancesTransformFeedback={id:null,vertexShader:null,fragmentShader:null,program:null,centersBuffer:null,transformIndexesBuffer:null,outDistancesBuffer:null,centersLoc:-1,modelViewProjLoc:-1,transformIndexesLoc:-1,transformsLocs:[]},this.renderer=null,this.globalSplatIndexToLocalSplatIndexMap=[],this.globalSplatIndexToSceneIndexMap=[],this.lastBuildSplatCount=0,this.lastBuildScenes=[],this.lastBuildMaxSplatCount=0,this.lastBuildSceneCount=0,this.firstRenderTime=-1,this.finalBuild=!1,this.webGLUtils=null,this.boundingBox=new e.Box3,this.calculatedSceneCenter=new e.Vector3,this.maxSplatDistanceFromSceneCenter=0,this.visibleRegionBufferRadius=0,this.visibleRegionRadius=0,this.visibleRegionFadeStartRadius=0,this.visibleRegionChanging=!1,this.splatScale=1,this.pointCloudModeEnabled=!1,this.disposed=!0,this.lastRenderer=null,this.visible=!1}disposeMeshData(){this.geometry&&this.geometry!==Te&&(this.geometry.dispose(),this.geometry=null),this.material&&(this.material.dispose(),this.material=null)}disposeTextures(){for(let e in this.splatDataTextures)if(this.splatDataTextures.hasOwnProperty(e)){const t=this.splatDataTextures[e];t.texture&&(t.texture.dispose(),t.texture=null)}this.splatDataTextures=null}disposeSplatTree(){this.splatTree?(this.splatTree.dispose(),this.splatTree=null):this.baseSplatTree&&(this.baseSplatTree.dispose(),this.baseSplatTree=null)}getSplatTree(){return this.splatTree}onSplatTreeReady(e){this.onSplatTreeReadyCallback=e}getDataForDistancesComputation(e,t){return{centers:this.integerBasedDistancesComputation?this.getIntegerCenters(e,t,!0):this.getFloatCenters(e,t,!0),sceneIndexes:this.getSceneIndexes(e,t)}}refreshGPUDataFromSplatBuffers(e){const t=this.getSplatCount();this.refreshDataTexturesFromSplatBuffers(e);const n=e?this.lastBuildSplatCount:0,{centers:s,sceneIndexes:r}=this.getDataForDistancesComputation(n,t-1);return this.enableDistancesComputationOnGPU&&this.refreshGPUBuffersForDistancesComputation(s,r,e),{from:n,to:t-1,count:t-n,centers:s,sceneIndexes:r}}refreshGPUBuffersForDistancesComputation(e,t,n=!1){const s=n?this.lastBuildSplatCount:0;this.updateGPUCentersBufferForDistancesComputation(n,e,s),this.updateGPUTransformIndexesBufferForDistancesComputation(n,t,s)}refreshDataTexturesFromSplatBuffers(e){e?this.updateDataTextures():this.setupDataTextures(),this.updateVisibleRegion(e)}setupDataTextures(){const t=this.getMaxSplatCount(),n=this.getSplatCount();this.disposeTextures();const s=(n,s)=>{const r=new e.Vector2(4096,1024);for(;r.x*r.y*n<t*s;)r.y*=2;return r},r=this.getTargetCovarianceCompressionLevel(),i=this.getTargetSphericalHarmonicsCompressionLevel(),o=new Float32Array(6*t),a=new Float32Array(3*t),l=new Uint8Array(4*t);let c=Float32Array;1===i?c=Uint16Array:2===i&&(c=Uint8Array);const h=C(this.minSphericalHarmonicsDegree);let d=h;d%2!=0&&d++;const p=this.minSphericalHarmonicsDegree?new c(t*h):void 0;this.fillSplatDataArrays(o,a,l,p,void 0,r,i);const u=s(4,6);let m=r>=1?Uint16Array:Float32Array,f=r>=1?e.HalfFloatType:e.FloatType;const g=new m(u.x*u.y*4);g.set(o);const S=new e.DataTexture(g,u.x,u.y,e.RGBAFormat,f);S.needsUpdate=!0,this.material.uniforms.covariancesTexture.value=S,this.material.uniforms.covariancesTextureSize.value.copy(u);const y=s(4,4),A=new Uint32Array(y.x*y.y*4);Me.updateCenterColorsPaddedData(0,n,a,l,A);const x=new e.DataTexture(A,y.x,y.y,e.RGBAIntegerFormat,e.UnsignedIntType);if(x.internalFormat="RGBA32UI",x.needsUpdate=!0,this.material.uniforms.centersColorsTexture.value=x,this.material.uniforms.centersColorsTextureSize.value.copy(y),this.material.uniformsNeedUpdate=!0,this.splatDataTextures={baseData:{covariances:o,centers:a,colors:l,sphericalHarmonics:p},covariances:{data:g,texture:S,size:u,compressionLevel:r},centerColors:{data:A,texture:x,size:y}},p){const t=4,r=s(t,d),o=new c(r.x*r.y*t);for(let e=0;e<n;e++){const t=h*e,n=d*e;for(let e=0;e<h;e++)o[n+e]=p[t+e]}const a=2===i?e.UnsignedByteType:e.HalfFloatType,l=new e.DataTexture(o,r.x,r.y,e.RGBAFormat,a);l.needsUpdate=!0,this.material.uniforms.sphericalHarmonicsTexture.value=l,this.material.uniforms.sphericalHarmonicsTextureSize.value.copy(r),2===i&&(this.material.uniforms.sphericalHarmonics8BitMode.value=1),this.material.uniformsNeedUpdate=!0,this.splatDataTextures.sphericalHarmonics={componentCount:h,paddedComponentCount:d,data:o,texture:l,size:r,compressionLevel:i}}if(this.dynamicMode){const t=s(1,4),r=new Uint32Array(t.x*t.y*1);for(let e=0;e<n;e++)r[e]=this.globalSplatIndexToSceneIndexMap[e];const i=new e.DataTexture(r,t.x,t.y,e.RedIntegerFormat,e.UnsignedIntType);i.internalFormat="R32UI",i.needsUpdate=!0,this.material.uniforms.transformIndexesTexture.value=i,this.material.uniforms.transformIndexesTextureSize.value.copy(t),this.material.uniformsNeedUpdate=!0,this.splatDataTextures.tansformIndexes={data:r,texture:i,size:t}}}updateDataTextures(){const e=this.getSplatCount(),t=this.splatDataTextures.covariances.compressionLevel,n=this.splatDataTextures.sphericalHarmonics,s=n?n.compressionLevel:0;this.fillSplatDataArrays(this.splatDataTextures.baseData.covariances,this.splatDataTextures.baseData.centers,this.splatDataTextures.baseData.colors,this.splatDataTextures.baseData.sphericalHarmonics,void 0,t,s,this.lastBuildSplatCount,e-1,this.lastBuildSplatCount);const r=this.splatDataTextures.covariances,i=r.data,o=r.texture,a=6*e;for(let e=6*this.lastBuildSplatCount;e<a;e++){const t=this.splatDataTextures.baseData.covariances[e];i[e]=t}const l=this.renderer?this.renderer.properties.get(o):null;if(l&&l.__webglTexture){const n=t?2:4;this.updateDataTexture(i,r,l,4,6,n,this.lastBuildSplatCount,e-1)}else o.needsUpdate=!0;const c=this.splatDataTextures.centerColors,h=c.data,d=c.texture;Me.updateCenterColorsPaddedData(this.lastBuildSplatCount,e,this.splatDataTextures.baseData.centers,this.splatDataTextures.baseData.colors,h);const p=this.renderer?this.renderer.properties.get(d):null;if(p&&p.__webglTexture?this.updateDataTexture(h,c,p,4,4,4,this.lastBuildSplatCount,e-1):d.needsUpdate=!0,this.splatDataTextures.baseData.sphericalHarmonics){const t=n.componentCount,r=n.paddedComponentCount,i=n.data;for(let n=this.lastBuildSplatCount;n<e;n++){const e=t*n,s=r*n;for(let n=0;n<t;n++)i[s+n]=this.splatDataTextures.baseData.sphericalHarmonics[e+n]}const o=n.texture,a=this.renderer?this.renderer.properties.get(o):null;if(a&&a.__webglTexture){const t=4;let o=4;1===s?o=2:2===s&&(o=1),this.updateDataTexture(i,n,a,t,r,o,this.lastBuildSplatCount,e-1)}else o.needsUpdate=!0}if(this.dynamicMode){const t=this.splatDataTextures.tansformIndexes,n=t.data;for(let t=this.lastBuildSplatCount;t<e;t++)n[t]=this.globalSplatIndexToSceneIndexMap[t];const s=t.texture,r=this.renderer?this.renderer.properties.get(s):null;r&&r.__webglTexture?this.updateDataTexture(n,t,r,1,1,1,this.lastBuildSplatCount,e-1):s.needsUpdate=!0}}getTargetCovarianceCompressionLevel(){return this.halfPrecisionCovariancesOnGPU?1:0}getTargetSphericalHarmonicsCompressionLevel(){return Math.max(1,this.getMaximumSplatBufferCompressionLevel())}getMaximumSplatBufferCompressionLevel(){let e;for(let t=0;t<this.scenes.length;t++){const n=this.getScene(t).splatBuffer;(0===t||n.compressionLevel>e)&&(e=n.compressionLevel)}return e}getMinimumSplatBufferCompressionLevel(){let e;for(let t=0;t<this.scenes.length;t++){const n=this.getScene(t).splatBuffer;(0===t||n.compressionLevel<e)&&(e=n.compressionLevel)}return e}static computeTextureUpdateRegion(e,t,n,s,r){const i=r/s,o=e*i,a=Math.floor(o/n),l=a*n*s,c=t*i,h=Math.floor(c/n);return{dataStart:l,dataEnd:h*n*s+n*s,startRow:a,endRow:h}}updateDataTexture(e,t,n,s,r,i,o,a){const l=this.renderer.getContext(),c=Me.computeTextureUpdateRegion(o,a,t.size.x,s,r),h=c.dataEnd-c.dataStart,d=new e.constructor(e.buffer,c.dataStart*i,h),p=c.endRow-c.startRow+1,u=t.texture,m=this.webGLUtils.convert(u.type),f=this.webGLUtils.convert(u.format,u.colorSpace),g=l.getParameter(l.TEXTURE_BINDING_2D);l.bindTexture(l.TEXTURE_2D,n.__webglTexture),l.texSubImage2D(l.TEXTURE_2D,0,0,c.startRow,t.size.x,p,f,m,d),l.bindTexture(l.TEXTURE_2D,g)}static updateCenterColorsPaddedData(e,t,n,s,r){for(let a=e;a<t;a++){const e=4*a,t=3*a,l=4*a;r[l]=(i=s)[o=e]+(i[o+1]<<8)+(i[o+2]<<16)+(i[o+3]<<24),r[l+1]=u(n[t]),r[l+2]=u(n[t+1]),r[l+3]=u(n[t+2])}var i,o}updateVisibleRegion(t){const n=this.getSplatCount(),s=new e.Vector3;if(!t){const t=new e.Vector3;this.scenes.forEach((e=>{t.add(e.splatBuffer.sceneCenter)})),t.multiplyScalar(1/this.scenes.length),this.calculatedSceneCenter.copy(t),this.material.uniforms.sceneCenter.value.copy(this.calculatedSceneCenter),this.material.uniformsNeedUpdate=!0}for(let e=t?this.lastBuildSplatCount:0;e<n;e++){this.getSplatCenter(e,s,!1);const t=s.sub(this.calculatedSceneCenter).length();t>this.maxSplatDistanceFromSceneCenter&&(this.maxSplatDistanceFromSceneCenter=t)}this.maxSplatDistanceFromSceneCenter-this.visibleRegionBufferRadius>1&&(this.visibleRegionBufferRadius=this.maxSplatDistanceFromSceneCenter,this.visibleRegionRadius=Math.max(this.visibleRegionBufferRadius-1,0)),this.finalBuild&&(this.visibleRegionRadius=this.visibleRegionBufferRadius=this.maxSplatDistanceFromSceneCenter),this.updateVisibleRegionFadeDistance()}updateVisibleRegionFadeDistance(e=we.Default){const t=this.finalBuild?.012:.003,n=e===we.Default?t:.003;this.visibleRegionFadeStartRadius=(this.visibleRegionRadius-this.visibleRegionFadeStartRadius)*n+this.visibleRegionFadeStartRadius;const s=(this.visibleRegionBufferRadius>0?this.visibleRegionFadeStartRadius/this.visibleRegionBufferRadius:0)>.99,r=s||e===we.Instant?1:0;this.material.uniforms.visibleRegionFadeStartRadius.value=this.visibleRegionFadeStartRadius,this.material.uniforms.visibleRegionRadius.value=this.visibleRegionRadius,this.material.uniforms.firstRenderTime.value=this.firstRenderTime,this.material.uniforms.currentTime.value=performance.now(),this.material.uniforms.fadeInComplete.value=r,this.material.uniformsNeedUpdate=!0,this.visibleRegionChanging=!s}updateRenderIndexes(e,t){const n=this.geometry;n.attributes.splatIndex.set(e),n.attributes.splatIndex.needsUpdate=!0,t>0&&-1===this.firstRenderTime&&(this.firstRenderTime=performance.now()),n.instanceCount=t}updateTransforms(){for(let e=0;e<this.scenes.length;e++){this.getScene(e).updateTransform()}}updateUniforms=function(){const t=new e.Vector2;return function(e,n,s,r,i,o){if(this.getSplatCount()>0){if(t.set(e.x*this.devicePixelRatio,e.y*this.devicePixelRatio),this.material.uniforms.viewport.value.copy(t),this.material.uniforms.basisViewport.value.set(1/t.x,1/t.y),this.material.uniforms.focal.value.set(n,s),this.material.uniforms.orthographicMode.value=r?1:0,this.material.uniforms.orthoZoom.value=i,this.material.uniforms.inverseFocalAdjustment.value=o,this.dynamicMode)for(let e=0;e<this.scenes.length;e++)this.material.uniforms.transforms.value[e].copy(this.getScene(e).transform);this.material.uniformsNeedUpdate=!0}}}();setSplatScale(e=1){this.splatScale=e,this.material.uniforms.splatScale.value=e,this.material.uniformsNeedUpdate=!0}getSplatScale(){return this.splatScale}setPointCloudModeEnabled(e){this.pointCloudModeEnabled=e,this.material.uniforms.pointCloudModeEnabled.value=e?1:0,this.material.uniformsNeedUpdate=!0}getPointCloudModeEnabled(){return this.pointCloudModeEnabled}getSplatDataTextures(){return this.splatDataTextures}getSplatCount(){return Me.getTotalSplatCountForScenes(this.scenes)}static getTotalSplatCountForScenes(e){let t=0;for(let n of e)n&&n.splatBuffer&&(t+=n.splatBuffer.getSplatCount());return t}static getTotalSplatCountForSplatBuffers(e){let t=0;for(let n of e)t+=n.getSplatCount();return t}getMaxSplatCount(){return Me.getTotalMaxSplatCountForScenes(this.scenes)}static getTotalMaxSplatCountForScenes(e){let t=0;for(let n of e)n&&n.splatBuffer&&(t+=n.splatBuffer.getMaxSplatCount());return t}static getTotalMaxSplatCountForSplatBuffers(e){let t=0;for(let n of e)t+=n.getMaxSplatCount();return t}disposeDistancesComputationGPUResources(){if(!this.renderer)return;const e=this.renderer.getContext();this.distancesTransformFeedback.vao&&(e.deleteVertexArray(this.distancesTransformFeedback.vao),this.distancesTransformFeedback.vao=null),this.distancesTransformFeedback.program&&(e.deleteProgram(this.distancesTransformFeedback.program),e.deleteShader(this.distancesTransformFeedback.vertexShader),e.deleteShader(this.distancesTransformFeedback.fragmentShader),this.distancesTransformFeedback.program=null,this.distancesTransformFeedback.vertexShader=null,this.distancesTransformFeedback.fragmentShader=null),this.disposeDistancesComputationGPUBufferResources(),this.distancesTransformFeedback.id&&(e.deleteTransformFeedback(this.distancesTransformFeedback.id),this.distancesTransformFeedback.id=null)}disposeDistancesComputationGPUBufferResources(){if(!this.renderer)return;const e=this.renderer.getContext();this.distancesTransformFeedback.centersBuffer&&(this.distancesTransformFeedback.centersBuffer=null,e.deleteBuffer(this.distancesTransformFeedback.centersBuffer)),this.distancesTransformFeedback.outDistancesBuffer&&(e.deleteBuffer(this.distancesTransformFeedback.outDistancesBuffer),this.distancesTransformFeedback.outDistancesBuffer=null)}setRenderer(t){if(t!==this.renderer){this.renderer=t;const n=this.renderer.getContext(),s=new xe(n),r=new ve(n,s,{});if(s.init(r),this.webGLUtils=new e.WebGLUtils(n,s,r),this.enableDistancesComputationOnGPU&&this.getSplatCount()>0){this.setupDistancesComputationTransformFeedback();const{centers:e,sceneIndexes:t}=this.getDataForDistancesComputation(0,this.getSplatCount()-1);this.refreshGPUBuffersForDistancesComputation(e,t)}}}setupDistancesComputationTransformFeedback=function(){let e;return function(){const t=this.getMaxSplatCount();if(!this.renderer)return;const n=this.lastRenderer!==this.renderer,s=e!==t;if(!n&&!s)return;n?this.disposeDistancesComputationGPUResources():s&&this.disposeDistancesComputationGPUBufferResources();const r=this.renderer.getContext(),i=(e,t,n)=>{const s=e.createShader(t);if(!s)return console.error("Fatal error: gl could not create a shader object."),null;e.shaderSource(s,n),e.compileShader(s);if(!e.getShaderParameter(s,e.COMPILE_STATUS)){let n="unknown";t===e.VERTEX_SHADER?n="vertex shader":t===e.FRAGMENT_SHADER&&(n="fragement shader");const r=e.getShaderInfoLog(s);return console.error("Failed to compile "+n+" with these errors:"+r),e.deleteShader(s),null}return s};let o;this.integerBasedDistancesComputation?(o="#version 300 es\n in ivec4 center;\n flat out int distance;",this.dynamicMode?o+=`\n in uint transformIndex;\n uniform ivec4 transforms[${W.MaxScenes}];\n void main(void) {\n ivec4 transform = transforms[transformIndex];\n distance = center.x * transform.x + center.y * transform.y + center.z * transform.z + transform.w * center.w;\n }\n `:o+="\n uniform ivec3 modelViewProj;\n void main(void) {\n distance = center.x * modelViewProj.x + center.y * modelViewProj.y + center.z * modelViewProj.z;\n }\n "):(o="#version 300 es\n in vec4 center;\n flat out float distance;",this.dynamicMode?o+=`\n in uint transformIndex;\n uniform mat4 transforms[${W.MaxScenes}];\n void main(void) {\n vec4 transformedCenter = transforms[transformIndex] * vec4(center.xyz, 1.0);\n distance = transformedCenter.z;\n }\n `:o+="\n uniform vec3 modelViewProj;\n void main(void) {\n distance = center.x * modelViewProj.x + center.y * modelViewProj.y + center.z * modelViewProj.z;\n }\n ");const a=r.getParameter(r.VERTEX_ARRAY_BINDING),l=r.getParameter(r.CURRENT_PROGRAM),c=!!l&&r.getProgramParameter(l,r.DELETE_STATUS);if(n&&(this.distancesTransformFeedback.vao=r.createVertexArray()),r.bindVertexArray(this.distancesTransformFeedback.vao),n){const e=r.createProgram(),t=i(r,r.VERTEX_SHADER,o),n=i(r,r.FRAGMENT_SHADER,"#version 300 es\n precision lowp float;\n out vec4 fragColor;\n void main(){}\n ");if(!t||!n)throw new Error("Could not compile shaders for distances computation on GPU.");r.attachShader(e,t),r.attachShader(e,n),r.transformFeedbackVaryings(e,["distance"],r.SEPARATE_ATTRIBS),r.linkProgram(e);if(!r.getProgramParameter(e,r.LINK_STATUS)){const s=r.getProgramInfoLog(e);throw console.error("Fatal error: Failed to link program: "+s),r.deleteProgram(e),r.deleteShader(n),r.deleteShader(t),new Error("Could not link shaders for distances computation on GPU.")}this.distancesTransformFeedback.program=e,this.distancesTransformFeedback.vertexShader=t,this.distancesTransformFeedback.vertexShader=n}if(r.useProgram(this.distancesTransformFeedback.program),this.distancesTransformFeedback.centersLoc=r.getAttribLocation(this.distancesTransformFeedback.program,"center"),this.dynamicMode){this.distancesTransformFeedback.transformIndexesLoc=r.getAttribLocation(this.distancesTransformFeedback.program,"transformIndex");for(let e=0;e<this.scenes.length;e++)this.distancesTransformFeedback.transformsLocs[e]=r.getUniformLocation(this.distancesTransformFeedback.program,`transforms[${e}]`)}else this.distancesTransformFeedback.modelViewProjLoc=r.getUniformLocation(this.distancesTransformFeedback.program,"modelViewProj");(n||s)&&(this.distancesTransformFeedback.centersBuffer=r.createBuffer(),r.bindBuffer(r.ARRAY_BUFFER,this.distancesTransformFeedback.centersBuffer),r.enableVertexAttribArray(this.distancesTransformFeedback.centersLoc),this.integerBasedDistancesComputation?r.vertexAttribIPointer(this.distancesTransformFeedback.centersLoc,4,r.INT,0,0):r.vertexAttribPointer(this.distancesTransformFeedback.centersLoc,4,r.FLOAT,!1,0,0),this.dynamicMode&&(this.distancesTransformFeedback.transformIndexesBuffer=r.createBuffer(),r.bindBuffer(r.ARRAY_BUFFER,this.distancesTransformFeedback.transformIndexesBuffer),r.enableVertexAttribArray(this.distancesTransformFeedback.transformIndexesLoc),r.vertexAttribIPointer(this.distancesTransformFeedback.transformIndexesLoc,1,r.UNSIGNED_INT,0,0))),(n||s)&&(this.distancesTransformFeedback.outDistancesBuffer=r.createBuffer()),r.bindBuffer(r.ARRAY_BUFFER,this.distancesTransformFeedback.outDistancesBuffer),r.bufferData(r.ARRAY_BUFFER,4*t,r.STATIC_READ),n&&(this.distancesTransformFeedback.id=r.createTransformFeedback()),r.bindTransformFeedback(r.TRANSFORM_FEEDBACK,this.distancesTransformFeedback.id),r.bindBufferBase(r.TRANSFORM_FEEDBACK_BUFFER,0,this.distancesTransformFeedback.outDistancesBuffer),l&&!0!==c&&r.useProgram(l),a&&r.bindVertexArray(a),this.lastRenderer=this.renderer,e=t}}();updateGPUCentersBufferForDistancesComputation(e,t,n){if(!this.renderer)return;const s=this.renderer.getContext(),r=s.getParameter(s.VERTEX_ARRAY_BINDING);s.bindVertexArray(this.distancesTransformFeedback.vao);const i=this.integerBasedDistancesComputation?Uint32Array:Float32Array,o=16*n;if(s.bindBuffer(s.ARRAY_BUFFER,this.distancesTransformFeedback.centersBuffer),e)s.bufferSubData(s.ARRAY_BUFFER,o,t);else{const e=new i(16*this.getMaxSplatCount());e.set(t),s.bufferData(s.ARRAY_BUFFER,e,s.STATIC_DRAW)}s.bindBuffer(s.ARRAY_BUFFER,null),r&&s.bindVertexArray(r)}updateGPUTransformIndexesBufferForDistancesComputation(e,t,n){if(!this.renderer||!this.dynamicMode)return;const s=this.renderer.getContext(),r=s.getParameter(s.VERTEX_ARRAY_BINDING);s.bindVertexArray(this.distancesTransformFeedback.vao);const i=4*n;if(s.bindBuffer(s.ARRAY_BUFFER,this.distancesTransformFeedback.transformIndexesBuffer),e)s.bufferSubData(s.ARRAY_BUFFER,i,t);else{const e=new Uint32Array(4*this.getMaxSplatCount());e.set(t),s.bufferData(s.ARRAY_BUFFER,e,s.STATIC_DRAW)}s.bindBuffer(s.ARRAY_BUFFER,null),r&&s.bindVertexArray(r)}getSceneIndexes(e,t){let n;n=new Uint32Array(t-e+1);for(let s=e;s<=t;s++)n[s]=this.globalSplatIndexToSceneIndexMap[s];return n}fillTransformsArray=function(){const e=[];return function(t){e.length!==t.length&&(e.length=t.length);for(let t=0;t<this.scenes.length;t++){const n=this.getScene(t).transform.elements;for(let s=0;s<16;s++)e[16*t+s]=n[s]}t.set(e)}}();computeDistancesOnGPU=function(){const t=new e.Matrix4;return function(e,n){if(!this.renderer)return;const s=this.renderer.getContext(),r=s.getParameter(s.VERTEX_ARRAY_BINDING),i=s.getParameter(s.CURRENT_PROGRAM),o=!!i&&s.getProgramParameter(i,s.DELETE_STATUS);if(s.bindVertexArray(this.distancesTransformFeedback.vao),s.useProgram(this.distancesTransformFeedback.program),s.enable(s.RASTERIZER_DISCARD),this.dynamicMode)for(let n=0;n<this.scenes.length;n++)if(t.copy(this.getScene(n).transform),t.premultiply(e),this.integerBasedDistancesComputation){const e=Me.getIntegerMatrixArray(t),r=[e[2],e[6],e[10],e[14]];s.uniform4i(this.distancesTransformFeedback.transformsLocs[n],r[0],r[1],r[2],r[3])}else s.uniformMatrix4fv(this.distancesTransformFeedback.transformsLocs[n],!1,t.elements);else if(this.integerBasedDistancesComputation){const t=Me.getIntegerMatrixArray(e),n=[t[2],t[6],t[10]];s.uniform3i(this.distancesTransformFeedback.modelViewProjLoc,n[0],n[1],n[2])}else{const t=[e.elements[2],e.elements[6],e.elements[10]];s.uniform3f(this.distancesTransformFeedback.modelViewProjLoc,t[0],t[1],t[2])}s.bindBuffer(s.ARRAY_BUFFER,this.distancesTransformFeedback.centersBuffer),s.enableVertexAttribArray(this.distancesTransformFeedback.centersLoc),this.integerBasedDistancesComputation?s.vertexAttribIPointer(this.distancesTransformFeedback.centersLoc,4,s.INT,0,0):s.vertexAttribPointer(this.distancesTransformFeedback.centersLoc,4,s.FLOAT,!1,0,0),this.dynamicMode&&(s.bindBuffer(s.ARRAY_BUFFER,this.distancesTransformFeedback.transformIndexesBuffer),s.enableVertexAttribArray(this.distancesTransformFeedback.transformIndexesLoc),s.vertexAttribIPointer(this.distancesTransformFeedback.transformIndexesLoc,1,s.UNSIGNED_INT,0,0)),s.bindTransformFeedback(s.TRANSFORM_FEEDBACK,this.distancesTransformFeedback.id),s.bindBufferBase(s.TRANSFORM_FEEDBACK_BUFFER,0,this.distancesTransformFeedback.outDistancesBuffer),s.beginTransformFeedback(s.POINTS),s.drawArrays(s.POINTS,0,this.getSplatCount()),s.endTransformFeedback(),s.bindBufferBase(s.TRANSFORM_FEEDBACK_BUFFER,0,null),s.bindTransformFeedback(s.TRANSFORM_FEEDBACK,null),s.disable(s.RASTERIZER_DISCARD);const a=s.fenceSync(s.SYNC_GPU_COMMANDS_COMPLETE,0);s.flush();const l=new Promise((e=>{const t=()=>{if(this.disposed)e();else{const r=0,i=0;switch(s.clientWaitSync(a,i,r)){case s.TIMEOUT_EXPIRED:return this.computeDistancesOnGPUSyncTimeout=setTimeout(t),this.computeDistancesOnGPUSyncTimeout;case s.WAIT_FAILED:throw new Error("should never get here");default:this.computeDistancesOnGPUSyncTimeout=null,s.deleteSync(a);const r=s.getParameter(s.VERTEX_ARRAY_BINDING);s.bindVertexArray(this.distancesTransformFeedback.vao),s.bindBuffer(s.ARRAY_BUFFER,this.distancesTransformFeedback.outDistancesBuffer),s.getBufferSubData(s.ARRAY_BUFFER,0,n),s.bindBuffer(s.ARRAY_BUFFER,null),r&&s.bindVertexArray(r),e()}}};this.computeDistancesOnGPUSyncTimeout=setTimeout(t)}));return i&&!0!==o&&s.useProgram(i),r&&s.bindVertexArray(r),l}}();getLocalSplatParameters(e,t,n){null==n&&(n=!this.dynamicMode),t.splatBuffer=this.getSplatBufferForSplat(e),t.localIndex=this.getSplatLocalIndex(e),t.sceneTransform=n?this.getSceneTransformForSplat(e):null}fillSplatDataArrays(e,t,n,s,r,i=0,o=1,a,l,c=0){for(let h=0;h<this.scenes.length;h++){null==r&&(r=!this.dynamicMode);const d=this.getScene(h),p=d.splatBuffer,u=r?d.transform:null;e&&p.fillSplatCovarianceArray(e,u,a,l,c,i),t&&p.fillSplatCenterArray(t,u,a,l,c),n&&p.fillSplatColorArray(n,d.minimumAlpha,a,l,c),s&&p.fillSphericalHarmonicsArray(s,this.minSphericalHarmonicsDegree,u,a,l,c,o),c+=p.getSplatCount()}}getIntegerCenters(e,t,n=!1){const s=t-e+1,r=new Float32Array(3*s);let i;this.fillSplatDataArrays(null,r,null,null,void 0,void 0,void 0,e);let o=n?4:3;i=new Int32Array(s*o);for(let e=0;e<s;e++){for(let t=0;t<3;t++)i[e*o+t]=Math.round(1e3*r[3*e+t]);n&&(i[e*o+3]=1e3)}return i}getFloatCenters(e,t,n=!1){const s=t-e+1,r=new Float32Array(3*s);if(this.fillSplatDataArrays(null,r,null,null,void 0,void 0,void 0,e),!n)return r;let i=new Float32Array(4*s);for(let e=0;e<s;e++){for(let t=0;t<3;t++)i[4*e+t]=r[3*e+t];i[4*e+3]=1}return i}getSplatCenter=function(){const e={};return function(t,n,s){this.getLocalSplatParameters(t,e,s),e.splatBuffer.getSplatCenter(e.localIndex,n,e.sceneTransform)}}();getSplatScaleAndRotation=function(){const e={};return function(t,n,s,r){this.getLocalSplatParameters(t,e,r),e.splatBuffer.getSplatScaleAndRotation(e.localIndex,n,s,e.sceneTransform)}}();getSplatColor=function(){const e={};return function(t,n){this.getLocalSplatParameters(t,e),e.splatBuffer.getSplatColor(e.localIndex,n)}}();getSceneTransform(e,t){const n=this.getScene(e);n.updateTransform(),t.copy(n.transform)}getScene(e){if(e<0||e>=this.scenes.length)throw new Error("SplatMesh::getScene() -> Invalid scene index.");return this.scenes[e]}getSplatBufferForSplat(e){return this.getScene(this.globalSplatIndexToSceneIndexMap[e]).splatBuffer}getSceneIndexForSplat(e){return this.globalSplatIndexToSceneIndexMap[e]}getSceneTransformForSplat(e){return this.getScene(this.globalSplatIndexToSceneIndexMap[e]).transform}getSplatLocalIndex(e){return this.globalSplatIndexToLocalSplatIndexMap[e]}static getIntegerMatrixArray(e){const t=e.elements,n=[];for(let e=0;e<16;e++)n[e]=Math.round(1e3*t[e]);return n}}function Be(e){let t,n,s,r,i,o,a,l,c,h,d,p,u,m,f,g,S,y;e.onmessage=C=>{if(C.data.centers)centers=C.data.centers,transformIndexes=C.data.transformIndexes,r?new Int32Array(n,m+C.data.range.from*y.BytesPerInt*4,4*C.data.range.count).set(new Int32Array(centers)):new Float32Array(n,m+C.data.range.from*y.BytesPerFloat*4,4*C.data.range.count).set(new Float32Array(centers)),i&&new Uint32Array(n,c+4*C.data.range.from,C.data.range.count).set(new Uint32Array(transformIndexes)),e.postMessage({centerDataSet:!0});else if(C.data.sort){const A=C.data.sort.splatRenderCount||0,x=C.data.sort.splatSortCount||0,v=C.data.sort.usePrecomputedDistances;let w,b,T;s||(w=C.data.sort.indexesToSort,T=C.data.sort.transforms,v&&(b=C.data.sort.precomputedDistances)),function(C,A,x,v,w,b,T){const F=performance.now();if(!s&&(new Uint32Array(n,a,w.byteLength/y.BytesPerInt).set(w),new Float32Array(n,h,T.byteLength/y.BytesPerFloat).set(T),v)){let e;e=r?new Int32Array(n,d,b.byteLength/y.BytesPerInt):new Float32Array(n,d,b.byteLength/y.BytesPerFloat),e.set(b)}g||(g=new Uint32Array(y.DepthMapRange)),new Float32Array(n,f,16).set(x),new Uint32Array(n,u,y.DepthMapRange).set(g),t.exports.sortIndexes(a,m,d,p,u,f,l,c,h,y.DepthMapRange,C,A,o,v,r,i);const M={sortDone:!0,splatSortCount:C,splatRenderCount:A,sortTime:0};if(!s){const e=new Uint32Array(n,l,A);(!S||S.length<A)&&(S=new Uint32Array(A)),S.set(e),M.sortedIndexes=S}const B=performance.now();M.sortTime=B-F,e.postMessage(M)}(x,A,C.data.sort.modelViewProj,v,w,b,T)}else if(C.data.init){y=C.data.init.Constants,o=C.data.init.splatCount,s=C.data.init.useSharedMemory,r=C.data.init.integerBasedSort,i=C.data.init.dynamicMode;const g=r?4*y.BytesPerInt:4*y.BytesPerFloat,S=new Uint8Array(C.data.init.sorterWasmBytes),A=16*y.BytesPerFloat,x=o*y.BytesPerInt,v=o*g,w=A,b=r?o*y.BytesPerInt:o*y.BytesPerFloat,T=o*y.BytesPerInt,F=o*y.BytesPerInt,M=y.DepthMapRange*y.BytesPerInt*2,B=i?o*y.BytesPerInt:0,E=i?y.MaxScenes*A:0,D=32*y.MemoryPageSize,P=x+v+w+b+T+M+F+B+E+D,R=Math.floor(P/y.MemoryPageSize)+1,I={module:{},env:{memory:new WebAssembly.Memory({initial:2*R,maximum:4*R,shared:!0})}};WebAssembly.compile(S).then((e=>WebAssembly.instantiate(e,I))).then((r=>{t=r,a=0,m=a+x,f=m+v,d=f+w,p=d+b,u=p+T,l=u+M,c=l+F,h=c+B,n=I.env.memory.buffer,s?e.postMessage({sortSetupPhase1Complete:!0,indexesToSortBuffer:n,indexesToSortOffset:a,sortedIndexesBuffer:n,sortedIndexesOffset:l,precomputedDistancesBuffer:n,precomputedDistancesOffset:d,transformsBuffer:n,transformsOffset:h}):e.postMessage({sortSetupPhase1Complete:!0})}))}}}const Ee={None:0,VR:1,AR:2};class De{static createButton(e){const t=document.createElement("button");function n(){t.style.display="",t.style.cursor="auto",t.style.left="calc(50% - 75px)",t.style.width="150px",t.onmouseenter=null,t.onmouseleave=null,t.onclick=null}function s(e){e.style.position="absolute",e.style.bottom="20px",e.style.padding="12px 6px",e.style.border="1px solid #fff",e.style.borderRadius="4px",e.style.background="rgba(0,0,0,0.1)",e.style.color="#fff",e.style.font="normal 13px sans-serif",e.style.textAlign="center",e.style.opacity="0.5",e.style.outline="none",e.style.zIndex="999"}if("xr"in navigator)return t.id="VRButton",t.style.display="none",s(t),navigator.xr.isSessionSupported("immersive-vr").then((function(s){s?function(){let n=null;async function s(s){s.addEventListener("end",r),await e.xr.setSession(s),t.textContent="EXIT VR",n=s}function r(){n.removeEventListener("end",r),t.textContent="ENTER VR",n=null}t.style.display="",t.style.cursor="pointer",t.style.left="calc(50% - 50px)",t.style.width="100px",t.textContent="ENTER VR";const i={optionalFeatures:["local-floor","bounded-floor","hand-tracking","layers"]};t.onmouseenter=function(){t.style.opacity="1.0"},t.onmouseleave=function(){t.style.opacity="0.5"},t.onclick=function(){null===n?navigator.xr.requestSession("immersive-vr",i).then(s):(n.end(),void 0!==navigator.xr.offerSession&&navigator.xr.offerSession("immersive-vr",i).then(s).catch((e=>{console.warn(e)})))},void 0!==navigator.xr.offerSession&&navigator.xr.offerSession("immersive-vr",i).then(s).catch((e=>{console.warn(e)}))}():(n(),t.textContent="VR NOT SUPPORTED"),s&&De.xrSessionIsGranted&&t.click()})).catch((function(e){n(),console.warn("Exception when trying to call xr.isSessionSupported",e),t.textContent="VR NOT ALLOWED"})),t;{const e=document.createElement("a");return!1===window.isSecureContext?(e.href=document.location.href.replace(/^http:/,"https:"),e.innerHTML="WEBXR NEEDS HTTPS"):(e.href="https://immersiveweb.dev/",e.innerHTML="WEBXR NOT AVAILABLE"),e.style.left="calc(50% - 90px)",e.style.width="180px",e.style.textDecoration="none",s(e),e}}static registerSessionGrantedListener(){if("undefined"!=typeof navigator&&"xr"in navigator){if(/WebXRViewer\//i.test(navigator.userAgent))return;navigator.xr.addEventListener("sessiongranted",(()=>{De.xrSessionIsGranted=!0}))}}}De.xrSessionIsGranted=!1,De.registerSessionGrantedListener();class Pe{static createButton(e,t={}){const n=document.createElement("button");function s(){n.style.display="",n.style.cursor="auto",n.style.left="calc(50% - 75px)",n.style.width="150px",n.onmouseenter=null,n.onmouseleave=null,n.onclick=null}function r(e){e.style.position="absolute",e.style.bottom="20px",e.style.padding="12px 6px",e.style.border="1px solid #fff",e.style.borderRadius="4px",e.style.background="rgba(0,0,0,0.1)",e.style.color="#fff",e.style.font="normal 13px sans-serif",e.style.textAlign="center",e.style.opacity="0.5",e.style.outline="none",e.style.zIndex="999"}if("xr"in navigator)return n.id="ARButton",n.style.display="none",r(n),navigator.xr.isSessionSupported("immersive-ar").then((function(r){r?function(){if(void 0===t.domOverlay){const e=document.createElement("div");e.style.display="none",document.body.appendChild(e);const n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("width",38),n.setAttribute("height",38),n.style.position="absolute",n.style.right="20px",n.style.top="20px",n.addEventListener("click",(function(){s.end()})),e.appendChild(n);const r=document.createElementNS("http://www.w3.org/2000/svg","path");r.setAttribute("d","M 12,12 L 28,28 M 28,12 12,28"),r.setAttribute("stroke","#fff"),r.setAttribute("stroke-width",2),n.appendChild(r),void 0===t.optionalFeatures&&(t.optionalFeatures=[]),t.optionalFeatures.push("dom-overlay"),t.domOverlay={root:e}}let s=null;async function r(r){r.addEventListener("end",i),e.xr.setReferenceSpaceType("local"),await e.xr.setSession(r),n.textContent="STOP AR",t.domOverlay.root.style.display="",s=r}function i(){s.removeEventListener("end",i),n.textContent="START AR",t.domOverlay.root.style.display="none",s=null}n.style.display="",n.style.cursor="pointer",n.style.left="calc(50% - 50px)",n.style.width="100px",n.textContent="START AR",n.onmouseenter=function(){n.style.opacity="1.0"},n.onmouseleave=function(){n.style.opacity="0.5"},n.onclick=function(){null===s?navigator.xr.requestSession("immersive-ar",t).then(r):(s.end(),void 0!==navigator.xr.offerSession&&navigator.xr.offerSession("immersive-ar",t).then(r).catch((e=>{console.warn(e)})))},void 0!==navigator.xr.offerSession&&navigator.xr.offerSession("immersive-ar",t).then(r).catch((e=>{console.warn(e)}))}():(s(),n.textContent="AR NOT SUPPORTED")})).catch((function(e){s(),console.warn("Exception when trying to call xr.isSessionSupported",e),n.textContent="AR NOT ALLOWED"})),n;{const e=document.createElement("a");return!1===window.isSecureContext?(e.href=document.location.href.replace(/^http:/,"https:"),e.innerHTML="WEBXR NEEDS HTTPS"):(e.href="https://immersiveweb.dev/",e.innerHTML="WEBXR NOT AVAILABLE"),e.style.left="calc(50% - 90px)",e.style.width="180px",e.style.textDecoration="none",r(e),e}}}const Re={Always:0,OnChange:1,Never:2};class Ie{constructor(t={}){t.cameraUp||(t.cameraUp=[0,1,0]),this.cameraUp=(new e.Vector3).fromArray(t.cameraUp),t.initialCameraPosition||(t.initialCameraPosition=[0,10,15]),this.initialCameraPosition=(new e.Vector3).fromArray(t.initialCameraPosition),t.initialCameraLookAt||(t.initialCameraLookAt=[0,0,0]),this.initialCameraLookAt=(new e.Vector3).fromArray(t.initialCameraLookAt),this.dropInMode=t.dropInMode||!1,void 0!==t.selfDrivenMode&&null!==t.selfDrivenMode||(t.selfDrivenMode=!0),this.selfDrivenMode=t.selfDrivenMode&&!this.dropInMode,this.selfDrivenUpdateFunc=this.selfDrivenUpdate.bind(this),void 0===t.useBuiltInControls&&(t.useBuiltInControls=!0),this.useBuiltInControls=t.useBuiltInControls,this.rootElement=t.rootElement,this.ignoreDevicePixelRatio=t.ignoreDevicePixelRatio||!1,this.devicePixelRatio=this.ignoreDevicePixelRatio?1:window.devicePixelRatio,this.halfPrecisionCovariancesOnGPU=t.halfPrecisionCovariancesOnGPU||!1,this.threeScene=t.threeScene,this.renderer=t.renderer,this.camera=t.camera,this.gpuAcceleratedSort=t.gpuAcceleratedSort||!1,void 0!==t.integerBasedSort&&null!==t.integerBasedSort||(t.integerBasedSort=!0),this.integerBasedSort=t.integerBasedSort,void 0!==t.sharedMemoryForWorkers&&null!==t.sharedMemoryForWorkers||(t.sharedMemoryForWorkers=!0),this.sharedMemoryForWorkers=t.sharedMemoryForWorkers,this.dynamicScene=!!t.dynamicScene,this.antialiased=t.antialiased||!1,this.webXRMode=t.webXRMode||Ee.None,this.webXRMode!==Ee.None&&(this.gpuAcceleratedSort=!1),this.webXRActive=!1,this.renderMode=t.renderMode||Re.Always,this.sceneRevealMode=t.sceneRevealMode||we.Default,this.focalAdjustment=t.focalAdjustment||1,this.maxScreenSpaceSplatSize=t.maxScreenSpaceSplatSize||2048,this.logLevel=t.logLevel||be.None,this.sphericalHarmonicsDegree=t.sphericalHarmonicsDegree||0,this.createSplatMesh(),this.controls=null,this.perspectiveControls=null,this.orthographicControls=null,this.orthographicCamera=null,this.perspectiveCamera=null,this.showMeshCursor=!1,this.showControlPlane=!1,this.showInfo=!1,this.sceneHelper=null,this.sortWorker=null,this.sortRunning=!1,this.splatRenderCount=0,this.sortWorkerIndexesToSort=null,this.sortWorkerSortedIndexes=null,this.sortWorkerPrecomputedDistances=null,this.sortWorkerTransforms=null,this.runAfterFirstSort=[],this.selfDrivenModeRunning=!1,this.splatRenderReady=!1,this.raycaster=new fe,this.infoPanel=null,this.startInOrthographicMode=!1,this.currentFPS=0,this.lastSortTime=0,this.consecutiveRenderFrames=0,this.previousCameraTarget=new e.Vector3,this.nextCameraTarget=new e.Vector3,this.mousePosition=new e.Vector2,this.mouseDownPosition=new e.Vector2,this.mouseDownTime=null,this.resizeObserver=null,this.mouseMoveListener=null,this.mouseDownListener=null,this.mouseUpListener=null,this.keyDownListener=null,this.sortPromise=null,this.sortPromiseResolver=null,this.splatSceneDownloadPromises={},this.splatSceneDownloadAndBuildPromise=null,this.splatSceneRemovalPromise=null,this.loadingSpinner=new ie(null,this.rootElement||document.body),this.loadingSpinner.hide(),this.loadingProgressBar=new oe(this.rootElement||document.body),this.loadingProgressBar.hide(),this.infoPanel=new ae(this.rootElement||document.body),this.infoPanel.hide(),this.usingExternalCamera=!(!this.dropInMode&&!this.camera),this.usingExternalRenderer=!(!this.dropInMode&&!this.renderer),this.initialized=!1,this.disposing=!1,this.disposed=!1,this.dropInMode||this.init(),window.viewer=this,window.THREE=e}createSplatMesh(){this.splatMesh=new Me(this.dynamicScene,this.halfPrecisionCovariancesOnGPU,this.devicePixelRatio,this.gpuAcceleratedSort,this.integerBasedSort,this.antialiased,this.maxScreenSpaceSplatSize,this.logLevel,this.sphericalHarmonicsDegree),this.splatMesh.frustumCulled=!1}init(){this.initialized||(this.rootElement||(this.usingExternalRenderer?this.rootElement=this.renderer.domElement.parentElement||document.body:(this.rootElement=document.createElement("div"),this.rootElement.style.width="100%",this.rootElement.style.height="100%",this.rootElement.style.position="absolute",document.body.appendChild(this.rootElement))),this.setupCamera(),this.setupRenderer(),this.setupWebXR(),this.setupControls(),this.setupEventHandlers(),this.threeScene=this.threeScene||new e.Scene,this.sceneHelper=new ce(this.threeScene),this.sceneHelper.setupMeshCursor(),this.sceneHelper.setupFocusMarker(),this.sceneHelper.setupControlPlane(),this.loadingProgressBar.setContainer(this.rootElement),this.loadingSpinner.setContainer(this.rootElement),this.infoPanel.setContainer(this.rootElement),this.initialized=!0)}setupCamera(){if(!this.usingExternalCamera){const t=new e.Vector2;this.getRenderDimensions(t),this.perspectiveCamera=new e.PerspectiveCamera(50,t.x/t.y,.1,1e3),this.orthographicCamera=new e.OrthographicCamera(t.x/-2,t.x/2,t.y/2,t.y/-2,.1,1e3),this.camera=this.startInOrthographicMode?this.orthographicCamera:this.perspectiveCamera,this.camera.position.copy(this.initialCameraPosition),this.camera.up.copy(this.cameraUp).normalize(),this.camera.lookAt(this.initialCameraLookAt)}}setupRenderer(){if(!this.usingExternalRenderer){const t=new e.Vector2;this.getRenderDimensions(t),this.renderer=new e.WebGLRenderer({antialias:!1,precision:"highp"}),this.renderer.setPixelRatio(this.devicePixelRatio),this.renderer.autoClear=!0,this.renderer.setClearColor(new e.Color(0),0),this.renderer.setSize(t.x,t.y),this.resizeObserver=new ResizeObserver((()=>{this.getRenderDimensions(t),this.renderer.setSize(t.x,t.y),this.forceRenderNextFrame()})),this.resizeObserver.observe(this.rootElement),this.rootElement.appendChild(this.renderer.domElement)}}setupWebXR(){this.webXRMode&&(this.webXRMode===Ee.VR?this.rootElement.appendChild(De.createButton(this.renderer)):this.webXRMode===Ee.AR&&this.rootElement.appendChild(Pe.createButton(this.renderer)),this.renderer.xr.addEventListener("sessionstart",(e=>{this.webXRActive=!0})),this.renderer.xr.addEventListener("sessionend",(e=>{this.webXRActive=!1})),this.renderer.xr.enabled=!0,this.camera.position.copy(this.initialCameraPosition),this.camera.up.copy(this.cameraUp).normalize(),this.camera.lookAt(this.initialCameraLookAt))}setupControls(){if(this.useBuiltInControls&&this.webXRMode===Ee.None){this.usingExternalCamera?this.camera.isOrthographicCamera?this.orthographicControls=new re(this.camera,this.renderer.domElement):this.perspectiveControls=new re(this.camera,this.renderer.domElement):(this.perspectiveControls=new re(this.perspectiveCamera,this.renderer.domElement),this.orthographicControls=new re(this.orthographicCamera,this.renderer.domElement));for(let e of[this.perspectiveControls,this.orthographicControls])e&&(e.listenToKeyEvents(window),e.rotateSpeed=.5,e.maxPolarAngle=.75*Math.PI,e.minPolarAngle=.1,e.enableDamping=!0,e.dampingFactor=.05,e.target.copy(this.initialCameraLookAt));this.controls=this.camera.isOrthographicCamera?this.orthographicControls:this.perspectiveControls}}setupEventHandlers(){this.useBuiltInControls&&this.webXRMode===Ee.None&&(this.mouseMoveListener=this.onMouseMove.bind(this),this.renderer.domElement.addEventListener("pointermove",this.mouseMoveListener,!1),this.mouseDownListener=this.onMouseDown.bind(this),this.renderer.domElement.addEventListener("pointerdown",this.mouseDownListener,!1),this.mouseUpListener=this.onMouseUp.bind(this),this.renderer.domElement.addEventListener("pointerup",this.mouseUpListener,!1),this.keyDownListener=this.onKeyDown.bind(this),window.addEventListener("keydown",this.keyDownListener,!1))}removeEventHandlers(){this.useBuiltInControls&&(this.renderer.domElement.removeEventListener("pointermove",this.mouseMoveListener),this.mouseMoveListener=null,this.renderer.domElement.removeEventListener("pointerdown",this.mouseDownListener),this.mouseDownListener=null,this.renderer.domElement.removeEventListener("pointerup",this.mouseUpListener),this.mouseUpListener=null,window.removeEventListener("keydown",this.keyDownListener),this.keyDownListener=null)}setRenderMode(e){this.renderMode=e}onKeyDown=function(){const t=new e.Vector3,n=new e.Matrix4,s=new e.Matrix4;return function(e){switch(t.set(0,0,-1),t.transformDirection(this.camera.matrixWorld),n.makeRotationAxis(t,Math.PI/128),s.makeRotationAxis(t,-Math.PI/128),e.code){case"KeyG":this.focalAdjustment+=.02,this.forceRenderNextFrame();break;case"KeyF":this.focalAdjustment-=.02,this.forceRenderNextFrame();break;case"ArrowLeft":this.camera.up.transformDirection(n);break;case"ArrowRight":this.camera.up.transformDirection(s);break;case"KeyC":this.showMeshCursor=!this.showMeshCursor;break;case"KeyU":this.showControlPlane=!this.showControlPlane;break;case"KeyI":this.showInfo=!this.showInfo,this.showInfo?this.infoPanel.show():this.infoPanel.hide();break;case"KeyO":this.usingExternalCamera||this.setOrthographicMode(!this.camera.isOrthographicCamera);break;case"KeyP":this.usingExternalCamera||this.splatMesh.setPointCloudModeEnabled(!this.splatMesh.getPointCloudModeEnabled());break;case"Equal":this.usingExternalCamera||this.splatMesh.setSplatScale(this.splatMesh.getSplatScale()+.05);break;case"Minus":this.usingExternalCamera||this.splatMesh.setSplatScale(Math.max(this.splatMesh.getSplatScale()-.05,0))}}}();onMouseMove(e){this.mousePosition.set(e.offsetX,e.offsetY)}onMouseDown(){this.mouseDownPosition.copy(this.mousePosition),this.mouseDownTime=g()}onMouseUp=function(){const t=new e.Vector2;return function(e){t.copy(this.mousePosition).sub(this.mouseDownPosition);g()-this.mouseDownTime<.5&&t.length()<2&&this.onMouseClick(e)}}();onMouseClick(e){this.mousePosition.set(e.offsetX,e.offsetY),this.checkForFocalPointChange()}checkForFocalPointChange=function(){const t=new e.Vector2,n=new e.Vector3,s=[];return function(){if(!this.transitioningCameraTarget&&(this.getRenderDimensions(t),s.length=0,this.raycaster.setFromCameraAndScreenPosition(this.camera,this.mousePosition,t),this.raycaster.intersectSplatMesh(this.splatMesh,s),s.length>0)){const e=s[0].origin;n.copy(e).sub(this.camera.position),n.length()>.75&&(this.previousCameraTarget.copy(this.controls.target),this.nextCameraTarget.copy(e),this.transitioningCameraTarget=!0,this.transitioningCameraTargetStartTime=g())}}}();getRenderDimensions(e){this.rootElement?(e.x=this.rootElement.offsetWidth,e.y=this.rootElement.offsetHeight):this.renderer.getSize(e)}setOrthographicMode(e){if(e===this.camera.isOrthographicCamera)return;const t=this.camera,n=e?this.orthographicCamera:this.perspectiveCamera;if(n.position.copy(t.position),n.up.copy(t.up),n.rotation.copy(t.rotation),n.quaternion.copy(t.quaternion),n.matrix.copy(t.matrix),this.camera=n,this.controls){const s=e=>{e.saveState(),e.reset()},r=this.controls,i=e?this.orthographicControls:this.perspectiveControls;s(i),s(r),i.target.copy(r.target),e?Ie.setCameraZoomFromPosition(n,t,r):Ie.setCameraPositionFromZoom(n,t,i),this.controls=i,this.camera.lookAt(this.controls.target)}}static setCameraPositionFromZoom=function(){const t=new e.Vector3;return function(e,n,s){const r=1/(.001*n.zoom);t.copy(s.target).sub(e.position).normalize().multiplyScalar(r).negate(),e.position.copy(s.target).add(t)}}();static setCameraZoomFromPosition=function(){const t=new e.Vector3;return function(e,n,s){const r=t.copy(s.target).sub(n.position).length();e.zoom=1/(.001*r)}}();updateSplatMesh=function(){const t=new e.Vector2;return function(){if(!this.splatMesh)return;if(this.splatMesh.getSplatCount()>0){this.splatMesh.updateTransforms(),this.getRenderDimensions(t);const e=.5*this.camera.projectionMatrix.elements[0]*this.devicePixelRatio*t.x,n=.5*this.camera.projectionMatrix.elements[5]*this.devicePixelRatio*t.y,s=this.camera.isOrthographicCamera?1/this.devicePixelRatio:1,r=this.focalAdjustment*s,i=1/r;this.adjustForWebXRStereo(t),this.splatMesh.updateUniforms(t,e*r,n*r,this.camera.isOrthographicCamera,this.camera.zoom||1,i)}}}();adjustForWebXRStereo(e){if(this.camera&&this.webXRActive){const t=this.renderer.xr.getCamera().projectionMatrix.elements[0],n=this.camera.projectionMatrix.elements[0];e.x*=n/t}}isLoadingOrUnloading(){return Object.keys(this.splatSceneDownloadPromises).length>0||null!==this.splatSceneDownloadAndBuildPromise||null!==this.splatSceneRemovalPromise}isDisposingOrDisposed(){return this.disposing||this.disposed}addSplatSceneDownloadPromise(e){this.splatSceneDownloadPromises[e.id]=e}removeSplatSceneDownloadPromise(e){delete this.splatSceneDownloadPromises[e.id]}setSplatSceneDownloadAndBuildPromise(e){this.splatSceneDownloadAndBuildPromise=e}clearSplatSceneDownloadAndBuildPromise(){this.splatSceneDownloadAndBuildPromise=null}addSplatScene(e,t={}){if(this.isLoadingOrUnloading())throw new Error("Cannot add splat scene while another load or unload is already in progress.");if(this.isDisposingOrDisposed())throw new Error("Cannot add splat scene after dispose() is called.");const n=void 0!==t.format&&null!==t.format?t.format:K(e),s=Ie.isStreamable(n)&&t.streamView,r=void 0===t.showLoadingUI||null===t.showLoadingUI||t.showLoadingUI;let i=null;r&&(this.loadingSpinner.removeAllTasks(),i=this.loadingSpinner.addTask("Downloading..."));const o=(e,t,n)=>{if(r)if(n===U)if(100==e)this.loadingSpinner.setMessageForTask(i,"Download complete!");else if(s)this.loadingSpinner.setMessageForTask(i,"Downloading splats...");else{const e=t?`: ${t}`:"...";this.loadingSpinner.setMessageForTask(i,`Downloading${e}`)}else n===V?this.loadingSpinner.setMessageForTask(i,"Processing splats..."):this.loadingSpinner.setMessageForTask(i,"Ready!")};let a=!1,l=0;const c=(e,t)=>{r&&((e&&s||t&&!s)&&this.runAfterFirstSort.push((()=>{this.loadingSpinner.removeTask(i),t||a||this.loadingProgressBar.show()})),s&&(t?(a=!0,this.loadingProgressBar.hide()):this.loadingProgressBar.setProgress(l)))};return(s?this.downloadAndBuildSingleSplatSceneStreaming.bind(this):this.downloadAndBuildSingleSplatSceneNonStreaming.bind(this))(e,n,t.splatAlphaRemovalThreshold,((e,n,i)=>{!s&&t.onProgress&&t.onProgress(0,"0%",V);const o={rotation:t.rotation||t.orientation,position:t.position,scale:t.scale,splatAlphaRemovalThreshold:t.splatAlphaRemovalThreshold};return this.addSplatBuffers([e],[o],i,n&&r,r).then((()=>{!s&&t.onProgress&&t.onProgress(100,"100%",V),c(n,i)}))}).bind(this),((e,n,s)=>{l=e,o(e,n,s),t.onProgress&&t.onProgress(e,n,s)}),(()=>{this.loadingProgressBar.hide(),this.loadingSpinner.removeAllTasks()}).bind(this))}downloadAndBuildSingleSplatSceneNonStreaming(e,t,n,s,r,i){const o=this.downloadSplatSceneToSplatBuffer(e,n,r,!1,void 0,t).then((e=>(this.removeSplatSceneDownloadPromise(o),s(e,!0,!0).then((()=>{this.clearSplatSceneDownloadAndBuildPromise()}))))).catch((t=>{if(i&&i(),this.clearSplatSceneDownloadAndBuildPromise(),this.removeSplatSceneDownloadPromise(o),!(t instanceof p))throw new Error(`Viewer::addSplatScene -> Could not load file ${e}`)}));return this.addSplatSceneDownloadPromise(o),this.setSplatSceneDownloadAndBuildPromise(o),o}downloadAndBuildSingleSplatSceneStreaming(e,t,n,s,r,i){let o,a,l,c,h=0,u=!1;const m=[],f=()=>{if(m.length>0&&!u&&!this.isDisposingOrDisposed()){u=!0;const e=m.shift();s(e.splatBuffer,e.firstBuild,e.finalBuild).then((()=>{u=!1,e.firstBuild?(a=null,o()):e.finalBuild&&(l(),this.clearSplatSceneDownloadAndBuildPromise()),m.length>0&&y((()=>f()))}))}};let g=this.downloadSplatSceneToSplatBuffer(e,n,r,!0,((e,t)=>{this.isDisposingOrDisposed()||(t||0===m.length||e.getSplatCount()>m[0].splatBuffer.getSplatCount())&&(m.push({splatBuffer:e,firstBuild:0===h,finalBuild:t}),h++,f())}),t);const S=new d(((e,t)=>{o=e,a=t}),g.abortHandler),C=new d(((e,t)=>{l=e,c=t}));return this.addSplatSceneDownloadPromise(g),this.setSplatSceneDownloadAndBuildPromise(C),g.then((()=>{this.removeSplatSceneDownloadPromise(g)})).catch((e=>{this.clearSplatSceneDownloadAndBuildPromise(),this.removeSplatSceneDownloadPromise(g),e instanceof p||(c(e),a&&a(e),i&&i(e))})),S}addSplatScenes(e,t=!0,n=void 0){if(this.isLoadingOrUnloading())throw new Error("Cannot add splat scene while another load or unload is already in progress.");if(this.isDisposingOrDisposed())throw new Error("Cannot add splat scene after dispose() is called.");const s=e.length,r=[];t&&(this.loadingSpinner.removeAllTasks(),this.loadingSpinner.show());const i=(e,i,o)=>{r[e]=i;let a=0;for(let e=0;e<s;e++)a+=r[e]||0;a/=s,o=`${a.toFixed(2)}%`,t&&this.loadingSpinner.setMessage(100==a?"Download complete!":`Downloading: ${o}`),n&&n(a,o,U)},o=[],a=[],l=[];for(let t=0;t<e.length;t++){const n=e[t],s=void 0!==n.format&&null!==n.format?n.format:K(n.path),r=this.downloadSplatSceneToSplatBuffer(n.path,n.splatAlphaRemovalThreshold,i.bind(this,t),!1,void 0,s);l.push(r.abortHandler),o.push(r),a.push(r.promise),this.addSplatSceneDownloadPromise(r)}const c=new d(((s,r)=>{Promise.all(a).then((r=>{t&&this.loadingSpinner.hide(),n&&options.onProgress(0,"0%",V),this.addSplatBuffers(r,e,!0,t,t).then((()=>{n&&n(100,"100%",V),this.clearSplatSceneDownloadAndBuildPromise(),s()}))})).catch((e=>{t&&this.loadingSpinner.hide(),this.clearSplatSceneDownloadAndBuildPromise(),e instanceof p?s():r(new Error("Viewer::addSplatScenes -> Could not load one or more splat scenes."))})).finally((()=>{for(let e of o)this.removeSplatSceneDownloadPromise(e)}))}),(()=>{for(let e of l)e()}));return this.setSplatSceneDownloadAndBuildPromise(c),c}downloadSplatSceneToSplatBuffer(e,t=1,n=void 0,s=!1,r=void 0,i){return i===q.Splat?X.loadFromURL(e,n,s,r,t,0,!1):i===q.KSplat?Y.loadFromURL(e,n,s,r):i===q.Ply?G.loadFromURL(e,n,s,r,t,0,this.sphericalHarmonicsDegree):d.reject(new Error(`Viewer::downloadSplatSceneToSplatBuffer -> File format not supported: ${e}`))}static isStreamable(e){return e===q.Splat||e===q.KSplat||e===q.Ply}addSplatBuffers=function(){return function(e,t=[],n=!0,s=!0,r=!0){if(this.isDisposingOrDisposed())return Promise.resolve();this.splatRenderReady=!1;let i=null;const o=e=>{this.isDisposingOrDisposed()||(null!==i&&(this.loadingSpinner.removeTask(i),i=null),!this.gpuAcceleratedSort&&this.sortWorker&&this.sortWorker.postMessage({centers:e.centers.buffer,transformIndexes:e.sceneIndexes.buffer,range:{from:e.from,to:e.to,count:e.count}}),this.splatRenderReady=!0,this.sortNeededForSceneChange=!0)};return new Promise((a=>{s&&(i=this.loadingSpinner.addTask("Processing splats...")),y((()=>{if(this.isDisposingOrDisposed())a();else{const s=this.addSplatBuffersToMesh(e,t,n,r),i=this.splatMesh.getMaxSplatCount();this.sortWorker&&this.sortWorker.maxSplatCount!==i&&this.disposeSortWorker();(!this.sortWorker&&i>0?this.setupSortWorker(this.splatMesh):Promise.resolve()).then((()=>{o(s),a()}))}}),!0)}))}}();addSplatBuffersToMesh(e,t,n=!0,s=!1){if(this.isDisposingOrDisposed())return;const r=this.splatMesh.splatBuffers||[],i=this.splatMesh.splatBufferOptions||[];let o;r.push(...e),i.push(...t),this.renderer&&this.splatMesh.setRenderer(this.renderer);return this.splatMesh.build(r,i,!0,n,(e=>{if(this.isDisposingOrDisposed())return;const t=this.splatMesh.getSplatCount();s&&t>=15e5&&(e||o||(this.loadingSpinner.setMinimized(!0,!0),o=this.loadingSpinner.addTask("Optimizing splats...")))}),(e=>{this.isDisposingOrDisposed()||e&&o&&this.loadingSpinner.removeTask(o)}))}setupSortWorker(e){if(!this.isDisposingOrDisposed())return new Promise((t=>{const n=this.integerBasedSort?Int32Array:Float32Array,s=e.getSplatCount(),r=e.getMaxSplatCount();this.sortWorker=function(e,t,n,s){const r=new Worker(URL.createObjectURL(new Blob(["(",Be.toString(),")(self)"],{type:"application/javascript"}))),i=atob("AGFzbQEAAAAADAZkeWxpbmsAAAAAAAEbA2AAAGAQf39/f39/f39/f39/f39/fwBgAAF/AhIBA2VudgZtZW1vcnkCAwCAgAQDBAMAAQIHOQMRX193YXNtX2NhbGxfY3RvcnMAAAtzb3J0SW5kZXhlcwABE2Vtc2NyaXB0ZW5fdGxzX2luaXQAAgrHEAMDAAELuxAFAXwDewJ/A30CfiALIAprIQwCQCAOBEAgDQRAQfj///8HIQ5BiICAgHghDSALIAxNDQIgDCEBA0AgAyABQQJ0IgVqIAIgACAFaigCAEECdGooAgAiBTYCACAFIA4gBSAOSBshDiAFIA0gBSANShshDSABQQFqIgEgC0cNAAsMAgsgDwRAQfj///8HIQ5BiICAgHghDSALIAxNDQJBfyEPIAwhAgNAIA8gByAAIAJBAnQiFGooAgAiFUECdGooAgAiCkcEQAJ+IAX9CQIIIAggCkEGdGoiD/0JAgAgDyoCEP0gASAPKgIg/SACIA8qAjD9IAP95gEgBf0JAhggD/0JAgQgDyoCFP0gASAPKgIk/SACIA8qAjT9IAP95gH95AEgBf0JAiggD/0JAgggDyoCGP0gASAPKgIo/SACIA8qAjj9IAP95gH95AEgBf0JAjggD/0JAgwgDyoCHP0gASAPKgIs/SACIA8qAjz9IAP95gH95AEiEf0fArv9FCAR/R8Du/0iAf0MAAAAAABAj0AAAAAAAECPQCIS/fIBIhP9IQEiEJlEAAAAAAAA4ENjBEAgELAMAQtCgICAgICAgICAfwshGQJ+IBP9IQAiEJlEAAAAAAAA4ENjBEAgELAMAQtCgICAgICAgICAfwv9EiETAn4gEf0fALv9FCAR/R8Bu/0iASAS/fIBIhH9IQEiEJlEAAAAAAAA4ENjBEAgELAMAQtCgICAgICAgICAfwshGiATIBn9HgEhEgJ+IBH9IQAiEJlEAAAAAAAA4ENjBEAgELAMAQtCgICAgICAgICAfwv9EiAa/R4BIBL9DQABAgMICQoLEBESExgZGhshEiAKIQ8LIAMgFGogASAVQQR0av0AAAAgEv21ASIR/RsAIBH9GwFqIBH9GwJqIBH9GwNqIgo2AgAgCiAOIAogDkgbIQ4gCiANIAogDUobIQ0gAkEBaiICIAtHDQALDAILAn8gBSoCGLtEAAAAAABAj0CiIhCZRAAAAAAAAOBBYwRAIBCqDAELQYCAgIB4CyEKAn8gBSoCCLtEAAAAAABAj0CiIhCZRAAAAAAAAOBBYwRAIBCqDAELQYCAgIB4CyECAn8gBSoCKLtEAAAAAABAj0CiIhCZRAAAAAAAAOBBYwRAIBCqDAELQYCAgIB4CyEFQfj///8HIQ5BiICAgHghDSALIAxNDQEgAv0RIAr9HAEgBf0cAiESIAwhBQNAIAMgBUECdCICaiABIAAgAmooAgBBBHRq/QAAACAS/bUBIhH9GwAgEf0bAWogEf0bAmoiAjYCACACIA4gAiAOSBshDiACIA0gAiANShshDSAFQQFqIgUgC0cNAAsMAQsgDQRAQfj///8HIQ5BiICAgHghDSALIAxNDQEgDCEBA0AgAyABQQJ0IgVqAn8gAiAAIAVqKAIAQQJ0aioCALtEAAAAAAAAsECiIhCZRAAAAAAAAOBBYwRAIBCqDAELQYCAgIB4CyIKNgIAIAogDiAKIA5IGyEOIAogDSAKIA1KGyENIAFBAWoiASALRw0ACwwBCwJAIA9FBEAgCyAMSw0BQYiAgIB4IQ1B+P///wchDgwCC0H4////ByEOQYiAgIB4IQ0gCyAMTQ0BQX8hDyAMIQIDQCAPIAcgACACQQJ0IhRqKAIAQQJ0IhVqKAIAIgpHBEAgBf0JAgggCCAKQQZ0aiIP/QkCACAPKgIQ/SABIA8qAiD9IAIgDyoCMP0gA/3mASAF/QkCGCAP/QkCBCAPKgIU/SABIA8qAiT9IAIgDyoCNP0gA/3mAf3kASAF/QkCKCAP/QkCCCAPKgIY/SABIA8qAij9IAIgDyoCOP0gA/3mAf3kASAF/QkCOCAP/QkCDCAPKgIc/SABIA8qAiz9IAIgDyoCPP0gA/3mAf3kASERIAohDwsgAyAUagJ/IBEgASAVQQJ0IgpqKQIA/RL95gEiEv0fACAS/R8BkiARIBH9DQgJCgsMDQ4PAAAAAAAAAAAgASAKQQhyaikCAP0S/eYBIhL9HwCSIBL9HwGSu0QAAAAAAACwQKIiEJlEAAAAAAAA4EFjBEAgEKoMAQtBgICAgHgLIgo2AgAgCiAOIAogDkgbIQ4gCiANIAogDUobIQ0gAkEBaiICIAtHDQALDAELIAUqAighFiAFKgIYIRcgBSoCCCEYQfj///8HIQ5BiICAgHghDSAMIQUDQAJ/IBggASAAIAVBAnQiB2ooAgBBBHRqIgIqAgCUIBcgAioCBJSSIBYgAioCCJSSu0QAAAAAAACwQKIiEJlEAAAAAAAA4EFjBEAgEKoMAQtBgICAgHgLIQogAyAHaiAKNgIAIAogDiAKIA5IGyEOIAogDSAKIA1KGyENIAVBAWoiBSALRw0ACwsgCyAMSwRAIAlBAWuzIA2yIA6yk5UhFiAMIQ0DQAJ/IBYgAyANQQJ0aiIBKAIAIA5rspQiF4tDAAAAT10EQCAXqAwBC0GAgICAeAshCiABIAo2AgAgBCAKQQJ0aiIBIAEoAgBBAWo2AgAgDUEBaiINIAtHDQALCyAJQQJPBEAgBCgCACENQQEhDgNAIAQgDkECdGoiASABKAIAIA1qIg02AgAgDkEBaiIOIAlHDQALCyAMQQBKBEAgDCEOA0AgBiAOQQFrIgFBAnQiAmogACACaigCADYCACAOQQFKIQIgASEOIAINAAsLIAsgDEoEQCALIQ4DQCAGIAsgBCADIA5BAWsiDkECdCIBaigCAEECdGoiAigCACIFa0ECdGogACABaigCADYCACACIAVBAWs2AgAgDCAOSA0ACwsLBABBAAs="),o=new Uint8Array(i.length);for(let e=0;e<i.length;e++)o[e]=i.charCodeAt(e);return r.postMessage({init:{sorterWasmBytes:o.buffer,splatCount:e,useSharedMemory:t,integerBasedSort:n,dynamicMode:s,Constants:{BytesPerFloat:W.BytesPerFloat,BytesPerInt:W.BytesPerInt,DepthMapRange:W.DepthMapRange,MemoryPageSize:W.MemoryPageSize,MaxScenes:W.MaxScenes}}}),r}(r,this.sharedMemoryForWorkers,this.integerBasedSort,this.splatMesh.dynamicMode);let i=0;this.sortWorker.onmessage=e=>{if(e.data.sortDone){if(this.sortRunning=!1,this.sharedMemoryForWorkers)this.splatMesh.updateRenderIndexes(this.sortWorkerSortedIndexes,e.data.splatRenderCount);else{const t=new Uint32Array(e.data.sortedIndexes.buffer,0,e.data.splatRenderCount);this.splatMesh.updateRenderIndexes(t,e.data.splatRenderCount)}this.lastSortTime=e.data.sortTime,this.sortPromiseResolver(),this.sortPromiseResolver=null,this.forceRenderNextFrame(),0===i&&(this.runAfterFirstSort.forEach((e=>{e()})),this.runAfterFirstSort.length=0),i++}else if(e.data.sortCanceled)this.sortRunning=!1;else if(e.data.sortSetupPhase1Complete){this.logLevel>=be.Info&&console.log("Sorting web worker WASM setup complete."),this.sharedMemoryForWorkers?(this.sortWorkerSortedIndexes=new Uint32Array(e.data.sortedIndexesBuffer,e.data.sortedIndexesOffset,r),this.sortWorkerIndexesToSort=new Uint32Array(e.data.indexesToSortBuffer,e.data.indexesToSortOffset,r),this.sortWorkerPrecomputedDistances=new n(e.data.precomputedDistancesBuffer,e.data.precomputedDistancesOffset,r),this.sortWorkerTransforms=new Float32Array(e.data.transformsBuffer,e.data.transformsOffset,16*W.MaxScenes)):(this.sortWorkerIndexesToSort=new Uint32Array(r),this.sortWorkerPrecomputedDistances=new n(r),this.sortWorkerTransforms=new Float32Array(16*W.MaxScenes));for(let e=0;e<s;e++)this.sortWorkerIndexesToSort[e]=e;if(this.sortWorker.maxSplatCount=r,this.logLevel>=be.Info){console.log("Sorting web worker ready.");const e=this.splatMesh.getSplatDataTextures(),t=e.covariances.size,n=e.centerColors.size;console.log("Covariances texture size: "+t.x+" x "+t.y),console.log("Centers/colors texture size: "+n.x+" x "+n.y)}t()}}}))}disposeSortWorker(){this.sortWorker&&this.sortWorker.terminate(),this.sortWorker=null,this.sortPromise=null,this.sortPromiseResolver&&(this.sortPromiseResolver(),this.sortPromiseResolver=null),this.sortRunning=!1}removeSplatScene(e,t=!0){if(this.isLoadingOrUnloading())throw new Error("Cannot remove splat scene while another load or unload is already in progress.");if(this.isDisposingOrDisposed())throw new Error("Cannot remove splat scene after dispose() is called.");let n;return this.splatSceneRemovalPromise=new Promise(((s,r)=>{let i;t&&(this.loadingSpinner.removeAllTasks(),this.loadingSpinner.show(),i=this.loadingSpinner.addTask("Removing splat scene..."));const o=()=>{t&&(this.loadingSpinner.hide(),this.loadingSpinner.removeTask(i))},a=e=>{o(),this.splatSceneRemovalPromise=null,e?r(e):s()},l=()=>!!this.isDisposingOrDisposed()&&(a(),!0);n=this.sortPromise||Promise.resolve(),n.then((()=>{if(l())return;const t=[],s=[],r=[],i=this.splatMesh.visibleRegionFadeStartRadius;for(let n=0;n<this.splatMesh.scenes.length;n++)if(n!==e){const e=this.splatMesh.scenes[n];t.push(e.splatBuffer),s.push(this.splatMesh.sceneOptions[n]),r.push({position:e.position.clone(),quaternion:e.quaternion.clone(),scale:e.scale.clone()})}this.disposeSortWorker(),this.splatMesh.dispose(),this.createSplatMesh(),this.addSplatBuffers(t,s,!0,!1,!0).then((()=>{l()||(o(),this.splatMesh.visibleRegionFadeStartRadius=i,this.splatMesh.scenes.forEach(((e,t)=>{e.position.copy(r[t].position),e.quaternion.copy(r[t].quaternion),e.scale.copy(r[t].scale)})),this.splatMesh.updateTransforms(),this.splatRenderReady=!1,this.updateSplatSort(!0).then((()=>{l()?this.splatRenderReady=!0:(n=this.sortPromise||Promise.resolve(),n.then((()=>{this.splatRenderReady=!0,a()})))})))})).catch((e=>{a(e)}))}))})),this.splatSceneRemovalPromise}start(){if(!this.selfDrivenMode)throw new Error("Cannot start viewer unless it is in self driven mode.");this.webXRMode?this.renderer.setAnimationLoop(this.selfDrivenUpdateFunc):this.requestFrameId=requestAnimationFrame(this.selfDrivenUpdateFunc),this.selfDrivenModeRunning=!0}stop(){this.selfDrivenMode&&this.selfDrivenModeRunning&&(this.webXRMode||cancelAnimationFrame(this.requestFrameId),this.selfDrivenModeRunning=!1)}async dispose(){this.disposing=!0;let e=[],t=[];for(let n in this.splatSceneDownloadPromises)if(this.splatSceneDownloadPromises.hasOwnProperty(n)){const s=this.splatSceneDownloadPromises[n];t.push(s),e.push(s.promise)}this.sortPromise&&e.push(this.sortPromise);const n=Promise.all(e).finally((()=>{this.stop(),this.controls&&(this.controls.dispose(),this.controls=null),this.splatMesh&&(this.splatMesh.dispose(),this.splatMesh=null),this.sceneHelper&&(this.sceneHelper.dispose(),this.sceneHelper=null),this.resizeObserver&&(this.resizeObserver.unobserve(this.rootElement),this.resizeObserver=null),this.disposeSortWorker(),this.removeEventHandlers(),this.loadingSpinner.removeAllTasks(),this.loadingSpinner.setContainer(null),this.loadingProgressBar.hide(),this.loadingProgressBar.setContainer(null),this.infoPanel.setContainer(null),this.camera=null,this.threeScene=null,this.splatRenderReady=!1,this.initialized=!1,this.renderer&&(this.usingExternalRenderer||(this.rootElement.removeChild(this.renderer.domElement),this.renderer.dispose()),this.renderer=null),this.usingExternalRenderer||document.body.removeChild(this.rootElement),this.sortWorkerSortedIndexes=null,this.sortWorkerIndexesToSort=null,this.sortWorkerPrecomputedDistances=null,this.sortWorkerTransforms=null,this.disposed=!0,this.disposing=!1}));return t.forEach((e=>{e.abort()})),n}selfDrivenUpdate(){this.selfDrivenMode&&!this.webXRMode&&(this.requestFrameId=requestAnimationFrame(this.selfDrivenUpdateFunc)),this.update(),this.shouldRender()?(this.render(),this.consecutiveRenderFrames++):this.consecutiveRenderFrames=0,this.renderNextFrame=!1}forceRenderNextFrame(){this.renderNextFrame=!0}shouldRender=function(){let t=0;const n=new e.Vector3,s=new e.Quaternion,r=1e-4;return function(){let e=!1,i=!1;if(this.camera){const e=this.camera.position,t=this.camera.quaternion;i=Math.abs(e.x-n.x)>r||Math.abs(e.y-n.y)>r||Math.abs(e.z-n.z)>r||Math.abs(t.x-s.x)>r||Math.abs(t.y-s.y)>r||Math.abs(t.z-s.z)>r||Math.abs(t.w-s.w)>r}return e=this.renderMode!==Re.Never&&(0===t||this.splatMesh.visibleRegionChanging||i||this.renderMode===Re.Always||!0===this.dynamicMode||this.renderNextFrame),this.camera&&(n.copy(this.camera.position),s.copy(this.camera.quaternion)),t++,e}}();render=function(){if(!this.initialized||!this.splatRenderReady)return;const e=this.renderer.autoClear;(e=>{for(let t of e.children)if(t.visible)return!0;return!1})(this.threeScene)&&(this.renderer.render(this.threeScene,this.camera),this.renderer.autoClear=!1),this.renderer.render(this.splatMesh,this.camera),this.renderer.autoClear=!1,this.sceneHelper.getFocusMarkerOpacity()>0&&this.renderer.render(this.sceneHelper.focusMarker,this.camera),this.showControlPlane&&this.renderer.render(this.sceneHelper.controlPlane,this.camera),this.renderer.autoClear=e};update(e,t){this.dropInMode&&this.updateForDropInMode(e,t),this.initialized&&this.splatRenderReady&&(this.controls&&(this.controls.update(),this.camera.isOrthographicCamera&&!this.usingExternalCamera&&Ie.setCameraPositionFromZoom(this.camera,this.camera,this.controls)),this.splatMesh.updateVisibleRegionFadeDistance(this.sceneRevealMode),this.updateSplatSort(),this.updateForRendererSizeChanges(),this.updateSplatMesh(),this.updateMeshCursor(),this.updateFPS(),this.timingSensitiveUpdates(),this.updateInfoPanel(),this.updateControlPlane())}updateForDropInMode(e,t){this.renderer=e,this.splatMesh&&this.splatMesh.setRenderer(this.renderer),this.camera=t,this.controls&&(this.controls.object=t),this.init()}updateFPS=function(){let e=g(),t=0;return function(){if(this.consecutiveRenderFrames>60){const n=g();n-e>=1?(this.currentFPS=t,t=0,e=n):t++}else this.currentFPS=null}}();updateForRendererSizeChanges=function(){const t=new e.Vector2,n=new e.Vector2;let s;return function(){this.usingExternalCamera||(this.renderer.getSize(n),void 0!==s&&s===this.camera.isOrthographicCamera&&n.x===t.x&&n.y===t.y||(this.camera.isOrthographicCamera?(this.camera.left=-n.x/2,this.camera.right=n.x/2,this.camera.top=n.y/2,this.camera.bottom=-n.y/2):this.camera.aspect=n.x/n.y,this.camera.updateProjectionMatrix(),t.copy(n),s=this.camera.isOrthographicCamera))}}();timingSensitiveUpdates=function(){let e;return function(){const t=g();e||(e=t);const n=t-e;this.updateCameraTransition(t),this.updateFocusMarker(n),e=t}}();updateCameraTransition=function(){let t=new e.Vector3,n=new e.Vector3,s=new e.Vector3;return function(e){if(this.transitioningCameraTarget){n.copy(this.previousCameraTarget).sub(this.camera.position).normalize(),s.copy(this.nextCameraTarget).sub(this.camera.position).normalize();const r=Math.acos(n.dot(s)),i=(r/(Math.PI/3)*.65+.3)/r*(e-this.transitioningCameraTargetStartTime);t.copy(this.previousCameraTarget).lerp(this.nextCameraTarget,i),this.camera.lookAt(t),this.controls.target.copy(t),i>=1&&(this.transitioningCameraTarget=!1)}}}();updateFocusMarker=function(){const t=new e.Vector2;let n=!1;return function(e){if(this.getRenderDimensions(t),this.transitioningCameraTarget){this.sceneHelper.setFocusMarkerVisibility(!0);const s=Math.max(this.sceneHelper.getFocusMarkerOpacity(),0);let r=Math.min(s+10*e,1);this.sceneHelper.setFocusMarkerOpacity(r),this.sceneHelper.updateFocusMarker(this.nextCameraTarget,this.camera,t),n=!0,this.forceRenderNextFrame()}else{let s;if(s=n?1:Math.min(this.sceneHelper.getFocusMarkerOpacity(),1),s>0){this.sceneHelper.updateFocusMarker(this.nextCameraTarget,this.camera,t);let n=Math.max(s-2.5*e,0);this.sceneHelper.setFocusMarkerOpacity(n),0===n&&this.sceneHelper.setFocusMarkerVisibility(!1)}s>0&&this.forceRenderNextFrame(),n=!1}}}();updateMeshCursor=function(){const t=[],n=new e.Vector2;return function(){this.showMeshCursor?(this.forceRenderNextFrame(),this.getRenderDimensions(n),t.length=0,this.raycaster.setFromCameraAndScreenPosition(this.camera,this.mousePosition,n),this.raycaster.intersectSplatMesh(this.splatMesh,t),t.length>0?(this.sceneHelper.setMeshCursorVisibility(!0),this.sceneHelper.positionAndOrientMeshCursor(t[0].origin,this.camera)):this.sceneHelper.setMeshCursorVisibility(!1)):(this.sceneHelper.getMeschCursorVisibility()&&this.forceRenderNextFrame(),this.sceneHelper.setMeshCursorVisibility(!1))}}();updateInfoPanel=function(){const t=new e.Vector2;return function(){if(!this.showInfo)return;const e=this.splatMesh.getSplatCount();this.getRenderDimensions(t);const n=this.controls?this.controls.target:null,s=this.showMeshCursor?this.sceneHelper.meshCursor.position:null,r=e>0?this.splatRenderCount/e*100:0;this.infoPanel.update(t,this.camera.position,n,this.camera.up,this.camera.isOrthographicCamera,s,this.currentFPS||"N/A",e,this.splatRenderCount,r,this.lastSortTime,this.focalAdjustment,this.splatMesh.getSplatScale(),this.splatMesh.getPointCloudModeEnabled())}}();updateControlPlane(){this.showControlPlane?(this.sceneHelper.setControlPlaneVisibility(!0),this.sceneHelper.positionAndOrientControlPlane(this.controls.target,this.camera.up)):this.sceneHelper.setControlPlaneVisibility(!1)}updateSplatSort=function(){const t=new e.Matrix4,n=[],s=new e.Vector3(0,0,-1),r=new e.Vector3(0,0,-1),i=new e.Vector3,o=new e.Vector3,a=[],l=[{angleThreshold:.55,sortFractions:[.125,.33333,.75]},{angleThreshold:.65,sortFractions:[.33333,.66667]},{angleThreshold:.8,sortFractions:[.5]}];return async function(e=!1){if(this.sortRunning)return;if(this.splatMesh.getSplatCount()<=0)return;let c=0,h=0,d=!1,p=!1;if(r.set(0,0,-1).applyQuaternion(this.camera.quaternion),c=r.dot(s),h=o.copy(this.camera.position).sub(i).length(),!e&&!(this.sortNeededForSceneChange||this.splatMesh.dynamicMode||0!==a.length||(c<=.99&&(d=!0),h>=1&&(p=!0),d||p)))return;this.sortRunning=!0;const{splatRenderCount:u,shouldSortAll:m}=this.gatherSceneNodesForSort();this.splatRenderCount=u,t.copy(this.camera.matrixWorld).invert();const f=this.perspectiveCamera||this.camera;if(t.premultiply(f.projectionMatrix),t.multiply(this.splatMesh.matrixWorld),this.gpuAcceleratedSort&&(a.length<=1||a.length%2==0)&&await this.splatMesh.computeDistancesOnGPU(t,this.sortWorkerPrecomputedDistances),this.splatMesh.dynamicMode||m)a.push(this.splatRenderCount);else if(0===a.length){for(let e of l)if(c<e.angleThreshold){for(let t of e.sortFractions)a.push(Math.floor(this.splatRenderCount*t));break}a.push(this.splatRenderCount)}let g=Math.min(a.shift(),this.splatRenderCount);n[0]=this.camera.position.x,n[1]=this.camera.position.y,n[2]=this.camera.position.z;const S={modelViewProj:t.elements,cameraPosition:n,splatRenderCount:this.splatRenderCount,splatSortCount:g,usePrecomputedDistances:this.gpuAcceleratedSort};this.splatMesh.dynamicMode&&this.splatMesh.fillTransformsArray(this.sortWorkerTransforms),this.sharedMemoryForWorkers||(S.indexesToSort=this.sortWorkerIndexesToSort,S.transforms=this.sortWorkerTransforms,this.gpuAcceleratedSort&&(S.precomputedDistances=this.sortWorkerPrecomputedDistances)),this.sortPromise=new Promise((e=>{this.sortPromiseResolver=e})),this.sortWorker.postMessage({sort:S}),0===a.length&&(i.copy(this.camera.position),s.copy(r)),this.sortNeededForSceneChange=!1}}();gatherSceneNodesForSort=function(){const t=[];let n=null;const s=new e.Vector3,r=new e.Vector3,i=new e.Vector3,o=new e.Matrix4,a=new e.Matrix4,l=new e.Matrix4,c=new e.Vector3,h=new e.Vector3(0,0,-1),d=new e.Vector3,p=e=>d.copy(e.max).sub(e.min).length();return function(d=!1){this.getRenderDimensions(c);const u=c.y/2/Math.tan(this.camera.fov/2*e.MathUtils.DEG2RAD),m=Math.atan(c.x/2/u),f=Math.atan(c.y/2/u),g=Math.cos(m),S=Math.cos(f),y=this.splatMesh.getSplatTree();if(y){a.copy(this.camera.matrixWorld).invert(),a.multiply(this.splatMesh.matrixWorld);let e=0,n=0;for(let c=0;c<y.subTrees.length;c++){const u=y.subTrees[c];o.copy(a),this.splatMesh.dynamicMode&&(this.splatMesh.getSceneTransform(c,l),o.multiply(l));const m=u.nodesWithIndexes.length;for(let a=0;a<m;a++){const l=u.nodesWithIndexes[a];if(!l.data||!l.data.indexes||0===l.data.indexes.length)continue;i.copy(l.center).applyMatrix4(o);const c=i.length();i.normalize(),s.copy(i).setX(0).normalize(),r.copy(i).setY(0).normalize();const m=h.dot(r),f=h.dot(s),y=p(l);!d&&(m<g-.6||f<S-.6)&&c>y||(n+=l.data.indexes.length,t[e]=l,l.data.distanceToNode=c,e++)}}t.length=e,t.sort(((e,t)=>e.data.distanceToNode<t.data.distanceToNode?-1:1));let c=n*W.BytesPerInt;for(let n=0;n<e;n++){const e=t[n],s=e.data.indexes.length,r=s*W.BytesPerInt;new Uint32Array(this.sortWorkerIndexesToSort.buffer,c-r,s).set(e.data.indexes),c-=r}return{splatRenderCount:n,shouldSortAll:!1}}{const e=this.splatMesh.getSplatCount();if(!n||n.length!==e){n=new Uint32Array(e);for(let t=0;t<e;t++)n[t]=t}return this.sortWorkerIndexesToSort.set(n),{splatRenderCount:e,shouldSortAll:!0}}}}();getSplatMesh(){return this.splatMesh}getSplatScene(e){return this.splatMesh.getScene(e)}isMobile(){return navigator.userAgent.includes("Mobi")}}class ke extends e.Group{constructor(e={}){super(),e.selfDrivenMode=!1,e.useBuiltInControls=!1,e.rootElement=null,e.ignoreDevicePixelRatio=!1,e.dropInMode=!0,e.camera=void 0,e.renderer=void 0,this.viewer=new Ie(e),this.splatMesh=null,this.callbackMesh=ke.createCallbackMesh(),this.add(this.callbackMesh),this.callbackMesh.onBeforeRender=ke.onBeforeRender.bind(this,this.viewer)}addSplatScene(e,t={}){return!1!==t.showLoadingUI&&(t.showLoadingUI=!0),this.viewer.addSplatScene(e,t)}addSplatScenes(e,t){return!1!==t&&(t=!0),this.viewer.addSplatScenes(e,t)}getSplatScene(e){return this.viewer.getSplatScene(e)}removeSplatScene(e){return this.viewer.removeSplatScene(e)}dispose(){return this.viewer.dispose()}static onBeforeRender(e,t,n,s){this.splatMesh!==this.viewer.splatMesh&&(this.splatMesh&&this.remove(this.splatMesh),this.splatMesh=this.viewer.splatMesh,this.add(this.viewer.splatMesh)),e.update(t,s)}static createCallbackMesh(){const t=new e.SphereGeometry(1,8,8),n=new e.MeshBasicMaterial;n.colorWrite=!1,n.depthWrite=!1;const s=new e.Mesh(t,n);return s.frustumCulled=!1,s}}export{d as AbortablePromise,L as CompressedPlyParser,ke as DropInViewer,Y as KSplatLoader,Z as LoaderUtils,be as LogLevel,re as OrbitControls,G as PlyLoader,z as PlyParser,Re as RenderMode,q as SceneFormat,we as SceneRevealMode,M as SplatBuffer,_ as SplatBufferGenerator,X as SplatLoader,Q as SplatParser,H as SplatPartitioner,Ie as Viewer,Ee as WebXRMode};
  2. //# sourceMappingURL=gaussian-splats-3d.module.min.js.map