@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 3.14 kB
JavaScript
import{EventHandler as e}from"../../core/event-handler.js";import{TEXTURELOCK_READ as t}from"../../platform/graphics/constants.js";function r(){let e,t,r,a,s,o=!1;const n={x:0,y:0,z:0},i={x:0,y:0,z:0},c={x:0,y:0,z:0},h={x:0,y:0,z:0};let l,f;self.onmessage=d=>{if(d.data.order&&(e=new Uint32Array(d.data.order)),d.data.centers){t=new Float32Array(d.data.centers),c.x=h.x=t[0],c.y=h.y=t[1],c.z=h.z=t[2];const e=t.length/3;for(let r=1;r<e;++r){const e=t[3*r+0],a=t[3*r+1],s=t[3*r+2];c.x=Math.min(c.x,e),c.y=Math.min(c.y,a),c.z=Math.min(c.z,s),h.x=Math.max(h.x,e),h.y=Math.max(h.y,a),h.z=Math.max(h.z,s)}o=!0}d.data.hasOwnProperty("mapping")&&(r=d.data.mapping?new Uint32Array(d.data.mapping):null,o=!0),d.data.cameraPosition&&(a=d.data.cameraPosition),d.data.cameraDirection&&(s=d.data.cameraDirection),(()=>{var d;if(!(e&&t&&0!==t.length&&a&&s))return;const u=a.x,x=a.y,m=a.z,y=s.x,p=s.y,M=s.z,g=.001;if(!o&&Math.abs(u-n.x)<g&&Math.abs(x-n.y)<g&&Math.abs(m-n.z)<g&&Math.abs(y-i.x)<g&&Math.abs(p-i.y)<g&&Math.abs(M-i.z)<g)return;let z,b;o=!1,n.x=u,n.y=x,n.z=m,i.x=y,i.y=p,i.z=M;for(let e=0;e<8;++e){const t=((1&e?c.x:h.x)-u)*y+((2&e?c.y:h.y)-x)*p+((4&e?c.z:h.z)-m)*M;0===e?z=b=t:(z=Math.min(z,t),b=Math.max(b,t))}const w=t.length/3,k=Math.max(10,Math.min(20,Math.round(Math.log2(w/4)))),v=2**k+1;(null==(d=l)?void 0:d.length)!==w&&(l=new Uint32Array(w)),f&&f.length===v?f.fill(0):f=new Uint32Array(v);const A=b-z,T=A<1e-6?0:1/A*2**k;for(let e=0;e<w;++e){const r=3*e,a=(t[r+0]-u)*y+(t[r+1]-x)*p+(t[r+2]-m)*M,s=Math.floor((a-z)*T);l[e]=s,f[s]++}for(let e=1;e<v;e++)f[e]+=f[e-1];for(let t=0;t<w;t++){const r=l[t],a=--f[r];e[a]=t}const U=t=>l[e[t]]/T+z,j=U(w-1)>=0?(()=>{const e=((e,t,r)=>{for(;e<=t;){const a=t+e>>1,s=r(a);if(s>0)e=a+1;else{if(!(s<0))return a;t=a-1}}return~e})(0,w-1,(e=>-U(e)));return Math.min(w,Math.abs(e))})():w;if(r)for(let t=0;t<w;++t)e[t]=r[e[t]];self.postMessage({order:e.buffer,count:j},[e.buffer]),e=null})()}}class a extends e{constructor(){super(),this.worker=void 0,this.orderTexture=void 0,this.centers=void 0,this.worker=new Worker(URL.createObjectURL(new Blob([`(${r.toString()})()`],{type:"application/javascript"}))),this.worker.onmessage=e=>{const t=e.data.order,r=this.orderTexture._levels[0].buffer;this.worker.postMessage({order:r},[r]),this.orderTexture._levels[0]=new Uint32Array(t),this.orderTexture.upload(),this.fire("updated",e.data.count)}}destroy(){this.worker.terminate(),this.worker=null}init(e,r){this.orderTexture=e,this.centers=r.slice();const a=this.orderTexture.lock({mode:t}).buffer.slice();this.orderTexture.unlock(),this.worker.postMessage({order:a,centers:r.buffer},[a,r.buffer])}setMapping(e){if(e){const t=new Float32Array(3*e.length);for(let r=0;r<e.length;++r){const a=3*e[r],s=3*r;t[s+0]=this.centers[a+0],t[s+1]=this.centers[a+1],t[s+2]=this.centers[a+2]}this.worker.postMessage({centers:t.buffer,mapping:e.buffer},[t.buffer,e.buffer])}else{const e=this.centers.slice();this.worker.postMessage({centers:e.buffer,mapping:null},[e.buffer])}}setCamera(e,t){this.worker.postMessage({cameraPosition:{x:e.x,y:e.y,z:e.z},cameraDirection:{x:t.x,y:t.y,z:t.z}})}}export{a as GSplatSorter};