@speridlabs/visus 2.4.3 → 2.5.0

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,57 @@
1
- (function(H,te){typeof exports=="object"&&typeof module<"u"?te(exports,require("three")):typeof define=="function"&&define.amd?define(["exports","three"],te):(H=typeof globalThis<"u"?globalThis:H||self,te(H.Visus={},H.THREE))})(this,function(H,te){"use strict";var bt=Object.defineProperty;var St=(H,te,xe)=>te in H?bt(H,te,{enumerable:!0,configurable:!0,writable:!0,value:xe}):H[te]=xe;var x=(H,te,xe)=>St(H,typeof te!="symbol"?te+"":te,xe);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 xe(a){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(a){for(const t in a)if(t!=="default"){const s=Object.getOwnPropertyDescriptor(a,t);Object.defineProperty(e,t,s.get?s:{enumerable:!0,get:()=>a[t]})}}return e.default=a,Object.freeze(e)}const l=xe(te);class ge{constructor(){x(this,"min",new l.Vector3(1/0,1/0,1/0));x(this,"max",new l.Vector3(-1/0,-1/0,-1/0));x(this,"center",new l.Vector3);x(this,"halfExtents",new l.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 l.Box3().set(this.min,this.max)}clone(){const e=new ge;return e.min.copy(this.min),e.max.copy(this.max),e.center.copy(this.center),e.halfExtents.copy(this.halfExtents),e}}class Xe{constructor(e=0){x(this,"numSplats",0);x(this,"positions");x(this,"rotations");x(this,"scales");x(this,"colors");x(this,"opacities");x(this,"boundingBox",new ge);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,t,s,n,r,o){if(e>=this.numSplats)throw new Error(`Splat index out of bounds: ${e} >= ${this.numSplats}`);const i=e*3,u=e*4,y=e*3,m=e*3;this.positions[i]=t.x,this.positions[i+1]=t.y,this.positions[i+2]=t.z,this.rotations[u]=s.x,this.rotations[u+1]=s.y,this.rotations[u+2]=s.z,this.rotations[u+3]=s.w,this.scales[y]=n.x,this.scales[y+1]=n.y,this.scales[y+2]=n.z,this.colors[m]=r.r,this.colors[m+1]=r.g,this.colors[m+2]=r.b,this.opacities[e]=o}getSplat(e){if(e>=this.numSplats)throw new Error(`Splat index out of bounds: ${e} >= ${this.numSplats}`);const t=e*3,s=e*4,n=e*3,r=e*3;return{position:new l.Vector3(this.positions[t],this.positions[t+1],this.positions[t+2]),rotation:new l.Quaternion(this.rotations[s],this.rotations[s+1],this.rotations[s+2],this.rotations[s+3]),scale:new l.Vector3(Math.exp(this.scales[n]),Math.exp(this.scales[n+1]),Math.exp(this.scales[n+2])),color:new l.Color(this.colors[r],this.colors[r+1],this.colors[r+2]),opacity:this.opacities[e]}}calculateBoundingBox(){this.boundingBox.reset();const e=new l.Vector3;for(let t=0;t<this.numSplats;t++){const s=t*3;e.set(this.positions[s],this.positions[s+1],this.positions[s+2]),this.boundingBox.expandByPoint(e)}return this.boundingBox}createDebugGeometry(){const e=new l.BufferGeometry;e.setAttribute("position",new l.BufferAttribute(this.positions,3));const t=new Float32Array(this.numSplats*3),s=new l.Quaternion,n=new l.Euler;for(let r=0;r<this.numSplats;r++){const o=r*4,i=r*3;s.set(this.rotations[o],this.rotations[o+1],this.rotations[o+2],this.rotations[o+3]),n.setFromQuaternion(s),t[i]=n.x,t[i+1]=n.y,t[i+2]=n.z}return e.setAttribute("rotation",new l.BufferAttribute(t,3)),e.setAttribute("scale",new l.BufferAttribute(this.scales,3)),e.setAttribute("color",new l.BufferAttribute(this.colors,3)),e.setAttribute("opacity",new l.BufferAttribute(this.opacities,1)),e}dispose(){this.numSplats=0,this.scales=new Float32Array(0),this.colors=new Float32Array(0),this.positions=new Float32Array(0),this.rotations=new Float32Array(0),this.opacities=new Float32Array(0)}}class _e{constructor(e,t,s){x(this,"ranges");x(this,"version",1);x(this,"numSplats",0);x(this,"boundingBox",new ge);x(this,"sh0");x(this,"quats");x(this,"scales");x(this,"means_l");x(this,"means_u");this.ranges=t,this.numSplats=e,this.sh0=s.sh0,this.quats=s.quats,this.scales=s.scales,this.means_l=s.means_l,this.means_u=s.means_u,this.boundingBox=this.calculateBoundingBox()}calculateBoundingBox(){this.boundingBox.reset();const{mins:e,maxs:t}=this.ranges.means,s=n=>Math.sign(n)*(Math.exp(Math.abs(n))-1);return this.boundingBox.center.set((s(e[0])+s(t[0]))*.5,(s(e[1])+s(t[1]))*.5,(s(e[2])+s(t[2]))*.5),this.boundingBox.halfExtents.set((s(t[0])-s(e[0]))*.5,(s(t[1])-s(e[1]))*.5,(s(t[2])-s(e[2]))*.5),this.boundingBox}dispose(){this.sh0.dispose(),this.quats.dispose(),this.scales.dispose(),this.means_l.dispose(),this.means_u.dispose()}}class Te{constructor(e,t,s){x(this,"ranges");x(this,"version",2);x(this,"numSplats",0);x(this,"boundingBox",new ge);x(this,"sh0");x(this,"quats");x(this,"scales");x(this,"means_l");x(this,"means_u");this.ranges=t,this.numSplats=e,this.sh0=s.sh0,this.quats=s.quats,this.scales=s.scales,this.means_l=s.means_l,this.means_u=s.means_u,this.boundingBox=this.calculateBoundingBox()}calculateBoundingBox(){this.boundingBox.reset();const{mins:e,maxs:t}=this.ranges.means,s=n=>Math.sign(n)*(Math.exp(Math.abs(n))-1);return this.boundingBox.center.set((s(e[0])+s(t[0]))*.5,(s(e[1])+s(t[1]))*.5,(s(e[2])+s(t[2]))*.5),this.boundingBox.halfExtents.set((s(t[0])-s(e[0]))*.5,(s(t[1])-s(e[1]))*.5,(s(t[2])-s(e[2]))*.5),this.boundingBox}dispose(){this.sh0.dispose(),this.quats.dispose(),this.scales.dispose(),this.means_l.dispose(),this.means_u.dispose()}}class Ae{constructor(e,t,s,n,r,o,i,u){x(this,"numSplats");x(this,"textureWidth");x(this,"textureHeight");x(this,"ranges");x(this,"centers");x(this,"boundingBox");x(this,"packedColor");x(this,"packedGeometry");this.numSplats=e,this.textureWidth=t,this.textureHeight=s,this.boundingBox=u,this.ranges=i,this.centers=n,this.packedColor=o,this.packedGeometry=r}dispose(){this.centers=new Float32Array(0),this.packedColor=new Uint8Array(0),this.packedGeometry=new Uint32Array(0)}}class Ve extends l.EventDispatcher{constructor(){super();x(this,"worker");x(this,"centers",null);x(this,"orderTexture",null);x(this,"chunks",null);x(this,"lastCameraPosition",new l.Vector3);x(this,"lastCameraDirection",new l.Vector3);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(t){if(!this.orderTexture||!this.orderTexture.image)return console.error("SplatSorter: Order texture not initialized!");const{order:s,count:n}=t.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(s)),this.orderTexture.source.data.updateRanges||(this.orderTexture.source.data.updateRanges=[]),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(t,s,n,r=!1){if(!t||!(t.image.data instanceof Uint32Array))throw new Error("SplatSorter: Invalid orderTexture provided. Must be DataTexture with Uint32Array data.");if(!s||s.length%3!==0)throw new Error("SplatSorter: Invalid centers array provided. Length must be multiple of 3.");if(t.image.data.length<s.length/3)throw new Error("SplatSorter: orderTexture data buffer is smaller than the number of splats.");if(s.buffer.byteLength===0)throw new Error("SplatSorter: positions buffer is detached (likely React StrictMode + cached asset). ");const o=s.length/3;this.orderTexture=t,r?this.centers=null:this.centers=s.slice();const i=this.orderTexture.image.data;for(let h=0;h<o;h++)i[h]=h;this.orderTexture.source.data.updateRanges||(this.orderTexture.source.data.updateRanges=[]),this.orderTexture.needsUpdate=!0;const u=i.buffer.slice(0),y=r?s.buffer:s.buffer.slice(0),m={order:u,centers:y},c=[u,y];if(n){this.chunks=n.slice();const h=this.chunks.buffer.slice(0);m.chunks=h,c.push(h)}this.worker.postMessage(m,c),queueMicrotask(()=>{this.dispatchEvent({type:"updated",count:o})})}setMapping(t){if(!this.centers)return console.warn("SplatSorter: Cannot set mapping before initialization.");let s;const n=[];if(!t){const u=this.centers.buffer.slice(0);return s={centers:u,mapping:null},n.push(u),this.worker.postMessage(s,n)}const r=new Float32Array(t.length*3);for(let u=0;u<t.length;u++){const y=t[u];if(y*3+2>=this.centers.length){console.warn(`SplatSorter: Mapping index ${y} out of bounds.`);continue}const m=y*3,c=u*3;r[c+0]=this.centers[m+0],r[c+1]=this.centers[m+1],r[c+2]=this.centers[m+2]}const o=r.buffer.slice(0),i=t.buffer.slice(0);s={centers:o,mapping:i},n.push(o,i),this.worker.postMessage(s,n)}setCamera(t,s){const n=this.lastCameraPosition.distanceToSquared(t)>1e-7,r=this.lastCameraDirection.dot(s)<.9999;if(!n&&!r)return;this.lastCameraPosition.copy(t),this.lastCameraDirection.copy(s);const o={cameraPosition:{x:t.x,y:t.y,z:t.z},cameraDirection:{x:s.x,y:s.y,z:s.z}};this.worker.postMessage(o)}dispose(){this.worker&&this.worker.terminate(),this.orderTexture=null,this.centers=null,this.chunks=null}createWorkerCode(){return`(${(function(){let s=null,n=null,r=null,o=null,i=null,u=null,y=!1;const m={x:0,y:0,z:0},c={x:0,y:0,z:0},h={x:0,y:0,z:0},d={x:0,y:0,z:0};let w=null,A=null;const b=32,z=new Array(b).fill(0),_=new Array(b).fill(0),F=new Array(b).fill(0),O=(k,M,B)=>{for(;k<=M;){const S=M+k>>1,g=B(S);if(g>0)k=S+1;else if(g<0)M=S-1;else return S}return~k},V=()=>{if(!s||!n||!i||!u)return;if(n.length===0){const p={order:s.buffer,count:0};self.postMessage(p,[s.buffer]),s=null;return}const k=i.x,M=i.y,B=i.z,S=u.x,g=u.y,v=u.z,U=1e-4,T=Math.abs(k-m.x)>U||Math.abs(M-m.y)>U||Math.abs(B-m.z)>U,I=Math.abs(S-c.x)>U||Math.abs(g-c.y)>U||Math.abs(v-c.z)>U;if(!y&&!T&&!I)return;y=!1,m.x=k,m.y=M,m.z=B,c.x=S,c.y=g,c.z=v;let P=1/0,f=-1/0;for(let p=0;p<8;++p){const E=p&1?h.x:d.x,L=p&2?h.y:d.y,q=p&4?h.z:d.z,G=E*S+L*g+q*v;P=Math.min(P,G),f=Math.max(f,G)}const C=n.length/3,Y=f-P,R=(1<<Math.max(10,Math.min(20,Math.ceil(Math.log2(C/4)))))+1;if((!w||w.length!==C)&&(w=new Uint32Array(C)),!A||A.length!==R?A=new Uint32Array(R):A.fill(0),Y<1e-7){for(let p=0;p<C;++p)w[p]=0;A[0]=C}else if(r&&r.length>0){const p=r.length/6;z.fill(0);for(let q=0;q<p;++q){const G=q*6,Q=r[G+0],$=r[G+1],J=r[G+2],N=r[G+3],ee=Q*S+$*g+J*v-P,ne=ee-N,re=ee+N,fe=Math.max(0,Math.floor(ne*b/Y)),pe=Math.min(b,Math.ceil(re*b/Y));for(let le=fe;le<pe;++le)z[le]++}let E=0;for(let q=0;q<b;++q)E+=z[q];F[0]=0,_[0]=0;for(let q=1;q<b;++q)F[q-1]=z[q-1]/E*R>>>0,_[q]=_[q-1]+F[q-1];F[b-1]=z[b-1]/E*R>>>0;const L=Y/b;for(let q=0;q<C;++q){const G=q*3,Q=n[G+0],$=n[G+1],J=n[G+2],N=Q*S+$*g+J*v,ne=(f-N)/L,re=Math.max(0,Math.min(b-1,Math.floor(ne))),fe=ne-re,pe=_[re]+F[re]*fe>>>0,le=Math.min(pe,R-1);w[q]=le,A[le]++}}else{const p=(R-1)/Y;for(let E=0;E<C;++E){const L=E*3,q=n[L+0],G=n[L+1],Q=n[L+2],$=q*S+G*g+Q*v,N=(f-$)*p>>>0,ee=Math.min(N,R-1);w[E]=ee,A[ee]++}}for(let p=1;p<R;p++)A[p]+=A[p-1];for(let p=C-1;p>=0;p--){const E=w[p],L=--A[E];s[L]=o?o[p]:p}const K=k*S+M*g+B*v,X=p=>{if(!s)return-1/0;const E=s[p],L=E;if(!n||L*3+2>=n.length)return-1/0;const q=L*3;return n[q]*S+n[q+1]*g+n[q+2]*v-K};let Z=C;if(C>0&&X(C-1)<0){const p=O(0,C-1,X);Z=p<0?~p:p}const D={order:s.buffer,count:Z};self.postMessage(D,[s.buffer]),s=null};self.onmessage=k=>{const M=k.data;M.order&&(s=new Uint32Array(M.order));let B=!1;if(M.centers&&(n=new Float32Array(M.centers),B=!0,y=!0),Object.prototype.hasOwnProperty.call(M,"mapping")&&(o=M.mapping?new Uint32Array(M.mapping):null,y=!0),M.chunks){if(r=new Float32Array(M.chunks),r.length>0&&r[3]>0)for(let S=0;S<r.length/6;++S){const g=S*6,v=r[g+0],U=r[g+1],T=r[g+2],I=r[g+3],P=r[g+4],f=r[g+5];r[g+0]=(v+I)*.5,r[g+1]=(U+P)*.5,r[g+2]=(T+f)*.5,r[g+3]=Math.sqrt((I-v)**2+(P-U)**2+(f-T)**2)*.5}y=!0}if(B&&n&&n.length>0){h.x=d.x=n[0],h.y=d.y=n[1],h.z=d.z=n[2];for(let S=1;S<n.length/3;S++){const g=S*3;h.x=Math.min(h.x,n[g+0]),d.x=Math.max(d.x,n[g+0]),h.y=Math.min(h.y,n[g+1]),d.y=Math.max(d.y,n[g+1]),h.z=Math.min(h.z,n[g+2]),d.z=Math.max(d.z,n[g+2])}}else B&&n&&n.length===0&&(h.x=d.x=h.y=d.y=h.z=d.z=0);M.cameraPosition&&(i=M.cameraPosition),M.cameraDirection&&(u=M.cameraDirection),V()}}).toString()})();`}}class Ue{constructor(e){x(this,"packedGeometry");x(this,"packedColor");x(this,"orderTexture");x(this,"width");x(this,"height");this.width=e.textureWidth,this.height=e.textureHeight,this.packedColor=this.createColorTexture(e),this.packedGeometry=this.createGeometryTexture(e),this.orderTexture=this.createOrderTexture(e.numSplats)}createGeometryTexture(e){const t=new l.DataTexture(e.packedGeometry,this.width,this.height,l.RGBAIntegerFormat,l.UnsignedIntType);return t.internalFormat="RGBA32UI",t.minFilter=l.NearestFilter,t.magFilter=l.NearestFilter,t.needsUpdate=!0,t}createColorTexture(e){const t=new l.DataTexture(e.packedColor,this.width,this.height,l.RGBAFormat,l.UnsignedByteType);return t.minFilter=l.NearestFilter,t.magFilter=l.NearestFilter,t.needsUpdate=!0,t}createOrderTexture(e){const t=new Uint32Array(this.width*this.height);for(let n=0;n<e;n++)t[n]=n;const s=new l.DataTexture(t,this.width,this.height,l.RedIntegerFormat,l.UnsignedIntType);return s.minFilter=l.NearestFilter,s.magFilter=l.NearestFilter,s.needsUpdate=!0,s}dispose(){this.packedGeometry.dispose(),this.packedColor.dispose(),this.orderTexture.dispose()}}const Qe=`
1
+ (function(j,te){typeof exports=="object"&&typeof module<"u"?te(exports,require("three")):typeof define=="function"&&define.amd?define(["exports","three"],te):(j=typeof globalThis<"u"?globalThis:j||self,te(j.Visus={},j.THREE))})(this,function(j,te){"use strict";var _t=Object.defineProperty;var kt=(j,te,ge)=>te in j?_t(j,te,{enumerable:!0,configurable:!0,writable:!0,value:ge}):j[te]=ge;var d=(j,te,ge)=>kt(j,typeof te!="symbol"?te+"":te,ge);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 ge(a){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(a){for(const t in a)if(t!=="default"){const s=Object.getOwnPropertyDescriptor(a,t);Object.defineProperty(e,t,s.get?s:{enumerable:!0,get:()=>a[t]})}}return e.default=a,Object.freeze(e)}const c=ge(te);class xe{constructor(){d(this,"min",new c.Vector3(1/0,1/0,1/0));d(this,"max",new c.Vector3(-1/0,-1/0,-1/0));d(this,"center",new c.Vector3);d(this,"halfExtents",new c.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 c.Box3().set(this.min,this.max)}clone(){const e=new xe;return e.min.copy(this.min),e.max.copy(this.max),e.center.copy(this.center),e.halfExtents.copy(this.halfExtents),e}}class tt{constructor(e=0){d(this,"numSplats",0);d(this,"positions");d(this,"rotations");d(this,"scales");d(this,"colors");d(this,"opacities");d(this,"boundingBox",new xe);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,t,s,n,r,i){if(e>=this.numSplats)throw new Error(`Splat index out of bounds: ${e} >= ${this.numSplats}`);const o=e*3,u=e*4,y=e*3,m=e*3;this.positions[o]=t.x,this.positions[o+1]=t.y,this.positions[o+2]=t.z,this.rotations[u]=s.x,this.rotations[u+1]=s.y,this.rotations[u+2]=s.z,this.rotations[u+3]=s.w,this.scales[y]=n.x,this.scales[y+1]=n.y,this.scales[y+2]=n.z,this.colors[m]=r.r,this.colors[m+1]=r.g,this.colors[m+2]=r.b,this.opacities[e]=i}getSplat(e){if(e>=this.numSplats)throw new Error(`Splat index out of bounds: ${e} >= ${this.numSplats}`);const t=e*3,s=e*4,n=e*3,r=e*3;return{position:new c.Vector3(this.positions[t],this.positions[t+1],this.positions[t+2]),rotation:new c.Quaternion(this.rotations[s],this.rotations[s+1],this.rotations[s+2],this.rotations[s+3]),scale:new c.Vector3(Math.exp(this.scales[n]),Math.exp(this.scales[n+1]),Math.exp(this.scales[n+2])),color:new c.Color(this.colors[r],this.colors[r+1],this.colors[r+2]),opacity:this.opacities[e]}}calculateBoundingBox(){this.boundingBox.reset();const e=new c.Vector3;for(let t=0;t<this.numSplats;t++){const s=t*3;e.set(this.positions[s],this.positions[s+1],this.positions[s+2]),this.boundingBox.expandByPoint(e)}return this.boundingBox}createDebugGeometry(){const e=new c.BufferGeometry;e.setAttribute("position",new c.BufferAttribute(this.positions,3));const t=new Float32Array(this.numSplats*3),s=new c.Quaternion,n=new c.Euler;for(let r=0;r<this.numSplats;r++){const i=r*4,o=r*3;s.set(this.rotations[i],this.rotations[i+1],this.rotations[i+2],this.rotations[i+3]),n.setFromQuaternion(s),t[o]=n.x,t[o+1]=n.y,t[o+2]=n.z}return e.setAttribute("rotation",new c.BufferAttribute(t,3)),e.setAttribute("scale",new c.BufferAttribute(this.scales,3)),e.setAttribute("color",new c.BufferAttribute(this.colors,3)),e.setAttribute("opacity",new c.BufferAttribute(this.opacities,1)),e}dispose(){this.numSplats=0,this.scales=new Float32Array(0),this.colors=new Float32Array(0),this.positions=new Float32Array(0),this.rotations=new Float32Array(0),this.opacities=new Float32Array(0)}}class Ve{constructor(e,t,s){d(this,"ranges");d(this,"version",1);d(this,"numSplats",0);d(this,"boundingBox",new xe);d(this,"sh0");d(this,"quats");d(this,"scales");d(this,"means_l");d(this,"means_u");this.ranges=t,this.numSplats=e,this.sh0=s.sh0,this.quats=s.quats,this.scales=s.scales,this.means_l=s.means_l,this.means_u=s.means_u,this.boundingBox=this.calculateBoundingBox()}calculateBoundingBox(){this.boundingBox.reset();const{mins:e,maxs:t}=this.ranges.means,s=n=>Math.sign(n)*(Math.exp(Math.abs(n))-1);return this.boundingBox.center.set((s(e[0])+s(t[0]))*.5,(s(e[1])+s(t[1]))*.5,(s(e[2])+s(t[2]))*.5),this.boundingBox.halfExtents.set((s(t[0])-s(e[0]))*.5,(s(t[1])-s(e[1]))*.5,(s(t[2])-s(e[2]))*.5),this.boundingBox}dispose(){this.sh0.dispose(),this.quats.dispose(),this.scales.dispose(),this.means_l.dispose(),this.means_u.dispose()}}class Oe{constructor(e,t,s){d(this,"ranges");d(this,"version",2);d(this,"numSplats",0);d(this,"boundingBox",new xe);d(this,"sh0");d(this,"quats");d(this,"scales");d(this,"means_l");d(this,"means_u");this.ranges=t,this.numSplats=e,this.sh0=s.sh0,this.quats=s.quats,this.scales=s.scales,this.means_l=s.means_l,this.means_u=s.means_u,this.boundingBox=this.calculateBoundingBox()}calculateBoundingBox(){this.boundingBox.reset();const{mins:e,maxs:t}=this.ranges.means,s=n=>Math.sign(n)*(Math.exp(Math.abs(n))-1);return this.boundingBox.center.set((s(e[0])+s(t[0]))*.5,(s(e[1])+s(t[1]))*.5,(s(e[2])+s(t[2]))*.5),this.boundingBox.halfExtents.set((s(t[0])-s(e[0]))*.5,(s(t[1])-s(e[1]))*.5,(s(t[2])-s(e[2]))*.5),this.boundingBox}dispose(){this.sh0.dispose(),this.quats.dispose(),this.scales.dispose(),this.means_l.dispose(),this.means_u.dispose()}}class Ae{constructor(e,t,s,n,r,i,o,u){d(this,"numSplats");d(this,"textureWidth");d(this,"textureHeight");d(this,"ranges");d(this,"centers");d(this,"boundingBox");d(this,"packedColor");d(this,"packedGeometry");this.numSplats=e,this.textureWidth=t,this.textureHeight=s,this.boundingBox=u,this.ranges=o,this.centers=n,this.packedColor=i,this.packedGeometry=r}dispose(){this.centers=new Float32Array(0),this.packedColor=new Uint8Array(0),this.packedGeometry=new Uint32Array(0)}}class Re extends c.EventDispatcher{constructor(){super();d(this,"worker");d(this,"centers",null);d(this,"orderTexture",null);d(this,"chunks",null);d(this,"lastCameraPosition",new c.Vector3);d(this,"lastCameraDirection",new c.Vector3);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(t){if(!this.orderTexture||!this.orderTexture.image)return console.error("SplatSorter: Order texture not initialized!");const{order:s,count:n}=t.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(s)),this.orderTexture.source.data.updateRanges||(this.orderTexture.source.data.updateRanges=[]),this.orderTexture.needsUpdate=!0;const i=r.buffer.slice(0),o={order:i};this.worker.postMessage(o,[i]),this.dispatchEvent({type:"updated",count:n})}init(t,s,n,r=!1){if(!t||!(t.image.data instanceof Uint32Array))throw new Error("SplatSorter: Invalid orderTexture provided. Must be DataTexture with Uint32Array data.");if(!s||s.length%3!==0)throw new Error("SplatSorter: Invalid centers array provided. Length must be multiple of 3.");if(t.image.data.length<s.length/3)throw new Error("SplatSorter: orderTexture data buffer is smaller than the number of splats.");if(s.buffer.byteLength===0)throw new Error("SplatSorter: positions buffer is detached (likely React StrictMode + cached asset). ");const i=s.length/3;this.orderTexture=t,r?this.centers=null:this.centers=s.slice();const o=this.orderTexture.image.data;for(let h=0;h<i;h++)o[h]=h;this.orderTexture.source.data.updateRanges||(this.orderTexture.source.data.updateRanges=[]),this.orderTexture.needsUpdate=!0;const u=o.buffer.slice(0),y=r?s.buffer:s.buffer.slice(0),m={order:u,centers:y},l=[u,y];if(n){this.chunks=n.slice();const h=this.chunks.buffer.slice(0);m.chunks=h,l.push(h)}this.worker.postMessage(m,l),queueMicrotask(()=>{this.dispatchEvent({type:"updated",count:i})})}setMapping(t){if(!this.centers)return console.warn("SplatSorter: Cannot set mapping before initialization.");let s;const n=[];if(!t){const u=this.centers.buffer.slice(0);return s={centers:u,mapping:null},n.push(u),this.worker.postMessage(s,n)}const r=new Float32Array(t.length*3);for(let u=0;u<t.length;u++){const y=t[u];if(y*3+2>=this.centers.length){console.warn(`SplatSorter: Mapping index ${y} out of bounds.`);continue}const m=y*3,l=u*3;r[l+0]=this.centers[m+0],r[l+1]=this.centers[m+1],r[l+2]=this.centers[m+2]}const i=r.buffer.slice(0),o=t.buffer.slice(0);s={centers:i,mapping:o},n.push(i,o),this.worker.postMessage(s,n)}setCamera(t,s){const n=this.lastCameraPosition.distanceToSquared(t)>1e-7,r=this.lastCameraDirection.dot(s)<.9999;if(!n&&!r)return;this.lastCameraPosition.copy(t),this.lastCameraDirection.copy(s);const i={cameraPosition:{x:t.x,y:t.y,z:t.z},cameraDirection:{x:s.x,y:s.y,z:s.z}};this.worker.postMessage(i)}dispose(){this.worker&&this.worker.terminate(),this.orderTexture=null,this.centers=null,this.chunks=null}createWorkerCode(){return`(${(function(){let s=null,n=null,r=null,i=null,o=null,u=null,y=!1;const m={x:0,y:0,z:0},l={x:0,y:0,z:0},h={x:0,y:0,z:0},f={x:0,y:0,z:0};let w=null,A=null;const b=32,B=new Array(b).fill(0),F=new Array(b).fill(0),P=new Array(b).fill(0),U=(C,M,k)=>{for(;C<=M;){const S=M+C>>1,x=k(S);if(x>0)C=S+1;else if(x<0)M=S-1;else return S}return~C},O=()=>{if(!s||!n||!o||!u)return;if(n.length===0){const g={order:s.buffer,count:0};self.postMessage(g,[s.buffer]),s=null;return}const C=o.x,M=o.y,k=o.z,S=u.x,x=u.y,v=u.z,R=1e-4,V=Math.abs(C-m.x)>R||Math.abs(M-m.y)>R||Math.abs(k-m.z)>R,I=Math.abs(S-l.x)>R||Math.abs(x-l.y)>R||Math.abs(v-l.z)>R;if(!y&&!V&&!I)return;y=!1,m.x=C,m.y=M,m.z=k,l.x=S,l.y=x,l.z=v;let q=1/0,p=-1/0;for(let g=0;g<8;++g){const E=g&1?h.x:f.x,L=g&2?h.y:f.y,D=g&4?h.z:f.z,G=E*S+L*x+D*v;q=Math.min(q,G),p=Math.max(p,G)}const _=n.length/3,Y=p-q,T=(1<<Math.max(10,Math.min(20,Math.ceil(Math.log2(_/4)))))+1;if((!w||w.length!==_)&&(w=new Uint32Array(_)),!A||A.length!==T?A=new Uint32Array(T):A.fill(0),Y<1e-7){for(let g=0;g<_;++g)w[g]=0;A[0]=_}else if(r&&r.length>0){const g=r.length/6;B.fill(0);for(let D=0;D<g;++D){const G=D*6,Q=r[G+0],H=r[G+1],J=r[G+2],$=r[G+3],ee=Q*S+H*x+J*v-q,ne=ee-$,ae=ee+$,fe=Math.max(0,Math.floor(ne*b/Y)),pe=Math.min(b,Math.ceil(ae*b/Y));for(let le=fe;le<pe;++le)B[le]++}let E=0;for(let D=0;D<b;++D)E+=B[D];P[0]=0,F[0]=0;for(let D=1;D<b;++D)P[D-1]=B[D-1]/E*T>>>0,F[D]=F[D-1]+P[D-1];P[b-1]=B[b-1]/E*T>>>0;const L=Y/b;for(let D=0;D<_;++D){const G=D*3,Q=n[G+0],H=n[G+1],J=n[G+2],$=Q*S+H*x+J*v,ne=(p-$)/L,ae=Math.max(0,Math.min(b-1,Math.floor(ne))),fe=ne-ae,pe=F[ae]+P[ae]*fe>>>0,le=Math.min(pe,T-1);w[D]=le,A[le]++}}else{const g=(T-1)/Y;for(let E=0;E<_;++E){const L=E*3,D=n[L+0],G=n[L+1],Q=n[L+2],H=D*S+G*x+Q*v,$=(p-H)*g>>>0,ee=Math.min($,T-1);w[E]=ee,A[ee]++}}for(let g=1;g<T;g++)A[g]+=A[g-1];for(let g=_-1;g>=0;g--){const E=w[g],L=--A[E];s[L]=i?i[g]:g}const K=C*S+M*x+k*v,X=g=>{if(!s)return-1/0;const E=s[g],L=E;if(!n||L*3+2>=n.length)return-1/0;const D=L*3;return n[D]*S+n[D+1]*x+n[D+2]*v-K};let Z=_;if(_>0&&X(_-1)<0){const g=U(0,_-1,X);Z=g<0?~g:g}const z={order:s.buffer,count:Z};self.postMessage(z,[s.buffer]),s=null};self.onmessage=C=>{const M=C.data;M.order&&(s=new Uint32Array(M.order));let k=!1;if(M.centers&&(n=new Float32Array(M.centers),k=!0,y=!0),Object.prototype.hasOwnProperty.call(M,"mapping")&&(i=M.mapping?new Uint32Array(M.mapping):null,y=!0),M.chunks){if(r=new Float32Array(M.chunks),r.length>0&&r[3]>0)for(let S=0;S<r.length/6;++S){const x=S*6,v=r[x+0],R=r[x+1],V=r[x+2],I=r[x+3],q=r[x+4],p=r[x+5];r[x+0]=(v+I)*.5,r[x+1]=(R+q)*.5,r[x+2]=(V+p)*.5,r[x+3]=Math.sqrt((I-v)**2+(q-R)**2+(p-V)**2)*.5}y=!0}if(k&&n&&n.length>0){h.x=f.x=n[0],h.y=f.y=n[1],h.z=f.z=n[2];for(let S=1;S<n.length/3;S++){const x=S*3;h.x=Math.min(h.x,n[x+0]),f.x=Math.max(f.x,n[x+0]),h.y=Math.min(h.y,n[x+1]),f.y=Math.max(f.y,n[x+1]),h.z=Math.min(h.z,n[x+2]),f.z=Math.max(f.z,n[x+2])}}else k&&n&&n.length===0&&(h.x=f.x=h.y=f.y=h.z=f.z=0);M.cameraPosition&&(o=M.cameraPosition),M.cameraDirection&&(u=M.cameraDirection),O()}}).toString()})();`}}const Ue={spread:{type:"spread",defaultDuration:3,shaderCode:`
3
+ void applyAnimation(
4
+ inout vec3 position,
5
+ inout vec3 scale,
6
+ inout vec4 color,
7
+ float progress,
8
+ vec3 center
9
+ ) {
10
+ const float DIST_K = 0.3;
11
+ const float WAVE_GAIN = 1.2;
12
+ const float SPHERE_LOG = -6.0;
13
+ const float INV_WAVE_W = 20.0; // 1.0 / 0.05 wave width, precomputed
14
+ const vec3 GOLD = vec3(1.0, 1.0, 1.0); // pure white
15
+
16
+ float dist = length(position - center);
17
+ float normalizedDist = 1.0 - exp(-dist * DIST_K);
18
+ float waveProgress = progress * WAVE_GAIN;
19
+
20
+ float revealed = step(normalizedDist, waveProgress);
21
+ scale = mix(vec3(SPHERE_LOG), scale, revealed);
22
+
23
+ float glowIntensity = clamp(1.0 - abs(normalizedDist - waveProgress) * INV_WAVE_W, 0.0, 1.0);
24
+ color.rgb = mix(color.rgb, GOLD, glowIntensity);
25
+ }
26
+ `},wave:{type:"wave",defaultDuration:3,shaderCode:`
27
+ void applyAnimation(
28
+ inout vec3 position,
29
+ inout vec3 scale,
30
+ inout vec4 color,
31
+ float progress,
32
+ vec3 center
33
+ ) {
34
+ const float DIST_K = 0.3;
35
+ const float WAVE_GAIN = 1.2;
36
+ const float INV_WAVE_W = 20.0;
37
+ const vec3 GLOW = vec3(1.0, 1.0, 1.0);
38
+
39
+ float dist = length(position - center);
40
+ float normalizedDist = 1.0 - exp(-dist * DIST_K);
41
+ float waveProgress = progress * WAVE_GAIN;
42
+
43
+ float glowIntensity = clamp(1.0 - abs(normalizedDist - waveProgress) * INV_WAVE_W, 0.0, 1.0);
44
+ color.rgb = mix(color.rgb, GLOW, glowIntensity);
45
+ }
46
+ `},none:{type:"none",defaultDuration:0,shaderCode:`
47
+ void applyAnimation(
48
+ inout vec3 position,
49
+ inout vec3 scale,
50
+ inout vec4 color,
51
+ float progress,
52
+ vec3 center
53
+ ) {}
54
+ `}},Ie=a=>Ue[a]??Ue.none,Le={linear:a=>a,easeInQuad:a=>a*a,easeOutQuad:a=>a*(2-a),easeInOutQuad:a=>a<.5?2*a*a:-1+(4-2*a)*a,easeInCubic:a=>a*a*a,easeOutCubic:a=>1-Math.pow(1-a,3),easeInOutCubic:a=>a<.5?4*a*a*a:1-Math.pow(-2*a+2,3)/2,easeOutExpo:a=>a===1?1:1-Math.pow(2,-10*a)},st=a=>Le[a]??Le.linear;class Ge{constructor(e){d(this,"_progress",0);d(this,"_isPlaying",!1);d(this,"_isComplete",!1);d(this,"_startTime",0);d(this,"_duration");d(this,"_delay");d(this,"_easing");d(this,"_type");d(this,"_autoPlay");d(this,"_center",new c.Vector3);const t=Ie(e.type);this._type=e.type,this._duration=e.duration??t.defaultDuration,this._delay=e.delay??0,this._easing=st(e.easing??"easeOutCubic"),this._autoPlay=e.autoPlay??!0}get progress(){return this._progress}get isPlaying(){return this._isPlaying}get isComplete(){return this._isComplete}get type(){return this._type}get center(){return this._center}setCenter(e){this._center.copy(e)}play(){this._startTime=-1,this._isPlaying=!0,this._isComplete=!1,this._progress=0}stop(){this._isPlaying=!1}reset(){this._progress=0,this._isPlaying=!1,this._isComplete=!1,this._startTime=0}complete(){this._progress=1,this._isPlaying=!1,this._isComplete=!0}update(e){if(!this._isPlaying)return!1;this._startTime<0&&(this._startTime=e+this._delay);const t=e-this._startTime;if(t<0)return!1;const s=Math.min(t/this._duration,1);return this._progress=this._easing(s),s>=1&&(this._isPlaying=!1,this._isComplete=!0,this._progress=1),!0}shouldAutoPlay(){return this._autoPlay&&!this._isComplete}}class We{constructor(e){d(this,"packedGeometry");d(this,"packedColor");d(this,"orderTexture");d(this,"width");d(this,"height");this.width=e.textureWidth,this.height=e.textureHeight,this.packedColor=this.createColorTexture(e),this.packedGeometry=this.createGeometryTexture(e),this.orderTexture=this.createOrderTexture(e.numSplats)}createGeometryTexture(e){const t=new c.DataTexture(e.packedGeometry,this.width,this.height,c.RGBAIntegerFormat,c.UnsignedIntType);return t.internalFormat="RGBA32UI",t.minFilter=c.NearestFilter,t.magFilter=c.NearestFilter,t.needsUpdate=!0,t}createColorTexture(e){const t=new c.DataTexture(e.packedColor,this.width,this.height,c.RGBAFormat,c.UnsignedByteType);return t.minFilter=c.NearestFilter,t.magFilter=c.NearestFilter,t.needsUpdate=!0,t}createOrderTexture(e){const t=new Uint32Array(this.width*this.height);for(let n=0;n<e;n++)t[n]=n;const s=new c.DataTexture(t,this.width,this.height,c.RedIntegerFormat,c.UnsignedIntType);return s.minFilter=c.NearestFilter,s.magFilter=c.NearestFilter,s.needsUpdate=!0,s}dispose(){this.packedGeometry.dispose(),this.packedColor.dispose(),this.orderTexture.dispose()}}const Ne=`
3
55
  precision highp float;
4
56
  precision highp int;
5
57
  precision highp usampler2D;
@@ -22,6 +74,12 @@ uniform vec3 scalesMax;
22
74
  uniform vec3 sh0Min;
23
75
  uniform vec3 sh0Max;
24
76
 
77
+ // --- Animation Uniforms ---
78
+ uniform float animationProgress; // 0 = start, 1 = complete
79
+ uniform vec3 animationCenter; // Center point for animation
80
+
81
+ /* @ANIMATION_CODE */
82
+
25
83
  // --- Attributes ---
26
84
  in uint splatInstanceIndex;
27
85
 
@@ -120,11 +178,10 @@ void main() {
120
178
  else if (mode == 2u) quat = vec4(abc.xy, d, abc.z); // stored (w,x,z)
121
179
  else quat = vec4(abc, d); // stored (w,x,y)
122
180
 
123
- // Decompress Scale
181
+ // Decompress Scale (log-space)
124
182
  uvec3 sB = unpackBytes(geom.w).xyz;
125
183
  vec3 sNorm = vec3(sB) * (1.0 / 255.0);
126
- vec3 sLerp = mix(scalesMin, scalesMax, sNorm);
127
- vec3 scale = exp(sLerp); // log scale stored
184
+ vec3 scale = mix(scalesMin, scalesMax, sNorm); // log-space scale
128
185
 
129
186
  // Decompress Color & Opacity
130
187
  vec4 clr;
@@ -132,6 +189,12 @@ void main() {
132
189
  clr.rgb = vec3(0.5) + sh * SH_C0;
133
190
  clr.a = colorRaw.a; // Opacity passed directly (linear or sigmoid handled by loader)
134
191
 
192
+ // --- Apply Animation (modifies position, scale, color in place) ---
193
+ /* @ANIMATION_CALL */
194
+
195
+ // Convert log-space scale to linear scale
196
+ scale = exp(scale);
197
+
135
198
  // --- Standard Gaussian Splat Projection ---
136
199
 
137
200
  // View Space Setup
@@ -185,9 +248,12 @@ void main() {
185
248
  float l2 = 2.0 * min(sqrt(2.0 * lambda2), vmin);
186
249
 
187
250
  // Discard tiny splats
188
- if (l1 < 2.0 && l2 < 2.0) {
189
- gl_Position = DISCARD_VERTEX;
190
- return;
251
+ // TODO: this branch might create some performance issues - check
252
+ if (animationProgress >= 1.0) {
253
+ if (l1 < 2.0 && l2 < 2.0) {
254
+ gl_Position = DISCARD_VERTEX;
255
+ return;
256
+ }
191
257
  }
192
258
 
193
259
  vec2 diagVec = normalize(vec2(offDiagonal, lambda1 - diagonal1));
@@ -221,7 +287,7 @@ void main() {
221
287
  vUv = clippedUV;
222
288
  vColor = vec4(max(clr.rgb, vec3(0.0)), clr.a);
223
289
  }
224
- `,Je=`
290
+ `,nt=`
225
291
  precision highp float;
226
292
 
227
293
  in vec4 vColor; // Color and opacity passed from vertex shader
@@ -253,7 +319,9 @@ void main(void) {
253
319
  // Premultiply color by alpha (required for correct blending)
254
320
  fragColor = vec4(vColor.rgb * alpha, alpha);
255
321
  }
256
- `;class Oe extends l.ShaderMaterial{constructor(e={}){const t={packedGeometry:{value:null},packedColor:{value:null},splatOrder:{value:null},meansMin:{value:new l.Vector3},meansMax:{value:new l.Vector3},scalesMin:{value:new l.Vector3},scalesMax:{value:new l.Vector3},sh0Min:{value:new l.Vector3},sh0Max:{value:new l.Vector3},texWidth:{value:0},viewport:{value:new l.Vector2(1,1)},numSplats:{value:0}};super({uniforms:t,vertexShader:Qe,fragmentShader:Je,transparent:!0,glslVersion:l.GLSL3,blendSrc:l.OneFactor,blendSrcAlpha:l.OneFactor,blending:l.CustomBlending,blendEquation:l.AddEquation,blendEquationAlpha:l.AddEquation,blendDst:l.OneMinusSrcAlphaFactor,blendDstAlpha:l.OneMinusSrcAlphaFactor,depthTest:!0,depthWrite:!1,side:l.DoubleSide,alphaTest:e.alphaTest??0,toneMapped:e.toneMapped??!1}),e.alphaHash&&(this.alphaHash=!0,this.depthWrite=!0,this.blending=l.NoBlending)}setTexWidth(e){this.uniforms.texWidth.value=e|0}updateViewport(e,t){this.uniforms.viewport.value.set(e,t)}setPackedGeometry(e){this.uniforms.packedGeometry.value=e}setPackedColor(e){this.uniforms.packedColor.value=e}setOrderTexture(e){this.uniforms.splatOrder.value=e}setRanges(e){this.uniforms.meansMin.value.copy(e.means.min),this.uniforms.meansMax.value.copy(e.means.max),this.uniforms.scalesMin.value.copy(e.scales.min),this.uniforms.scalesMax.value.copy(e.scales.max),this.uniforms.sh0Min.value.copy(e.sh0.min),this.uniforms.sh0Max.value.copy(e.sh0.max)}setNumSplats(e){this.uniforms.numSplats.value=e}}const ve=class ve extends l.Mesh{constructor(t,s={}){const n=new Oe(s),r=ve.createInstancedGeometry(t.numSplats,ve.INSTANCE_SIZE);super(r,n);x(this,"sorter");x(this,"options");x(this,"splatData");x(this,"textureManager");x(this,"material");x(this,"geometry");x(this,"lastCameraPositionLocal",new l.Vector3);x(this,"lastCameraDirectionLocal",new l.Vector3);x(this,"invModelMatrix",new l.Matrix4);x(this,"_vpW",-1);x(this,"_vpH",-1);x(this,"_size",new l.Vector2);x(this,"_camPosW",new l.Vector3);x(this,"_camDirW",new l.Vector3);x(this,"_camPosL",new l.Vector3);x(this,"_camDirL",new l.Vector3);x(this,"onSorterUpdated",t=>{const s=t.count;this.geometry.instanceCount=Math.ceil(s/ve.INSTANCE_SIZE),this.material.setNumSplats(s)});this.geometry=r,this.material=n,this.options={autoSort:!0,...s},this.splatData=t,this.frustumCulled=!1,this.sorter=new Ve,this.textureManager=new Ue(t);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.options.keepSplatData),this.material.setRanges(t.ranges),this.material.setTexWidth(t.textureWidth),this.material.setPackedColor(this.textureManager.packedColor),this.material.setOrderTexture(this.textureManager.orderTexture),this.material.setPackedGeometry(this.textureManager.packedGeometry),this.material.setNumSplats(0),this.geometry.boundingBox=t.boundingBox.toBox3(),this.geometry.boundingSphere=new l.Sphere,this.geometry.boundingBox.getBoundingSphere(this.geometry.boundingSphere),this.options.keepSplatData||(this.splatData=null)}static createInstancedGeometry(t,s){const n=Math.ceil(t/s),r=new l.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]),u=new Float32Array(4*3*s);for(let h=0;h<s;h++){const d=h*4*3;for(let w=0;w<4;w++)u[d+w*3+0]=o[w*3+0],u[d+w*3+1]=o[w*3+1],u[d+w*3+2]=h}const y=new Uint32Array(6*s);for(let h=0;h<s;h++){const d=h*6,w=h*4;y[d+0]=i[0]+w,y[d+1]=i[1]+w,y[d+2]=i[2]+w,y[d+3]=i[3]+w,y[d+4]=i[4]+w,y[d+5]=i[5]+w}r.setAttribute("position",new l.BufferAttribute(u,3)),r.setIndex(new l.BufferAttribute(y,1));const m=new l.InstancedBufferGeometry;m.index=r.index,m.setAttribute("position",r.getAttribute("position"));const c=new Uint32Array(n);for(let h=0;h<n;h++)c[h]=h*s;return m.setAttribute("splatInstanceIndex",new l.InstancedBufferAttribute(c,1,!1)),m.instanceCount=0,m}createChunks(){if(!this.splatData)return null;const t=this.splatData.boundingBox;return t.min.x===1/0||t.max.x===-1/0?null:new Float32Array([t.min.x,t.min.y,t.min.z,t.max.x,t.max.y,t.max.z])}updateViewport(t,s){t===this._vpW&&s===this._vpH||(this._vpW=t,this._vpH=s,this.material.updateViewport(t,s))}sort(t){t.getWorldPosition(this._camPosW),t.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 s=this.lastCameraPositionLocal.distanceToSquared(this._camPosL)>1e-6,n=this.lastCameraDirectionLocal.dot(this._camDirL)<.999;this.options.autoSort&&(s||n)&&(this.lastCameraPositionLocal.copy(this._camPosL),this.lastCameraDirectionLocal.copy(this._camDirL),this.sorter.setCamera(this._camPosL,this._camDirL))}onBeforeRender(t,s,n){this.sort(n),t.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()}};x(ve,"INSTANCE_SIZE",128);let Ie=ve;const ye=.28209479177387814;class Me{static packPly(e){const t=e.numSplats,s=Math.ceil(Math.sqrt(t)),n=Math.ceil(t/s),r=s*n,{ranges:o,colorScale:i}=this.calculatePlyRanges(e),u=new Uint32Array(r*4),y=new Uint8Array(r*4),m=new l.Quaternion;for(let c=0;c<t;c++){const h=c*4,d=c*3,w=c*4,A=e.positions[d+0],b=e.positions[d+1],z=e.positions[d+2],_=this.clamp01(this.norm(A,o.means.min.x,o.means.max.x)),F=this.clamp01(this.norm(b,o.means.min.y,o.means.max.y)),O=this.clamp01(this.norm(z,o.means.min.z,o.means.max.z)),V=_*65535|0,k=F*65535|0,M=O*65535|0;u[h+0]=this.pack4Bytes(V&255,k&255,M&255,0),u[h+1]=this.pack4Bytes(V>>8,k>>8,M>>8,0),m.set(e.rotations[w],e.rotations[w+1],e.rotations[w+2],e.rotations[w+3]).normalize();let B=m.w,S=m.x,g=m.y,v=m.z;const U=Math.abs(B),T=Math.abs(S),I=Math.abs(g),P=Math.abs(v);let f=0,C=U;T>C&&(C=T,f=1),I>C&&(C=I,f=2),P>C&&(C=P,f=3),(f===0?B:f===1?S:f===2?g:v)<0&&(B=-B,S=-S,g=-g,v=-v);let W=0,R=0,K=0;f===0&&(W=S,R=g,K=v),f===1&&(W=B,R=g,K=v),f===2&&(W=B,R=S,K=v),f===3&&(W=B,R=S,K=g);const X=re=>Math.min(255,Math.max(0,Math.round((.5+re/Math.SQRT2)*255)));u[h+2]=this.pack4Bytes(X(W),X(R),X(K),f);const Z=this.norm(e.scales[d+0],o.scales.min.x,o.scales.max.x),D=this.norm(e.scales[d+1],o.scales.min.y,o.scales.max.y),p=this.norm(e.scales[d+2],o.scales.min.z,o.scales.max.z);u[h+3]=this.pack4Bytes(Math.floor(Z*255),Math.floor(D*255),Math.floor(p*255),0);const E=this.clamp01(e.colors[d+0]*i),L=this.clamp01(e.colors[d+1]*i),q=this.clamp01(e.colors[d+2]*i),G=(E-.5)/ye,Q=(L-.5)/ye,$=(q-.5)/ye,J=this.clamp01(this.norm(G,o.sh0.min.x,o.sh0.max.x)),N=this.clamp01(this.norm(Q,o.sh0.min.y,o.sh0.max.y)),ee=this.clamp01(this.norm($,o.sh0.min.z,o.sh0.max.z)),ne=this.clamp01(e.opacities[c]);y[h+0]=Math.round(J*255),y[h+1]=Math.round(N*255),y[h+2]=Math.round(ee*255),y[h+3]=Math.round(ne*255)}return new Ae(t,s,n,e.positions,u,y,o,e.boundingBox)}static packSogs(e){var g,v,U;const t=e.numSplats;let s=Math.ceil(Math.sqrt(t)),n=Math.ceil(t/s);const r=((g=e.means_l)==null?void 0:g.image)??((v=e.sh0)==null?void 0:v.image)??((U=e.quats)==null?void 0:U.image);r&&typeof r.width=="number"&&typeof r.height=="number"&&(s=r.width,n=r.height);const o=s*n;if(o<t)throw new Error(`SOG v1 texture too small: ${s}x${n}=${o} < count=${t}`);const i=this.convertSogsRanges(e.ranges),u=e.ranges.means.mins[0],y=e.ranges.means.mins[1],m=e.ranges.means.mins[2],c=e.ranges.means.maxs[0],h=e.ranges.means.maxs[1],d=e.ranges.means.maxs[2],w=T=>Math.sign(T)*(Math.exp(Math.abs(T))-1),A=new l.Vector3(w(u),w(y),w(m)),b=new l.Vector3(w(c),w(h),w(d));i.means.min.copy(A),i.means.max.copy(b);const z=e,_=this.getPixels(z.means_l),F=this.getPixels(z.means_u),O=this.getPixels(z.quats),V=this.getPixels(z.scales),k=this.getPixels(z.sh0),M=new Uint32Array(o*4),B=new Uint8Array(o*4),S=new Float32Array(t*3);for(let T=0;T<t;T++){const I=T*4,P=F[I+0],f=_[I+0],C=F[I+1],Y=_[I+1],W=F[I+2],R=_[I+2],K=(P<<8|f)/65535,X=(C<<8|Y)/65535,Z=(W<<8|R)/65535,D=this.sogsDecode(K,u,c),p=this.sogsDecode(X,y,h),E=this.sogsDecode(Z,m,d);S[T*3+0]=D,S[T*3+1]=p,S[T*3+2]=E;const L=this.clamp01(this.norm(D,A.x,b.x))*65535|0,q=this.clamp01(this.norm(p,A.y,b.y))*65535|0,G=this.clamp01(this.norm(E,A.z,b.z))*65535|0;M[I+0]=this.pack4Bytes(L&255,q&255,G&255,0),M[I+1]=this.pack4Bytes(L>>8,q>>8,G>>8,0),M[I+3]=this.pack4Bytes(V[I],V[I+1],V[I+2],0);const $=O[I+3]-252;M[I+2]=this.pack4Bytes(O[I+0],O[I+1],O[I+2],$),B[I+0]=k[I],B[I+1]=k[I+1],B[I+2]=k[I+2];const J=k[I+3]/255,N=e.ranges.sh0.mins[3]+(e.ranges.sh0.maxs[3]-e.ranges.sh0.mins[3])*J,ee=1/(1+Math.exp(-N));B[I+3]=Math.round(Math.max(0,Math.min(1,ee))*255)}return new Ae(t,s,n,S,M,B,i,e.boundingBox)}static packSog2(e){var U,T,I;const t=e.numSplats;let s=Math.ceil(Math.sqrt(t)),n=Math.ceil(t/s);const r=((U=e.means_l)==null?void 0:U.image)??((T=e.sh0)==null?void 0:T.image)??((I=e.quats)==null?void 0:I.image);r&&typeof r.width=="number"&&typeof r.height=="number"&&(s=r.width,n=r.height);const o=s*n;if(o<t)throw new Error(`SOG v2 texture too small: ${s}x${n}=${o} < count=${t}`);const i=e.ranges.means.mins[0],u=e.ranges.means.mins[1],y=e.ranges.means.mins[2],m=e.ranges.means.maxs[0],c=e.ranges.means.maxs[1],h=e.ranges.means.maxs[2],d=P=>Math.sign(P)*(Math.exp(Math.abs(P))-1),w=new l.Vector3(d(i),d(u),d(y)),A=new l.Vector3(d(m),d(c),d(h)),b=P=>{let f=1/0,C=-1/0;for(const R of P)Number.isFinite(R)&&(f=Math.min(f,R),C=Math.max(C,R));(!Number.isFinite(f)||!Number.isFinite(C))&&(f=0,C=1);const Y=C-f||1,W=new Uint8Array(256);for(let R=0;R<256;R++){const X=((R<P.length&&Number.isFinite(P[R])?P[R]:f+(C-f)*(R/255))-f)/Y,Z=Math.max(0,Math.min(255,Math.round(X*255)));W[R]=Z}return{cbMin:f,cbMax:C,lut:W}},z=b(e.ranges.scales.codebook),_=b(e.ranges.sh0.codebook),F={means:{min:w.clone(),max:A.clone()},scales:{min:new l.Vector3(z.cbMin,z.cbMin,z.cbMin),max:new l.Vector3(z.cbMax,z.cbMax,z.cbMax)},sh0:{min:new l.Vector3(_.cbMin,_.cbMin,_.cbMin),max:new l.Vector3(_.cbMax,_.cbMax,_.cbMax)}},O=this.getPixels(e.means_l),V=this.getPixels(e.means_u),k=this.getPixels(e.quats),M=this.getPixels(e.scales),B=this.getPixels(e.sh0),S=new Uint32Array(o*4),g=new Uint8Array(o*4),v=new Float32Array(t*3);for(let P=0;P<t;P++){const f=P*4,C=V[f+0],Y=O[f+0],W=V[f+1],R=O[f+1],K=V[f+2],X=O[f+2],Z=(C<<8|Y)/65535,D=(W<<8|R)/65535,p=(K<<8|X)/65535,E=this.sogsDecode(Z,i,m),L=this.sogsDecode(D,u,c),q=this.sogsDecode(p,y,h);v[P*3+0]=E,v[P*3+1]=L,v[P*3+2]=q;const G=this.clamp01(this.norm(E,w.x,A.x))*65535|0,Q=this.clamp01(this.norm(L,w.y,A.y))*65535|0,$=this.clamp01(this.norm(q,w.z,A.z))*65535|0;S[f+0]=this.pack4Bytes(G&255,Q&255,$&255,0),S[f+1]=this.pack4Bytes(G>>8,Q>>8,$>>8,0);const N=k[f+3]-252&3;S[f+2]=this.pack4Bytes(k[f+0],k[f+1],k[f+2],N);const ee=z.lut[M[f+0]],ne=z.lut[M[f+1]],re=z.lut[M[f+2]];S[f+3]=this.pack4Bytes(ee,ne,re,0),g[f+0]=_.lut[B[f+0]],g[f+1]=_.lut[B[f+1]],g[f+2]=_.lut[B[f+2]],g[f+3]=B[f+3]}return new Ae(t,s,n,v,S,g,F,e.boundingBox)}static pack4Bytes(e,t,s,n){return(e&255)<<24|(t&255)<<16|(s&255)<<8|n&255}static getPixels(e){const t=e.image,s=t.width,n=t.height;if(t.data&&(t.data instanceof Uint8Array||t.data instanceof Uint8ClampedArray))return new Uint8Array(t.data);const r=document.createElement("canvas");r.width=s,r.height=n;const o=r.getContext("2d",{willReadFrequently:!0});if(!o)throw new Error("Canvas init failed");return o.drawImage(t,0,0),new Uint8Array(o.getImageData(0,0,s,n).data)}static convertSogsRanges(e){const t=s=>new l.Vector3(s[0],s[1],s[2]);return{sh0:{min:t(e.sh0.mins),max:t(e.sh0.maxs)},means:{min:t(e.means.mins),max:t(e.means.maxs)},scales:{min:t(e.scales.mins),max:t(e.scales.maxs)}}}static calculatePlyRanges(e){const t=new l.Vector3(1/0,1/0,1/0),s=new l.Vector3(-1/0,-1/0,-1/0),n=new l.Vector3(1/0,1/0,1/0),r=new l.Vector3(-1/0,-1/0,-1/0),o=new l.Vector3(1/0,1/0,1/0),i=new l.Vector3(-1/0,-1/0,-1/0);let u=0;for(let m=0;m<e.numSplats;m++){const c=m*3,h=e.positions[c+0],d=e.positions[c+1],w=e.positions[c+2];t.x=Math.min(t.x,h),s.x=Math.max(s.x,h),t.y=Math.min(t.y,d),s.y=Math.max(s.y,d),t.z=Math.min(t.z,w),s.z=Math.max(s.z,w),n.x=Math.min(n.x,e.scales[c]),r.x=Math.max(r.x,e.scales[c]),n.y=Math.min(n.y,e.scales[c+1]),r.y=Math.max(r.y,e.scales[c+1]),n.z=Math.min(n.z,e.scales[c+2]),r.z=Math.max(r.z,e.scales[c+2]),u=Math.max(u,e.colors[c],e.colors[c+1],e.colors[c+2])}const y=u>1.5?1/255:1;for(let m=0;m<e.numSplats;m++){const c=m*3,h=this.clamp01(e.colors[c+0]*y),d=this.clamp01(e.colors[c+1]*y),w=this.clamp01(e.colors[c+2]*y),A=(h-.5)/ye,b=(d-.5)/ye,z=(w-.5)/ye;o.x=Math.min(o.x,A),i.x=Math.max(i.x,A),o.y=Math.min(o.y,b),i.y=Math.max(i.y,b),o.z=Math.min(o.z,z),i.z=Math.max(i.z,z)}return{colorScale:y,ranges:{sh0:{min:o,max:i},means:{min:t,max:s},scales:{min:n,max:r}}}}static clamp01(e){return Math.max(0,Math.min(1,e))}static norm(e,t,s){return(e-t)/(s-t||1)}static sogsDecode(e,t,s){const n=t+(s-t)*e;return Math.sign(n)*(Math.exp(Math.abs(n))-1)}}class Ke extends l.Loader{constructor(t,s){super(t);x(this,"requestId",0);x(this,"worker");x(this,"pendingCallbacks",new Map);this.withCredentials=(s==null?void 0:s.withCredentials)??!1;const n=this.createWorkerCode(),r=new Blob([n],{type:"application/javascript"});this.worker=new Worker(URL.createObjectURL(r)),this.worker.onmessage=this.onWorkerMessage.bind(this)}onWorkerMessage(t){const{requestId:s,error:n,result:r}=t.data,o=this.pendingCallbacks.get(s);if(!o)return console.warn(`PlyLoader: Received response for unknown request ${s}`);if(this.pendingCallbacks.delete(s),n)return o.reject(new Error(n));if(!r)return o.reject(new Error("Worker returned no result"));try{const i=new Xe(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),this.worker.terminate();const u=Me.packPly(i);i.dispose(),o.resolve(u)}catch(i){o.reject(i)}}load(t,s,n,r){const o=new l.FileLoader(this.manager);o.setResponseType("arraybuffer"),o.setRequestHeader(this.requestHeader),o.setPath(this.path),o.setWithCredentials(this.withCredentials),o.load(t,i=>{this.parseAsync(i).then(u=>{s&&s(u)}).catch(u=>{r?r(u):console.error(u),this.manager.itemError(t)})},n,r)}loadAsync(t,s){return new Promise((n,r)=>{const o=new l.FileLoader(this.manager);o.setResponseType("arraybuffer"),o.setRequestHeader(this.requestHeader),o.setPath(this.path),o.setWithCredentials(this.withCredentials),o.load(t,i=>{this.parseAsync(i).then(n).catch(u=>{r(u),this.manager.itemError(t)})},s,i=>{r(i),this.manager.itemError(t)})})}parseAsync(t){return new Promise((s,n)=>{const r=this.requestId++;this.pendingCallbacks.set(r,{resolve:s,reject:n});const o={requestId:r,buffer:t};this.worker.postMessage(o,[t])})}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=s(o),u={requestId:r,result:i};self.postMessage(u,[i.positions,i.rotations,i.scales,i.colors,i.opacities])}catch(i){const u={requestId:r,error:i instanceof Error?i.message:String(i)};self.postMessage(u)}};function s(n){const r=new TextDecoder,o=new Uint8Array(n),i=[112,108,121,10],u=`
322
+ `;class je extends c.ShaderMaterial{constructor(t={}){const s={packedGeometry:{value:null},packedColor:{value:null},splatOrder:{value:null},meansMin:{value:new c.Vector3},meansMax:{value:new c.Vector3},scalesMin:{value:new c.Vector3},scalesMax:{value:new c.Vector3},sh0Min:{value:new c.Vector3},sh0Max:{value:new c.Vector3},texWidth:{value:0},viewport:{value:new c.Vector2(1,1)},numSplats:{value:0},animationProgress:{value:1},animationCenter:{value:new c.Vector3}};super({uniforms:s,vertexShader:Ne,fragmentShader:nt,transparent:!0,glslVersion:c.GLSL3,blendSrc:c.OneFactor,blendSrcAlpha:c.OneFactor,blending:c.CustomBlending,blendEquation:c.AddEquation,blendEquationAlpha:c.AddEquation,blendDst:c.OneMinusSrcAlphaFactor,blendDstAlpha:c.OneMinusSrcAlphaFactor,depthTest:!0,depthWrite:!1,side:c.DoubleSide,alphaTest:t.alphaTest??0,toneMapped:t.toneMapped??!1});d(this,"_shaderTemplate");t.alphaHash&&(this.alphaHash=!0,this.depthWrite=!0,this.blending=c.NoBlending),this._shaderTemplate=Ne}setTexWidth(t){this.uniforms.texWidth.value=t|0}updateViewport(t,s){this.uniforms.viewport.value.set(t,s)}setPackedGeometry(t){this.uniforms.packedGeometry.value=t}setPackedColor(t){this.uniforms.packedColor.value=t}setOrderTexture(t){this.uniforms.splatOrder.value=t}setRanges(t){this.uniforms.meansMin.value.copy(t.means.min),this.uniforms.meansMax.value.copy(t.means.max),this.uniforms.scalesMin.value.copy(t.scales.min),this.uniforms.scalesMax.value.copy(t.scales.max),this.uniforms.sh0Min.value.copy(t.sh0.min),this.uniforms.sh0Max.value.copy(t.sh0.max)}setNumSplats(t){this.uniforms.numSplats.value=t}setAnimation(t){let s=this._shaderTemplate;t&&t.type!=="none"?(s=s.replace("/* @ANIMATION_CODE */",t.shaderCode),s=s.replace("/* @ANIMATION_CALL */",`if (animationProgress < 1.0) {
323
+ applyAnimation(modelCenter, scale, clr, animationProgress, animationCenter);
324
+ }`)):(s=s.replace("/* @ANIMATION_CODE */",""),s=s.replace("/* @ANIMATION_CALL */","")),this.vertexShader=s,this.needsUpdate=!0}setAnimationProgress(t){this.uniforms.animationProgress.value=t}setAnimationCenter(t){this.uniforms.animationCenter.value.copy(t)}}const ve=class ve extends c.Mesh{constructor(t,s={}){const n=new je(s),r=ve.createInstancedGeometry(t.numSplats,ve.INSTANCE_SIZE);super(r,n);d(this,"sorter");d(this,"options");d(this,"splatData");d(this,"textureManager");d(this,"animation",null);d(this,"material");d(this,"geometry");d(this,"lastCameraPositionLocal",new c.Vector3);d(this,"lastCameraDirectionLocal",new c.Vector3);d(this,"invModelMatrix",new c.Matrix4);d(this,"_vpW",-1);d(this,"_vpH",-1);d(this,"_size",new c.Vector2);d(this,"_camPosW",new c.Vector3);d(this,"_camDirW",new c.Vector3);d(this,"_camPosL",new c.Vector3);d(this,"_camDirL",new c.Vector3);d(this,"onSorterUpdated",t=>{const s=t.count;this.geometry.instanceCount=Math.ceil(s/ve.INSTANCE_SIZE),this.material.setNumSplats(s)});this.geometry=r,this.material=n,this.options={autoSort:!0,...s},this.splatData=t,this.frustumCulled=!1,this.sorter=new Re,this.textureManager=new We(t);let i=this.createChunks()||void 0;if(i===null&&console.warn("Visus: Could not create sorter chunks, bounding box might be invalid."),i=void 0,this.sorter.addEventListener("updated",this.onSorterUpdated),this.sorter.init(this.textureManager.orderTexture,this.splatData.centers,i??void 0,!this.options.keepSplatData),this.material.setRanges(t.ranges),this.material.setTexWidth(t.textureWidth),this.material.setPackedColor(this.textureManager.packedColor),this.material.setOrderTexture(this.textureManager.orderTexture),this.material.setPackedGeometry(this.textureManager.packedGeometry),this.material.setNumSplats(0),s.animation&&s.animation.type!=="none"){this.animation=new Ge(s.animation);const o=new c.Vector3;t.boundingBox.toBox3().getCenter(o),this.animation.setCenter(o);const u=Ie(s.animation.type);this.material.setAnimation(u),this.material.setAnimationCenter(o),this.material.setAnimationProgress(0)}this.geometry.boundingBox=t.boundingBox.toBox3(),this.geometry.boundingSphere=new c.Sphere,this.geometry.boundingBox.getBoundingSphere(this.geometry.boundingSphere),this.options.keepSplatData||(this.splatData=null)}static createInstancedGeometry(t,s){const n=Math.ceil(t/s),r=new c.BufferGeometry,i=new Float32Array([-1,-1,0,1,-1,0,1,1,0,-1,1,0]),o=new Uint16Array([0,1,2,0,2,3]),u=new Float32Array(4*3*s);for(let h=0;h<s;h++){const f=h*4*3;for(let w=0;w<4;w++)u[f+w*3+0]=i[w*3+0],u[f+w*3+1]=i[w*3+1],u[f+w*3+2]=h}const y=new Uint32Array(6*s);for(let h=0;h<s;h++){const f=h*6,w=h*4;y[f+0]=o[0]+w,y[f+1]=o[1]+w,y[f+2]=o[2]+w,y[f+3]=o[3]+w,y[f+4]=o[4]+w,y[f+5]=o[5]+w}r.setAttribute("position",new c.BufferAttribute(u,3)),r.setIndex(new c.BufferAttribute(y,1));const m=new c.InstancedBufferGeometry;m.index=r.index,m.setAttribute("position",r.getAttribute("position"));const l=new Uint32Array(n);for(let h=0;h<n;h++)l[h]=h*s;return m.setAttribute("splatInstanceIndex",new c.InstancedBufferAttribute(l,1,!1)),m.instanceCount=0,m}createChunks(){if(!this.splatData)return null;const t=this.splatData.boundingBox;return t.min.x===1/0||t.max.x===-1/0?null:new Float32Array([t.min.x,t.min.y,t.min.z,t.max.x,t.max.y,t.max.z])}updateViewport(t,s){t===this._vpW&&s===this._vpH||(this._vpW=t,this._vpH=s,this.material.updateViewport(t,s))}sort(t){t.getWorldPosition(this._camPosW),t.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 s=this.lastCameraPositionLocal.distanceToSquared(this._camPosL)>1e-6,n=this.lastCameraDirectionLocal.dot(this._camDirL)<.999;this.options.autoSort&&(s||n)&&(this.lastCameraPositionLocal.copy(this._camPosL),this.lastCameraDirectionLocal.copy(this._camDirL),this.sorter.setCamera(this._camPosL,this._camDirL))}onBeforeRender(t,s,n){if(this.sort(n),t.getSize(this._size),this.updateViewport(this._size.x,this._size.y),this.animation){if(!this.animation.isPlaying&&this.animation.shouldAutoPlay())return this.animation.play();if(!this.animation.isPlaying||this.animation.isComplete)return;const r=performance.now()/1e3;this.animation.update(r)&&this.material.setAnimationProgress(this.animation.progress)}}dispose(){this.sorter.removeEventListener("updated",this.onSorterUpdated),this.sorter.dispose(),this.geometry.dispose(),this.material.dispose(),this.textureManager.dispose()}};d(ve,"INSTANCE_SIZE",128);let _e=ve;const ye=.28209479177387814;class Me{static packPly(e){const t=e.numSplats,s=Math.ceil(Math.sqrt(t)),n=Math.ceil(t/s),r=s*n,{ranges:i,colorScale:o}=this.calculatePlyRanges(e),u=new Uint32Array(r*4),y=new Uint8Array(r*4),m=new c.Quaternion;for(let l=0;l<t;l++){const h=l*4,f=l*3,w=l*4,A=e.positions[f+0],b=e.positions[f+1],B=e.positions[f+2],F=this.clamp01(this.norm(A,i.means.min.x,i.means.max.x)),P=this.clamp01(this.norm(b,i.means.min.y,i.means.max.y)),U=this.clamp01(this.norm(B,i.means.min.z,i.means.max.z)),O=F*65535|0,C=P*65535|0,M=U*65535|0;u[h+0]=this.pack4Bytes(O&255,C&255,M&255,0),u[h+1]=this.pack4Bytes(O>>8,C>>8,M>>8,0),m.set(e.rotations[w],e.rotations[w+1],e.rotations[w+2],e.rotations[w+3]).normalize();let k=m.w,S=m.x,x=m.y,v=m.z;const R=Math.abs(k),V=Math.abs(S),I=Math.abs(x),q=Math.abs(v);let p=0,_=R;V>_&&(_=V,p=1),I>_&&(_=I,p=2),q>_&&(_=q,p=3),(p===0?k:p===1?S:p===2?x:v)<0&&(k=-k,S=-S,x=-x,v=-v);let W=0,T=0,K=0;p===0&&(W=S,T=x,K=v),p===1&&(W=k,T=x,K=v),p===2&&(W=k,T=S,K=v),p===3&&(W=k,T=S,K=x);const X=ae=>Math.min(255,Math.max(0,Math.round((.5+ae/Math.SQRT2)*255)));u[h+2]=this.pack4Bytes(X(W),X(T),X(K),p);const Z=this.norm(e.scales[f+0],i.scales.min.x,i.scales.max.x),z=this.norm(e.scales[f+1],i.scales.min.y,i.scales.max.y),g=this.norm(e.scales[f+2],i.scales.min.z,i.scales.max.z);u[h+3]=this.pack4Bytes(Math.floor(Z*255),Math.floor(z*255),Math.floor(g*255),0);const E=this.clamp01(e.colors[f+0]*o),L=this.clamp01(e.colors[f+1]*o),D=this.clamp01(e.colors[f+2]*o),G=(E-.5)/ye,Q=(L-.5)/ye,H=(D-.5)/ye,J=this.clamp01(this.norm(G,i.sh0.min.x,i.sh0.max.x)),$=this.clamp01(this.norm(Q,i.sh0.min.y,i.sh0.max.y)),ee=this.clamp01(this.norm(H,i.sh0.min.z,i.sh0.max.z)),ne=this.clamp01(e.opacities[l]);y[h+0]=Math.round(J*255),y[h+1]=Math.round($*255),y[h+2]=Math.round(ee*255),y[h+3]=Math.round(ne*255)}return new Ae(t,s,n,e.positions,u,y,i,e.boundingBox)}static packSogs(e){var x,v,R;const t=e.numSplats;let s=Math.ceil(Math.sqrt(t)),n=Math.ceil(t/s);const r=((x=e.means_l)==null?void 0:x.image)??((v=e.sh0)==null?void 0:v.image)??((R=e.quats)==null?void 0:R.image);r&&typeof r.width=="number"&&typeof r.height=="number"&&(s=r.width,n=r.height);const i=s*n;if(i<t)throw new Error(`SOG v1 texture too small: ${s}x${n}=${i} < count=${t}`);const o=this.convertSogsRanges(e.ranges),u=e.ranges.means.mins[0],y=e.ranges.means.mins[1],m=e.ranges.means.mins[2],l=e.ranges.means.maxs[0],h=e.ranges.means.maxs[1],f=e.ranges.means.maxs[2],w=V=>Math.sign(V)*(Math.exp(Math.abs(V))-1),A=new c.Vector3(w(u),w(y),w(m)),b=new c.Vector3(w(l),w(h),w(f));o.means.min.copy(A),o.means.max.copy(b);const B=e,F=this.getPixels(B.means_l),P=this.getPixels(B.means_u),U=this.getPixels(B.quats),O=this.getPixels(B.scales),C=this.getPixels(B.sh0),M=new Uint32Array(i*4),k=new Uint8Array(i*4),S=new Float32Array(t*3);for(let V=0;V<t;V++){const I=V*4,q=P[I+0],p=F[I+0],_=P[I+1],Y=F[I+1],W=P[I+2],T=F[I+2],K=(q<<8|p)/65535,X=(_<<8|Y)/65535,Z=(W<<8|T)/65535,z=this.sogsDecode(K,u,l),g=this.sogsDecode(X,y,h),E=this.sogsDecode(Z,m,f);S[V*3+0]=z,S[V*3+1]=g,S[V*3+2]=E;const L=this.clamp01(this.norm(z,A.x,b.x))*65535|0,D=this.clamp01(this.norm(g,A.y,b.y))*65535|0,G=this.clamp01(this.norm(E,A.z,b.z))*65535|0;M[I+0]=this.pack4Bytes(L&255,D&255,G&255,0),M[I+1]=this.pack4Bytes(L>>8,D>>8,G>>8,0),M[I+3]=this.pack4Bytes(O[I],O[I+1],O[I+2],0);const H=U[I+3]-252;M[I+2]=this.pack4Bytes(U[I+0],U[I+1],U[I+2],H),k[I+0]=C[I],k[I+1]=C[I+1],k[I+2]=C[I+2];const J=C[I+3]/255,$=e.ranges.sh0.mins[3]+(e.ranges.sh0.maxs[3]-e.ranges.sh0.mins[3])*J,ee=1/(1+Math.exp(-$));k[I+3]=Math.round(Math.max(0,Math.min(1,ee))*255)}return new Ae(t,s,n,S,M,k,o,e.boundingBox)}static packSog2(e){var R,V,I;const t=e.numSplats;let s=Math.ceil(Math.sqrt(t)),n=Math.ceil(t/s);const r=((R=e.means_l)==null?void 0:R.image)??((V=e.sh0)==null?void 0:V.image)??((I=e.quats)==null?void 0:I.image);r&&typeof r.width=="number"&&typeof r.height=="number"&&(s=r.width,n=r.height);const i=s*n;if(i<t)throw new Error(`SOG v2 texture too small: ${s}x${n}=${i} < count=${t}`);const o=e.ranges.means.mins[0],u=e.ranges.means.mins[1],y=e.ranges.means.mins[2],m=e.ranges.means.maxs[0],l=e.ranges.means.maxs[1],h=e.ranges.means.maxs[2],f=q=>Math.sign(q)*(Math.exp(Math.abs(q))-1),w=new c.Vector3(f(o),f(u),f(y)),A=new c.Vector3(f(m),f(l),f(h)),b=q=>{let p=1/0,_=-1/0;for(const T of q)Number.isFinite(T)&&(p=Math.min(p,T),_=Math.max(_,T));(!Number.isFinite(p)||!Number.isFinite(_))&&(p=0,_=1);const Y=_-p||1,W=new Uint8Array(256);for(let T=0;T<256;T++){const X=((T<q.length&&Number.isFinite(q[T])?q[T]:p+(_-p)*(T/255))-p)/Y,Z=Math.max(0,Math.min(255,Math.round(X*255)));W[T]=Z}return{cbMin:p,cbMax:_,lut:W}},B=b(e.ranges.scales.codebook),F=b(e.ranges.sh0.codebook),P={means:{min:w.clone(),max:A.clone()},scales:{min:new c.Vector3(B.cbMin,B.cbMin,B.cbMin),max:new c.Vector3(B.cbMax,B.cbMax,B.cbMax)},sh0:{min:new c.Vector3(F.cbMin,F.cbMin,F.cbMin),max:new c.Vector3(F.cbMax,F.cbMax,F.cbMax)}},U=this.getPixels(e.means_l),O=this.getPixels(e.means_u),C=this.getPixels(e.quats),M=this.getPixels(e.scales),k=this.getPixels(e.sh0),S=new Uint32Array(i*4),x=new Uint8Array(i*4),v=new Float32Array(t*3);for(let q=0;q<t;q++){const p=q*4,_=O[p+0],Y=U[p+0],W=O[p+1],T=U[p+1],K=O[p+2],X=U[p+2],Z=(_<<8|Y)/65535,z=(W<<8|T)/65535,g=(K<<8|X)/65535,E=this.sogsDecode(Z,o,m),L=this.sogsDecode(z,u,l),D=this.sogsDecode(g,y,h);v[q*3+0]=E,v[q*3+1]=L,v[q*3+2]=D;const G=this.clamp01(this.norm(E,w.x,A.x))*65535|0,Q=this.clamp01(this.norm(L,w.y,A.y))*65535|0,H=this.clamp01(this.norm(D,w.z,A.z))*65535|0;S[p+0]=this.pack4Bytes(G&255,Q&255,H&255,0),S[p+1]=this.pack4Bytes(G>>8,Q>>8,H>>8,0);const $=C[p+3]-252&3;S[p+2]=this.pack4Bytes(C[p+0],C[p+1],C[p+2],$);const ee=B.lut[M[p+0]],ne=B.lut[M[p+1]],ae=B.lut[M[p+2]];S[p+3]=this.pack4Bytes(ee,ne,ae,0),x[p+0]=F.lut[k[p+0]],x[p+1]=F.lut[k[p+1]],x[p+2]=F.lut[k[p+2]],x[p+3]=k[p+3]}return new Ae(t,s,n,v,S,x,P,e.boundingBox)}static pack4Bytes(e,t,s,n){return(e&255)<<24|(t&255)<<16|(s&255)<<8|n&255}static getPixels(e){const t=e.image,s=t.width,n=t.height;if(t.data&&(t.data instanceof Uint8Array||t.data instanceof Uint8ClampedArray))return new Uint8Array(t.data);const r=document.createElement("canvas");r.width=s,r.height=n;const i=r.getContext("2d",{willReadFrequently:!0});if(!i)throw new Error("Canvas init failed");return i.drawImage(t,0,0),new Uint8Array(i.getImageData(0,0,s,n).data)}static convertSogsRanges(e){const t=s=>new c.Vector3(s[0],s[1],s[2]);return{sh0:{min:t(e.sh0.mins),max:t(e.sh0.maxs)},means:{min:t(e.means.mins),max:t(e.means.maxs)},scales:{min:t(e.scales.mins),max:t(e.scales.maxs)}}}static calculatePlyRanges(e){const t=new c.Vector3(1/0,1/0,1/0),s=new c.Vector3(-1/0,-1/0,-1/0),n=new c.Vector3(1/0,1/0,1/0),r=new c.Vector3(-1/0,-1/0,-1/0),i=new c.Vector3(1/0,1/0,1/0),o=new c.Vector3(-1/0,-1/0,-1/0);let u=0;for(let m=0;m<e.numSplats;m++){const l=m*3,h=e.positions[l+0],f=e.positions[l+1],w=e.positions[l+2];t.x=Math.min(t.x,h),s.x=Math.max(s.x,h),t.y=Math.min(t.y,f),s.y=Math.max(s.y,f),t.z=Math.min(t.z,w),s.z=Math.max(s.z,w),n.x=Math.min(n.x,e.scales[l]),r.x=Math.max(r.x,e.scales[l]),n.y=Math.min(n.y,e.scales[l+1]),r.y=Math.max(r.y,e.scales[l+1]),n.z=Math.min(n.z,e.scales[l+2]),r.z=Math.max(r.z,e.scales[l+2]),u=Math.max(u,e.colors[l],e.colors[l+1],e.colors[l+2])}const y=u>1.5?1/255:1;for(let m=0;m<e.numSplats;m++){const l=m*3,h=this.clamp01(e.colors[l+0]*y),f=this.clamp01(e.colors[l+1]*y),w=this.clamp01(e.colors[l+2]*y),A=(h-.5)/ye,b=(f-.5)/ye,B=(w-.5)/ye;i.x=Math.min(i.x,A),o.x=Math.max(o.x,A),i.y=Math.min(i.y,b),o.y=Math.max(o.y,b),i.z=Math.min(i.z,B),o.z=Math.max(o.z,B)}return{colorScale:y,ranges:{sh0:{min:i,max:o},means:{min:t,max:s},scales:{min:n,max:r}}}}static clamp01(e){return Math.max(0,Math.min(1,e))}static norm(e,t,s){return(e-t)/(s-t||1)}static sogsDecode(e,t,s){const n=t+(s-t)*e;return Math.sign(n)*(Math.exp(Math.abs(n))-1)}}class at extends c.Loader{constructor(t,s){super(t);d(this,"requestId",0);d(this,"worker");d(this,"pendingCallbacks",new Map);this.withCredentials=(s==null?void 0:s.withCredentials)??!1;const n=this.createWorkerCode(),r=new Blob([n],{type:"application/javascript"});this.worker=new Worker(URL.createObjectURL(r)),this.worker.onmessage=this.onWorkerMessage.bind(this)}onWorkerMessage(t){const{requestId:s,error:n,result:r}=t.data,i=this.pendingCallbacks.get(s);if(!i)return console.warn(`PlyLoader: Received response for unknown request ${s}`);if(this.pendingCallbacks.delete(s),n)return i.reject(new Error(n));if(!r)return i.reject(new Error("Worker returned no result"));try{const o=new tt(0);o.numSplats=r.numSplats,o.positions=new Float32Array(r.positions),o.rotations=new Float32Array(r.rotations),o.scales=new Float32Array(r.scales),o.colors=new Float32Array(r.colors),o.opacities=new Float32Array(r.opacities),o.boundingBox.min.set(r.boundingBox.minX,r.boundingBox.minY,r.boundingBox.minZ),o.boundingBox.max.set(r.boundingBox.maxX,r.boundingBox.maxY,r.boundingBox.maxZ),this.worker.terminate();const u=Me.packPly(o);o.dispose(),i.resolve(u)}catch(o){i.reject(o)}}load(t,s,n,r){const i=new c.FileLoader(this.manager);i.setResponseType("arraybuffer"),i.setRequestHeader(this.requestHeader),i.setPath(this.path),i.setWithCredentials(this.withCredentials),i.load(t,o=>{this.parseAsync(o).then(u=>{s&&s(u)}).catch(u=>{r?r(u):console.error(u),this.manager.itemError(t)})},n,r)}loadAsync(t,s){return new Promise((n,r)=>{const i=new c.FileLoader(this.manager);i.setResponseType("arraybuffer"),i.setRequestHeader(this.requestHeader),i.setPath(this.path),i.setWithCredentials(this.withCredentials),i.load(t,o=>{this.parseAsync(o).then(n).catch(u=>{r(u),this.manager.itemError(t)})},s,o=>{r(o),this.manager.itemError(t)})})}parseAsync(t){return new Promise((s,n)=>{const r=this.requestId++;this.pendingCallbacks.set(r,{resolve:s,reject:n});const i={requestId:r,buffer:t};this.worker.postMessage(i,[t])})}dispose(){this.worker&&this.worker.terminate(),this.pendingCallbacks.clear()}createWorkerCode(){return`(${(function(){self.onmessage=n=>{const{requestId:r,buffer:i}=n.data;try{const o=s(i),u={requestId:r,result:o};self.postMessage(u,[o.positions,o.rotations,o.scales,o.colors,o.opacities])}catch(o){const u={requestId:r,error:o instanceof Error?o.message:String(o)};self.postMessage(u)}};function s(n){const r=new TextDecoder,i=new Uint8Array(n),o=[112,108,121,10],u=`
257
325
  end_header
258
- `;for(let D=0;D<i.length;D++)if(o[D]!==i[D])throw new Error("Invalid PLY file: Missing magic bytes");let y=0;for(let D=0;D<o.length-u.length;D++){let p=!0;for(let E=0;E<u.length;E++)if(o[D+E]!==u.charCodeAt(E)){p=!1;break}if(p){y=D+u.length;break}}if(y===0)throw new Error("Invalid PLY file: Could not find end of header");const c=r.decode(o.subarray(0,y)).split(`
259
- `),h=[];let d=null;for(let D=1;D<c.length;D++){const p=c[D].trim();if(p===""||p==="end_header")continue;const E=p.split(" ");switch(E[0]){case"format":d=E[1];break;case"element":h.push({name:E[1],count:parseInt(E[2],10),properties:[]});break;case"property":if(h.length===0)throw new Error("Invalid PLY file: Property without element");h[h.length-1].properties.push({type:E[1],name:E[2]});break}}if(d!=="binary_little_endian")throw new Error(`Unsupported PLY format: ${d}`);const w=h.find(D=>D.name==="vertex");if(!w)throw new Error("Invalid PLY file: No vertex element found");const A=w.count,b=new Float32Array(A*3),z=new Float32Array(A*4),_=new Float32Array(A*3),F=new Float32Array(A*3),O=new Float32Array(A),V=new DataView(n);let k=y;const M=D=>w.properties.findIndex(p=>p.name===D),B=M("x"),S=M("y"),g=M("z"),v=[M("rot_0"),M("rot_1"),M("rot_2"),M("rot_3")],U=[M("scale_0"),M("scale_1"),M("scale_2")],T=[M("f_dc_0"),M("f_dc_1"),M("f_dc_2")],I=M("opacity");if([B,S,g,...v,...U,...T,I].some(D=>D===-1))throw new Error("Invalid PLY file: Missing required properties");const f=.28209479177387814,C=D=>{if(D>0)return 1/(1+Math.exp(-D));const p=Math.exp(D);return p/(1+p)};let Y=1/0,W=1/0,R=1/0,K=-1/0,X=-1/0,Z=-1/0;for(let D=0;D<A;D++){const p=[];for(let Re=0;Re<w.properties.length;Re++){const Ze=w.properties[Re].type;let he;switch(Ze){case"char":he=V.getInt8(k),k+=1;break;case"uchar":he=V.getUint8(k),k+=1;break;case"short":he=V.getInt16(k,!0),k+=2;break;case"ushort":he=V.getUint16(k,!0),k+=2;break;case"int":he=V.getInt32(k,!0),k+=4;break;case"uint":he=V.getUint32(k,!0),k+=4;break;case"float":he=V.getFloat32(k,!0),k+=4;break;case"double":he=V.getFloat64(k,!0),k+=8;break;default:throw new Error(`Unsupported property type: ${Ze}`)}p.push(he)}const E=p[B],L=p[S],q=p[g],G=D*3;b[G]=E,b[G+1]=L,b[G+2]=q,Y=Math.min(Y,E),W=Math.min(W,L),R=Math.min(R,q),K=Math.max(K,E),X=Math.max(X,L),Z=Math.max(Z,q);let Q=p[v[1]],$=p[v[2]],J=p[v[3]],N=p[v[0]];const ee=Math.sqrt(Q*Q+$*$+J*J+N*N);ee>0&&(Q/=ee,$/=ee,J/=ee,N/=ee),N<0&&(Q=-Q,$=-$,J=-J,N=-N);const ne=D*4;z[ne]=Q,z[ne+1]=$,z[ne+2]=J,z[ne+3]=N;const re=D*3;_[re]=p[U[0]],_[re+1]=p[U[1]],_[re+2]=p[U[2]];let fe=.5+p[T[0]]*f,pe=.5+p[T[1]]*f,le=.5+p[T[2]]*f;fe=Math.max(0,Math.min(1,fe)),pe=Math.max(0,Math.min(1,pe)),le=Math.max(0,Math.min(1,le));const Pe=D*3;F[Pe]=fe,F[Pe+1]=pe,F[Pe+2]=le,O[D]=C(p[I])}return{numSplats:A,positions:b.buffer,rotations:z.buffer,scales:_.buffer,colors:F.buffer,opacities:O.buffer,boundingBox:{minX:Y,minY:W,minZ:R,maxX:K,maxY:X,maxZ:Z}}}}).toString()})();`}}var se=Uint8Array,we=Uint16Array,et=Int32Array,Le=new se([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),Ge=new se([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),tt=new se([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),We=function(a,e){for(var t=new we(31),s=0;s<31;++s)t[s]=e+=1<<a[s-1];for(var n=new et(t[30]),s=1;s<30;++s)for(var r=t[s];r<t[s+1];++r)n[r]=r-t[s]<<5|s;return{b:t,r:n}},je=We(Le,2),Ne=je.b,st=je.r;Ne[28]=258,st[258]=28;for(var nt=We(Ge,0),rt=nt.b,Ce=new we(32768),j=0;j<32768;++j){var ue=(j&43690)>>1|(j&21845)<<1;ue=(ue&52428)>>2|(ue&13107)<<2,ue=(ue&61680)>>4|(ue&3855)<<4,Ce[j]=((ue&65280)>>8|(ue&255)<<8)>>1}for(var be=function(a,e,t){for(var s=a.length,n=0,r=new we(e);n<s;++n)a[n]&&++r[a[n]-1];var o=new we(e);for(n=1;n<e;++n)o[n]=o[n-1]+r[n-1]<<1;var i;if(t){i=new we(1<<e);var u=15-e;for(n=0;n<s;++n)if(a[n])for(var y=n<<4|a[n],m=e-a[n],c=o[a[n]-1]++<<m,h=c|(1<<m)-1;c<=h;++c)i[Ce[c]>>u]=y}else for(i=new we(s),n=0;n<s;++n)a[n]&&(i[n]=Ce[o[a[n]-1]++]>>15-a[n]);return i},Se=new se(288),j=0;j<144;++j)Se[j]=8;for(var j=144;j<256;++j)Se[j]=9;for(var j=256;j<280;++j)Se[j]=7;for(var j=280;j<288;++j)Se[j]=8;for(var $e=new se(32),j=0;j<32;++j)$e[j]=5;var at=be(Se,9,1),ot=be($e,5,1),Be=function(a){for(var e=a[0],t=1;t<a.length;++t)a[t]>e&&(e=a[t]);return e},oe=function(a,e,t){var s=e/8|0;return(a[s]|a[s+1]<<8)>>(e&7)&t},ze=function(a,e){var t=e/8|0;return(a[t]|a[t+1]<<8|a[t+2]<<16)>>(e&7)},it=function(a){return(a+7)/8|0},De=function(a,e,t){return(e==null||e<0)&&(e=0),(t==null||t>a.length)&&(t=a.length),new se(a.subarray(e,t))},ct=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],ae=function(a,e,t){var s=new Error(e||ct[a]);if(s.code=a,Error.captureStackTrace&&Error.captureStackTrace(s,ae),!t)throw s;return s},lt=function(a,e,t,s){var n=a.length,r=s?s.length:0;if(!n||e.f&&!e.l)return t||new se(0);var o=!t,i=o||e.i!=2,u=e.i;o&&(t=new se(n*3));var y=function($){var J=t.length;if($>J){var N=new se(Math.max(J*2,$));N.set(t),t=N}},m=e.f||0,c=e.p||0,h=e.b||0,d=e.l,w=e.d,A=e.m,b=e.n,z=n*8;do{if(!d){m=oe(a,c,1);var _=oe(a,c+1,3);if(c+=3,_)if(_==1)d=at,w=ot,A=9,b=5;else if(_==2){var k=oe(a,c,31)+257,M=oe(a,c+10,15)+4,B=k+oe(a,c+5,31)+1;c+=14;for(var S=new se(B),g=new se(19),v=0;v<M;++v)g[tt[v]]=oe(a,c+v*3,7);c+=M*3;for(var U=Be(g),T=(1<<U)-1,I=be(g,U,1),v=0;v<B;){var P=I[oe(a,c,T)];c+=P&15;var F=P>>4;if(F<16)S[v++]=F;else{var f=0,C=0;for(F==16?(C=3+oe(a,c,3),c+=2,f=S[v-1]):F==17?(C=3+oe(a,c,7),c+=3):F==18&&(C=11+oe(a,c,127),c+=7);C--;)S[v++]=f}}var Y=S.subarray(0,k),W=S.subarray(k);A=Be(Y),b=Be(W),d=be(Y,A,1),w=be(W,b,1)}else ae(1);else{var F=it(c)+4,O=a[F-4]|a[F-3]<<8,V=F+O;if(V>n){u&&ae(0);break}i&&y(h+O),t.set(a.subarray(F,V),h),e.b=h+=O,e.p=c=V*8,e.f=m;continue}if(c>z){u&&ae(0);break}}i&&y(h+131072);for(var R=(1<<A)-1,K=(1<<b)-1,X=c;;X=c){var f=d[ze(a,c)&R],Z=f>>4;if(c+=f&15,c>z){u&&ae(0);break}if(f||ae(2),Z<256)t[h++]=Z;else if(Z==256){X=c,d=null;break}else{var D=Z-254;if(Z>264){var v=Z-257,p=Le[v];D=oe(a,c,(1<<p)-1)+Ne[v],c+=p}var E=w[ze(a,c)&K],L=E>>4;E||ae(3),c+=E&15;var W=rt[L];if(L>3){var p=Ge[L];W+=ze(a,c)&(1<<p)-1,c+=p}if(c>z){u&&ae(0);break}i&&y(h+131072);var q=h+D;if(h<W){var G=r-W,Q=Math.min(W,q);for(G+h<0&&ae(3);h<Q;++h)t[h]=s[G+h]}for(;h<q;++h)t[h]=t[h-W]}}e.l=d,e.p=X,e.b=h,e.f=m,d&&(m=1,e.m=A,e.d=w,e.n=b)}while(!m);return h!=t.length&&o?De(t,0,h):t.subarray(0,h)},ht=new se(0),ce=function(a,e){return a[e]|a[e+1]<<8},ie=function(a,e){return(a[e]|a[e+1]<<8|a[e+2]<<16|a[e+3]<<24)>>>0},Ee=function(a,e){return ie(a,e)+ie(a,e+4)*4294967296};function ut(a,e){return lt(a,{i:2},e&&e.out,e&&e.dictionary)}var qe=typeof TextDecoder<"u"&&new TextDecoder,mt=0;try{qe.decode(ht,{stream:!0}),mt=1}catch{}var dt=function(a){for(var e="",t=0;;){var s=a[t++],n=(s>127)+(s>223)+(s>239);if(t+n>a.length)return{s:e,r:De(a,t-1)};n?n==3?(s=((s&15)<<18|(a[t++]&63)<<12|(a[t++]&63)<<6|a[t++]&63)-65536,e+=String.fromCharCode(55296|s>>10,56320|s&1023)):n&1?e+=String.fromCharCode((s&31)<<6|a[t++]&63):e+=String.fromCharCode((s&15)<<12|(a[t++]&63)<<6|a[t++]&63):e+=String.fromCharCode(s)}};function ft(a,e){if(e){for(var t="",s=0;s<a.length;s+=16384)t+=String.fromCharCode.apply(null,a.subarray(s,s+16384));return t}else{if(qe)return qe.decode(a);var n=dt(a),r=n.s,t=n.r;return t.length&&ae(8),r}}var pt=function(a,e){return e+30+ce(a,e+26)+ce(a,e+28)},xt=function(a,e,t){var s=ce(a,e+28),n=ft(a.subarray(e+46,e+46+s),!(ce(a,e+8)&2048)),r=e+46+s,o=ie(a,e+20),i=t&&o==4294967295?gt(a,r):[o,ie(a,e+24),ie(a,e+42)],u=i[0],y=i[1],m=i[2];return[ce(a,e+10),u,y,n,r+ce(a,e+30)+ce(a,e+32),m]},gt=function(a,e){for(;ce(a,e)!=1;e+=4+ce(a,e+2));return[Ee(a,e+12),Ee(a,e+4),Ee(a,e+20)]};function yt(a,e){for(var t={},s=a.length-22;ie(a,s)!=101010256;--s)(!s||a.length-s>65558)&&ae(13);var n=ce(a,s+8);if(!n)return{};var r=ie(a,s+16),o=r==4294967295||n==65535;if(o){var i=ie(a,s-12);o=ie(a,i)==101075792,o&&(n=ie(a,i+32),r=ie(a,i+48))}for(var u=0;u<n;++u){var y=xt(a,r,o),m=y[0],c=y[1],h=y[2],d=y[3],w=y[4],A=y[5],b=pt(a,A);r=w,m?m==8?t[d]=ut(a.subarray(b,b+c),{out:new se(h)}):ae(14,"unknown compression type "+m):t[d]=De(a,b,b+c)}return t}const ke=a=>typeof a=="number"&&Number.isFinite(a),me=(a,e)=>{const t=a[e];if(typeof t!="object"||t===null)throw new Error(`Invalid SOG metadata section: ${e}`);return t},de=(a,e)=>{const t=a.files;if(!Array.isArray(t))throw new Error(`${e}.files is not an array`);if(!t.every(s=>typeof s=="string"))throw new Error(`${e}.files contains non-strings`);return t},Fe=(a,e)=>{const t=a.mins,s=a.maxs;if(!Array.isArray(t)||t.length!==3)throw new Error(`${e}.mins must be length-3`);if(!Array.isArray(s)||s.length!==3)throw new Error(`${e}.maxs must be length-3`);if(![...t,...s].every(ke))throw new Error(`${e}.mins/maxs must be finite numbers`);return{mins:[t[0],t[1],t[2]],maxs:[s[0],s[1],s[2]]}},wt=(a,e)=>{const t=a.mins,s=a.maxs;if(!Array.isArray(t)||t.length!==4)throw new Error(`${e}.mins must be length-4`);if(!Array.isArray(s)||s.length!==4)throw new Error(`${e}.maxs must be length-4`);if(![...t,...s].every(ke))throw new Error(`${e}.mins/maxs must be finite numbers`);return{mins:[t[0],t[1],t[2],t[3]],maxs:[s[0],s[1],s[2],s[3]]}},He=(a,e)=>{const t=a.codebook;if(!Array.isArray(t))throw new Error(`${e}.codebook is not an array`);if(!t.every(ke))throw new Error(`${e}.codebook contains non-finite numbers`);return t},Ye=a=>{if(typeof a!="object"||a===null)throw new Error("Invalid SOG metadata: not an object");const e=a,t=e.version??1;if(t!==1&&t!==2)throw new Error(`Unsupported SOG version: ${String(t)}`);if(t===1){const m=me(e,"means"),c=me(e,"sh0"),h=me(e,"quats"),d=me(e,"scales"),w=typeof e.count=="number"&&Number.isFinite(e.count)?e.count:void 0,A=Array.isArray(m.shape)?m.shape:void 0,b=A&&typeof A[0]=="number"?A[0]:void 0;if(w===void 0&&b===void 0)throw new Error("Invalid SOGS metadata: unable to determine splat count");if(w!==void 0&&b!==void 0&&w!==b)throw new Error("Inconsistent SOGS metadata: count does not match means.shape[0]");return{version:1,numSplats:(w??b)|0,files:{sh0:de(c,"sh0"),means:de(m,"means"),quats:de(h,"quats"),scales:de(d,"scales")},ranges:{sh0:wt(c,"sh0"),means:Fe(m,"means"),scales:Fe(d,"scales")}}}const s=e.count;if(!ke(s))throw new Error('Invalid SOG v2 metadata: missing/invalid "count"');const n=s|0,r=me(e,"means"),o=me(e,"sh0"),i=me(e,"quats"),u=me(e,"scales");return{version:2,numSplats:n,files:{sh0:de(o,"sh0"),means:de(r,"means"),quats:de(i,"quats"),scales:de(u,"scales")},ranges:{means:Fe(r,"means"),sh0:{codebook:He(o,"sh0")},scales:{codebook:He(u,"scales")}},antialias:typeof e.antialias=="boolean"?e.antialias:void 0}};class vt extends l.Loader{constructor(e,t){super(e),this.withCredentials=(t==null?void 0:t.withCredentials)??!1}isZipBuffer(e){if(e.byteLength<4)return!1;const t=new Uint8Array(e,0,4);return t[0]===80&&t[1]===75&&t[2]===3&&t[3]===4}load(e,t,s,n){const r=new l.FileLoader(this.manager);r.setResponseType("arraybuffer"),r.setRequestHeader(this.requestHeader),r.setPath(this.path),r.setWithCredentials(this.withCredentials),r.load(e,o=>{this.parseAsync(e,o).then(i=>{t&&t(i)}).catch(i=>{this.manager.itemError(e),n&&n(i),console.error("Error loading SOGS meta:",i)})},s,n)}loadAsync(e,t){return new Promise((s,n)=>{const r=new l.FileLoader(this.manager);r.setResponseType("arraybuffer"),r.setRequestHeader(this.requestHeader),r.setPath(this.path),r.setWithCredentials(this.withCredentials),r.load(e,o=>{this.parseAsync(e,o).then(s).catch(i=>{n(i),this.manager.itemError(e)})},t,o=>{n(o),this.manager.itemError(e)})})}async parseAsync(e,t){if(!(t instanceof ArrayBuffer))throw new Error("SOGS loader: expected ArrayBuffer payload");if(this.isZipBuffer(t))return this.parseZipAsync(t);const n=new TextDecoder("utf-8").decode(t),r=JSON.parse(n);return this.parseMetaAsync(e,r)}async parseMetaAsync(e,t){const s=Ye(t),{numSplats:n,files:r,ranges:o,version:i}=s,u=new l.TextureLoader(this.manager);u.setPath(this.path),u.setRequestHeader(this.requestHeader),u.setWithCredentials(this.withCredentials);const y=(F,O)=>{try{return new URL(O,F).toString()}catch{return F.substring(0,F.lastIndexOf("/")+1)+O}},m=(F,O)=>{const V=y(e,F);return new Promise((k,M)=>{u.load(V,B=>{B.generateMipmaps=!1,B.magFilter=l.NearestFilter,B.minFilter=l.NearestFilter,B.flipY=!1,k(B)},void 0,B=>{const S=B instanceof Error?B.message:String(B);M(new Error(`SOGS loader: failed to load ${O} (${F}): ${S}`))})})};if(!Array.isArray(r.sh0)||r.sh0.length<1)throw new Error("SOGS loader: files.sh0 must have at least 1 entry (sh0)");if(!Array.isArray(r.means)||r.means.length<2)throw new Error("SOGS loader: files.means must have at least 2 entries (means_l, means_u)");if(!Array.isArray(r.quats)||r.quats.length<1)throw new Error("SOGS loader: files.quats must have at least 1 entry");if(!Array.isArray(r.scales)||r.scales.length<1)throw new Error("SOGS loader: files.scales must have at least 1 entry");const[c,h,d,w,A]=await Promise.all([m(r.means[0],"means_l"),m(r.means[1],"means_u"),m(r.quats[0],"quats"),m(r.scales[0],"scales"),m(r.sh0[0],"sh0")]),b={means_l:c,means_u:h,quats:d,scales:w,sh0:A};if(i===1){const F=new _e(n,o,b),O=Me.packSogs(F);return F.dispose(),O}const z=new Te(n,o,b),_=Me.packSog2(z);return z.dispose(),_}async parseZipAsync(e){const t=yt(new Uint8Array(e)),s=Object.keys(t),n=s.find(g=>g.toLowerCase().endsWith("meta.json"))??null;if(!n)throw new Error("SOGS loader: zip missing meta.json");const r=n.includes("/")?n.slice(0,n.lastIndexOf("/")+1):"",o=new TextDecoder,i=JSON.parse(o.decode(t[n])),u=Ye(i),{numSplats:y,files:m,ranges:c,version:h}=u,d=g=>g.replace(/\\/g,"/").replace(/^\.?\//,""),w=g=>{const v=d(g),U=[d(r+v),v];for(const P of U){const f=t[P];if(f)return f}const T=v.split("/").pop(),I=s.find(P=>d(P).endsWith("/"+v))??s.find(P=>d(P).endsWith("/"+T))??s.find(P=>d(P)===T)??null;if(I)return t[I];throw new Error(`SOGS loader: zip missing file "${g}"`)},A=g=>{const v=g.toLowerCase();return v.endsWith(".png")?"image/png":v.endsWith(".jpg")||v.endsWith(".jpeg")?"image/jpeg":v.endsWith(".webp")?"image/webp":"application/octet-stream"},b=new l.TextureLoader(this.manager);b.setRequestHeader(this.requestHeader),b.setWithCredentials(this.withCredentials);const z=(g,v)=>{const U=w(g),T=new Blob([U],{type:A(g)}),I=URL.createObjectURL(T);return new Promise((P,f)=>{b.load(I,C=>{URL.revokeObjectURL(I),C.generateMipmaps=!1,C.magFilter=l.NearestFilter,C.minFilter=l.NearestFilter,C.flipY=!1,P(C)},void 0,C=>{URL.revokeObjectURL(I);const Y=C instanceof Error?C.message:String(C);f(new Error(`SOGS loader: failed to load ${v} from zip (${g}): ${Y}`))})})};if(!Array.isArray(m.sh0)||m.sh0.length<1)throw new Error("SOGS loader: files.sh0 must have at least 1 entry (sh0)");if(!Array.isArray(m.means)||m.means.length<2)throw new Error("SOGS loader: files.means must have at least 2 entries (means_l, means_u)");if(!Array.isArray(m.quats)||m.quats.length<1)throw new Error("SOGS loader: files.quats must have at least 1 entry");if(!Array.isArray(m.scales)||m.scales.length<1)throw new Error("SOGS loader: files.scales must have at least 1 entry");const[_,F,O,V,k]=await Promise.all([z(m.means[0],"means_l"),z(m.means[1],"means_u"),z(m.quats[0],"quats"),z(m.scales[0],"scales"),z(m.sh0[0],"sh0")]),M={means_l:_,means_u:F,quats:O,scales:V,sh0:k};if(h===1){const g=new _e(y,c,M),v=Me.packSogs(g);return g.dispose(),v}const B=new Te(y,c,M),S=Me.packSog2(B);return B.dispose(),S}}const Mt="0.3.0";H.BoundingBox=ge,H.PlyLoader=Ke,H.SogsLoader=vt,H.SplatData=Ae,H.SplatMaterial=Oe,H.SplatMesh=Ie,H.SplatSorter=Ve,H.TextureManager=Ue,H.VERSION=Mt,Object.defineProperty(H,Symbol.toStringTag,{value:"Module"})});
326
+ `;for(let z=0;z<o.length;z++)if(i[z]!==o[z])throw new Error("Invalid PLY file: Missing magic bytes");let y=0;for(let z=0;z<i.length-u.length;z++){let g=!0;for(let E=0;E<u.length;E++)if(i[z+E]!==u.charCodeAt(E)){g=!1;break}if(g){y=z+u.length;break}}if(y===0)throw new Error("Invalid PLY file: Could not find end of header");const l=r.decode(i.subarray(0,y)).split(`
327
+ `),h=[];let f=null;for(let z=1;z<l.length;z++){const g=l[z].trim();if(g===""||g==="end_header")continue;const E=g.split(" ");switch(E[0]){case"format":f=E[1];break;case"element":h.push({name:E[1],count:parseInt(E[2],10),properties:[]});break;case"property":if(h.length===0)throw new Error("Invalid PLY file: Property without element");h[h.length-1].properties.push({type:E[1],name:E[2]});break}}if(f!=="binary_little_endian")throw new Error(`Unsupported PLY format: ${f}`);const w=h.find(z=>z.name==="vertex");if(!w)throw new Error("Invalid PLY file: No vertex element found");const A=w.count,b=new Float32Array(A*3),B=new Float32Array(A*4),F=new Float32Array(A*3),P=new Float32Array(A*3),U=new Float32Array(A),O=new DataView(n);let C=y;const M=z=>w.properties.findIndex(g=>g.name===z),k=M("x"),S=M("y"),x=M("z"),v=[M("rot_0"),M("rot_1"),M("rot_2"),M("rot_3")],R=[M("scale_0"),M("scale_1"),M("scale_2")],V=[M("f_dc_0"),M("f_dc_1"),M("f_dc_2")],I=M("opacity");if([k,S,x,...v,...R,...V,I].some(z=>z===-1))throw new Error("Invalid PLY file: Missing required properties");const p=.28209479177387814,_=z=>{if(z>0)return 1/(1+Math.exp(-z));const g=Math.exp(z);return g/(1+g)};let Y=1/0,W=1/0,T=1/0,K=-1/0,X=-1/0,Z=-1/0;for(let z=0;z<A;z++){const g=[];for(let Fe=0;Fe<w.properties.length;Fe++){const et=w.properties[Fe].type;let he;switch(et){case"char":he=O.getInt8(C),C+=1;break;case"uchar":he=O.getUint8(C),C+=1;break;case"short":he=O.getInt16(C,!0),C+=2;break;case"ushort":he=O.getUint16(C,!0),C+=2;break;case"int":he=O.getInt32(C,!0),C+=4;break;case"uint":he=O.getUint32(C,!0),C+=4;break;case"float":he=O.getFloat32(C,!0),C+=4;break;case"double":he=O.getFloat64(C,!0),C+=8;break;default:throw new Error(`Unsupported property type: ${et}`)}g.push(he)}const E=g[k],L=g[S],D=g[x],G=z*3;b[G]=E,b[G+1]=L,b[G+2]=D,Y=Math.min(Y,E),W=Math.min(W,L),T=Math.min(T,D),K=Math.max(K,E),X=Math.max(X,L),Z=Math.max(Z,D);let Q=g[v[1]],H=g[v[2]],J=g[v[3]],$=g[v[0]];const ee=Math.sqrt(Q*Q+H*H+J*J+$*$);ee>0&&(Q/=ee,H/=ee,J/=ee,$/=ee),$<0&&(Q=-Q,H=-H,J=-J,$=-$);const ne=z*4;B[ne]=Q,B[ne+1]=H,B[ne+2]=J,B[ne+3]=$;const ae=z*3;F[ae]=g[R[0]],F[ae+1]=g[R[1]],F[ae+2]=g[R[2]];let fe=.5+g[V[0]]*p,pe=.5+g[V[1]]*p,le=.5+g[V[2]]*p;fe=Math.max(0,Math.min(1,fe)),pe=Math.max(0,Math.min(1,pe)),le=Math.max(0,Math.min(1,le));const Te=z*3;P[Te]=fe,P[Te+1]=pe,P[Te+2]=le,U[z]=_(g[I])}return{numSplats:A,positions:b.buffer,rotations:B.buffer,scales:F.buffer,colors:P.buffer,opacities:U.buffer,boundingBox:{minX:Y,minY:W,minZ:T,maxX:K,maxY:X,maxZ:Z}}}}).toString()})();`}}var se=Uint8Array,we=Uint16Array,rt=Int32Array,$e=new se([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),He=new se([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),it=new se([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Ye=function(a,e){for(var t=new we(31),s=0;s<31;++s)t[s]=e+=1<<a[s-1];for(var n=new rt(t[30]),s=1;s<30;++s)for(var r=t[s];r<t[s+1];++r)n[r]=r-t[s]<<5|s;return{b:t,r:n}},Ze=Ye($e,2),Xe=Ze.b,ot=Ze.r;Xe[28]=258,ot[258]=28;for(var ct=Ye(He,0),lt=ct.b,ke=new we(32768),N=0;N<32768;++N){var ue=(N&43690)>>1|(N&21845)<<1;ue=(ue&52428)>>2|(ue&13107)<<2,ue=(ue&61680)>>4|(ue&3855)<<4,ke[N]=((ue&65280)>>8|(ue&255)<<8)>>1}for(var be=function(a,e,t){for(var s=a.length,n=0,r=new we(e);n<s;++n)a[n]&&++r[a[n]-1];var i=new we(e);for(n=1;n<e;++n)i[n]=i[n-1]+r[n-1]<<1;var o;if(t){o=new we(1<<e);var u=15-e;for(n=0;n<s;++n)if(a[n])for(var y=n<<4|a[n],m=e-a[n],l=i[a[n]-1]++<<m,h=l|(1<<m)-1;l<=h;++l)o[ke[l]>>u]=y}else for(o=new we(s),n=0;n<s;++n)a[n]&&(o[n]=ke[i[a[n]-1]++]>>15-a[n]);return o},Se=new se(288),N=0;N<144;++N)Se[N]=8;for(var N=144;N<256;++N)Se[N]=9;for(var N=256;N<280;++N)Se[N]=7;for(var N=280;N<288;++N)Se[N]=8;for(var Qe=new se(32),N=0;N<32;++N)Qe[N]=5;var ht=be(Se,9,1),ut=be(Qe,5,1),Be=function(a){for(var e=a[0],t=1;t<a.length;++t)a[t]>e&&(e=a[t]);return e},ie=function(a,e,t){var s=e/8|0;return(a[s]|a[s+1]<<8)>>(e&7)&t},ze=function(a,e){var t=e/8|0;return(a[t]|a[t+1]<<8|a[t+2]<<16)>>(e&7)},mt=function(a){return(a+7)/8|0},Ee=function(a,e,t){return(e==null||e<0)&&(e=0),(t==null||t>a.length)&&(t=a.length),new se(a.subarray(e,t))},dt=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],re=function(a,e,t){var s=new Error(e||dt[a]);if(s.code=a,Error.captureStackTrace&&Error.captureStackTrace(s,re),!t)throw s;return s},ft=function(a,e,t,s){var n=a.length,r=s?s.length:0;if(!n||e.f&&!e.l)return t||new se(0);var i=!t,o=i||e.i!=2,u=e.i;i&&(t=new se(n*3));var y=function(H){var J=t.length;if(H>J){var $=new se(Math.max(J*2,H));$.set(t),t=$}},m=e.f||0,l=e.p||0,h=e.b||0,f=e.l,w=e.d,A=e.m,b=e.n,B=n*8;do{if(!f){m=ie(a,l,1);var F=ie(a,l+1,3);if(l+=3,F)if(F==1)f=ht,w=ut,A=9,b=5;else if(F==2){var C=ie(a,l,31)+257,M=ie(a,l+10,15)+4,k=C+ie(a,l+5,31)+1;l+=14;for(var S=new se(k),x=new se(19),v=0;v<M;++v)x[it[v]]=ie(a,l+v*3,7);l+=M*3;for(var R=Be(x),V=(1<<R)-1,I=be(x,R,1),v=0;v<k;){var q=I[ie(a,l,V)];l+=q&15;var P=q>>4;if(P<16)S[v++]=P;else{var p=0,_=0;for(P==16?(_=3+ie(a,l,3),l+=2,p=S[v-1]):P==17?(_=3+ie(a,l,7),l+=3):P==18&&(_=11+ie(a,l,127),l+=7);_--;)S[v++]=p}}var Y=S.subarray(0,C),W=S.subarray(C);A=Be(Y),b=Be(W),f=be(Y,A,1),w=be(W,b,1)}else re(1);else{var P=mt(l)+4,U=a[P-4]|a[P-3]<<8,O=P+U;if(O>n){u&&re(0);break}o&&y(h+U),t.set(a.subarray(P,O),h),e.b=h+=U,e.p=l=O*8,e.f=m;continue}if(l>B){u&&re(0);break}}o&&y(h+131072);for(var T=(1<<A)-1,K=(1<<b)-1,X=l;;X=l){var p=f[ze(a,l)&T],Z=p>>4;if(l+=p&15,l>B){u&&re(0);break}if(p||re(2),Z<256)t[h++]=Z;else if(Z==256){X=l,f=null;break}else{var z=Z-254;if(Z>264){var v=Z-257,g=$e[v];z=ie(a,l,(1<<g)-1)+Xe[v],l+=g}var E=w[ze(a,l)&K],L=E>>4;E||re(3),l+=E&15;var W=lt[L];if(L>3){var g=He[L];W+=ze(a,l)&(1<<g)-1,l+=g}if(l>B){u&&re(0);break}o&&y(h+131072);var D=h+z;if(h<W){var G=r-W,Q=Math.min(W,D);for(G+h<0&&re(3);h<Q;++h)t[h]=s[G+h]}for(;h<D;++h)t[h]=t[h-W]}}e.l=f,e.p=X,e.b=h,e.f=m,f&&(m=1,e.m=A,e.d=w,e.n=b)}while(!m);return h!=t.length&&i?Ee(t,0,h):t.subarray(0,h)},pt=new se(0),ce=function(a,e){return a[e]|a[e+1]<<8},oe=function(a,e){return(a[e]|a[e+1]<<8|a[e+2]<<16|a[e+3]<<24)>>>0},De=function(a,e){return oe(a,e)+oe(a,e+4)*4294967296};function gt(a,e){return ft(a,{i:2},e&&e.out,e&&e.dictionary)}var Pe=typeof TextDecoder<"u"&&new TextDecoder,xt=0;try{Pe.decode(pt,{stream:!0}),xt=1}catch{}var yt=function(a){for(var e="",t=0;;){var s=a[t++],n=(s>127)+(s>223)+(s>239);if(t+n>a.length)return{s:e,r:Ee(a,t-1)};n?n==3?(s=((s&15)<<18|(a[t++]&63)<<12|(a[t++]&63)<<6|a[t++]&63)-65536,e+=String.fromCharCode(55296|s>>10,56320|s&1023)):n&1?e+=String.fromCharCode((s&31)<<6|a[t++]&63):e+=String.fromCharCode((s&15)<<12|(a[t++]&63)<<6|a[t++]&63):e+=String.fromCharCode(s)}};function wt(a,e){if(e){for(var t="",s=0;s<a.length;s+=16384)t+=String.fromCharCode.apply(null,a.subarray(s,s+16384));return t}else{if(Pe)return Pe.decode(a);var n=yt(a),r=n.s,t=n.r;return t.length&&re(8),r}}var vt=function(a,e){return e+30+ce(a,e+26)+ce(a,e+28)},Mt=function(a,e,t){var s=ce(a,e+28),n=wt(a.subarray(e+46,e+46+s),!(ce(a,e+8)&2048)),r=e+46+s,i=oe(a,e+20),o=t&&i==4294967295?bt(a,r):[i,oe(a,e+24),oe(a,e+42)],u=o[0],y=o[1],m=o[2];return[ce(a,e+10),u,y,n,r+ce(a,e+30)+ce(a,e+32),m]},bt=function(a,e){for(;ce(a,e)!=1;e+=4+ce(a,e+2));return[De(a,e+12),De(a,e+4),De(a,e+20)]};function St(a,e){for(var t={},s=a.length-22;oe(a,s)!=101010256;--s)(!s||a.length-s>65558)&&re(13);var n=ce(a,s+8);if(!n)return{};var r=oe(a,s+16),i=r==4294967295||n==65535;if(i){var o=oe(a,s-12);i=oe(a,o)==101075792,i&&(n=oe(a,o+32),r=oe(a,o+48))}for(var u=0;u<n;++u){var y=Mt(a,r,i),m=y[0],l=y[1],h=y[2],f=y[3],w=y[4],A=y[5],b=vt(a,A);r=w,m?m==8?t[f]=gt(a.subarray(b,b+l),{out:new se(h)}):re(14,"unknown compression type "+m):t[f]=Ee(a,b,b+l)}return t}const Ce=a=>typeof a=="number"&&Number.isFinite(a),me=(a,e)=>{const t=a[e];if(typeof t!="object"||t===null)throw new Error(`Invalid SOG metadata section: ${e}`);return t},de=(a,e)=>{const t=a.files;if(!Array.isArray(t))throw new Error(`${e}.files is not an array`);if(!t.every(s=>typeof s=="string"))throw new Error(`${e}.files contains non-strings`);return t},qe=(a,e)=>{const t=a.mins,s=a.maxs;if(!Array.isArray(t)||t.length!==3)throw new Error(`${e}.mins must be length-3`);if(!Array.isArray(s)||s.length!==3)throw new Error(`${e}.maxs must be length-3`);if(![...t,...s].every(Ce))throw new Error(`${e}.mins/maxs must be finite numbers`);return{mins:[t[0],t[1],t[2]],maxs:[s[0],s[1],s[2]]}},At=(a,e)=>{const t=a.mins,s=a.maxs;if(!Array.isArray(t)||t.length!==4)throw new Error(`${e}.mins must be length-4`);if(!Array.isArray(s)||s.length!==4)throw new Error(`${e}.maxs must be length-4`);if(![...t,...s].every(Ce))throw new Error(`${e}.mins/maxs must be finite numbers`);return{mins:[t[0],t[1],t[2],t[3]],maxs:[s[0],s[1],s[2],s[3]]}},Je=(a,e)=>{const t=a.codebook;if(!Array.isArray(t))throw new Error(`${e}.codebook is not an array`);if(!t.every(Ce))throw new Error(`${e}.codebook contains non-finite numbers`);return t},Ke=a=>{if(typeof a!="object"||a===null)throw new Error("Invalid SOG metadata: not an object");const e=a,t=e.version??1;if(t!==1&&t!==2)throw new Error(`Unsupported SOG version: ${String(t)}`);if(t===1){const m=me(e,"means"),l=me(e,"sh0"),h=me(e,"quats"),f=me(e,"scales"),w=typeof e.count=="number"&&Number.isFinite(e.count)?e.count:void 0,A=Array.isArray(m.shape)?m.shape:void 0,b=A&&typeof A[0]=="number"?A[0]:void 0;if(w===void 0&&b===void 0)throw new Error("Invalid SOGS metadata: unable to determine splat count");if(w!==void 0&&b!==void 0&&w!==b)throw new Error("Inconsistent SOGS metadata: count does not match means.shape[0]");return{version:1,numSplats:(w??b)|0,files:{sh0:de(l,"sh0"),means:de(m,"means"),quats:de(h,"quats"),scales:de(f,"scales")},ranges:{sh0:At(l,"sh0"),means:qe(m,"means"),scales:qe(f,"scales")}}}const s=e.count;if(!Ce(s))throw new Error('Invalid SOG v2 metadata: missing/invalid "count"');const n=s|0,r=me(e,"means"),i=me(e,"sh0"),o=me(e,"quats"),u=me(e,"scales");return{version:2,numSplats:n,files:{sh0:de(i,"sh0"),means:de(r,"means"),quats:de(o,"quats"),scales:de(u,"scales")},ranges:{means:qe(r,"means"),sh0:{codebook:Je(i,"sh0")},scales:{codebook:Je(u,"scales")}},antialias:typeof e.antialias=="boolean"?e.antialias:void 0}};class Ct extends c.Loader{constructor(e,t){super(e),this.withCredentials=(t==null?void 0:t.withCredentials)??!1}isZipBuffer(e){if(e.byteLength<4)return!1;const t=new Uint8Array(e,0,4);return t[0]===80&&t[1]===75&&t[2]===3&&t[3]===4}load(e,t,s,n){const r=new c.FileLoader(this.manager);r.setResponseType("arraybuffer"),r.setRequestHeader(this.requestHeader),r.setPath(this.path),r.setWithCredentials(this.withCredentials),r.load(e,i=>{this.parseAsync(e,i).then(o=>{t&&t(o)}).catch(o=>{this.manager.itemError(e),n&&n(o),console.error("Error loading SOGS meta:",o)})},s,n)}loadAsync(e,t){return new Promise((s,n)=>{const r=new c.FileLoader(this.manager);r.setResponseType("arraybuffer"),r.setRequestHeader(this.requestHeader),r.setPath(this.path),r.setWithCredentials(this.withCredentials),r.load(e,i=>{this.parseAsync(e,i).then(s).catch(o=>{n(o),this.manager.itemError(e)})},t,i=>{n(i),this.manager.itemError(e)})})}async parseAsync(e,t){if(!(t instanceof ArrayBuffer))throw new Error("SOGS loader: expected ArrayBuffer payload");if(this.isZipBuffer(t))return this.parseZipAsync(t);const n=new TextDecoder("utf-8").decode(t),r=JSON.parse(n);return this.parseMetaAsync(e,r)}async parseMetaAsync(e,t){const s=Ke(t),{numSplats:n,files:r,ranges:i,version:o}=s,u=new c.TextureLoader(this.manager);u.setPath(this.path),u.setRequestHeader(this.requestHeader),u.setWithCredentials(this.withCredentials);const y=(P,U)=>{try{return new URL(U,P).toString()}catch{return P.substring(0,P.lastIndexOf("/")+1)+U}},m=(P,U)=>{const O=y(e,P);return new Promise((C,M)=>{u.load(O,k=>{k.generateMipmaps=!1,k.magFilter=c.NearestFilter,k.minFilter=c.NearestFilter,k.flipY=!1,C(k)},void 0,k=>{const S=k instanceof Error?k.message:String(k);M(new Error(`SOGS loader: failed to load ${U} (${P}): ${S}`))})})};if(!Array.isArray(r.sh0)||r.sh0.length<1)throw new Error("SOGS loader: files.sh0 must have at least 1 entry (sh0)");if(!Array.isArray(r.means)||r.means.length<2)throw new Error("SOGS loader: files.means must have at least 2 entries (means_l, means_u)");if(!Array.isArray(r.quats)||r.quats.length<1)throw new Error("SOGS loader: files.quats must have at least 1 entry");if(!Array.isArray(r.scales)||r.scales.length<1)throw new Error("SOGS loader: files.scales must have at least 1 entry");const[l,h,f,w,A]=await Promise.all([m(r.means[0],"means_l"),m(r.means[1],"means_u"),m(r.quats[0],"quats"),m(r.scales[0],"scales"),m(r.sh0[0],"sh0")]),b={means_l:l,means_u:h,quats:f,scales:w,sh0:A};if(o===1){const P=new Ve(n,i,b),U=Me.packSogs(P);return P.dispose(),U}const B=new Oe(n,i,b),F=Me.packSog2(B);return B.dispose(),F}async parseZipAsync(e){const t=St(new Uint8Array(e)),s=Object.keys(t),n=s.find(x=>x.toLowerCase().endsWith("meta.json"))??null;if(!n)throw new Error("SOGS loader: zip missing meta.json");const r=n.includes("/")?n.slice(0,n.lastIndexOf("/")+1):"",i=new TextDecoder,o=JSON.parse(i.decode(t[n])),u=Ke(o),{numSplats:y,files:m,ranges:l,version:h}=u,f=x=>x.replace(/\\/g,"/").replace(/^\.?\//,""),w=x=>{const v=f(x),R=[f(r+v),v];for(const q of R){const p=t[q];if(p)return p}const V=v.split("/").pop(),I=s.find(q=>f(q).endsWith("/"+v))??s.find(q=>f(q).endsWith("/"+V))??s.find(q=>f(q)===V)??null;if(I)return t[I];throw new Error(`SOGS loader: zip missing file "${x}"`)},A=x=>{const v=x.toLowerCase();return v.endsWith(".png")?"image/png":v.endsWith(".jpg")||v.endsWith(".jpeg")?"image/jpeg":v.endsWith(".webp")?"image/webp":"application/octet-stream"},b=new c.TextureLoader(this.manager);b.setRequestHeader(this.requestHeader),b.setWithCredentials(this.withCredentials);const B=(x,v)=>{const R=w(x),V=new Blob([R],{type:A(x)}),I=URL.createObjectURL(V);return new Promise((q,p)=>{b.load(I,_=>{URL.revokeObjectURL(I),_.generateMipmaps=!1,_.magFilter=c.NearestFilter,_.minFilter=c.NearestFilter,_.flipY=!1,q(_)},void 0,_=>{URL.revokeObjectURL(I);const Y=_ instanceof Error?_.message:String(_);p(new Error(`SOGS loader: failed to load ${v} from zip (${x}): ${Y}`))})})};if(!Array.isArray(m.sh0)||m.sh0.length<1)throw new Error("SOGS loader: files.sh0 must have at least 1 entry (sh0)");if(!Array.isArray(m.means)||m.means.length<2)throw new Error("SOGS loader: files.means must have at least 2 entries (means_l, means_u)");if(!Array.isArray(m.quats)||m.quats.length<1)throw new Error("SOGS loader: files.quats must have at least 1 entry");if(!Array.isArray(m.scales)||m.scales.length<1)throw new Error("SOGS loader: files.scales must have at least 1 entry");const[F,P,U,O,C]=await Promise.all([B(m.means[0],"means_l"),B(m.means[1],"means_u"),B(m.quats[0],"quats"),B(m.scales[0],"scales"),B(m.sh0[0],"sh0")]),M={means_l:F,means_u:P,quats:U,scales:O,sh0:C};if(h===1){const x=new Ve(y,l,M),v=Me.packSogs(x);return x.dispose(),v}const k=new Oe(y,l,M),S=Me.packSog2(k);return k.dispose(),S}}const It="0.3.0";j.AnimationController=Ge,j.BoundingBox=xe,j.PlyLoader=at,j.SogsLoader=Ct,j.SplatData=Ae,j.SplatMaterial=je,j.SplatMesh=_e,j.SplatSorter=Re,j.TextureManager=We,j.VERSION=It,j.getEffect=Ie,Object.defineProperty(j,Symbol.toStringTag,{value:"Module"})});
package/dist/react.d.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  import type { FC } from 'react';
2
2
  import type { ThreeElements } from '@react-three/fiber';
3
- import type { PlyLoader, SplatMesh, SplatMeshOptions } from '@speridlabs/visus';
3
+ import type {
4
+ PlyLoader,
5
+ SplatMesh,
6
+ SplatMeshOptions,
7
+ AnimationOptions,
8
+ } from '@speridlabs/visus';
4
9
 
5
10
  export type SplatFileType = 'ply' | 'sogs';
6
11
 
@@ -14,6 +19,8 @@ export interface SplatProps extends Omit<ThreeElements['mesh'], 'args'> {
14
19
  type?: SplatFileType;
15
20
  /** Options passed to the underlying SplatMesh */
16
21
  splatOptions?: SplatMeshOptions;
22
+ /** Animation configuration */
23
+ animation?: AnimationOptions;
17
24
  /** Whether to send credentials with the request (default: false) */
18
25
  withCredentials?: boolean;
19
26
  debug?: boolean;