UNPKG

@animech-public/playcanvas

Version:
2 lines (1 loc) 7.96 kB
import{math as t}from"../../core/math/math.js";import{Mat4 as e}from"../../core/math/mat4.js";import{Vec3 as a}from"../../core/math/vec3.js";import{EMITTERSHAPE_BOX as o,EMITTERSHAPE_SPHERE as r,EMITTERSHAPE_HEMISPHERE as n,EMITTERSHAPE_CYLINDER as l,EMITTERSHAPE_CONE as i,PARTICLESORT_NONE as c}from"../constants.js";let s,m=1;const u=new e,d=new e,P=new a,p=new a,y=new a,h=new a,S=new a,z=new a,x=new a,f=new a,q=new a,M=new a,w=new a,V=new a,R=new a;function b(t){return t-Math.floor(t)}function L(t,e){return t-e*Math.floor(t/e)}function g(t){let e=b(t),a=b(255*t);return e-=a/255,a-=a/255,[e,a]}class U{constructor(t){this._emitter=t}calcSpawnPosition(e,a,c,s,m){const u=this._emitter,d=Math.random(),y=Math.random(),h=Math.random(),S=Math.random();if(u.useCpu&&(e[4*m+0+2*u.numParticlesPot*4]=d,e[4*m+1+2*u.numParticlesPot*4]=y,e[4*m+2+2*u.numParticlesPot*4]=h),p.x=d-.5,p.y=y-.5,p.z=h-.5,u.emitterShape===o){const t=Math.max(Math.abs(p.x),Math.max(Math.abs(p.y),Math.abs(p.z))),e=t+(.5-t)*c[0],o=t+(.5-t)*c[1],r=t+(.5-t)*c[2];p.x=e*(t===Math.abs(p.x)?Math.sign(p.x):2*p.x),p.y=o*(t===Math.abs(p.y)?Math.sign(p.y):2*p.y),p.z=r*(t===Math.abs(p.z)?Math.sign(p.z):2*p.z),u.localSpace?P.copy(a.transformPoint(p)):P.copy(s).add(a.transformPoint(p))}else if(u.emitterShape===r){p.normalize();const t=0===u.emitterRadius?0:u.emitterRadiusInner/u.emitterRadius,e=S*(1-t)+t;u.localSpace?P.copy(p.mulScalar(e*u.emitterRadius)):P.copy(s).add(p.mulScalar(e*u.emitterRadius))}else if(u.emitterShape===n){p.z=Math.abs(p.z),p.normalize();const t=0===u.emitterRadius?0:u.emitterRadiusInner/u.emitterRadius,e=S*(1-t)+t;u.localSpace?P.copy(p.mulScalar(a.transformPoint(e*u.emitterRadius))):P.copy(s).add(a.transformPoint(p.mulScalar(e*u.emitterRadius)))}else if(u.emitterShape===l){p.z=0,p.normalize();const t=0===u.emitterRadius?0:u.emitterRadiusInner/u.emitterRadius,e=S*(1-t)+t,o=0===u.emitterLength?0:u.emitterLengthInner/u.emitterLength,r=h*(1-o)+o;p.mulScalar(e*u.emitterRadius),p.z=(r-.5)*u.emitterLength,u.localSpace?P.copy(p.mulScalar(a.transformPoint(p))):P.copy(s).add(a.transformPoint(p))}else if(u.emitterShape===i){p.z=0,p.normalize();const t=0===u.emitterRadius?0:u.emitterRadiusInner/u.emitterRadius,e=S*(1-t)+t,o=0===u.emitterLength?0:u.emitterLengthInner/u.emitterLength,r=h*(1-o)+o;p.mulScalar(e*r*u.emitterRadius),p.z=(r-.5)*u.emitterLength,u.localSpace?P.copy(p.mulScalar(a.transformPoint(p))):P.copy(s).add(a.transformPoint(p))}else console.warn(`ParticleCPUUpdater: Unknown emitter shape ${this.emitterShape}`);let z=-t.lerp(u.rate,u.rate2,d)*m;if(u.pack8){const a=(P.x-u.worldBounds.center.x)/u.worldBoundsSize.x+.5,o=(P.y-u.worldBounds.center.y)/u.worldBoundsSize.y+.5,r=(P.z-u.worldBounds.center.z)/u.worldBoundsSize.z+.5;let n=t.lerp(u.startAngle*t.DEG_TO_RAD,u.startAngle2*t.DEG_TO_RAD,d);n=n%(2*Math.PI)/(2*Math.PI);const l=g(a);e[4*m]=l[0],e[4*m+1]=l[1];const i=g(o);e[4*m+2]=i[0],e[4*m+3]=i[1];const c=g(r);e[4*m+0+4*u.numParticlesPot]=c[0],e[4*m+1+4*u.numParticlesPot]=c[1];const s=g(n);e[4*m+2+4*u.numParticlesPot]=s[0],e[4*m+3+4*u.numParticlesPot]=s[1];const p=1;e[4*m+3+4*u.numParticlesPot*2]=p;const y=Math.max(u.lifetime,(u.numParticles-1)*Math.max(u.rate,u.rate2));z=(z+y)/(y+(u.lifetime+1));const h=function(t){let e=b(t),a=b(255*t),o=b(65025*t),r=b(160581375*t);return e-=a/255,a-=o/255,o-=r/255,r-=r/255,[e,a,o,r]}(z);e[4*m+0+4*u.numParticlesPot*3]=h[0],e[4*m+1+4*u.numParticlesPot*3]=h[1],e[4*m+2+4*u.numParticlesPot*3]=h[2],e[4*m+3+4*u.numParticlesPot*3]=h[3]}else e[4*m]=P.x,e[4*m+1]=P.y,e[4*m+2]=P.z,e[4*m+3]=t.lerp(u.startAngle*t.DEG_TO_RAD,u.startAngle2*t.DEG_TO_RAD,d),e[4*m+3+4*u.numParticlesPot]=z}update(t,e,l,P,b,g,U,v){let I,A,B;const C=this._emitter;if(C.meshInstance.node){const t=C.meshInstance.node.worldTransform;for(let e=0;e<12;e++)u.data[e]=t.data[e];d.copy(u),d.invert(),s=C.meshInstance.node.localScale,m=Math.max(Math.max(s.x,s.y),s.z)}g=null===C.meshInstance.node||C.localSpace?a.ZERO:C.meshInstance.node.getPosition();const D=C.camera?C.camera._node.getPosition():a.ZERO,_=C.useMesh?17:15;let O,E,T,j,G,k,Z,$,F;const N=C.precision-1;for(let e=0;e<C.numParticles;e++){const c=Math.floor(C.vbCPU[e*C.numParticleVerts*(C.useMesh?6:4)+3]),H=l[4*c+0+2*C.numParticlesPot*4];y.x=H,y.y=l[4*c+1+2*C.numParticlesPot*4],y.z=l[4*c+2+2*C.numParticlesPot*4];const J=C.rate+(C.rate2-C.rate)*H,K=C.lifetime;let Q=l[4*c+3+4*C.numParticlesPot]+U;const X=(W=Q/K,Math.max(Math.min(W,1),0));let Y=0,tt=0;const et=0;(Q-U<=0||Q>=K)&&this.calcSpawnPosition(l,P,b,g,c);let at=Q>0&&Q<K;at&&(B=X*N,O=Math.floor(B),E=Math.ceil(B),B%=1,I=C.qRotSpeed[O],A=C.qRotSpeed[E],T=I+(A-I)*B,I=C.qRotSpeed2[O],A=C.qRotSpeed2[E],j=I+(A-I)*B,I=C.qScale[O],A=C.qScale[E],Y=I+(A-I)*B,I=C.qScale2[O],A=C.qScale2[E],G=I+(A-I)*B,I=C.qAlpha[O],A=C.qAlpha[E],k=I+(A-I)*B,I=C.qAlpha2[O],A=C.qAlpha2[E],Z=I+(A-I)*B,I=C.qRadialSpeed[O],A=C.qRadialSpeed[E],$=I+(A-I)*B,I=C.qRadialSpeed2[O],A=C.qRadialSpeed2[E],F=I+(A-I)*B,$+=100*H%1*(F-$),h.x=l[4*c],h.y=l[4*c+1],h.z=l[4*c+2],C.localSpace?q.copy(h):q.copy(h).sub(g),q.normalize().mulScalar($),O*=3,E*=3,I=C.qLocalVelocity[O],A=C.qLocalVelocity[E],z.x=I+(A-I)*B,I=C.qLocalVelocity[O+1],A=C.qLocalVelocity[E+1],z.y=I+(A-I)*B,I=C.qLocalVelocity[O+2],A=C.qLocalVelocity[E+2],z.z=I+(A-I)*B,I=C.qLocalVelocity2[O],A=C.qLocalVelocity2[E],f.x=I+(A-I)*B,I=C.qLocalVelocity2[O+1],A=C.qLocalVelocity2[E+1],f.y=I+(A-I)*B,I=C.qLocalVelocity2[O+2],A=C.qLocalVelocity2[E+2],f.z=I+(A-I)*B,I=C.qVelocity[O],A=C.qVelocity[E],S.x=I+(A-I)*B,I=C.qVelocity[O+1],A=C.qVelocity[E+1],S.y=I+(A-I)*B,I=C.qVelocity[O+2],A=C.qVelocity[E+2],S.z=I+(A-I)*B,I=C.qVelocity2[O],A=C.qVelocity2[E],x.x=I+(A-I)*B,I=C.qVelocity2[O+1],A=C.qVelocity2[E+1],x.y=I+(A-I)*B,I=C.qVelocity2[O+2],A=C.qVelocity2[E+2],x.z=I+(A-I)*B,z.x+=(f.x-z.x)*y.x,z.y+=(f.y-z.y)*y.y,z.z+=(f.z-z.z)*y.z,C.initialVelocity>0&&(C.emitterShape===o?z.add(a.FORWARD.mulScalar(C.initialVelocity)):C.emitterShape===r||C.emitterShape===n||C.emitterShape===i?(p.copy(y).mulScalar(2).sub(a.ONE).normalize(),z.add(p.mulScalar(C.initialVelocity))):console.warn(`ParticleCPUUpdater: Unknown emitter shape ${this.emitterShape}`)),S.x+=(x.x-S.x)*y.x,S.y+=(x.y-S.y)*y.y,S.z+=(x.z-S.z)*y.z,T+=(j-T)*y.y,Y=(Y+1e4*H%1*(G-Y))*m,tt=1e3*H%1*(Z-k),C.meshInstance.node&&(C.localSpace?(z.x/=s.x,z.y/=s.y,z.z/=s.z):u.transformPoint(z,z)),C.localSpace?(d.transformPoint(S,S),z.add(S).add(q)):(z.add(S.mul(s)),z.add(q.mul(s))),V.copy(z),M.copy(h).add(z.mulScalar(U)),w.copy(M),l[4*c]=w.x,l[4*c+1]=w.y,l[4*c+2]=w.z,l[4*c+3]+=T*U,C.wrap&&C.wrapBounds&&(C.localSpace||w.sub(g),w.x=L(w.x,C.wrapBounds.x)-.5*C.wrapBounds.x,w.y=L(w.y,C.wrapBounds.y)-.5*C.wrapBounds.y,w.z=L(w.z,C.wrapBounds.z)-.5*C.wrapBounds.z,C.localSpace||w.add(g)),C.sort>0&&(1===C.sort?(R.copy(w).sub(D),C.particleDistance[c]=-(R.x*R.x+R.y*R.y+R.z*R.z)):2===C.sort?C.particleDistance[c]=Q:3===C.sort&&(C.particleDistance[c]=-Q))),v?Q<0&&(l[4*c+3+2*C.numParticlesPot*4]=-1):(Q>=K&&(Q-=Math.max(K,(C.numParticles-1)*J),l[4*c+3+2*C.numParticlesPot*4]=C.loop?1:-1),Q<0&&C.loop&&(l[4*c+3+2*C.numParticlesPot*4]=1)),l[4*c+3+2*C.numParticlesPot*4]<0&&(at=!1),l[4*c+3+4*C.numParticlesPot]=Q;for(let a=0;a<C.numParticleVerts;a++){const o=(e*C.numParticleVerts+a)*(C.useMesh?6:4);let r=C.vbCPU[o],n=C.vbCPU[o+1],i=C.vbCPU[o+2];at||(r=n=i=0);const s=e*C.numParticleVerts*_+a*_;t[s]=w.x,t[s+1]=w.y,t[s+2]=w.z,t[s+3]=X,t[s+4]=C.alignToMotion?et:l[4*c+3],t[s+5]=Y,t[s+6]=tt,t[s+7]=V.x,t[s+8]=r,t[s+9]=n,t[s+10]=i,t[s+11]=V.y,t[s+12]=c,t[s+13]=V.z,t[s+14]=C.vbCPU[o+3],C.useMesh&&(t[s+15]=C.vbCPU[o+4],t[s+16]=C.vbCPU[o+5])}}var W;if(C.sort>c&&C.camera){const t=C.useMesh?6:4,a=C.particleDistance;for(let o=0;o<C.numParticles;o++)e[o][0]=o,e[o][1]=a[Math.floor(C.vbCPU[o*C.numParticleVerts*t+3])];C.vbOld.set(C.vbCPU),e.sort(((t,e)=>t[1]-e[1]));for(let a=0;a<C.numParticles;a++){const o=e[a][0]*C.numParticleVerts*t,r=a*C.numParticleVerts*t;for(let e=0;e<C.numParticleVerts*t;e++)C.vbCPU[r+e]=C.vbOld[o+e]}}}}export{U as ParticleCPUUpdater};