@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 5.53 kB
JavaScript
import{extends as t}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{FloatPacking as e}from"../../core/math/float-packing.js";import{Quat as r}from"../../core/math/quat.js";import{Vec2 as s}from"../../core/math/vec2.js";import{Vec3 as o}from"../../core/math/vec3.js";import{Mat3 as a}from"../../core/math/mat3.js";import{PIXELFORMAT_RGBA8 as h,PIXELFORMAT_RGBA32U as i,PIXELFORMAT_RGBA16F as u,FILTER_NEAREST as l,ADDRESS_CLAMP_TO_EDGE as n}from"../../platform/graphics/constants.js";import{Texture as c}from"../../platform/graphics/texture.js";import{BoundingBox as m}from"../../core/shape/bounding-box.js";import{createGSplatMaterial as x}from"./gsplat-material.js";class f{constructor(t,e){this.device=void 0,this.numSplats=void 0,this.centers=void 0,this.aabb=void 0,this.colorTexture=void 0,this.transformATexture=void 0,this.transformBTexture=void 0,this.hasSH=void 0,this.sh1to3Texture=void 0,this.sh4to7Texture=void 0,this.sh8to11Texture=void 0,this.sh12to15Texture=void 0;const r=e.numSplats;this.device=t,this.numSplats=r,this.centers=new Float32Array(3*e.numSplats),e.getCenters(this.centers),this.aabb=new m,e.calcAabb(this.aabb);const s=this.evalTextureSize(r);this.colorTexture=this.createTexture("splatColor",h,s),this.transformATexture=this.createTexture("transformA",i,s),this.transformBTexture=this.createTexture("transformB",u,s),this.updateColorData(e),this.updateTransformData(e),this.hasSH=e.hasSHData,this.hasSH&&(this.sh1to3Texture=this.createTexture("splatSH_1to3",i,s),this.sh4to7Texture=this.createTexture("splatSH_4to7",i,s),this.sh8to11Texture=this.createTexture("splatSH_8to11",i,s),this.sh12to15Texture=this.createTexture("splatSH_12to15",i,s),this.updateSHData(e))}destroy(){var t,e,r,s,o,a,h;null==(t=this.colorTexture)||t.destroy(),null==(e=this.transformATexture)||e.destroy(),null==(r=this.transformBTexture)||r.destroy(),null==(s=this.sh1to3Texture)||s.destroy(),null==(o=this.sh4to7Texture)||o.destroy(),null==(a=this.sh8to11Texture)||a.destroy(),null==(h=this.sh12to15Texture)||h.destroy()}createMaterial(e){const r=x(t({},this.hasSH?{defines:["USE_SH1","USE_SH2","USE_SH3"]}:{},e));return r.setParameter("splatColor",this.colorTexture),r.setParameter("transformA",this.transformATexture),r.setParameter("transformB",this.transformBTexture),r.setParameter("tex_params",new Float32Array([this.numSplats,this.colorTexture.width,0,0])),this.hasSH&&(r.setParameter("splatSH_1to3",this.sh1to3Texture),r.setParameter("splatSH_4to7",this.sh4to7Texture),r.setParameter("splatSH_8to11",this.sh8to11Texture),r.setParameter("splatSH_12to15",this.sh12to15Texture)),r}evalTextureSize(t){const e=Math.ceil(Math.sqrt(t)),r=Math.ceil(t/e);return new s(e,r)}createTexture(t,e,r){return new c(this.device,{name:t,width:r.x,height:r.y,format:e,cubemap:!1,mipmaps:!1,minFilter:l,magFilter:l,addressU:n,addressV:n})}getTextureFormat(t,e){t.isWebGL1&&(e=!1);const r=t.extTextureHalfFloat&&t.textureHalfFloatUpdatable,s=t.extTextureFloat;let o;return e?s?o=!1:r&&(o=!0):r?o=!0:s&&(o=!1),o}updateColorData(t){const e=this.colorTexture;if(!e)return;const r=e.lock(),s=t.getProp("f_dc_0"),o=t.getProp("f_dc_1"),a=t.getProp("f_dc_2"),h=t.getProp("opacity"),i=.28209479177387814;for(let t=0;t<this.numSplats;++t){const e=255*(s[t]*i+.5),u=255*(o[t]*i+.5),l=255*(a[t]*i+.5),n=255/(1+Math.exp(-h[t]));r[4*t+0]=e<0?0:e>255?255:e,r[4*t+1]=u<0?0:u>255?255:u,r[4*t+2]=l<0?0:l>255?255:l,r[4*t+3]=n<0?0:n>255?255:n}e.unlock()}updateTransformData(t){const s=e.float2Half;if(!this.transformATexture)return;const h=this.transformATexture.lock(),i=new Float32Array(h.buffer),u=this.transformBTexture.lock(),l=new o,n=new r,c=new o,m=t.createIter(l,n,c),x=new a,f=new o,p=new o;for(let t=0;t<this.numSplats;t++)m.read(t),n.normalize(),x.setFromQuat(n),this.computeCov3d(x,c,f,p),i[4*t+0]=l.x,i[4*t+1]=l.y,i[4*t+2]=l.z,h[4*t+3]=s(p.x)|s(p.y)<<16,u[4*t+0]=s(f.x),u[4*t+1]=s(f.y),u[4*t+2]=s(f.z),u[4*t+3]=s(p.z);this.transformATexture.unlock(),this.transformBTexture.unlock()}computeCov3d(t,e,r,s){const o=e.x,a=e.y,h=e.z,i=t.data,u=i[0]*o,l=i[1]*o,n=i[2]*o,c=i[3]*a,m=i[4]*a,x=i[5]*a,f=i[6]*h,p=i[7]*h,T=i[8]*h;r.x=u*u+c*c+f*f,r.y=u*l+c*m+f*p,r.z=u*n+c*x+f*T,s.x=l*l+m*m+p*p,s.y=l*n+m*x+p*T,s.z=n*n+x*x+T*T}updateSHData(t){const e=this.sh1to3Texture.lock(),r=this.sh4to7Texture.lock(),s=this.sh8to11Texture.lock(),o=this.sh12to15Texture.lock(),a=(t=>{const e=[];for(let r=0;r<45;++r)e.push(t.getProp(`f_rest_${r}`));return e})(t),h=2047,i=1023,u=(t,e,r)=>{const s=Math.floor(t*h+.5),o=Math.floor(e*i+.5),a=Math.floor(r*h+.5);return(s<0?0:s>h?h:s)<<21|(o<0?0:o>i?i:o)<<11|(a<0?0:a>h?h:a)},l=new Float32Array(1),n=new Uint32Array(l.buffer),c=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(let h=0;h<t.numSplats;++h){for(let t=0;t<45;++t)c[t]=a[t][h];let t=Math.abs(c[0]);for(let e=1;e<45;++e){const r=Math.abs(c[e]);r>t&&(t=r)}if(0!==t){for(let e=0;e<45;++e)c[e]=c[e]/t*.5+.5;l[0]=t,e[4*h+0]=n[0],e[4*h+1]=u(c[0],c[15],c[30]),e[4*h+2]=u(c[1],c[16],c[31]),e[4*h+3]=u(c[2],c[17],c[32]),r[4*h+0]=u(c[3],c[18],c[33]),r[4*h+1]=u(c[4],c[19],c[34]),r[4*h+2]=u(c[5],c[20],c[35]),r[4*h+3]=u(c[6],c[21],c[36]),s[4*h+0]=u(c[7],c[22],c[37]),s[4*h+1]=u(c[8],c[23],c[38]),s[4*h+2]=u(c[9],c[24],c[39]),s[4*h+3]=u(c[10],c[25],c[40]),o[4*h+0]=u(c[11],c[26],c[41]),o[4*h+1]=u(c[12],c[27],c[42]),o[4*h+2]=u(c[13],c[28],c[43]),o[4*h+3]=u(c[14],c[29],c[44])}}this.sh1to3Texture.unlock(),this.sh4to7Texture.unlock(),this.sh8to11Texture.unlock(),this.sh12to15Texture.unlock()}}export{f as GSplat};