@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 4.47 kB
JavaScript
import{Color as t}from"../../core/math/color.js";import{Mat4 as e}from"../../core/math/mat4.js";import{Quat as r}from"../../core/math/quat.js";import{Vec3 as o}from"../../core/math/vec3.js";import{BoundingBox as s}from"../../core/shape/bounding-box.js";const a=new e,n=new r,i=new s,h=new s,l=new t(1,1,0,.4),c=.28209479177387814;class p{constructor(t,e,r,o,s){const a=t.getProp("x"),n=t.getProp("y"),i=t.getProp("z"),h=t.getProp("rot_1"),l=t.getProp("rot_2"),p=t.getProp("rot_3"),m=t.getProp("rot_0"),g=t.getProp("scale_0"),f=t.getProp("scale_1"),u=t.getProp("scale_2"),x=t.getProp("f_dc_0"),P=t.getProp("f_dc_1"),d=t.getProp("f_dc_2"),w=t.getProp("opacity");this.read=t=>{e&&(e.x=a[t],e.y=n[t],e.z=i[t]),r&&r.set(h[t],l[t],p[t],m[t]),o&&o.set(Math.exp(g[t]),Math.exp(f[t]),Math.exp(u[t])),s&&s.set(.5+x[t]*c,.5+P[t]*c,.5+d[t]*c,(t=>{if(t>0)return 1/(1+Math.exp(-t));const e=Math.exp(t);return e/(1+e)})(w[t]))}}}const m=(t,e,r)=>{n.set(r.x,r.y,r.z,r.w).normalize(),t.setTRS(e,n,o.ONE)};class g{constructor(t){this.elements=void 0,this.numSplats=void 0,this.elements=t,this.numSplats=this.getElement("vertex").count}static calcSplatAabb(t,e,r,o){m(a,e,r),i.center.set(0,0,0),i.halfExtents.set(2*o.x,2*o.y,2*o.z),t.setFromTransformedAabb(i,a)}getProp(t,e="vertex"){var r;return null==(r=this.getElement(e))||null==(r=r.properties.find((e=>e.name===t)))?void 0:r.storage}getElement(t){return this.elements.find((e=>e.name===t))}addProp(t,e){this.getElement("vertex").properties.push({type:"float",name:t,storage:e,byteSize:4})}createIter(t,e,r,o){return new p(this,t,e,r,o)}calcAabb(t,e){let r,o,s,a,n,i,h=!0;const l=this.getProp("x"),c=this.getProp("y"),p=this.getProp("z"),m=this.getProp("scale_0"),g=this.getProp("scale_1"),f=this.getProp("scale_2");for(let t=0;t<this.numSplats;++t){if(e&&!e(t))continue;const u=2*Math.exp(Math.max(m[t],g[t],f[t])),x=l[t],P=c[t],d=p[t];h?(h=!1,r=x-u,o=P-u,s=d-u,a=x+u,n=P+u,i=d+u):(r=Math.min(r,x-u),o=Math.min(o,P-u),s=Math.min(s,d-u),a=Math.max(a,x+u),n=Math.max(n,P+u),i=Math.max(i,d+u))}return h||(t.center.set(.5*(r+a),.5*(o+n),.5*(s+i)),t.halfExtents.set(.5*(a-r),.5*(n-o),.5*(i-s))),!h}calcAabbExact(t,e){const s=new o,a=new r,n=new o,i=this.createIter(s,a,n);let l=!0;for(let r=0;r<this.numSplats;++r)e&&!e(r)||(i.read(r),l?(l=!1,g.calcSplatAabb(t,s,a,n)):(g.calcSplatAabb(h,s,a,n),t.add(h)));return!l}getCenters(t){const e=this.getProp("x"),r=this.getProp("y"),o=this.getProp("z");for(let s=0;s<this.numSplats;++s)t[3*s+0]=e[s],t[3*s+1]=r[s],t[3*s+2]=o[s]}calcFocalPoint(t,e){const r=this.getProp("x"),o=this.getProp("y"),s=this.getProp("z"),a=this.getProp("scale_0"),n=this.getProp("scale_1"),i=this.getProp("scale_2");t.x=0,t.y=0,t.z=0;let h=0;for(let l=0;l<this.numSplats;++l){if(e&&!e(l))continue;const c=1/(1+Math.exp(Math.max(a[l],n[l],i[l])));t.x+=r[l]*c,t.y+=o[l]*c,t.z+=s[l]*c,h+=c}t.mulScalar(1/h)}renderWireframeBounds(t,e){const s=new o,n=new r,i=new o,h=new o,c=new o,p=this.createIter(s,n,i);for(let r=0;r<this.numSplats;++r)p.read(r),m(a,s,n),a.mul2(e,a),h.set(-2*i.x,-2*i.y,-2*i.z),c.set(2*i.x,2*i.y,2*i.z),t.immediate.drawWireAlignedBox(h,c,l,!0,t.defaultDrawLayer,a)}get isCompressed(){return!1}get hasSHData(){for(let t=0;t<45;++t)if(!this.getProp(`f_rest_${t}`))return!1;return!0}calcMortonOrder(){const t=t=>{let e=t[0],r=t[0];for(let o=1;o<t.length;o++)t[o]<e&&(e=t[o]),t[o]>r&&(r=t[o]);return{min:e,max:r}},e=(t,e,r)=>{const o=t=>t=153391689&((t=51130563&((t=50393103&((t=4278190335&((t&=1023)^t<<16))^t<<8))^t<<4))^t<<2);return(o(r)<<2)+(o(e)<<1)+o(t)},r=this.getProp("x"),o=this.getProp("y"),s=this.getProp("z"),{min:a,max:n}=t(r),{min:i,max:h}=t(o),{min:l,max:c}=t(s),p=a===n?0:1024/(n-a),m=i===h?0:1024/(h-i),g=l===c?0:1024/(c-l),f=new Map;for(let t=0;t<this.numSplats;t++){const n=e(Math.floor((r[t]-a)*p),Math.floor((o[t]-i)*m),Math.floor((s[t]-l)*g)),h=f.get(n);h?h.push(t):f.set(n,[t])}const u=Array.from(f.keys()).sort(((t,e)=>t-e)),x=new Uint32Array(this.numSplats);let P=0;for(let t=0;t<u.length;++t){const e=f.get(u[t]);for(let t=0;t<e.length;++t)x[P++]=e[t]}return x}reorder(t){const e=new Map,r=r=>{const o=new r.constructor((t=>{if(e.has(t)){const r=e.get(t);return e.delete(t),r}return new ArrayBuffer(t)})(r.byteLength));for(let e=0;e<t.length;e++)o[e]=r[t[e]];var s;return s=r.buffer,e.set(s.byteLength,s),o};this.elements.forEach((t=>{t.properties.forEach((t=>{t.storage&&(t.storage=r(t.storage))}))}))}reorderData(){this.reorder(this.calcMortonOrder())}}export{g as GSplatData};