@speridlabs/visus 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.umd.js CHANGED
@@ -1,5 +1,5 @@
1
- (function(C,D){typeof exports=="object"&&typeof module<"u"?D(exports,require("three")):typeof define=="function"&&define.amd?define(["exports","three"],D):(C=typeof globalThis<"u"?globalThis:C||self,D(C.Visus={},C.THREE))})(this,function(C,D){"use strict";var Tt=Object.defineProperty;var Bt=(C,D,tt)=>D in C?Tt(C,D,{enumerable:!0,configurable:!0,writable:!0,value:tt}):C[D]=tt;var h=(C,D,tt)=>Bt(C,typeof D!="symbol"?D+"":D,tt);if(typeof THREE>"u")throw new Error(`Visus UMD build requires Three.js as a global "THREE".
2
- Please include <script src="https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.min.js"><\/script> before loading visus/main.umd.js`);function tt(B){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(B){for(const s in B)if(s!=="default"){const e=Object.getOwnPropertyDescriptor(B,s);Object.defineProperty(t,s,e.get?e:{enumerable:!0,get:()=>B[s]})}}return t.default=B,Object.freeze(t)}const a=tt(D);class at{constructor(){h(this,"min",new a.Vector3(1/0,1/0,1/0));h(this,"max",new a.Vector3(-1/0,-1/0,-1/0));h(this,"center",new a.Vector3);h(this,"halfExtents",new a.Vector3)}reset(){this.min.set(1/0,1/0,1/0),this.max.set(-1/0,-1/0,-1/0),this.center.set(0,0,0),this.halfExtents.set(0,0,0)}expandByPoint(t){this.min.x=Math.min(this.min.x,t.x),this.min.y=Math.min(this.min.y,t.y),this.min.z=Math.min(this.min.z,t.z),this.max.x=Math.max(this.max.x,t.x),this.max.y=Math.max(this.max.y,t.y),this.max.z=Math.max(this.max.z,t.z),this.updateDerived()}expandByBox(t){this.min.x=Math.min(this.min.x,t.min.x),this.min.y=Math.min(this.min.y,t.min.y),this.min.z=Math.min(this.min.z,t.min.z),this.max.x=Math.max(this.max.x,t.max.x),this.max.y=Math.max(this.max.y,t.max.y),this.max.z=Math.max(this.max.z,t.max.z),this.updateDerived()}updateDerived(){this.center.addVectors(this.min,this.max).multiplyScalar(.5),this.halfExtents.subVectors(this.max,this.min).multiplyScalar(.5)}containsPoint(t){return t.x>=this.min.x&&t.x<=this.max.x&&t.y>=this.min.y&&t.y<=this.max.y&&t.z>=this.min.z&&t.z<=this.max.z}toBox3(){return new a.Box3().set(this.min,this.max)}clone(){const t=new at;return t.min.copy(this.min),t.max.copy(this.max),t.center.copy(this.center),t.halfExtents.copy(this.halfExtents),t}}class pt{constructor(t=0){h(this,"numSplats",0);h(this,"positions");h(this,"rotations");h(this,"scales");h(this,"colors");h(this,"opacities");h(this,"centers");h(this,"boundingBox",new at);this.numSplats=t,this.allocateBuffers(t)}allocateBuffers(t){this.positions=new Float32Array(t*3),this.rotations=new Float32Array(t*4),this.scales=new Float32Array(t*3),this.colors=new Float32Array(t*3),this.opacities=new Float32Array(t),this.centers=new Float32Array(t*3)}setSplat(t,s,e,n,r,o){if(t>=this.numSplats)throw new Error(`Splat index out of bounds: ${t} >= ${this.numSplats}`);const i=t*3,l=t*4,x=t*3,w=t*3;this.positions[i]=s.x,this.positions[i+1]=s.y,this.positions[i+2]=s.z,this.rotations[l]=e.x,this.rotations[l+1]=e.y,this.rotations[l+2]=e.z,this.rotations[l+3]=e.w,this.scales[x]=n.x,this.scales[x+1]=n.y,this.scales[x+2]=n.z,this.colors[w]=r.r,this.colors[w+1]=r.g,this.colors[w+2]=r.b,this.opacities[t]=o,this.centers[i]=s.x,this.centers[i+1]=s.y,this.centers[i+2]=s.z}getSplat(t){if(t>=this.numSplats)throw new Error(`Splat index out of bounds: ${t} >= ${this.numSplats}`);const s=t*3,e=t*4,n=t*3,r=t*3;return{position:new a.Vector3(this.positions[s],this.positions[s+1],this.positions[s+2]),rotation:new a.Quaternion(this.rotations[e],this.rotations[e+1],this.rotations[e+2],this.rotations[e+3]),scale:new a.Vector3(Math.exp(this.scales[n]),Math.exp(this.scales[n+1]),Math.exp(this.scales[n+2])),color:new a.Color(this.colors[r],this.colors[r+1],this.colors[r+2]),opacity:this.opacities[t]}}calculateBoundingBox(){this.boundingBox.reset();const t=new a.Vector3;for(let s=0;s<this.numSplats;s++){const e=s*3;t.set(this.positions[e],this.positions[e+1],this.positions[e+2]),this.boundingBox.expandByPoint(t)}return this.boundingBox}createDebugGeometry(){const t=new a.BufferGeometry;t.setAttribute("position",new a.BufferAttribute(this.positions,3));const s=new Float32Array(this.numSplats*3),e=new a.Quaternion,n=new a.Euler;for(let r=0;r<this.numSplats;r++){const o=r*4,i=r*3;e.set(this.rotations[o],this.rotations[o+1],this.rotations[o+2],this.rotations[o+3]),n.setFromQuaternion(e),s[i]=n.x,s[i+1]=n.y,s[i+2]=n.z}return t.setAttribute("rotation",new a.BufferAttribute(s,3)),t.setAttribute("scale",new a.BufferAttribute(this.scales,3)),t.setAttribute("color",new a.BufferAttribute(this.colors,3)),t.setAttribute("opacity",new a.BufferAttribute(this.opacities,1)),t}}class mt extends a.EventDispatcher{constructor(){super();h(this,"worker");h(this,"centers",null);h(this,"orderTexture",null);h(this,"chunks",null);h(this,"lastCameraPosition",new a.Vector3);h(this,"lastCameraDirection",new a.Vector3);const s=this.createWorkerCode(),e=new Blob([s],{type:"application/javascript"});this.worker=new Worker(URL.createObjectURL(e)),this.worker.onmessage=this.onWorkerMessage.bind(this)}onWorkerMessage(s){if(!this.orderTexture||!this.orderTexture.image)return console.error("SplatSorter: Order texture not initialized!");const{order:e,count:n}=s.data,r=this.orderTexture.image.data;if(!(r instanceof Uint32Array))return console.error("SplatSorter: Order texture data is not a Uint32Array!");r.set(new Uint32Array(e)),this.orderTexture.needsUpdate=!0;const o=r.buffer.slice(0),i={order:o};this.worker.postMessage(i,[o]),this.dispatchEvent({type:"updated",count:n})}init(s,e,n){if(!s||!(s.image.data instanceof Uint32Array))throw new Error("SplatSorter: Invalid orderTexture provided. Must be DataTexture with Uint32Array data.");if(!e||e.length%3!==0)throw new Error("SplatSorter: Invalid centers array provided. Length must be multiple of 3.");if(s.image.data.length<e.length/3)throw new Error("SplatSorter: orderTexture data buffer is smaller than the number of splats.");const r=e.length/3;this.orderTexture=s,this.centers=e.slice();const o=this.orderTexture.image.data;for(let b=0;b<r;b++)o[b]=b;this.orderTexture.needsUpdate=!0;const i=o.buffer.slice(0),l=this.centers.buffer.slice(0),x={order:i,centers:l},w=[i,l];if(n){this.chunks=n.slice();const b=this.chunks.buffer.slice(0);x.chunks=b,w.push(b)}this.worker.postMessage(x,w),queueMicrotask(()=>{this.dispatchEvent({type:"updated",count:r})})}setMapping(s){if(!this.centers)return console.warn("SplatSorter: Cannot set mapping before initialization.");let e;const n=[];if(!s){const l=this.centers.buffer.slice(0);return e={centers:l,mapping:null},n.push(l),this.worker.postMessage(e,n)}const r=new Float32Array(s.length*3);for(let l=0;l<s.length;l++){const x=s[l];if(x*3+2>=this.centers.length){console.warn(`SplatSorter: Mapping index ${x} out of bounds.`);continue}const w=x*3,b=l*3;r[b+0]=this.centers[w+0],r[b+1]=this.centers[w+1],r[b+2]=this.centers[w+2]}const o=r.buffer.slice(0),i=s.buffer.slice(0);e={centers:o,mapping:i},n.push(o,i),this.worker.postMessage(e,n)}setCamera(s,e){const n=this.lastCameraPosition.distanceToSquared(s)>1e-7,r=this.lastCameraDirection.dot(e)<.9999;if(!n&&!r)return;this.lastCameraPosition.copy(s),this.lastCameraDirection.copy(e);const o={cameraPosition:{x:s.x,y:s.y,z:s.z},cameraDirection:{x:e.x,y:e.y,z:e.z}};this.worker.postMessage(o)}dispose(){this.worker&&this.worker.terminate(),this.orderTexture=null,this.centers=null,this.chunks=null}createWorkerCode(){return`(${(function(){let e=null,n=null,r=null,o=null,i=null,l=null,x=!1;const w={x:0,y:0,z:0},b={x:0,y:0,z:0},f={x:0,y:0,z:0},y={x:0,y:0,z:0};let v=null,I=null;const T=32,O=new Array(T).fill(0),N=new Array(T).fill(0),W=new Array(T).fill(0),ct=(A,d,M)=>{for(;A<=d;){const S=d+A>>1,m=M(S);if(m>0)A=S+1;else if(m<0)d=S-1;else return S}return~A},rt=()=>{if(!e||!n||!i||!l)return;if(n.length===0){const c={order:e.buffer,count:0};self.postMessage(c,[e.buffer]),e=null;return}const A=i.x,d=i.y,M=i.z,S=l.x,m=l.y,F=l.z,_=1e-4,X=Math.abs(A-w.x)>_||Math.abs(d-w.y)>_||Math.abs(M-w.z)>_,Z=Math.abs(S-b.x)>_||Math.abs(m-b.y)>_||Math.abs(F-b.z)>_;if(!x&&!X&&!Z)return;x=!1,w.x=A,w.y=d,w.z=M,b.x=S,b.y=m,b.z=F;let L=1/0,G=-1/0;for(let c=0;c<8;++c){const u=c&1?f.x:y.x,g=c&2?f.y:y.y,p=c&4?f.z:y.z,z=u*S+g*m+p*F;L=Math.min(L,z),G=Math.max(G,z)}const k=n.length/3,J=G-L,U=(1<<Math.max(10,Math.min(20,Math.ceil(Math.log2(k/4)))))+1;if((!v||v.length!==k)&&(v=new Uint32Array(k)),!I||I.length!==U?I=new Uint32Array(U):I.fill(0),J<1e-7){for(let c=0;c<k;++c)v[c]=0;I[0]=k}else if(r&&r.length>0){const c=r.length/6;O.fill(0);for(let p=0;p<c;++p){const z=p*6,V=r[z+0],q=r[z+1],R=r[z+2],E=r[z+3],P=V*S+q*m+R*F-L,j=P-E,H=P+E,K=Math.max(0,Math.floor(j*T/J)),Q=Math.min(T,Math.ceil(H*T/J));for(let Y=K;Y<Q;++Y)O[Y]++}let u=0;for(let p=0;p<T;++p)u+=O[p];W[0]=0,N[0]=0;for(let p=1;p<T;++p)W[p-1]=O[p-1]/u*U>>>0,N[p]=N[p-1]+W[p-1];W[T-1]=O[T-1]/u*U>>>0;const g=J/T;for(let p=0;p<k;++p){const z=p*3,V=n[z+0],q=n[z+1],R=n[z+2],E=V*S+q*m+R*F,j=(G-E)/g,H=Math.max(0,Math.min(T-1,Math.floor(j))),K=j-H,Q=N[H]+W[H]*K>>>0,Y=Math.min(Q,U-1);v[p]=Y,I[Y]++}}else{const c=(U-1)/J;for(let u=0;u<k;++u){const g=u*3,p=n[g+0],z=n[g+1],V=n[g+2],q=p*S+z*m+V*F,E=(G-q)*c>>>0,P=Math.min(E,U-1);v[u]=P,I[P]++}}for(let c=1;c<U;c++)I[c]+=I[c-1];for(let c=k-1;c>=0;c--){const u=v[c],g=--I[u];e[g]=o?o[c]:c}const ot=A*S+d*m+M*F,st=c=>{if(!e)return-1/0;const u=e[c],g=u;if(!n||g*3+2>=n.length)return-1/0;const p=g*3;return n[p]*S+n[p+1]*m+n[p+2]*F-ot};let nt=k;if(k>0&&st(k-1)<0){const c=ct(0,k-1,st);nt=c<0?~c:c}const it={order:e.buffer,count:nt};self.postMessage(it,[e.buffer]),e=null};self.onmessage=A=>{const d=A.data;d.order&&(e=new Uint32Array(d.order));let M=!1;if(d.centers&&(n=new Float32Array(d.centers),M=!0,x=!0),Object.prototype.hasOwnProperty.call(d,"mapping")&&(o=d.mapping?new Uint32Array(d.mapping):null,x=!0),d.chunks){if(r=new Float32Array(d.chunks),r.length>0&&r[3]>0)for(let S=0;S<r.length/6;++S){const m=S*6,F=r[m+0],_=r[m+1],X=r[m+2],Z=r[m+3],L=r[m+4],G=r[m+5];r[m+0]=(F+Z)*.5,r[m+1]=(_+L)*.5,r[m+2]=(X+G)*.5,r[m+3]=Math.sqrt((Z-F)**2+(L-_)**2+(G-X)**2)*.5}x=!0}if(M&&n&&n.length>0){f.x=y.x=n[0],f.y=y.y=n[1],f.z=y.z=n[2];for(let S=1;S<n.length/3;S++){const m=S*3;f.x=Math.min(f.x,n[m+0]),y.x=Math.max(y.x,n[m+0]),f.y=Math.min(f.y,n[m+1]),y.y=Math.max(y.y,n[m+1]),f.z=Math.min(f.z,n[m+2]),y.z=Math.max(y.z,n[m+2])}}else M&&n&&n.length===0&&(f.x=y.x=f.y=y.y=f.z=y.z=0);d.cameraPosition&&(i=d.cameraPosition),d.cameraDirection&&(l=d.cameraDirection),rt()}}).toString()})();`}}const bt=(B,t)=>{const s=xt(B),e=xt(t);return s|e<<16};function xt(B){const t=new Float32Array([B]),e=new Int32Array(t.buffer)[0];let n=e>>16&32768,r=e>>12&2047;const o=e>>23&255;return o<103?n:o>142?(n|=31744,n|=(o===255?0:1)&&e&8388607,n):o<113?(r|=2048,n|=(r>>114-o)+(r>>113-o&1),n):(n|=o-112<<10|r>>1,n+=r&1,n)}const Mt=new ArrayBuffer(4),yt=new DataView(Mt),St=B=>(yt.setUint32(0,B,!0),yt.getFloat32(0,!0));class gt{constructor(t){h(this,"transformA");h(this,"transformB");h(this,"colorTexture");h(this,"orderTexture");h(this,"textureWidth");h(this,"textureHeight");const s=t.numSplats;this.textureWidth=Math.ceil(Math.sqrt(s)),this.textureHeight=Math.ceil(s/this.textureWidth),this.transformA=this.createTransformATexture(t),this.transformB=this.createTransformBTexture(t),this.colorTexture=this.createColorTexture(t),this.orderTexture=this.createOrderTexture(s)}createTransformATexture(t){const s=t.numSplats,e=new Float32Array(this.textureWidth*this.textureHeight*4);for(let r=0;r<s;r++){const o=r*4,i=r*3,l=r*4;e[o]=t.positions[i],e[o+1]=t.positions[i+1],e[o+2]=t.positions[i+2];const x=t.rotations[l+0],w=t.rotations[l+1],b=bt(x,w);e[o+3]=St(b)}const n=new a.DataTexture(e,this.textureWidth,this.textureHeight,a.RGBAFormat,a.FloatType);return n.needsUpdate=!0,n.magFilter=a.NearestFilter,n.minFilter=a.NearestFilter,n}createTransformBTexture(t){const s=t.numSplats,e=new Float32Array(this.textureWidth*this.textureHeight*4);for(let r=0;r<s;r++){const o=r*4,i=r*3,l=r*4;e[o]=t.scales[i],e[o+1]=t.scales[i+1],e[o+2]=t.scales[i+2],e[o+3]=t.rotations[l+2]}const n=new a.DataTexture(e,this.textureWidth,this.textureHeight,a.RGBAFormat,a.FloatType);return n.needsUpdate=!0,n.magFilter=a.NearestFilter,n.minFilter=a.NearestFilter,n}createColorTexture(t){const s=t.numSplats,e=new Float32Array(this.textureWidth*this.textureHeight*4);for(let r=0;r<s;r++){const o=r*4,i=r*3;e[o]=t.colors[i],e[o+1]=t.colors[i+1],e[o+2]=t.colors[i+2],e[o+3]=t.opacities[r]}const n=new a.DataTexture(e,this.textureWidth,this.textureHeight,a.RGBAFormat,a.FloatType);return n.needsUpdate=!0,n}createOrderTexture(t){const s=new Uint32Array(this.textureWidth*this.textureHeight);for(let n=0;n<t;n++)s[n]=n;const e=new a.DataTexture(s,this.textureWidth,this.textureHeight,a.RedIntegerFormat,a.UnsignedIntType);return e.needsUpdate=!0,e}dispose(){this.transformA.dispose(),this.transformB.dispose(),this.colorTexture.dispose(),this.orderTexture.dispose()}}const Ct=`
1
+ (function(C,D){typeof exports=="object"&&typeof module<"u"?D(exports,require("three")):typeof define=="function"&&define.amd?define(["exports","three"],D):(C=typeof globalThis<"u"?globalThis:C||self,D(C.Visus={},C.THREE))})(this,function(C,D){"use strict";var zt=Object.defineProperty;var Tt=(C,D,rt)=>D in C?zt(C,D,{enumerable:!0,configurable:!0,writable:!0,value:rt}):C[D]=rt;var h=(C,D,rt)=>Tt(C,typeof D!="symbol"?D+"":D,rt);if(typeof THREE>"u")throw new Error(`Visus UMD build requires Three.js as a global "THREE".
2
+ Please include <script src="https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.min.js"><\/script> before loading visus/main.umd.js`);function rt(k){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(k){for(const o in k)if(o!=="default"){const t=Object.getOwnPropertyDescriptor(k,o);Object.defineProperty(e,o,t.get?t:{enumerable:!0,get:()=>k[o]})}}return e.default=k,Object.freeze(e)}const a=rt(D);class at{constructor(){h(this,"min",new a.Vector3(1/0,1/0,1/0));h(this,"max",new a.Vector3(-1/0,-1/0,-1/0));h(this,"center",new a.Vector3);h(this,"halfExtents",new a.Vector3)}reset(){this.min.set(1/0,1/0,1/0),this.max.set(-1/0,-1/0,-1/0),this.center.set(0,0,0),this.halfExtents.set(0,0,0)}expandByPoint(e){this.min.x=Math.min(this.min.x,e.x),this.min.y=Math.min(this.min.y,e.y),this.min.z=Math.min(this.min.z,e.z),this.max.x=Math.max(this.max.x,e.x),this.max.y=Math.max(this.max.y,e.y),this.max.z=Math.max(this.max.z,e.z),this.updateDerived()}expandByBox(e){this.min.x=Math.min(this.min.x,e.min.x),this.min.y=Math.min(this.min.y,e.min.y),this.min.z=Math.min(this.min.z,e.min.z),this.max.x=Math.max(this.max.x,e.max.x),this.max.y=Math.max(this.max.y,e.max.y),this.max.z=Math.max(this.max.z,e.max.z),this.updateDerived()}updateDerived(){this.center.addVectors(this.min,this.max).multiplyScalar(.5),this.halfExtents.subVectors(this.max,this.min).multiplyScalar(.5)}containsPoint(e){return e.x>=this.min.x&&e.x<=this.max.x&&e.y>=this.min.y&&e.y<=this.max.y&&e.z>=this.min.z&&e.z<=this.max.z}toBox3(){return new a.Box3().set(this.min,this.max)}clone(){const e=new at;return e.min.copy(this.min),e.max.copy(this.max),e.center.copy(this.center),e.halfExtents.copy(this.halfExtents),e}}class ft{constructor(e=0){h(this,"numSplats",0);h(this,"positions");h(this,"rotations");h(this,"scales");h(this,"colors");h(this,"opacities");h(this,"boundingBox",new at);this.numSplats=e,this.allocateBuffers(e)}allocateBuffers(e){this.positions=new Float32Array(e*3),this.rotations=new Float32Array(e*4),this.scales=new Float32Array(e*3),this.colors=new Float32Array(e*3),this.opacities=new Float32Array(e)}setSplat(e,o,t,s,r,n){if(e>=this.numSplats)throw new Error(`Splat index out of bounds: ${e} >= ${this.numSplats}`);const i=e*3,l=e*4,x=e*3,b=e*3;this.positions[i]=o.x,this.positions[i+1]=o.y,this.positions[i+2]=o.z,this.rotations[l]=t.x,this.rotations[l+1]=t.y,this.rotations[l+2]=t.z,this.rotations[l+3]=t.w,this.scales[x]=s.x,this.scales[x+1]=s.y,this.scales[x+2]=s.z,this.colors[b]=r.r,this.colors[b+1]=r.g,this.colors[b+2]=r.b,this.opacities[e]=n}getSplat(e){if(e>=this.numSplats)throw new Error(`Splat index out of bounds: ${e} >= ${this.numSplats}`);const o=e*3,t=e*4,s=e*3,r=e*3;return{position:new a.Vector3(this.positions[o],this.positions[o+1],this.positions[o+2]),rotation:new a.Quaternion(this.rotations[t],this.rotations[t+1],this.rotations[t+2],this.rotations[t+3]),scale:new a.Vector3(Math.exp(this.scales[s]),Math.exp(this.scales[s+1]),Math.exp(this.scales[s+2])),color:new a.Color(this.colors[r],this.colors[r+1],this.colors[r+2]),opacity:this.opacities[e]}}calculateBoundingBox(){this.boundingBox.reset();const e=new a.Vector3;for(let o=0;o<this.numSplats;o++){const t=o*3;e.set(this.positions[t],this.positions[t+1],this.positions[t+2]),this.boundingBox.expandByPoint(e)}return this.boundingBox}createDebugGeometry(){const e=new a.BufferGeometry;e.setAttribute("position",new a.BufferAttribute(this.positions,3));const o=new Float32Array(this.numSplats*3),t=new a.Quaternion,s=new a.Euler;for(let r=0;r<this.numSplats;r++){const n=r*4,i=r*3;t.set(this.rotations[n],this.rotations[n+1],this.rotations[n+2],this.rotations[n+3]),s.setFromQuaternion(t),o[i]=s.x,o[i+1]=s.y,o[i+2]=s.z}return e.setAttribute("rotation",new a.BufferAttribute(o,3)),e.setAttribute("scale",new a.BufferAttribute(this.scales,3)),e.setAttribute("color",new a.BufferAttribute(this.colors,3)),e.setAttribute("opacity",new a.BufferAttribute(this.opacities,1)),e}}class pt extends a.EventDispatcher{constructor(){super();h(this,"worker");h(this,"centers",null);h(this,"orderTexture",null);h(this,"chunks",null);h(this,"lastCameraPosition",new a.Vector3);h(this,"lastCameraDirection",new a.Vector3);const o=this.createWorkerCode(),t=new Blob([o],{type:"application/javascript"});this.worker=new Worker(URL.createObjectURL(t)),this.worker.onmessage=this.onWorkerMessage.bind(this)}onWorkerMessage(o){if(!this.orderTexture||!this.orderTexture.image)return console.error("SplatSorter: Order texture not initialized!");const{order:t,count:s}=o.data,r=this.orderTexture.image.data;if(!(r instanceof Uint32Array))return console.error("SplatSorter: Order texture data is not a Uint32Array!");r.set(new Uint32Array(t)),this.orderTexture.needsUpdate=!0;const n=r.buffer.slice(0),i={order:n};this.worker.postMessage(i,[n]),this.dispatchEvent({type:"updated",count:s})}init(o,t,s,r=!1){if(!o||!(o.image.data instanceof Uint32Array))throw new Error("SplatSorter: Invalid orderTexture provided. Must be DataTexture with Uint32Array data.");if(!t||t.length%3!==0)throw new Error("SplatSorter: Invalid centers array provided. Length must be multiple of 3.");if(o.image.data.length<t.length/3)throw new Error("SplatSorter: orderTexture data buffer is smaller than the number of splats.");const n=t.length/3;this.orderTexture=o,r?this.centers=null:this.centers=t.slice();const i=this.orderTexture.image.data;for(let u=0;u<n;u++)i[u]=u;this.orderTexture.needsUpdate=!0;const l=i.buffer.slice(0),x=r?t.buffer:t.buffer.slice(0),b={order:l,centers:x},S=[l,x];if(s){this.chunks=s.slice();const u=this.chunks.buffer.slice(0);b.chunks=u,S.push(u)}this.worker.postMessage(b,S),queueMicrotask(()=>{this.dispatchEvent({type:"updated",count:n})})}setMapping(o){if(!this.centers)return console.warn("SplatSorter: Cannot set mapping before initialization.");let t;const s=[];if(!o){const l=this.centers.buffer.slice(0);return t={centers:l,mapping:null},s.push(l),this.worker.postMessage(t,s)}const r=new Float32Array(o.length*3);for(let l=0;l<o.length;l++){const x=o[l];if(x*3+2>=this.centers.length){console.warn(`SplatSorter: Mapping index ${x} out of bounds.`);continue}const b=x*3,S=l*3;r[S+0]=this.centers[b+0],r[S+1]=this.centers[b+1],r[S+2]=this.centers[b+2]}const n=r.buffer.slice(0),i=o.buffer.slice(0);t={centers:n,mapping:i},s.push(n,i),this.worker.postMessage(t,s)}setCamera(o,t){const s=this.lastCameraPosition.distanceToSquared(o)>1e-7,r=this.lastCameraDirection.dot(t)<.9999;if(!s&&!r)return;this.lastCameraPosition.copy(o),this.lastCameraDirection.copy(t);const n={cameraPosition:{x:o.x,y:o.y,z:o.z},cameraDirection:{x:t.x,y:t.y,z:t.z}};this.worker.postMessage(n)}dispose(){this.worker&&this.worker.terminate(),this.orderTexture=null,this.centers=null,this.chunks=null}createWorkerCode(){return`(${(function(){let t=null,s=null,r=null,n=null,i=null,l=null,x=!1;const b={x:0,y:0,z:0},S={x:0,y:0,z:0},u={x:0,y:0,z:0},g={x:0,y:0,z:0};let v=null,I=null;const A=32,W=new Array(A).fill(0),N=new Array(A).fill(0),j=new Array(A).fill(0),ct=(w,d,E)=>{for(;w<=d;){const M=d+w>>1,p=E(M);if(p>0)w=M+1;else if(p<0)d=M-1;else return M}return~w},H=()=>{if(!t||!s||!i||!l)return;if(s.length===0){const c={order:t.buffer,count:0};self.postMessage(c,[t.buffer]),t=null;return}const w=i.x,d=i.y,E=i.z,M=l.x,p=l.y,z=l.z,_=1e-4,X=Math.abs(w-b.x)>_||Math.abs(d-b.y)>_||Math.abs(E-b.z)>_,Q=Math.abs(M-S.x)>_||Math.abs(p-S.y)>_||Math.abs(z-S.z)>_;if(!x&&!X&&!Q)return;x=!1,b.x=w,b.y=d,b.z=E,S.x=M,S.y=p,S.z=z;let K=1/0,U=-1/0;for(let c=0;c<8;++c){const y=c&1?u.x:g.x,B=c&2?u.y:g.y,m=c&4?u.z:g.z,T=y*M+B*p+m*z;K=Math.min(K,T),U=Math.max(U,T)}const F=s.length/3,Z=U-K,V=(1<<Math.max(10,Math.min(20,Math.ceil(Math.log2(F/4)))))+1;if((!v||v.length!==F)&&(v=new Uint32Array(F)),!I||I.length!==V?I=new Uint32Array(V):I.fill(0),Z<1e-7){for(let c=0;c<F;++c)v[c]=0;I[0]=F}else if(r&&r.length>0){const c=r.length/6;W.fill(0);for(let m=0;m<c;++m){const T=m*6,q=r[T+0],O=r[T+1],L=r[T+2],P=r[T+3],R=q*M+O*p+L*z-K,G=R-P,$=R+P,tt=Math.max(0,Math.floor(G*A/Z)),et=Math.min(A,Math.ceil($*A/Z));for(let Y=tt;Y<et;++Y)W[Y]++}let y=0;for(let m=0;m<A;++m)y+=W[m];j[0]=0,N[0]=0;for(let m=1;m<A;++m)j[m-1]=W[m-1]/y*V>>>0,N[m]=N[m-1]+j[m-1];j[A-1]=W[A-1]/y*V>>>0;const B=Z/A;for(let m=0;m<F;++m){const T=m*3,q=s[T+0],O=s[T+1],L=s[T+2],P=q*M+O*p+L*z,G=(U-P)/B,$=Math.max(0,Math.min(A-1,Math.floor(G))),tt=G-$,et=N[$]+j[$]*tt>>>0,Y=Math.min(et,V-1);v[m]=Y,I[Y]++}}else{const c=(V-1)/Z;for(let y=0;y<F;++y){const B=y*3,m=s[B+0],T=s[B+1],q=s[B+2],O=m*M+T*p+q*z,P=(U-O)*c>>>0,R=Math.min(P,V-1);v[y]=R,I[R]++}}for(let c=1;c<V;c++)I[c]+=I[c-1];for(let c=F-1;c>=0;c--){const y=v[c],B=--I[y];t[B]=n?n[c]:c}const it=w*M+d*p+E*z,ot=c=>{if(!t)return-1/0;const y=t[c],B=y;if(!s||B*3+2>=s.length)return-1/0;const m=B*3;return s[m]*M+s[m+1]*p+s[m+2]*z-it};let nt=F;if(F>0&&ot(F-1)<0){const c=ct(0,F-1,ot);nt=c<0?~c:c}const f={order:t.buffer,count:nt};self.postMessage(f,[t.buffer]),t=null};self.onmessage=w=>{const d=w.data;d.order&&(t=new Uint32Array(d.order));let E=!1;if(d.centers&&(s=new Float32Array(d.centers),E=!0,x=!0),Object.prototype.hasOwnProperty.call(d,"mapping")&&(n=d.mapping?new Uint32Array(d.mapping):null,x=!0),d.chunks){if(r=new Float32Array(d.chunks),r.length>0&&r[3]>0)for(let M=0;M<r.length/6;++M){const p=M*6,z=r[p+0],_=r[p+1],X=r[p+2],Q=r[p+3],K=r[p+4],U=r[p+5];r[p+0]=(z+Q)*.5,r[p+1]=(_+K)*.5,r[p+2]=(X+U)*.5,r[p+3]=Math.sqrt((Q-z)**2+(K-_)**2+(U-X)**2)*.5}x=!0}if(E&&s&&s.length>0){u.x=g.x=s[0],u.y=g.y=s[1],u.z=g.z=s[2];for(let M=1;M<s.length/3;M++){const p=M*3;u.x=Math.min(u.x,s[p+0]),g.x=Math.max(g.x,s[p+0]),u.y=Math.min(u.y,s[p+1]),g.y=Math.max(g.y,s[p+1]),u.z=Math.min(u.z,s[p+2]),g.z=Math.max(g.z,s[p+2])}}else E&&s&&s.length===0&&(u.x=g.x=u.y=g.y=u.z=g.z=0);d.cameraPosition&&(i=d.cameraPosition),d.cameraDirection&&(l=d.cameraDirection),H()}}).toString()})();`}}const wt=(k,e)=>{const o=mt(k),t=mt(e);return o|t<<16};function mt(k){const e=new Float32Array([k]),t=new Int32Array(e.buffer)[0];let s=t>>16&32768,r=t>>12&2047;const n=t>>23&255;return n<103?s:n>142?(s|=31744,s|=(n===255?0:1)&&t&8388607,s):n<113?(r|=2048,s|=(r>>114-n)+(r>>113-n&1),s):(s|=n-112<<10|r>>1,s+=r&1,s)}const bt=new ArrayBuffer(4),xt=new DataView(bt),Mt=k=>(xt.setUint32(0,k,!0),xt.getFloat32(0,!0));class yt{constructor(e){h(this,"transformA");h(this,"transformB");h(this,"colorTexture");h(this,"orderTexture");h(this,"textureWidth");h(this,"textureHeight");const o=e.numSplats;this.textureWidth=Math.ceil(Math.sqrt(o)),this.textureHeight=Math.ceil(o/this.textureWidth),this.transformA=this.createTransformATexture(e),this.transformB=this.createTransformBTexture(e),this.colorTexture=this.createColorTexture(e),this.orderTexture=this.createOrderTexture(o)}createTransformATexture(e){const o=e.numSplats,t=new Float32Array(this.textureWidth*this.textureHeight*4);for(let r=0;r<o;r++){const n=r*4,i=r*3,l=r*4;t[n]=e.positions[i],t[n+1]=e.positions[i+1],t[n+2]=e.positions[i+2];const x=e.rotations[l+0],b=e.rotations[l+1],S=wt(x,b);t[n+3]=Mt(S)}const s=new a.DataTexture(t,this.textureWidth,this.textureHeight,a.RGBAFormat,a.FloatType);return s.needsUpdate=!0,s.magFilter=a.NearestFilter,s.minFilter=a.NearestFilter,s}createTransformBTexture(e){const o=e.numSplats,t=new Float32Array(this.textureWidth*this.textureHeight*4);for(let r=0;r<o;r++){const n=r*4,i=r*3,l=r*4;t[n]=e.scales[i],t[n+1]=e.scales[i+1],t[n+2]=e.scales[i+2],t[n+3]=e.rotations[l+2]}const s=new a.DataTexture(t,this.textureWidth,this.textureHeight,a.RGBAFormat,a.FloatType);return s.needsUpdate=!0,s.magFilter=a.NearestFilter,s.minFilter=a.NearestFilter,s}createColorTexture(e){const o=e.numSplats,t=new Float32Array(this.textureWidth*this.textureHeight*4);for(let r=0;r<o;r++){const n=r*4,i=r*3;t[n]=e.colors[i],t[n+1]=e.colors[i+1],t[n+2]=e.colors[i+2],t[n+3]=e.opacities[r]}const s=new a.DataTexture(t,this.textureWidth,this.textureHeight,a.RGBAFormat,a.FloatType);return s.needsUpdate=!0,s}createOrderTexture(e){const o=new Uint32Array(this.textureWidth*this.textureHeight);for(let s=0;s<e;s++)o[s]=s;const t=new a.DataTexture(o,this.textureWidth,this.textureHeight,a.RedIntegerFormat,a.UnsignedIntType);return t.needsUpdate=!0,t}dispose(){this.transformA.dispose(),this.transformB.dispose(),this.colorTexture.dispose(),this.orderTexture.dispose()}}const St=`
3
3
  precision highp float;
4
4
  precision highp int;
5
5
  precision highp usampler2D;
@@ -254,7 +254,7 @@ void main(void) {
254
254
  vColor = vec4(splatColor, splatOpacity);
255
255
  vUv = clippedCornerOffset;
256
256
  }
257
- `,It=`
257
+ `,Ct=`
258
258
  precision highp float;
259
259
 
260
260
  varying vec4 vColor; // Color and opacity passed from vertex shader
@@ -284,7 +284,7 @@ void main(void) {
284
284
  // Premultiply color by alpha (required for correct blending)
285
285
  gl_FragColor = vec4(vColor.rgb * alpha, alpha);
286
286
  }
287
- `;class vt extends a.ShaderMaterial{constructor(t={}){const s={transformA:{value:null},transformB:{value:null},splatColor:{value:null},splatOrder:{value:null},viewport:{value:new a.Vector2(1,1)},numSplats:{value:0}};super({vertexShader:Ct,fragmentShader:It,uniforms:s,transparent:!0,blending:a.CustomBlending,blendSrc:a.OneFactor,blendDst:a.OneMinusSrcAlphaFactor,blendSrcAlpha:a.OneFactor,blendDstAlpha:a.OneMinusSrcAlphaFactor,blendEquation:a.AddEquation,blendEquationAlpha:a.AddEquation,depthTest:!0,depthWrite:!1,side:a.DoubleSide,alphaTest:t.alphaTest!==void 0?t.alphaTest:0,toneMapped:t.toneMapped!==void 0?t.toneMapped:!1}),t.alphaHash&&(this.alphaHash=!0,this.depthWrite=!0,this.blending=a.NoBlending)}updateViewport(t,s){this.uniforms.viewport.value.set(t,s)}setTransformA(t){this.uniforms.transformA.value=t}setTransformB(t){this.uniforms.transformB.value=t}setColorTexture(t){this.uniforms.splatColor.value=t}setOrderTexture(t){this.uniforms.splatOrder.value=t}setNumSplats(t){this.uniforms.numSplats.value=t}}const et=class et extends a.Mesh{constructor(s,e={}){const n=new vt(e),r=et.createInstancedGeometry(s.numSplats,et.INSTANCE_SIZE);super(r,n);h(this,"sorter");h(this,"splatData");h(this,"options");h(this,"textureManager");h(this,"material");h(this,"geometry");h(this,"lastCameraPositionLocal",new a.Vector3);h(this,"lastCameraDirectionLocal",new a.Vector3);h(this,"invModelMatrix",new a.Matrix4);h(this,"_vpW",-1);h(this,"_vpH",-1);h(this,"_size",new a.Vector2);h(this,"_camPosW",new a.Vector3);h(this,"_camDirW",new a.Vector3);h(this,"_camPosL",new a.Vector3);h(this,"_camDirL",new a.Vector3);h(this,"onSorterUpdated",s=>{const e=s.count;this.geometry.instanceCount=Math.ceil(e/et.INSTANCE_SIZE),this.material.setNumSplats(e)});this.geometry=r,this.material=n,this.splatData=s,this.frustumCulled=!1,this.options={autoSort:!0,...e},this.textureManager=new gt(s),this.sorter=new mt;let o=this.createChunks()||void 0;o===null&&console.warn("Visus: Could not create sorter chunks, bounding box might be invalid."),o=void 0,this.sorter.addEventListener("updated",this.onSorterUpdated),this.sorter.init(this.textureManager.orderTexture,this.splatData.centers,o??void 0),this.material.setTransformA(this.textureManager.transformA),this.material.setTransformB(this.textureManager.transformB),this.material.setColorTexture(this.textureManager.colorTexture),this.material.setOrderTexture(this.textureManager.orderTexture),this.material.setNumSplats(0),this.geometry.boundingBox=s.boundingBox.toBox3(),this.geometry.boundingSphere=new a.Sphere,this.geometry.boundingBox.getBoundingSphere(this.geometry.boundingSphere)}static createInstancedGeometry(s,e){const n=Math.ceil(s/e),r=new a.BufferGeometry,o=new Float32Array([-1,-1,0,1,-1,0,1,1,0,-1,1,0]),i=new Uint16Array([0,1,2,0,2,3]),l=new Float32Array(4*3*e);for(let f=0;f<e;f++){const y=f*4*3;for(let v=0;v<4;v++)l[y+v*3+0]=o[v*3+0],l[y+v*3+1]=o[v*3+1],l[y+v*3+2]=f}const x=new Uint32Array(6*e);for(let f=0;f<e;f++){const y=f*6,v=f*4;x[y+0]=i[0]+v,x[y+1]=i[1]+v,x[y+2]=i[2]+v,x[y+3]=i[3]+v,x[y+4]=i[4]+v,x[y+5]=i[5]+v}r.setAttribute("position",new a.BufferAttribute(l,3)),r.setIndex(new a.BufferAttribute(x,1));const w=new a.InstancedBufferGeometry;w.index=r.index,w.setAttribute("position",r.getAttribute("position"));const b=new Uint32Array(n);for(let f=0;f<n;f++)b[f]=f*e;return w.setAttribute("splatInstanceIndex",new a.InstancedBufferAttribute(b,1,!1)),w.instanceCount=0,w}createChunks(){const s=this.splatData.boundingBox;return s.min.x===1/0||s.max.x===-1/0?null:new Float32Array([s.min.x,s.min.y,s.min.z,s.max.x,s.max.y,s.max.z])}updateViewport(s,e){s===this._vpW&&e===this._vpH||(this._vpW=s,this._vpH=e,this.material.updateViewport(s,e))}sort(s){s.getWorldPosition(this._camPosW),s.getWorldDirection(this._camDirW),this.invModelMatrix.copy(this.matrixWorld).invert(),this._camPosL.copy(this._camPosW).applyMatrix4(this.invModelMatrix),this._camDirL.copy(this._camDirW).transformDirection(this.invModelMatrix);const e=this.lastCameraPositionLocal.distanceToSquared(this._camPosL)>1e-6,n=this.lastCameraDirectionLocal.dot(this._camDirL)<.999;this.options.autoSort&&(e||n)&&(this.lastCameraPositionLocal.copy(this._camPosL),this.lastCameraDirectionLocal.copy(this._camDirL),this.sorter.setCamera(this._camPosL,this._camDirL))}onBeforeRender(s,e,n){this.sort(n),s.getSize(this._size),this.updateViewport(this._size.x,this._size.y)}dispose(){this.sorter.removeEventListener("updated",this.onSorterUpdated),this.sorter.dispose(),this.geometry.dispose(),this.material.dispose(),this.textureManager.dispose()}};h(et,"INSTANCE_SIZE",128);let ht=et;class At extends a.Loader{constructor(s){super(s);h(this,"requestId",0);h(this,"worker");h(this,"pendingCallbacks",new Map);const e=this.createWorkerCode(),n=new Blob([e],{type:"application/javascript"});this.worker=new Worker(URL.createObjectURL(n)),this.worker.onmessage=this.onWorkerMessage.bind(this)}onWorkerMessage(s){const{requestId:e,error:n,result:r}=s.data,o=this.pendingCallbacks.get(e);if(!o)return console.warn(`PlyLoader: Received response for unknown request ${e}`);if(this.pendingCallbacks.delete(e),n)return o.reject(new Error(n));if(!r)return o.reject(new Error("Worker returned no result"));try{const i=new pt(0);i.numSplats=r.numSplats,i.positions=new Float32Array(r.positions),i.rotations=new Float32Array(r.rotations),i.scales=new Float32Array(r.scales),i.colors=new Float32Array(r.colors),i.opacities=new Float32Array(r.opacities),i.centers=new Float32Array(r.centers),i.boundingBox.min.set(r.boundingBox.minX,r.boundingBox.minY,r.boundingBox.minZ),i.boundingBox.max.set(r.boundingBox.maxX,r.boundingBox.maxY,r.boundingBox.maxZ),o.resolve(i)}catch(i){o.reject(i)}}load(s,e,n,r){const o=new a.FileLoader(this.manager);o.setResponseType("arraybuffer"),o.setRequestHeader(this.requestHeader),o.setPath(this.path),o.setWithCredentials(this.withCredentials),o.load(s,i=>{this.parseAsync(i).then(l=>{e&&e(l)}).catch(l=>{r?r(l):console.error(l),this.manager.itemError(s)})},n,r)}loadAsync(s,e){return new Promise((n,r)=>{const o=new a.FileLoader(this.manager);o.setResponseType("arraybuffer"),o.setRequestHeader(this.requestHeader),o.setPath(this.path),o.setWithCredentials(this.withCredentials),o.load(s,i=>{this.parseAsync(i).then(n).catch(l=>{r(l),this.manager.itemError(s)})},e,i=>{r(i),this.manager.itemError(s)})})}parseAsync(s){return new Promise((e,n)=>{const r=this.requestId++;this.pendingCallbacks.set(r,{resolve:e,reject:n});const o={requestId:r,buffer:s};this.worker.postMessage(o,[s])})}dispose(){this.worker&&this.worker.terminate(),this.pendingCallbacks.clear()}createWorkerCode(){return`(${(function(){self.onmessage=n=>{const{requestId:r,buffer:o}=n.data;try{const i=e(o),l={requestId:r,result:i};self.postMessage(l,[i.positions,i.rotations,i.scales,i.colors,i.opacities,i.centers])}catch(i){const l={requestId:r,error:i instanceof Error?i.message:String(i)};self.postMessage(l)}};function e(n){const r=new TextDecoder,o=new Uint8Array(n),i=[112,108,121,10],l=`
287
+ `;class gt extends a.ShaderMaterial{constructor(e={}){const o={transformA:{value:null},transformB:{value:null},splatColor:{value:null},splatOrder:{value:null},viewport:{value:new a.Vector2(1,1)},numSplats:{value:0}};super({vertexShader:St,fragmentShader:Ct,uniforms:o,transparent:!0,blending:a.CustomBlending,blendSrc:a.OneFactor,blendDst:a.OneMinusSrcAlphaFactor,blendSrcAlpha:a.OneFactor,blendDstAlpha:a.OneMinusSrcAlphaFactor,blendEquation:a.AddEquation,blendEquationAlpha:a.AddEquation,depthTest:!0,depthWrite:!1,side:a.DoubleSide,alphaTest:e.alphaTest!==void 0?e.alphaTest:0,toneMapped:e.toneMapped!==void 0?e.toneMapped:!1}),e.alphaHash&&(this.alphaHash=!0,this.depthWrite=!0,this.blending=a.NoBlending)}updateViewport(e,o){this.uniforms.viewport.value.set(e,o)}setTransformA(e){this.uniforms.transformA.value=e}setTransformB(e){this.uniforms.transformB.value=e}setColorTexture(e){this.uniforms.splatColor.value=e}setOrderTexture(e){this.uniforms.splatOrder.value=e}setNumSplats(e){this.uniforms.numSplats.value=e}}const st=class st extends a.Mesh{constructor(o,t={}){const s=new gt(t),r=st.createInstancedGeometry(o.numSplats,st.INSTANCE_SIZE);super(r,s);h(this,"sorter");h(this,"splatData");h(this,"options");h(this,"textureManager");h(this,"material");h(this,"geometry");h(this,"lastCameraPositionLocal",new a.Vector3);h(this,"lastCameraDirectionLocal",new a.Vector3);h(this,"invModelMatrix",new a.Matrix4);h(this,"_vpW",-1);h(this,"_vpH",-1);h(this,"_size",new a.Vector2);h(this,"_camPosW",new a.Vector3);h(this,"_camDirW",new a.Vector3);h(this,"_camPosL",new a.Vector3);h(this,"_camDirL",new a.Vector3);h(this,"onSorterUpdated",o=>{const t=o.count;this.geometry.instanceCount=Math.ceil(t/st.INSTANCE_SIZE),this.material.setNumSplats(t)});this.geometry=r,this.material=s,this.splatData=o,this.frustumCulled=!1,this.options={autoSort:!0,...t},this.textureManager=new yt(o),this.sorter=new pt;let n=this.createChunks()||void 0;n===null&&console.warn("Visus: Could not create sorter chunks, bounding box might be invalid."),n=void 0,this.sorter.addEventListener("updated",this.onSorterUpdated),this.sorter.init(this.textureManager.orderTexture,this.splatData.positions,n??void 0,!this.options.keepSplatData),this.material.setTransformA(this.textureManager.transformA),this.material.setTransformB(this.textureManager.transformB),this.material.setColorTexture(this.textureManager.colorTexture),this.material.setOrderTexture(this.textureManager.orderTexture),this.material.setNumSplats(0),this.geometry.boundingBox=o.boundingBox.toBox3(),this.geometry.boundingSphere=new a.Sphere,this.geometry.boundingBox.getBoundingSphere(this.geometry.boundingSphere),this.options.keepSplatData||(this.splatData=null)}static createInstancedGeometry(o,t){const s=Math.ceil(o/t),r=new a.BufferGeometry,n=new Float32Array([-1,-1,0,1,-1,0,1,1,0,-1,1,0]),i=new Uint16Array([0,1,2,0,2,3]),l=new Float32Array(4*3*t);for(let u=0;u<t;u++){const g=u*4*3;for(let v=0;v<4;v++)l[g+v*3+0]=n[v*3+0],l[g+v*3+1]=n[v*3+1],l[g+v*3+2]=u}const x=new Uint32Array(6*t);for(let u=0;u<t;u++){const g=u*6,v=u*4;x[g+0]=i[0]+v,x[g+1]=i[1]+v,x[g+2]=i[2]+v,x[g+3]=i[3]+v,x[g+4]=i[4]+v,x[g+5]=i[5]+v}r.setAttribute("position",new a.BufferAttribute(l,3)),r.setIndex(new a.BufferAttribute(x,1));const b=new a.InstancedBufferGeometry;b.index=r.index,b.setAttribute("position",r.getAttribute("position"));const S=new Uint32Array(s);for(let u=0;u<s;u++)S[u]=u*t;return b.setAttribute("splatInstanceIndex",new a.InstancedBufferAttribute(S,1,!1)),b.instanceCount=0,b}createChunks(){if(!this.splatData)return null;const o=this.splatData.boundingBox;return o.min.x===1/0||o.max.x===-1/0?null:new Float32Array([o.min.x,o.min.y,o.min.z,o.max.x,o.max.y,o.max.z])}updateViewport(o,t){o===this._vpW&&t===this._vpH||(this._vpW=o,this._vpH=t,this.material.updateViewport(o,t))}sort(o){o.getWorldPosition(this._camPosW),o.getWorldDirection(this._camDirW),this.invModelMatrix.copy(this.matrixWorld).invert(),this._camPosL.copy(this._camPosW).applyMatrix4(this.invModelMatrix),this._camDirL.copy(this._camDirW).transformDirection(this.invModelMatrix);const t=this.lastCameraPositionLocal.distanceToSquared(this._camPosL)>1e-6,s=this.lastCameraDirectionLocal.dot(this._camDirL)<.999;this.options.autoSort&&(t||s)&&(this.lastCameraPositionLocal.copy(this._camPosL),this.lastCameraDirectionLocal.copy(this._camDirL),this.sorter.setCamera(this._camPosL,this._camDirL))}onBeforeRender(o,t,s){this.sort(s),o.getSize(this._size),this.updateViewport(this._size.x,this._size.y)}dispose(){this.sorter.removeEventListener("updated",this.onSorterUpdated),this.sorter.dispose(),this.geometry.dispose(),this.material.dispose(),this.textureManager.dispose()}};h(st,"INSTANCE_SIZE",128);let ht=st;class It extends a.Loader{constructor(o){super(o);h(this,"requestId",0);h(this,"worker");h(this,"pendingCallbacks",new Map);const t=this.createWorkerCode(),s=new Blob([t],{type:"application/javascript"});this.worker=new Worker(URL.createObjectURL(s)),this.worker.onmessage=this.onWorkerMessage.bind(this)}onWorkerMessage(o){const{requestId:t,error:s,result:r}=o.data,n=this.pendingCallbacks.get(t);if(!n)return console.warn(`PlyLoader: Received response for unknown request ${t}`);if(this.pendingCallbacks.delete(t),s)return n.reject(new Error(s));if(!r)return n.reject(new Error("Worker returned no result"));try{const i=new ft(0);i.numSplats=r.numSplats,i.positions=new Float32Array(r.positions),i.rotations=new Float32Array(r.rotations),i.scales=new Float32Array(r.scales),i.colors=new Float32Array(r.colors),i.opacities=new Float32Array(r.opacities),i.boundingBox.min.set(r.boundingBox.minX,r.boundingBox.minY,r.boundingBox.minZ),i.boundingBox.max.set(r.boundingBox.maxX,r.boundingBox.maxY,r.boundingBox.maxZ),n.resolve(i)}catch(i){n.reject(i)}}load(o,t,s,r){const n=new a.FileLoader(this.manager);n.setResponseType("arraybuffer"),n.setRequestHeader(this.requestHeader),n.setPath(this.path),n.setWithCredentials(this.withCredentials),n.load(o,i=>{this.parseAsync(i).then(l=>{t&&t(l)}).catch(l=>{r?r(l):console.error(l),this.manager.itemError(o)})},s,r)}loadAsync(o,t){return new Promise((s,r)=>{const n=new a.FileLoader(this.manager);n.setResponseType("arraybuffer"),n.setRequestHeader(this.requestHeader),n.setPath(this.path),n.setWithCredentials(this.withCredentials),n.load(o,i=>{this.parseAsync(i).then(s).catch(l=>{r(l),this.manager.itemError(o)})},t,i=>{r(i),this.manager.itemError(o)})})}parseAsync(o){return new Promise((t,s)=>{const r=this.requestId++;this.pendingCallbacks.set(r,{resolve:t,reject:s});const n={requestId:r,buffer:o};this.worker.postMessage(n,[o])})}dispose(){this.worker&&this.worker.terminate(),this.pendingCallbacks.clear()}createWorkerCode(){return`(${(function(){self.onmessage=s=>{const{requestId:r,buffer:n}=s.data;try{const i=t(n),l={requestId:r,result:i};self.postMessage(l,[i.positions,i.rotations,i.scales,i.colors,i.opacities])}catch(i){const l={requestId:r,error:i instanceof Error?i.message:String(i)};self.postMessage(l)}};function t(s){const r=new TextDecoder,n=new Uint8Array(s),i=[112,108,121,10],l=`
288
288
  end_header
289
- `;for(let c=0;c<i.length;c++)if(o[c]!==i[c])throw new Error("Invalid PLY file: Missing magic bytes");let x=0;for(let c=0;c<o.length-l.length;c++){let u=!0;for(let g=0;g<l.length;g++)if(o[c+g]!==l.charCodeAt(g)){u=!1;break}if(u){x=c+l.length;break}}if(x===0)throw new Error("Invalid PLY file: Could not find end of header");const b=r.decode(o.subarray(0,x)).split(`
290
- `),f=[];let y=null;for(let c=1;c<b.length;c++){const u=b[c].trim();if(u===""||u==="end_header")continue;const g=u.split(" ");switch(g[0]){case"format":y=g[1];break;case"element":f.push({name:g[1],count:parseInt(g[2],10),properties:[]});break;case"property":if(f.length===0)throw new Error("Invalid PLY file: Property without element");f[f.length-1].properties.push({type:g[1],name:g[2]});break}}if(y!=="binary_little_endian")throw new Error(`Unsupported PLY format: ${y}`);const v=f.find(c=>c.name==="vertex");if(!v)throw new Error("Invalid PLY file: No vertex element found");const I=v.count,T=new Float32Array(I*3),O=new Float32Array(I*4),N=new Float32Array(I*3),W=new Float32Array(I*3),ct=new Float32Array(I),rt=new Float32Array(I*3),A=new DataView(n);let d=x;const M=c=>v.properties.findIndex(u=>u.name===c),S=M("x"),m=M("y"),F=M("z"),_=[M("rot_0"),M("rot_1"),M("rot_2"),M("rot_3")],X=[M("scale_0"),M("scale_1"),M("scale_2")],Z=[M("f_dc_0"),M("f_dc_1"),M("f_dc_2")],L=M("opacity");if([S,m,F,..._,...X,...Z,L].some(c=>c===-1))throw new Error("Invalid PLY file: Missing required properties");const k=.28209479177387814,J=c=>{if(c>0)return 1/(1+Math.exp(-c));const u=Math.exp(c);return u/(1+u)};let lt=1/0,U=1/0,ot=1/0,st=-1/0,nt=-1/0,it=-1/0;for(let c=0;c<I;c++){const u=[];for(let ft=0;ft<v.properties.length;ft++){const wt=v.properties[ft].type;let $;switch(wt){case"char":$=A.getInt8(d),d+=1;break;case"uchar":$=A.getUint8(d),d+=1;break;case"short":$=A.getInt16(d,!0),d+=2;break;case"ushort":$=A.getUint16(d,!0),d+=2;break;case"int":$=A.getInt32(d,!0),d+=4;break;case"uint":$=A.getUint32(d,!0),d+=4;break;case"float":$=A.getFloat32(d,!0),d+=4;break;case"double":$=A.getFloat64(d,!0),d+=8;break;default:throw new Error(`Unsupported property type: ${wt}`)}u.push($)}const g=u[S],p=u[m],z=u[F],V=c*3;T[V]=g,T[V+1]=p,T[V+2]=z,lt=Math.min(lt,g),U=Math.min(U,p),ot=Math.min(ot,z),st=Math.max(st,g),nt=Math.max(nt,p),it=Math.max(it,z);let q=u[_[1]],R=u[_[2]],E=u[_[3]],P=u[_[0]];const j=Math.sqrt(q*q+R*R+E*E+P*P);j>0&&(q/=j,R/=j,E/=j,P/=j),P<0&&(q=-q,R=-R,E=-E,P=-P);const H=c*4;O[H]=q,O[H+1]=R,O[H+2]=E,O[H+3]=P;const K=c*3;N[K]=u[X[0]],N[K+1]=u[X[1]],N[K+2]=u[X[2]];let Q=.5+u[Z[0]]*k,Y=.5+u[Z[1]]*k,ut=.5+u[Z[2]]*k;Q=Math.max(0,Math.min(1,Q)),Y=Math.max(0,Math.min(1,Y)),ut=Math.max(0,Math.min(1,ut));const dt=c*3;W[dt]=Q,W[dt+1]=Y,W[dt+2]=ut,ct[c]=J(u[L]),rt[V]=g,rt[V+1]=p,rt[V+2]=z}return{numSplats:I,positions:T.buffer,rotations:O.buffer,scales:N.buffer,colors:W.buffer,opacities:ct.buffer,centers:rt.buffer,boundingBox:{minX:lt,minY:U,minZ:ot,maxX:st,maxY:nt,maxZ:it}}}}).toString()})();`}}const zt="0.3.0";C.BoundingBox=at,C.PlyLoader=At,C.SplatData=pt,C.SplatMaterial=vt,C.SplatMesh=ht,C.SplatSorter=mt,C.TextureManager=gt,C.VERSION=zt,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})});
289
+ `;for(let f=0;f<i.length;f++)if(n[f]!==i[f])throw new Error("Invalid PLY file: Missing magic bytes");let x=0;for(let f=0;f<n.length-l.length;f++){let c=!0;for(let y=0;y<l.length;y++)if(n[f+y]!==l.charCodeAt(y)){c=!1;break}if(c){x=f+l.length;break}}if(x===0)throw new Error("Invalid PLY file: Could not find end of header");const S=r.decode(n.subarray(0,x)).split(`
290
+ `),u=[];let g=null;for(let f=1;f<S.length;f++){const c=S[f].trim();if(c===""||c==="end_header")continue;const y=c.split(" ");switch(y[0]){case"format":g=y[1];break;case"element":u.push({name:y[1],count:parseInt(y[2],10),properties:[]});break;case"property":if(u.length===0)throw new Error("Invalid PLY file: Property without element");u[u.length-1].properties.push({type:y[1],name:y[2]});break}}if(g!=="binary_little_endian")throw new Error(`Unsupported PLY format: ${g}`);const v=u.find(f=>f.name==="vertex");if(!v)throw new Error("Invalid PLY file: No vertex element found");const I=v.count,A=new Float32Array(I*3),W=new Float32Array(I*4),N=new Float32Array(I*3),j=new Float32Array(I*3),ct=new Float32Array(I),H=new DataView(s);let w=x;const d=f=>v.properties.findIndex(c=>c.name===f),E=d("x"),M=d("y"),p=d("z"),z=[d("rot_0"),d("rot_1"),d("rot_2"),d("rot_3")],_=[d("scale_0"),d("scale_1"),d("scale_2")],X=[d("f_dc_0"),d("f_dc_1"),d("f_dc_2")],Q=d("opacity");if([E,M,p,...z,..._,...X,Q].some(f=>f===-1))throw new Error("Invalid PLY file: Missing required properties");const U=.28209479177387814,F=f=>{if(f>0)return 1/(1+Math.exp(-f));const c=Math.exp(f);return c/(1+c)};let Z=1/0,lt=1/0,V=1/0,it=-1/0,ot=-1/0,nt=-1/0;for(let f=0;f<I;f++){const c=[];for(let dt=0;dt<v.properties.length;dt++){const vt=v.properties[dt].type;let J;switch(vt){case"char":J=H.getInt8(w),w+=1;break;case"uchar":J=H.getUint8(w),w+=1;break;case"short":J=H.getInt16(w,!0),w+=2;break;case"ushort":J=H.getUint16(w,!0),w+=2;break;case"int":J=H.getInt32(w,!0),w+=4;break;case"uint":J=H.getUint32(w,!0),w+=4;break;case"float":J=H.getFloat32(w,!0),w+=4;break;case"double":J=H.getFloat64(w,!0),w+=8;break;default:throw new Error(`Unsupported property type: ${vt}`)}c.push(J)}const y=c[E],B=c[M],m=c[p],T=f*3;A[T]=y,A[T+1]=B,A[T+2]=m,Z=Math.min(Z,y),lt=Math.min(lt,B),V=Math.min(V,m),it=Math.max(it,y),ot=Math.max(ot,B),nt=Math.max(nt,m);let q=c[z[1]],O=c[z[2]],L=c[z[3]],P=c[z[0]];const R=Math.sqrt(q*q+O*O+L*L+P*P);R>0&&(q/=R,O/=R,L/=R,P/=R),P<0&&(q=-q,O=-O,L=-L,P=-P);const G=f*4;W[G]=q,W[G+1]=O,W[G+2]=L,W[G+3]=P;const $=f*3;N[$]=c[_[0]],N[$+1]=c[_[1]],N[$+2]=c[_[2]];let tt=.5+c[X[0]]*U,et=.5+c[X[1]]*U,Y=.5+c[X[2]]*U;tt=Math.max(0,Math.min(1,tt)),et=Math.max(0,Math.min(1,et)),Y=Math.max(0,Math.min(1,Y));const ut=f*3;j[ut]=tt,j[ut+1]=et,j[ut+2]=Y,ct[f]=F(c[Q])}return{numSplats:I,positions:A.buffer,rotations:W.buffer,scales:N.buffer,colors:j.buffer,opacities:ct.buffer,boundingBox:{minX:Z,minY:lt,minZ:V,maxX:it,maxY:ot,maxZ:nt}}}}).toString()})();`}}const At="0.3.0";C.BoundingBox=at,C.PlyLoader=It,C.SplatData=ft,C.SplatMaterial=gt,C.SplatMesh=ht,C.SplatSorter=pt,C.TextureManager=yt,C.VERSION=At,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})});