UNPKG

@animech-public/playcanvas

Version:
2 lines (1 loc) 3.03 kB
import{Mat4 as t}from"../../core/math/mat4.js";import{Vec3 as s}from"../../core/math/vec3.js";import{PIXELFORMAT_R32U as e,SEMANTIC_ATTR13 as r,TYPE_UINT32 as a,BUFFER_STATIC as i}from"../../platform/graphics/constants.js";import{DITHER_NONE as n}from"../constants.js";import{MeshInstance as o}from"../mesh-instance.js";import{Mesh as h}from"../mesh.js";import{GSplatSorter as m}from"./gsplat-sorter.js";import{VertexFormat as c}from"../../platform/graphics/vertex-format.js";import{VertexBuffer as l}from"../../platform/graphics/vertex-buffer.js";const p=new t,d=new s,u=new s,f=[0,0];class g{constructor(t,p){this.splat=void 0,this.mesh=void 0,this.meshInstance=void 0,this.material=void 0,this.orderTexture=void 0,this.options={},this.sorter=null,this.lastCameraPosition=new s,this.lastCameraDirection=new s,this.cameras=[],this.splat=t,p=Object.assign(this.options,p);const d=t.device;this.orderTexture=this.splat.createTexture("splatOrder",e,this.splat.evalTextureSize(this.splat.numSplats)),this.createMaterial(p);const u=128,f=Math.ceil(t.numSplats/u)*u/u,g=new Uint32Array(f);for(let t=0;t<f;++t)g[t]=t*u;const w=new c(d,[{semantic:r,components:1,type:a,asInt:!0}]),v=new l(d,w,f,{usage:i,data:g.buffer}),I=new Float32Array(1536),x=new Uint32Array(768);for(let t=0;t<u;++t){I.set([-2,-2,t,2,-2,t,2,2,t,-2,2,t],12*t);const s=4*t;x.set([0+s,1+s,2+s,0+s,2+s,3+s],6*t)}const y=new h(d);y.setPositions(I,3),y.setIndices(x),y.update(),this.mesh=y,this.mesh.aabb.copy(t.aabb),this.meshInstance=new o(this.mesh,this.material),this.meshInstance.setInstancing(v,!0),this.meshInstance.gsplatInstance=this,this.meshInstance.instancingCount=0,this.centers=new Float32Array(t.centers),p.dither&&p.dither!==n||(this.sorter=new m,this.sorter.init(this.orderTexture,this.centers),this.sorter.on("updated",(t=>{this.meshInstance.instancingCount=Math.ceil(t/u);const s=this.material.getParameter("tex_params");null!=s&&s.data&&(s.data[0]=t)})))}destroy(){var t,s,e;null==(t=this.material)||t.destroy(),null==(s=this.meshInstance)||s.destroy(),null==(e=this.sorter)||e.destroy()}clone(){return new g(this.splat,this.options)}createMaterial(t){this.material=this.splat.createMaterial(t),this.material.setParameter("splatOrder",this.orderTexture),this.meshInstance&&(this.meshInstance.material=this.material)}updateViewport(){const t=this.splat.device;if(f[0]=t.width,f[1]=t.height,this.cameras.length>0){const t=this.cameras[0].xr;t&&t.active&&2===t.views.list.length&&(f[0]/=2)}this.material.setParameter("viewport",f)}sort(t){if(this.sorter){const s=t.getWorldTransform();s.getTranslation(d),s.getZ(u);const e=this.meshInstance.node.getWorldTransform(),r=p.invert(e);r.transformPoint(d,d),r.transformVector(u,u),d.equalsApprox(this.lastCameraPosition)&&u.equalsApprox(this.lastCameraDirection)||(this.lastCameraPosition.copy(d),this.lastCameraDirection.copy(u),this.sorter.setCamera(d,u))}this.updateViewport()}update(){if(this.cameras.length>0){const t=this.cameras[0];this.sort(t._node),this.cameras.length=0}}}export{g as GSplatInstance};