hz-particles 1.4.0 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-lib/hz-particles-r3f.cjs +2 -2
- package/dist-lib/hz-particles-r3f.mjs +141 -140
- package/dist-lib/hz-particles.cjs +14 -14
- package/dist-lib/hz-particles.mjs +720 -714
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class vi{constructor(t={}){this.config=t,this._posOut=[0,0,0],this._rotMatrix=null,this._invRotMatrix=null,this._cachedRotX=void 0,this._cachedRotY=void 0,this._cachedRotZ=void 0}_updateRotationMatrix(){const t=this.config.emissionRotationX||0,e=this.config.emissionRotationY||0,i=this.config.emissionRotationZ||0;if(t===this._cachedRotX&&e===this._cachedRotY&&i===this._cachedRotZ)return;this._cachedRotX=t,this._cachedRotY=e,this._cachedRotZ=i;const r=t*Math.PI/180,n=e*Math.PI/180,a=i*Math.PI/180,o=Math.cos(r),c=Math.sin(r),l=Math.cos(n),u=Math.sin(n),h=Math.cos(a),p=Math.sin(a);this._rotMatrix=[l*h,c*u*h-o*p,o*u*h+c*p,l*p,c*u*p+o*h,o*u*p-c*h,-u,c*l,o*l],this._invRotMatrix=[this._rotMatrix[0],this._rotMatrix[3],this._rotMatrix[6],this._rotMatrix[1],this._rotMatrix[4],this._rotMatrix[7],this._rotMatrix[2],this._rotMatrix[5],this._rotMatrix[8]]}emitParticle(t,e,i){const r=this._posOut;if(this.config.emissionShape==="cube"||this.config.emissionShape==="box"?this._emitFromCube(r):this.config.emissionShape==="sphere"?this._emitFromSphere(r):this.config.emissionShape==="square"?this._emitFromSquare(r):this.config.emissionShape==="circle"?this._emitFromCircle(r):this.config.emissionShape==="cylinder"?this._emitFromCylinder(r):this.config.emissionShape==="plain"?this._emitFromPlain(r):this.config.emissionShape==="cone"?this._emitFromCone(r):this.config.emissionShape==="torus"?this._emitFromTorus(r):this.config.emissionShape==="line"?this._emitFromLine(r):this.config.emissionShape==="hemisphere"?this._emitFromHemisphere(r):this.config.emissionShape==="disc"?this._emitFromDisc(r):this.config.emissionShape==="annulus"?this._emitFromAnnulus(r):this.config.emissionShape==="capsule"?this._emitFromCapsule(r):this.config.emissionShape==="arc"?this._emitFromArc(r):this.config.emissionShape==="spiral"?this._emitFromSpiral(r):this.config.emissionShape==="frustum"?this._emitFromFrustum(r):this.config.emissionShape==="cubeSurface"?this._emitFromCubeSurface(r):this.config.emissionShape==="sphereSurface"?this._emitFromSphereSurface(r):this.config.emissionShape==="boxFrame"?this._emitFromBoxFrame(r):this.config.emissionShape==="polygon"?this._emitFromPolygon(r):this.config.emissionShape==="rectangle"?this._emitFromRectangle(r):(r[0]=0,r[1]=0,r[2]=0),this.config.emissionRotationX||this.config.emissionRotationY||this.config.emissionRotationZ){this._updateRotationMatrix();const o=this._rotMatrix,c=r[0],l=r[1],u=r[2];r[0]=o[0]*c+o[1]*l+o[2]*u,r[1]=o[3]*c+o[4]*l+o[5]*u,r[2]=o[6]*c+o[7]*l+o[8]*u}(this.config.emissionPositionX||this.config.emissionPositionY||this.config.emissionPositionZ)&&(r[0]+=this.config.emissionPositionX||0,r[1]+=this.config.emissionPositionY||0,r[2]+=this.config.emissionPositionZ||0);const n=e*8;t[n]=r[0],t[n+1]=r[1],t[n+2]=r[2];const a=e*4;this.calculateVelocity(r[0],r[1],r[2],i,a),this.setParticleColor(t,n),this.setParticleLifetime(t,n)}applyRotation(t,e,i){this._updateRotationMatrix();const r=this._rotMatrix;return[r[0]*t+r[1]*e+r[2]*i,r[3]*t+r[4]*e+r[5]*i,r[6]*t+r[7]*e+r[8]*i]}inverseRotation(t,e,i){this._updateRotationMatrix();const r=this._invRotMatrix;return[r[0]*t+r[1]*e+r[2]*i,r[3]*t+r[4]*e+r[5]*i,r[6]*t+r[7]*e+r[8]*i]}_emitFromCube(t){let e=this.config.innerLength||0,i=this.config.outerLength||this.config.cubeLength;if(e>0){const r=Math.floor(Math.random()*6),n=Math.random()-.5,a=Math.random()-.5;let o,c,l;switch(r){case 0:o=n,c=a,l=.5;break;case 1:o=n,c=a,l=-.5;break;case 2:o=.5,c=n,l=a;break;case 3:o=-.5,c=n,l=a;break;case 4:o=n,c=.5,l=a;break;case 5:o=n,c=-.5,l=a;break}const u=Math.random(),h=e+u*(i-e);t[0]=o*h,t[1]=c*h,t[2]=l*h}else t[0]=(Math.random()-.5)*i,t[1]=(Math.random()-.5)*i,t[2]=(Math.random()-.5)*i}_emitFromSphere(t){const e=Math.random()*2*Math.PI,i=Math.acos(2*Math.random()-1),r=Math.sin(i)*Math.cos(e),n=Math.sin(i)*Math.sin(e),a=Math.cos(i);let o;this.config.innerRadius===0?o=this.config.outerRadius*Math.cbrt(Math.random()):o=this.config.innerRadius+(this.config.outerRadius-this.config.innerRadius)*Math.random(),t[0]=r*o,t[1]=n*o,t[2]=a*o}_emitFromSquare(t){const e=this.config.squareInnerSize||0,i=this.config.squareSize||2;if(e>0){const r=Math.floor(Math.random()*4);let n=e+(i-e)*Math.random();switch(r){case 0:t[0]=(Math.random()*2-1)*n,t[1]=n;break;case 1:t[0]=n,t[1]=(Math.random()*2-1)*n;break;case 2:t[0]=(Math.random()*2-1)*n,t[1]=-n;break;case 3:t[0]=-n,t[1]=(Math.random()*2-1)*n;break}}else t[0]=(Math.random()*2-1)*i,t[1]=(Math.random()*2-1)*i;t[2]=0}_emitFromCircle(t){const e=this.config.circleInnerRadius||0,i=this.config.circleOuterRadius||2,r=Math.random()*Math.PI*2;let n;e>0?n=e+(i-e)*Math.random():n=i*Math.sqrt(Math.random()),t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t[2]=0}_emitFromPlain(t){const e=this.config.planeWidth||2,i=this.config.planeDepth||2;t[0]=(Math.random()-.5)*e,t[1]=0,t[2]=(Math.random()-.5)*i}_emitFromCone(t){const e=this.config.coneInnerRadius||0,i=this.config.coneOuterRadius||2,r=this.config.coneHeight||4,n=Math.random()*Math.PI*2,a=Math.random(),o=a*r,c=i*(1-a);let l;if(e>0){const u=e*(1-a);l=u+(c-u)*Math.random()}else l=c*Math.sqrt(Math.random());t[0]=Math.cos(n)*l,t[1]=o,t[2]=Math.sin(n)*l}_emitFromTorus(t){const e=this.config.torusMajorRadius||2,i=this.config.torusMinorRadius||.5,r=Math.random()*Math.PI*2,n=Math.random()*Math.PI*2,a=i*Math.sqrt(Math.random());t[0]=(e+a*Math.cos(n))*Math.cos(r),t[1]=a*Math.sin(n),t[2]=(e+a*Math.cos(n))*Math.sin(r)}_emitFromLine(t){const e=this.config.lineLength||4,i=Math.random();t[0]=0,t[1]=(i-.5)*e,t[2]=0}_emitFromHemisphere(t){const e=this.config.hemisphereInnerRadius||0,i=this.config.hemisphereOuterRadius||2,r=Math.random()*Math.PI*2,n=Math.acos(Math.random()),a=Math.sin(n)*Math.cos(r),o=Math.cos(n),c=Math.sin(n)*Math.sin(r);let l;e>0?l=e+(i-e)*Math.random():l=i*Math.cbrt(Math.random()),t[0]=a*l,t[1]=o*l,t[2]=c*l}_emitFromDisc(t){const e=this.config.discRadius||2,i=Math.random()*Math.PI*2,r=e*Math.sqrt(Math.random());t[0]=Math.cos(i)*r,t[1]=0,t[2]=Math.sin(i)*r}_emitFromAnnulus(t){const e=this.config.annulusInnerRadius||1,i=this.config.annulusOuterRadius||2,r=Math.random()*Math.PI*2,n=e+(i-e)*Math.random();t[0]=Math.cos(r)*n,t[1]=0,t[2]=Math.sin(r)*n}_emitFromCapsule(t){const e=this.config.capsuleRadius||.5,i=this.config.capsuleHeight||4,r=i*.5,n=Math.PI*e*e*i,a=4/3*Math.PI*e*e*e,o=n/(n+a);if(Math.random()<o){const c=Math.random()*Math.PI*2,l=e*Math.sqrt(Math.random());t[0]=Math.cos(c)*l,t[1]=(Math.random()-.5)*i,t[2]=Math.sin(c)*l}else{const c=Math.random()*Math.PI*2,l=Math.acos(2*Math.random()-1),u=e*Math.cbrt(Math.random());t[0]=u*Math.sin(l)*Math.cos(c),t[1]=u*Math.cos(l),t[2]=u*Math.sin(l)*Math.sin(c),t[1]+=t[1]>=0?r:-r}}_emitFromArc(t){const e=this.config.arcStartAngle||0,i=this.config.arcEndAngle||180,r=this.config.arcInnerRadius||0,n=this.config.arcOuterRadius||2,a=e*Math.PI/180,o=i*Math.PI/180,c=a+Math.random()*(o-a);let l;r>0?l=r+(n-r)*Math.random():l=n*Math.sqrt(Math.random()),t[0]=Math.cos(c)*l,t[1]=Math.sin(c)*l,t[2]=0}_emitFromSpiral(t){const e=this.config.spiralTurns||3,i=this.config.spiralRadiusStart||.5,r=this.config.spiralRadiusEnd||2,n=this.config.spiralHeight||4,a=Math.random(),o=a*e*Math.PI*2,c=i+(r-i)*a;t[0]=Math.cos(o)*c,t[1]=(a-.5)*n,t[2]=Math.sin(o)*c}_emitFromFrustum(t){const e=this.config.frustumRadiusNear||.5,i=this.config.frustumRadiusFar||2,r=this.config.frustumHeight||4,n=Math.random()*Math.PI*2,a=Math.random(),o=a*r,l=(e+(i-e)*a)*Math.sqrt(Math.random());t[0]=Math.cos(n)*l,t[1]=o,t[2]=Math.sin(n)*l}_emitFromCubeSurface(t){const e=this.config.cubeSurfaceSize||2,i=e*.5,r=Math.floor(Math.random()*6),n=(Math.random()-.5)*e,a=(Math.random()-.5)*e;switch(r){case 0:t[0]=n,t[1]=a,t[2]=i;break;case 1:t[0]=n,t[1]=a,t[2]=-i;break;case 2:t[0]=i,t[1]=n,t[2]=a;break;case 3:t[0]=-i,t[1]=n,t[2]=a;break;case 4:t[0]=n,t[1]=i,t[2]=a;break;case 5:t[0]=n,t[1]=-i,t[2]=a;break}}_emitFromSphereSurface(t){const e=this.config.sphereSurfaceRadius||2,i=Math.random()*Math.PI*2,r=Math.acos(2*Math.random()-1);t[0]=e*Math.sin(r)*Math.cos(i),t[1]=e*Math.sin(r)*Math.sin(i),t[2]=e*Math.cos(r)}_emitFromBoxFrame(t){const e=this.config.boxFrameSize||2,i=e*.5,r=Math.floor(Math.random()*12),a=(Math.random()-.5)*e,o=[[-1,-1],[-1,1],[1,-1],[1,1]];if(r<4){const[c,l]=o[r];t[0]=a,t[1]=c*i,t[2]=l*i}else if(r<8){const[c,l]=o[r-4];t[0]=c*i,t[1]=a,t[2]=l*i}else{const[c,l]=o[r-8];t[0]=c*i,t[1]=l*i,t[2]=a}}_emitFromPolygon(t){const e=Math.max(3,Math.floor(this.config.polygonSides||6)),i=this.config.polygonRadius||2,r=Math.floor(Math.random()*e),n=r/e*Math.PI*2,a=(r+1)/e*Math.PI*2;let o=Math.random(),c=Math.random();o+c>1&&(o=1-o,c=1-c);const l=o*Math.cos(n)+c*Math.cos(a),u=o*Math.sin(n)+c*Math.sin(a);t[0]=l*i,t[1]=u*i,t[2]=0}_emitFromRectangle(t){const e=this.config.rectangleWidth||2,i=this.config.rectangleHeight||2;t[0]=(Math.random()-.5)*e,t[1]=(Math.random()-.5)*i,t[2]=0}_emitFromCylinder(t){const e=this.config.cylinderInnerRadius||0,i=this.config.cylinderOuterRadius||2,r=this.config.cylinderHeight||4,n=Math.random()*Math.PI*2;let a;e>0?a=e+(i-e)*Math.random():a=i*Math.sqrt(Math.random()),t[0]=Math.cos(n)*a,t[1]=(Math.random()-.5)*r,t[2]=Math.sin(n)*a}calculateVelocity(t,e,i,r,n){const a=this.config.emissionPositionX||0,o=this.config.emissionPositionY||0,c=this.config.emissionPositionZ||0,l=t-a,u=e-o,h=i-c,p=Math.sqrt(l*l+u*u+h*h);let d,S,R;if(p>1e-4){let T=!1;if(this.config.emissionShape==="circle"&&this.config.circleVelocityDirection==="tangential"){const x=this.inverseRotation(l,u,h),L=Math.sqrt(x[0]*x[0]+x[1]*x[1]);if(L>1e-4){const P=-x[1]/L,B=x[0]/L,M=this.applyRotation(P,B,0);d=M[0],S=M[1],R=M[2],T=!0}}else if(this.config.emissionShape==="cylinder"&&this.config.cylinderVelocityDirection==="tangential"){const x=this.inverseRotation(l,u,h),L=Math.sqrt(x[0]*x[0]+x[2]*x[2]);if(L>1e-4){const P=-x[2]/L,B=x[0]/L,M=this.applyRotation(P,0,B);d=M[0],S=M[1],R=M[2],T=!0}else{const P=Math.random()*Math.PI*2,B=this.applyRotation(Math.cos(P),0,Math.sin(P));d=B[0],S=B[1],R=B[2],T=!0}}T||(d=l/p,S=u/p,R=h/p)}else{const T=Math.random()*Math.PI*2,x=Math.acos(2*Math.random()-1);d=Math.sin(x)*Math.cos(T),S=Math.sin(x)*Math.sin(T),R=Math.cos(x)}let E;this.config.randomSpeed?E=(this.config.minSpeed||0)+Math.random()*((this.config.maxSpeed||1)-(this.config.minSpeed||0)):E=this.config.particleSpeed,r[n]=this.config.overrideXVelocity?this.config.xVelocity:d*E,r[n+1]=this.config.overrideYVelocity?this.config.yVelocity:S*E,r[n+2]=this.config.overrideZVelocity?this.config.zVelocity:R*E,r[n+3]=0}setParticleColor(t,e){if(this.config.randomColorEnabled&&this.config.randomColors.length>0){const i=this.config.randomColors,r=i[Math.floor(Math.random()*i.length)];t[e+3]=r[0],t[e+4]=r[1],t[e+5]=r[2]}else this.config.colorTransitionEnabled?(t[e+3]=this.config.startColor[0],t[e+4]=this.config.startColor[1],t[e+5]=this.config.startColor[2]):(t[e+3]=this.config.particleColor[0],t[e+4]=this.config.particleColor[1],t[e+5]=this.config.particleColor[2])}setParticleLifetime(t,e){const i=this.config.lifetime||5;t[e+6]=0,t[e+7]=i+(Math.random()*.4-.2)*i}}const Pi=`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class wi{constructor(t={}){this.config=t,this._posOut=[0,0,0],this._rotMatrix=null,this._invRotMatrix=null,this._cachedRotX=void 0,this._cachedRotY=void 0,this._cachedRotZ=void 0}_updateRotationMatrix(){const t=this.config.emissionRotationX||0,e=this.config.emissionRotationY||0,i=this.config.emissionRotationZ||0;if(t===this._cachedRotX&&e===this._cachedRotY&&i===this._cachedRotZ)return;this._cachedRotX=t,this._cachedRotY=e,this._cachedRotZ=i;const r=t*Math.PI/180,n=e*Math.PI/180,a=i*Math.PI/180,o=Math.cos(r),c=Math.sin(r),l=Math.cos(n),u=Math.sin(n),m=Math.cos(a),p=Math.sin(a);this._rotMatrix=[l*m,c*u*m-o*p,o*u*m+c*p,l*p,c*u*p+o*m,o*u*p-c*m,-u,c*l,o*l],this._invRotMatrix=[this._rotMatrix[0],this._rotMatrix[3],this._rotMatrix[6],this._rotMatrix[1],this._rotMatrix[4],this._rotMatrix[7],this._rotMatrix[2],this._rotMatrix[5],this._rotMatrix[8]]}emitParticle(t,e,i){const r=this._posOut;if(this.config.emissionShape==="cube"||this.config.emissionShape==="box"?this._emitFromCube(r):this.config.emissionShape==="sphere"?this._emitFromSphere(r):this.config.emissionShape==="square"?this._emitFromSquare(r):this.config.emissionShape==="circle"?this._emitFromCircle(r):this.config.emissionShape==="cylinder"?this._emitFromCylinder(r):this.config.emissionShape==="plain"?this._emitFromPlain(r):this.config.emissionShape==="cone"?this._emitFromCone(r):this.config.emissionShape==="torus"?this._emitFromTorus(r):this.config.emissionShape==="line"?this._emitFromLine(r):this.config.emissionShape==="hemisphere"?this._emitFromHemisphere(r):this.config.emissionShape==="disc"?this._emitFromDisc(r):this.config.emissionShape==="annulus"?this._emitFromAnnulus(r):this.config.emissionShape==="capsule"?this._emitFromCapsule(r):this.config.emissionShape==="arc"?this._emitFromArc(r):this.config.emissionShape==="spiral"?this._emitFromSpiral(r):this.config.emissionShape==="frustum"?this._emitFromFrustum(r):this.config.emissionShape==="cubeSurface"?this._emitFromCubeSurface(r):this.config.emissionShape==="sphereSurface"?this._emitFromSphereSurface(r):this.config.emissionShape==="boxFrame"?this._emitFromBoxFrame(r):this.config.emissionShape==="polygon"?this._emitFromPolygon(r):this.config.emissionShape==="rectangle"?this._emitFromRectangle(r):(r[0]=0,r[1]=0,r[2]=0),this.config.emissionRotationX||this.config.emissionRotationY||this.config.emissionRotationZ){this._updateRotationMatrix();const o=this._rotMatrix,c=r[0],l=r[1],u=r[2];r[0]=o[0]*c+o[1]*l+o[2]*u,r[1]=o[3]*c+o[4]*l+o[5]*u,r[2]=o[6]*c+o[7]*l+o[8]*u}(this.config.emissionPositionX||this.config.emissionPositionY||this.config.emissionPositionZ)&&(r[0]+=this.config.emissionPositionX||0,r[1]+=this.config.emissionPositionY||0,r[2]+=this.config.emissionPositionZ||0);const n=e*8;t[n]=r[0],t[n+1]=r[1],t[n+2]=r[2];const a=e*4;this.calculateVelocity(r[0],r[1],r[2],i,a),this.setParticleColor(t,n),this.setParticleLifetime(t,n)}applyRotation(t,e,i){this._updateRotationMatrix();const r=this._rotMatrix;return[r[0]*t+r[1]*e+r[2]*i,r[3]*t+r[4]*e+r[5]*i,r[6]*t+r[7]*e+r[8]*i]}inverseRotation(t,e,i){this._updateRotationMatrix();const r=this._invRotMatrix;return[r[0]*t+r[1]*e+r[2]*i,r[3]*t+r[4]*e+r[5]*i,r[6]*t+r[7]*e+r[8]*i]}_emitFromCube(t){let e=this.config.innerLength||0,i=this.config.outerLength||this.config.cubeLength;if(e>0){const r=Math.floor(Math.random()*6),n=Math.random()-.5,a=Math.random()-.5;let o,c,l;switch(r){case 0:o=n,c=a,l=.5;break;case 1:o=n,c=a,l=-.5;break;case 2:o=.5,c=n,l=a;break;case 3:o=-.5,c=n,l=a;break;case 4:o=n,c=.5,l=a;break;case 5:o=n,c=-.5,l=a;break}const u=Math.random(),m=e+u*(i-e);t[0]=o*m,t[1]=c*m,t[2]=l*m}else t[0]=(Math.random()-.5)*i,t[1]=(Math.random()-.5)*i,t[2]=(Math.random()-.5)*i}_emitFromSphere(t){const e=Math.random()*2*Math.PI,i=Math.acos(2*Math.random()-1),r=Math.sin(i)*Math.cos(e),n=Math.sin(i)*Math.sin(e),a=Math.cos(i);let o;this.config.innerRadius===0?o=this.config.outerRadius*Math.cbrt(Math.random()):o=this.config.innerRadius+(this.config.outerRadius-this.config.innerRadius)*Math.random(),t[0]=r*o,t[1]=n*o,t[2]=a*o}_emitFromSquare(t){const e=this.config.squareInnerSize||0,i=this.config.squareSize||2;if(e>0){const r=Math.floor(Math.random()*4);let n=e+(i-e)*Math.random();switch(r){case 0:t[0]=(Math.random()*2-1)*n,t[1]=n;break;case 1:t[0]=n,t[1]=(Math.random()*2-1)*n;break;case 2:t[0]=(Math.random()*2-1)*n,t[1]=-n;break;case 3:t[0]=-n,t[1]=(Math.random()*2-1)*n;break}}else t[0]=(Math.random()*2-1)*i,t[1]=(Math.random()*2-1)*i;t[2]=0}_emitFromCircle(t){const e=this.config.circleInnerRadius||0,i=this.config.circleOuterRadius||2,r=Math.random()*Math.PI*2;let n;e>0?n=e+(i-e)*Math.random():n=i*Math.sqrt(Math.random()),t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t[2]=0}_emitFromPlain(t){const e=this.config.planeWidth||2,i=this.config.planeDepth||2;t[0]=(Math.random()-.5)*e,t[1]=0,t[2]=(Math.random()-.5)*i}_emitFromCone(t){const e=this.config.coneInnerRadius||0,i=this.config.coneOuterRadius||2,r=this.config.coneHeight||4,n=Math.random()*Math.PI*2,a=Math.random(),o=a*r,c=i*(1-a);let l;if(e>0){const u=e*(1-a);l=u+(c-u)*Math.random()}else l=c*Math.sqrt(Math.random());t[0]=Math.cos(n)*l,t[1]=o,t[2]=Math.sin(n)*l}_emitFromTorus(t){const e=this.config.torusMajorRadius||2,i=this.config.torusMinorRadius||.5,r=Math.random()*Math.PI*2,n=Math.random()*Math.PI*2,a=i*Math.sqrt(Math.random());t[0]=(e+a*Math.cos(n))*Math.cos(r),t[1]=a*Math.sin(n),t[2]=(e+a*Math.cos(n))*Math.sin(r)}_emitFromLine(t){const e=this.config.lineLength||4,i=Math.random();t[0]=0,t[1]=(i-.5)*e,t[2]=0}_emitFromHemisphere(t){const e=this.config.hemisphereInnerRadius||0,i=this.config.hemisphereOuterRadius||2,r=Math.random()*Math.PI*2,n=Math.acos(Math.random()),a=Math.sin(n)*Math.cos(r),o=Math.cos(n),c=Math.sin(n)*Math.sin(r);let l;e>0?l=e+(i-e)*Math.random():l=i*Math.cbrt(Math.random()),t[0]=a*l,t[1]=o*l,t[2]=c*l}_emitFromDisc(t){const e=this.config.discRadius||2,i=Math.random()*Math.PI*2,r=e*Math.sqrt(Math.random());t[0]=Math.cos(i)*r,t[1]=0,t[2]=Math.sin(i)*r}_emitFromAnnulus(t){const e=this.config.annulusInnerRadius||1,i=this.config.annulusOuterRadius||2,r=Math.random()*Math.PI*2,n=e+(i-e)*Math.random();t[0]=Math.cos(r)*n,t[1]=0,t[2]=Math.sin(r)*n}_emitFromCapsule(t){const e=this.config.capsuleRadius||.5,i=this.config.capsuleHeight||4,r=i*.5,n=Math.PI*e*e*i,a=4/3*Math.PI*e*e*e,o=n/(n+a);if(Math.random()<o){const c=Math.random()*Math.PI*2,l=e*Math.sqrt(Math.random());t[0]=Math.cos(c)*l,t[1]=(Math.random()-.5)*i,t[2]=Math.sin(c)*l}else{const c=Math.random()*Math.PI*2,l=Math.acos(2*Math.random()-1),u=e*Math.cbrt(Math.random());t[0]=u*Math.sin(l)*Math.cos(c),t[1]=u*Math.cos(l),t[2]=u*Math.sin(l)*Math.sin(c),t[1]+=t[1]>=0?r:-r}}_emitFromArc(t){const e=this.config.arcStartAngle||0,i=this.config.arcEndAngle||180,r=this.config.arcInnerRadius||0,n=this.config.arcOuterRadius||2,a=e*Math.PI/180,o=i*Math.PI/180,c=a+Math.random()*(o-a);let l;r>0?l=r+(n-r)*Math.random():l=n*Math.sqrt(Math.random()),t[0]=Math.cos(c)*l,t[1]=Math.sin(c)*l,t[2]=0}_emitFromSpiral(t){const e=this.config.spiralTurns||3,i=this.config.spiralRadiusStart||.5,r=this.config.spiralRadiusEnd||2,n=this.config.spiralHeight||4,a=Math.random(),o=a*e*Math.PI*2,c=i+(r-i)*a;t[0]=Math.cos(o)*c,t[1]=(a-.5)*n,t[2]=Math.sin(o)*c}_emitFromFrustum(t){const e=this.config.frustumRadiusNear||.5,i=this.config.frustumRadiusFar||2,r=this.config.frustumHeight||4,n=Math.random()*Math.PI*2,a=Math.random(),o=a*r,l=(e+(i-e)*a)*Math.sqrt(Math.random());t[0]=Math.cos(n)*l,t[1]=o,t[2]=Math.sin(n)*l}_emitFromCubeSurface(t){const e=this.config.cubeSurfaceSize||2,i=e*.5,r=Math.floor(Math.random()*6),n=(Math.random()-.5)*e,a=(Math.random()-.5)*e;switch(r){case 0:t[0]=n,t[1]=a,t[2]=i;break;case 1:t[0]=n,t[1]=a,t[2]=-i;break;case 2:t[0]=i,t[1]=n,t[2]=a;break;case 3:t[0]=-i,t[1]=n,t[2]=a;break;case 4:t[0]=n,t[1]=i,t[2]=a;break;case 5:t[0]=n,t[1]=-i,t[2]=a;break}}_emitFromSphereSurface(t){const e=this.config.sphereSurfaceRadius||2,i=Math.random()*Math.PI*2,r=Math.acos(2*Math.random()-1);t[0]=e*Math.sin(r)*Math.cos(i),t[1]=e*Math.sin(r)*Math.sin(i),t[2]=e*Math.cos(r)}_emitFromBoxFrame(t){const e=this.config.boxFrameSize||2,i=e*.5,r=Math.floor(Math.random()*12),a=(Math.random()-.5)*e,o=[[-1,-1],[-1,1],[1,-1],[1,1]];if(r<4){const[c,l]=o[r];t[0]=a,t[1]=c*i,t[2]=l*i}else if(r<8){const[c,l]=o[r-4];t[0]=c*i,t[1]=a,t[2]=l*i}else{const[c,l]=o[r-8];t[0]=c*i,t[1]=l*i,t[2]=a}}_emitFromPolygon(t){const e=Math.max(3,Math.floor(this.config.polygonSides||6)),i=this.config.polygonRadius||2,r=Math.floor(Math.random()*e),n=r/e*Math.PI*2,a=(r+1)/e*Math.PI*2;let o=Math.random(),c=Math.random();o+c>1&&(o=1-o,c=1-c);const l=o*Math.cos(n)+c*Math.cos(a),u=o*Math.sin(n)+c*Math.sin(a);t[0]=l*i,t[1]=u*i,t[2]=0}_emitFromRectangle(t){const e=this.config.rectangleWidth||2,i=this.config.rectangleHeight||2;t[0]=(Math.random()-.5)*e,t[1]=(Math.random()-.5)*i,t[2]=0}_emitFromCylinder(t){const e=this.config.cylinderInnerRadius||0,i=this.config.cylinderOuterRadius||2,r=this.config.cylinderHeight||4,n=Math.random()*Math.PI*2;let a;e>0?a=e+(i-e)*Math.random():a=i*Math.sqrt(Math.random()),t[0]=Math.cos(n)*a,t[1]=(Math.random()-.5)*r,t[2]=Math.sin(n)*a}calculateVelocity(t,e,i,r,n){const a=this.config.emissionPositionX||0,o=this.config.emissionPositionY||0,c=this.config.emissionPositionZ||0,l=t-a,u=e-o,m=i-c,p=Math.sqrt(l*l+u*u+m*m);let d,b,w;if(p>1e-4){let R=!1;if(this.config.emissionShape==="circle"&&this.config.circleVelocityDirection==="tangential"){const x=this.inverseRotation(l,u,m),L=Math.sqrt(x[0]*x[0]+x[1]*x[1]);if(L>1e-4){const P=-x[1]/L,T=x[0]/L,E=this.applyRotation(P,T,0);d=E[0],b=E[1],w=E[2],R=!0}}else if(this.config.emissionShape==="cylinder"&&this.config.cylinderVelocityDirection==="tangential"){const x=this.inverseRotation(l,u,m),L=Math.sqrt(x[0]*x[0]+x[2]*x[2]);if(L>1e-4){const P=-x[2]/L,T=x[0]/L,E=this.applyRotation(P,0,T);d=E[0],b=E[1],w=E[2],R=!0}else{const P=Math.random()*Math.PI*2,T=this.applyRotation(Math.cos(P),0,Math.sin(P));d=T[0],b=T[1],w=T[2],R=!0}}R||(d=l/p,b=u/p,w=m/p)}else{const R=Math.random()*Math.PI*2,x=Math.acos(2*Math.random()-1);d=Math.sin(x)*Math.cos(R),b=Math.sin(x)*Math.sin(R),w=Math.cos(x)}let M;this.config.randomSpeed?M=(this.config.minSpeed||0)+Math.random()*((this.config.maxSpeed||1)-(this.config.minSpeed||0)):M=this.config.particleSpeed,r[n]=this.config.overrideXVelocity?this.config.xVelocity:d*M,r[n+1]=this.config.overrideYVelocity?this.config.yVelocity:b*M,r[n+2]=this.config.overrideZVelocity?this.config.zVelocity:w*M,r[n+3]=0}setParticleColor(t,e){if(this.config.randomColorEnabled&&this.config.randomColors.length>0){const i=this.config.randomColors,r=i[Math.floor(Math.random()*i.length)];t[e+3]=r[0],t[e+4]=r[1],t[e+5]=r[2]}else this.config.colorTransitionEnabled?(t[e+3]=this.config.startColor[0],t[e+4]=this.config.startColor[1],t[e+5]=this.config.startColor[2]):(t[e+3]=this.config.particleColor[0],t[e+4]=this.config.particleColor[1],t[e+5]=this.config.particleColor[2])}setParticleLifetime(t,e){const i=this.config.lifetime||5;t[e+6]=0,t[e+7]=i+(Math.random()*.4-.2)*i}}const Bi=`
|
|
2
2
|
struct Uniforms {
|
|
3
3
|
transform: mat4x4<f32>,
|
|
4
4
|
cameraPosition: vec3<f32>,
|
|
@@ -420,7 +420,7 @@
|
|
|
420
420
|
return vec4<f32>(input.color, alpha);
|
|
421
421
|
}
|
|
422
422
|
}
|
|
423
|
-
`,
|
|
423
|
+
`,Mi=`
|
|
424
424
|
struct BloomUniforms {
|
|
425
425
|
direction: vec2<f32>,
|
|
426
426
|
resolution: vec2<f32>,
|
|
@@ -480,7 +480,7 @@
|
|
|
480
480
|
|
|
481
481
|
return result / totalWeight * 1.1;
|
|
482
482
|
}
|
|
483
|
-
`,
|
|
483
|
+
`,Ri=`
|
|
484
484
|
struct BloomIntensityUniforms {
|
|
485
485
|
intensity: f32,
|
|
486
486
|
color: vec3<f32>,
|
|
@@ -526,7 +526,7 @@
|
|
|
526
526
|
|
|
527
527
|
return vec4<f32>(originalColor.rgb + (mappedBloom * bloomUniforms.intensity), originalColor.a);
|
|
528
528
|
}
|
|
529
|
-
`,
|
|
529
|
+
`,Ti=`
|
|
530
530
|
struct BloomIntensityUniforms {
|
|
531
531
|
intensity: f32,
|
|
532
532
|
color: vec3<f32>,
|
|
@@ -567,7 +567,7 @@
|
|
|
567
567
|
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
568
568
|
return textureSample(originalTexture, texSampler, input.texCoord);
|
|
569
569
|
}
|
|
570
|
-
`,
|
|
570
|
+
`,Vs=`
|
|
571
571
|
@binding(0) @group(0) var texSampler: sampler;
|
|
572
572
|
@binding(1) @group(0) var originalTexture: texture_2d<f32>;
|
|
573
573
|
@binding(2) @group(0) var blurredTexture: texture_2d<f32>;
|
|
@@ -599,7 +599,7 @@
|
|
|
599
599
|
let c = textureSample(originalTexture, texSampler, input.texCoord);
|
|
600
600
|
return vec4<f32>(aces(c.rgb), c.a);
|
|
601
601
|
}
|
|
602
|
-
`,
|
|
602
|
+
`,Ei=`
|
|
603
603
|
struct PhysicsUniforms {
|
|
604
604
|
deltaTime: f32,
|
|
605
605
|
particleSpeed: f32,
|
|
@@ -809,7 +809,7 @@
|
|
|
809
809
|
particleBuffer[baseIndex + 1u] = newPos.y;
|
|
810
810
|
particleBuffer[baseIndex + 2u] = newPos.z;
|
|
811
811
|
}
|
|
812
|
-
`,
|
|
812
|
+
`,Os=`
|
|
813
813
|
@group(0) @binding(0) var<storage, read> restData: array<f32>;
|
|
814
814
|
@group(0) @binding(1) var<storage, read> jointWeightsData: array<f32>;
|
|
815
815
|
@group(0) @binding(2) var<storage, read> jointIndicesData: array<u32>;
|
|
@@ -865,7 +865,7 @@
|
|
|
865
865
|
outputData[outBase + 6u] = uv_u;
|
|
866
866
|
outputData[outBase + 7u] = uv_v;
|
|
867
867
|
}
|
|
868
|
-
`;class Ri{constructor(t,e=1e4){this.device=t,this.physicsSettings={deltaTime:.016,gravity:0,turbulence:0,attractorStrength:0,attractorPosition:[0,0,0],damping:0,confinementEnabled:!1,confinementShape:"box",confinementMode:"bounce",confinementSpace:"world",confinementBoxHalfSize:[2,2,2],confinementSphereRadius:3,confinementRestitution:.8,confinementFriction:.1,confinementCenter:[0,0,0],softBoundaryEnabled:!1,softBoundaryStrength:5,softBoundaryFalloff:.5},this.fixedDeltaTime=1/60,this.physicsClock=0,this.physicsAccumulator=0,this.minUpdatesPerSecond=30,this.lastUpdateTime=0,this.computeReady=!1,this.computePipeline=null,this.computeBindGroupLayout=null,this._physicsData=new Float32Array(32),this._physicsDataU32View=new Uint32Array(this._physicsData.buffer),this.physicsUniformBuffer=t.createBuffer({size:128,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,label:"physicsUniformBuffer"}),this._maxParticles=e,this._particleDataStagingBuffer=t.createBuffer({size:e*8*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,label:"ParticleDataReadbackBuffer_Pooled"}),this._velocityStagingBuffer=t.createBuffer({size:e*4*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,label:"VelocityReadbackBuffer_Pooled"}),this._stagingInUse=!1,this._renderStagingParticleBuffer=t.createBuffer({size:e*8*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,label:"RenderReadback_ParticleData"}),this._renderStagingVelocityBuffer=t.createBuffer({size:e*4*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,label:"RenderReadback_Velocity"}),this._renderStagingInUse=!1,this._scriptStagingParticleBuffer=t.createBuffer({size:e*8*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,label:"ScriptReadback_ParticleData"}),this._scriptStagingVelocityBuffer=t.createBuffer({size:e*4*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,label:"ScriptReadback_Velocity"}),this._scriptStagingInUse=!1}async initComputePipeline(t,e,i){try{return await this.createComputePipeline(t,e,i),this.computeReady=!0,!0}catch(r){return console.error("Error initializing compute pipeline:",r),!1}}async createComputePipeline(t,e,i){this.computeBindGroupLayout=this.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}),this.computePipeline=this.device.createComputePipeline({layout:this.device.createPipelineLayout({bindGroupLayouts:[this.computeBindGroupLayout]}),compute:{module:this.device.createShaderModule({code:Mi}),entryPoint:"main"}}),this.computeBindGroup=this.device.createBindGroup({layout:this.computeBindGroupLayout,entries:[{binding:0,resource:{buffer:this.physicsUniformBuffer}},{binding:1,resource:{buffer:t}},{binding:2,resource:{buffer:e}},{binding:3,resource:{buffer:i}}]})}updatePhysics(t,e,i,r,n,a){if(e<=0||!this.computeReady)return;const o=this._physicsData,c=this.physicsSettings;o[0]=t,o[1]=i.particleSpeed,o[2]=c.gravity,o[3]=c.turbulence,o[4]=c.attractorStrength,o[5]=c.damping,o[6]=c.attractorPosition[0],o[7]=c.attractorPosition[1],o[8]=c.attractorPosition[2],this._physicsDataU32View[9]=e,o[10]=c.confinementEnabled?1:0,o[11]=c.confinementShape==="sphere"?1:0,o[12]=c.confinementMode==="kill"?1:0,o[13]=c.confinementSpace==="local"?1:0,o[14]=c.confinementBoxHalfSize[0],o[15]=c.confinementBoxHalfSize[1],o[16]=c.confinementBoxHalfSize[2],o[17]=c.confinementSphereRadius,o[18]=c.confinementRestitution,o[19]=c.confinementFriction,o[20]=c.confinementCenter[0],o[21]=c.confinementCenter[1],o[22]=c.confinementCenter[2],o[23]=c.softBoundaryEnabled?1:0,o[24]=c.softBoundaryStrength,o[25]=c.softBoundaryFalloff,o[26]=i.velocityStretchEnabled?1:0,o[27]=i.velocityStretchFactor??1,o[28]=0,o[29]=0,o[30]=0,o[31]=0,this.device.queue.writeBuffer(this.physicsUniformBuffer,0,o);const l=a||this.device.createCommandEncoder({label:"ParticlePhysicsEncoder"}),u=l.beginComputePass({label:"ParticlePhysicsPass"});u.setPipeline(this.computePipeline),u.setBindGroup(0,this.computeBindGroup);const h=Math.max(1,Math.ceil(e/64));u.dispatchWorkgroups(h,1,1),u.end(),a||this.device.queue.submit([l.finish()]),this.lastUpdateTime=performance.now()/1e3}async readbackAndProcessParticles(t,e,i,r,n){if(t<=0)return{activeCount:0,shouldUpdate:!1};if(this._stagingInUse)return{activeCount:t,shouldUpdate:!1};try{this._stagingInUse=!0;const a=this.device.createCommandEncoder({label:"ParticleReadbackEncoder"}),o=t*8*4;a.copyBufferToBuffer(r,0,this._particleDataStagingBuffer,0,o);const c=t*4*4;return a.copyBufferToBuffer(n,0,this._velocityStagingBuffer,0,c),this.device.queue.submit([a.finish()]),await Promise.all([(async()=>{await this._particleDataStagingBuffer.mapAsync(GPUMapMode.READ,0,o);const l=new Float32Array(this._particleDataStagingBuffer.getMappedRange(0,o));e.set(l),this._particleDataStagingBuffer.unmap()})(),(async()=>{await this._velocityStagingBuffer.mapAsync(GPUMapMode.READ,0,c);const l=new Float32Array(this._velocityStagingBuffer.getMappedRange(0,c));i.set(l),this._velocityStagingBuffer.unmap()})()]),this._stagingInUse=!1,{particleData:e,particleVelocities:i,shouldUpdate:!0}}catch(a){return this._stagingInUse=!1,a&&a.name==="AbortError"||console.error("Error reading back particle data:",a),{activeCount:t,shouldUpdate:!1}}}setDamping(t){this.physicsSettings.damping=t}setGravity(t){this.physicsSettings.gravity=t}setAttractor(t,e){this.physicsSettings.attractorStrength=t,this.physicsSettings.attractorPosition=e}setConfinement(t){const e=this.physicsSettings;t.enabled!==void 0&&(e.confinementEnabled=t.enabled),t.shape!==void 0&&(e.confinementShape=t.shape),t.mode!==void 0&&(e.confinementMode=t.mode),t.space!==void 0&&(e.confinementSpace=t.space),t.boxSize!==void 0&&(e.confinementBoxHalfSize=t.boxSize),t.sphereRadius!==void 0&&(e.confinementSphereRadius=t.sphereRadius),t.restitution!==void 0&&(e.confinementRestitution=t.restitution),t.friction!==void 0&&(e.confinementFriction=t.friction),t.center!==void 0&&(e.confinementCenter=t.center)}async readbackForRendering(t,e,i,r,n){if(t<=0)return{shouldUpdate:!1};if(this._renderStagingInUse)return{shouldUpdate:!1};try{this._renderStagingInUse=!0;const a=t*8*4,o=t*4*4,c=this.device.createCommandEncoder({label:"RenderReadbackEncoder"});return c.copyBufferToBuffer(r,0,this._renderStagingParticleBuffer,0,a),c.copyBufferToBuffer(n,0,this._renderStagingVelocityBuffer,0,o),this.device.queue.submit([c.finish()]),await Promise.all([(async()=>{await this._renderStagingParticleBuffer.mapAsync(GPUMapMode.READ,0,a);const l=new Float32Array(this._renderStagingParticleBuffer.getMappedRange(0,a));e.set(l),this._renderStagingParticleBuffer.unmap()})(),(async()=>{await this._renderStagingVelocityBuffer.mapAsync(GPUMapMode.READ,0,o);const l=new Float32Array(this._renderStagingVelocityBuffer.getMappedRange(0,o));i.set(l),this._renderStagingVelocityBuffer.unmap()})()]),this._renderStagingInUse=!1,{particleData:e,particleVelocities:i,shouldUpdate:!0}}catch(a){return this._renderStagingInUse=!1,console.error("Error in rendering readback:",a),{shouldUpdate:!1}}}async readbackForScript(t,e,i,r,n){if(t<=0)return{shouldUpdate:!1};if(this._scriptStagingInUse)return{shouldUpdate:!1};try{this._scriptStagingInUse=!0;const a=t*8*4,o=t*4*4,c=this.device.createCommandEncoder({label:"ScriptReadbackEncoder"});return c.copyBufferToBuffer(r,0,this._scriptStagingParticleBuffer,0,a),c.copyBufferToBuffer(n,0,this._scriptStagingVelocityBuffer,0,o),this.device.queue.submit([c.finish()]),await Promise.all([(async()=>{await this._scriptStagingParticleBuffer.mapAsync(GPUMapMode.READ,0,a);const l=new Float32Array(this._scriptStagingParticleBuffer.getMappedRange(0,a));e.set(l),this._scriptStagingParticleBuffer.unmap()})(),(async()=>{await this._scriptStagingVelocityBuffer.mapAsync(GPUMapMode.READ,0,o);const l=new Float32Array(this._scriptStagingVelocityBuffer.getMappedRange(0,o));i.set(l),this._scriptStagingVelocityBuffer.unmap()})()]),this._scriptStagingInUse=!1,{shouldUpdate:!0}}catch(a){return this._scriptStagingInUse=!1,console.error("Error in script readback:",a),{shouldUpdate:!1}}}destroy(){this.physicsUniformBuffer.destroy(),this._particleDataStagingBuffer.destroy(),this._velocityStagingBuffer.destroy(),this._renderStagingParticleBuffer.destroy(),this._renderStagingVelocityBuffer.destroy(),this._scriptStagingParticleBuffer.destroy(),this._scriptStagingVelocityBuffer.destroy()}setSoftBoundary(t){const e=this.physicsSettings;t.enabled!==void 0&&(e.softBoundaryEnabled=t.enabled),t.strength!==void 0&&(e.softBoundaryStrength=t.strength),t.falloff!==void 0&&(e.softBoundaryFalloff=t.falloff)}}class Ti{constructor(t){this.device=t,this.defaultTexture=null,this.createDefaultTexture()}createDefaultTexture(){const t=new Uint8Array([255,255,255,255]);this.defaultTexture=this.device.createTexture({size:[1,1],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST,label:"defaultParticleTexture"}),this.device.queue.writeTexture({texture:this.defaultTexture},t,{bytesPerRow:4},[1,1])}async loadTexture(t){const e=this.device.createTexture({size:[t.width,t.height],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT,label:"particleTexture"});return this.device.queue.copyExternalImageToTexture({source:t},{texture:e},[t.width,t.height]),e}getDefaultTexture(){return this.defaultTexture}destroyTexture(t){t&&t.label!=="defaultParticleTexture"&&t.destroy()}}const Ei=Object.freeze({sin:Math.sin,cos:Math.cos,abs:Math.abs,floor:Math.floor,ceil:Math.ceil,round:Math.round,min:Math.min,max:Math.max,sqrt:Math.sqrt,pow:Math.pow,random:Math.random,PI:Math.PI,TAU:Math.PI*2,clamp(s,t,e){return s<t?t:s>e?e:s},lerp(s,t,e){return s+(t-s)*e},smoothstep(s,t,e){const i=Ei.clamp((e-s)/(t-s),0,1);return i*i*(3-2*i)}}),qe=new Set(["particleSize","particleSpeed","particleColor","startColor","endColor","opacity","emissionRate","gravityStrength","dampingStrength","attractorStrength","attractorPosition","pulseAmplitude","pulseFrequency","bloomIntensity"]);class Fs{constructor(t){this._collection=t,this._pd=null,this._vd=null,this._pi=0,this._vi=0}_bind(t,e,i){return this._pd=t,this._vd=e,this._pi=i*8,this._vi=i*4,this}get x(){return this._pd[this._pi]}set x(t){this._pd[this._pi]=t,this._collection._dirty=!0}get y(){return this._pd[this._pi+1]}set y(t){this._pd[this._pi+1]=t,this._collection._dirty=!0}get z(){return this._pd[this._pi+2]}set z(t){this._pd[this._pi+2]=t,this._collection._dirty=!0}get r(){return this._pd[this._pi+3]}set r(t){this._pd[this._pi+3]=t,this._collection._dirty=!0}get g(){return this._pd[this._pi+4]}set g(t){this._pd[this._pi+4]=t,this._collection._dirty=!0}get b(){return this._pd[this._pi+5]}set b(t){this._pd[this._pi+5]=t,this._collection._dirty=!0}get age(){return this._pd[this._pi+6]}set age(t){this._pd[this._pi+6]=t,this._collection._dirty=!0}get lifetime(){return this._pd[this._pi+7]}set lifetime(t){this._pd[this._pi+7]=t,this._collection._dirty=!0}get vx(){return this._vd[this._vi]}set vx(t){this._vd[this._vi]=t,this._collection._dirty=!0}get vy(){return this._vd[this._vi+1]}set vy(t){this._vd[this._vi+1]=t,this._collection._dirty=!0}get vz(){return this._vd[this._vi+2]}set vz(t){this._vd[this._vi+2]=t,this._collection._dirty=!0}}class Vs{constructor(){this._proxy=new Fs(this),this._pd=null,this._vd=null,this.count=0,this._dirty=!1}_bind(t,e,i){this._pd=t,this._vd=e,this.count=i,this._dirty=!1}get(t){return t<0||t>=this.count?null:this._proxy._bind(this._pd,this._vd,t)}}const Os=1e6;function Ls(s){let t=0;return s.replace(/\b(for|while)\s*\([^)]*\)\s*\{/g,e=>{const i=`__lc${t++}`;return`${e} if(++${i}>${Os})throw new Error("Loop limit exceeded");`}).replace(/\b(for|while)\s*\([^)]*\)\s*\{/g,e=>e).replace(/^/,()=>{let e="";for(let i=0;i<t;i++)e+=`let __lc${i}=0;`;return e})}const vt=new Map;for(const s of qe)vt.set(s.toLowerCase(),s);function Xs(s){const t={value:!1},e=new Set;return new Proxy(s,{get(r,n){if(n==="__dirty")return t.value;if(n==="__resetDirty")return()=>{t.value=!1};if(typeof n!="string")return;if(qe.has(n))return r[n];const a=vt.get(n.toLowerCase());if(a)return e.has(n)||(e.add(n),console.warn(`[ParticleScript] config.${n} → did you mean config.${a}?`)),r[a]},set(r,n,a){if(typeof n!="string")return!0;let o=n;if(!qe.has(o)){const c=vt.get(o.toLowerCase());if(c)e.has(n)||(e.add(n),console.warn(`[ParticleScript] config.${n} → did you mean config.${c}?`)),o=c;else return!0}return r[o]=a,t.value=!0,!0}})}class Pt{constructor(t,e,i){this._particles=new Vs,this._configProxy=Xs(e),this._configSnapshot=null,this._fn=null,this._error=!1,this.compile(t)}compile(t){if(this._fn=null,this._error=!1,!(!t||typeof t!="string"))try{const i=`
|
|
868
|
+
`;class Ci{constructor(t,e=1e4){this.device=t,this.physicsSettings={deltaTime:.016,gravity:0,turbulence:0,attractorStrength:0,attractorPosition:[0,0,0],damping:0,confinementEnabled:!1,confinementShape:"box",confinementMode:"bounce",confinementSpace:"world",confinementBoxHalfSize:[2,2,2],confinementSphereRadius:3,confinementRestitution:.8,confinementFriction:.1,confinementCenter:[0,0,0],softBoundaryEnabled:!1,softBoundaryStrength:5,softBoundaryFalloff:.5},this.fixedDeltaTime=1/60,this.physicsClock=0,this.physicsAccumulator=0,this.minUpdatesPerSecond=30,this.lastUpdateTime=0,this.computeReady=!1,this.computePipeline=null,this.computeBindGroupLayout=null,this._physicsData=new Float32Array(32),this._physicsDataU32View=new Uint32Array(this._physicsData.buffer),this.physicsUniformBuffer=t.createBuffer({size:128,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,label:"physicsUniformBuffer"}),this._maxParticles=e,this._particleDataStagingBuffer=t.createBuffer({size:e*8*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,label:"ParticleDataReadbackBuffer_Pooled"}),this._velocityStagingBuffer=t.createBuffer({size:e*4*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,label:"VelocityReadbackBuffer_Pooled"}),this._stagingInUse=!1,this._renderStagingParticleBuffer=t.createBuffer({size:e*8*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,label:"RenderReadback_ParticleData"}),this._renderStagingVelocityBuffer=t.createBuffer({size:e*4*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,label:"RenderReadback_Velocity"}),this._renderStagingInUse=!1,this._scriptStagingParticleBuffer=t.createBuffer({size:e*8*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,label:"ScriptReadback_ParticleData"}),this._scriptStagingVelocityBuffer=t.createBuffer({size:e*4*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,label:"ScriptReadback_Velocity"}),this._scriptStagingInUse=!1}async initComputePipeline(t,e,i){try{return await this.createComputePipeline(t,e,i),this.computeReady=!0,!0}catch(r){return console.error("Error initializing compute pipeline:",r),!1}}async createComputePipeline(t,e,i){this.computeBindGroupLayout=this.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}),this.computePipeline=this.device.createComputePipeline({layout:this.device.createPipelineLayout({bindGroupLayouts:[this.computeBindGroupLayout]}),compute:{module:this.device.createShaderModule({code:Ei}),entryPoint:"main"}}),this.computeBindGroup=this.device.createBindGroup({layout:this.computeBindGroupLayout,entries:[{binding:0,resource:{buffer:this.physicsUniformBuffer}},{binding:1,resource:{buffer:t}},{binding:2,resource:{buffer:e}},{binding:3,resource:{buffer:i}}]})}updatePhysics(t,e,i,r,n,a){if(e<=0||!this.computeReady)return;const o=this._physicsData,c=this.physicsSettings;o[0]=t,o[1]=i.particleSpeed,o[2]=c.gravity,o[3]=c.turbulence,o[4]=c.attractorStrength,o[5]=c.damping,o[6]=c.attractorPosition[0],o[7]=c.attractorPosition[1],o[8]=c.attractorPosition[2],this._physicsDataU32View[9]=e,o[10]=c.confinementEnabled?1:0,o[11]=c.confinementShape==="sphere"?1:0,o[12]=c.confinementMode==="kill"?1:0,o[13]=c.confinementSpace==="local"?1:0,o[14]=c.confinementBoxHalfSize[0],o[15]=c.confinementBoxHalfSize[1],o[16]=c.confinementBoxHalfSize[2],o[17]=c.confinementSphereRadius,o[18]=c.confinementRestitution,o[19]=c.confinementFriction,o[20]=c.confinementCenter[0],o[21]=c.confinementCenter[1],o[22]=c.confinementCenter[2],o[23]=c.softBoundaryEnabled?1:0,o[24]=c.softBoundaryStrength,o[25]=c.softBoundaryFalloff,o[26]=i.velocityStretchEnabled?1:0,o[27]=i.velocityStretchFactor??1,o[28]=0,o[29]=0,o[30]=0,o[31]=0,this.device.queue.writeBuffer(this.physicsUniformBuffer,0,o);const l=a||this.device.createCommandEncoder({label:"ParticlePhysicsEncoder"}),u=l.beginComputePass({label:"ParticlePhysicsPass"});u.setPipeline(this.computePipeline),u.setBindGroup(0,this.computeBindGroup);const m=Math.max(1,Math.ceil(e/64));u.dispatchWorkgroups(m,1,1),u.end(),a||this.device.queue.submit([l.finish()]),this.lastUpdateTime=performance.now()/1e3}async readbackAndProcessParticles(t,e,i,r,n){if(t<=0)return{activeCount:0,shouldUpdate:!1};if(this._stagingInUse)return{activeCount:t,shouldUpdate:!1};try{this._stagingInUse=!0;const a=this.device.createCommandEncoder({label:"ParticleReadbackEncoder"}),o=t*8*4;a.copyBufferToBuffer(r,0,this._particleDataStagingBuffer,0,o);const c=t*4*4;return a.copyBufferToBuffer(n,0,this._velocityStagingBuffer,0,c),this.device.queue.submit([a.finish()]),await Promise.all([(async()=>{await this._particleDataStagingBuffer.mapAsync(GPUMapMode.READ,0,o);const l=new Float32Array(this._particleDataStagingBuffer.getMappedRange(0,o));e.set(l),this._particleDataStagingBuffer.unmap()})(),(async()=>{await this._velocityStagingBuffer.mapAsync(GPUMapMode.READ,0,c);const l=new Float32Array(this._velocityStagingBuffer.getMappedRange(0,c));i.set(l),this._velocityStagingBuffer.unmap()})()]),this._stagingInUse=!1,{particleData:e,particleVelocities:i,shouldUpdate:!0}}catch(a){return this._stagingInUse=!1,a&&a.name==="AbortError"||console.error("Error reading back particle data:",a),{activeCount:t,shouldUpdate:!1}}}setDamping(t){this.physicsSettings.damping=t}setGravity(t){this.physicsSettings.gravity=t}setAttractor(t,e){this.physicsSettings.attractorStrength=t,this.physicsSettings.attractorPosition=e}setConfinement(t){const e=this.physicsSettings;t.enabled!==void 0&&(e.confinementEnabled=t.enabled),t.shape!==void 0&&(e.confinementShape=t.shape),t.mode!==void 0&&(e.confinementMode=t.mode),t.space!==void 0&&(e.confinementSpace=t.space),t.boxSize!==void 0&&(e.confinementBoxHalfSize=t.boxSize),t.sphereRadius!==void 0&&(e.confinementSphereRadius=t.sphereRadius),t.restitution!==void 0&&(e.confinementRestitution=t.restitution),t.friction!==void 0&&(e.confinementFriction=t.friction),t.center!==void 0&&(e.confinementCenter=t.center)}async readbackForRendering(t,e,i,r,n){if(t<=0)return{shouldUpdate:!1};if(this._renderStagingInUse)return{shouldUpdate:!1};try{this._renderStagingInUse=!0;const a=t*8*4,o=t*4*4,c=this.device.createCommandEncoder({label:"RenderReadbackEncoder"});return c.copyBufferToBuffer(r,0,this._renderStagingParticleBuffer,0,a),c.copyBufferToBuffer(n,0,this._renderStagingVelocityBuffer,0,o),this.device.queue.submit([c.finish()]),await Promise.all([(async()=>{await this._renderStagingParticleBuffer.mapAsync(GPUMapMode.READ,0,a);const l=new Float32Array(this._renderStagingParticleBuffer.getMappedRange(0,a));e.set(l),this._renderStagingParticleBuffer.unmap()})(),(async()=>{await this._renderStagingVelocityBuffer.mapAsync(GPUMapMode.READ,0,o);const l=new Float32Array(this._renderStagingVelocityBuffer.getMappedRange(0,o));i.set(l),this._renderStagingVelocityBuffer.unmap()})()]),this._renderStagingInUse=!1,{particleData:e,particleVelocities:i,shouldUpdate:!0}}catch(a){return this._renderStagingInUse=!1,console.error("Error in rendering readback:",a),{shouldUpdate:!1}}}async readbackForScript(t,e,i,r,n){if(t<=0)return{shouldUpdate:!1};if(this._scriptStagingInUse)return{shouldUpdate:!1};try{this._scriptStagingInUse=!0;const a=t*8*4,o=t*4*4,c=this.device.createCommandEncoder({label:"ScriptReadbackEncoder"});return c.copyBufferToBuffer(r,0,this._scriptStagingParticleBuffer,0,a),c.copyBufferToBuffer(n,0,this._scriptStagingVelocityBuffer,0,o),this.device.queue.submit([c.finish()]),await Promise.all([(async()=>{await this._scriptStagingParticleBuffer.mapAsync(GPUMapMode.READ,0,a);const l=new Float32Array(this._scriptStagingParticleBuffer.getMappedRange(0,a));e.set(l),this._scriptStagingParticleBuffer.unmap()})(),(async()=>{await this._scriptStagingVelocityBuffer.mapAsync(GPUMapMode.READ,0,o);const l=new Float32Array(this._scriptStagingVelocityBuffer.getMappedRange(0,o));i.set(l),this._scriptStagingVelocityBuffer.unmap()})()]),this._scriptStagingInUse=!1,{shouldUpdate:!0}}catch(a){return this._scriptStagingInUse=!1,console.error("Error in script readback:",a),{shouldUpdate:!1}}}destroy(){this.physicsUniformBuffer.destroy(),this._particleDataStagingBuffer.destroy(),this._velocityStagingBuffer.destroy(),this._renderStagingParticleBuffer.destroy(),this._renderStagingVelocityBuffer.destroy(),this._scriptStagingParticleBuffer.destroy(),this._scriptStagingVelocityBuffer.destroy()}setSoftBoundary(t){const e=this.physicsSettings;t.enabled!==void 0&&(e.softBoundaryEnabled=t.enabled),t.strength!==void 0&&(e.softBoundaryStrength=t.strength),t.falloff!==void 0&&(e.softBoundaryFalloff=t.falloff)}}class Ai{constructor(t){this.device=t,this.defaultTexture=null,this.createDefaultTexture()}createDefaultTexture(){const t=new Uint8Array([255,255,255,255]);this.defaultTexture=this.device.createTexture({size:[1,1],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST,label:"defaultParticleTexture"}),this.device.queue.writeTexture({texture:this.defaultTexture},t,{bytesPerRow:4},[1,1])}async loadTexture(t){const e=this.device.createTexture({size:[t.width,t.height],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT,label:"particleTexture"});return this.device.queue.copyExternalImageToTexture({source:t},{texture:e},[t.width,t.height]),e}getDefaultTexture(){return this.defaultTexture}destroyTexture(t){t&&t.label!=="defaultParticleTexture"&&t.destroy()}}const Ui=Object.freeze({sin:Math.sin,cos:Math.cos,abs:Math.abs,floor:Math.floor,ceil:Math.ceil,round:Math.round,min:Math.min,max:Math.max,sqrt:Math.sqrt,pow:Math.pow,random:Math.random,PI:Math.PI,TAU:Math.PI*2,clamp(s,t,e){return s<t?t:s>e?e:s},lerp(s,t,e){return s+(t-s)*e},smoothstep(s,t,e){const i=Ui.clamp((e-s)/(t-s),0,1);return i*i*(3-2*i)}}),$e=new Set(["particleSize","particleSpeed","particleColor","startColor","endColor","opacity","emissionRate","gravityStrength","dampingStrength","attractorStrength","attractorPosition","pulseAmplitude","pulseFrequency","bloomIntensity"]);class Ls{constructor(t){this._collection=t,this._pd=null,this._vd=null,this._pi=0,this._vi=0}_bind(t,e,i){return this._pd=t,this._vd=e,this._pi=i*8,this._vi=i*4,this}get x(){return this._pd[this._pi]}set x(t){this._pd[this._pi]=t,this._collection._dirty=!0}get y(){return this._pd[this._pi+1]}set y(t){this._pd[this._pi+1]=t,this._collection._dirty=!0}get z(){return this._pd[this._pi+2]}set z(t){this._pd[this._pi+2]=t,this._collection._dirty=!0}get r(){return this._pd[this._pi+3]}set r(t){this._pd[this._pi+3]=t,this._collection._dirty=!0}get g(){return this._pd[this._pi+4]}set g(t){this._pd[this._pi+4]=t,this._collection._dirty=!0}get b(){return this._pd[this._pi+5]}set b(t){this._pd[this._pi+5]=t,this._collection._dirty=!0}get age(){return this._pd[this._pi+6]}set age(t){this._pd[this._pi+6]=t,this._collection._dirty=!0}get lifetime(){return this._pd[this._pi+7]}set lifetime(t){this._pd[this._pi+7]=t,this._collection._dirty=!0}get vx(){return this._vd[this._vi]}set vx(t){this._vd[this._vi]=t,this._collection._dirty=!0}get vy(){return this._vd[this._vi+1]}set vy(t){this._vd[this._vi+1]=t,this._collection._dirty=!0}get vz(){return this._vd[this._vi+2]}set vz(t){this._vd[this._vi+2]=t,this._collection._dirty=!0}}class Xs{constructor(){this._proxy=new Ls(this),this._pd=null,this._vd=null,this.count=0,this._dirty=!1}_bind(t,e,i){this._pd=t,this._vd=e,this.count=i,this._dirty=!1}get(t){return t<0||t>=this.count?null:this._proxy._bind(this._pd,this._vd,t)}}const ks=1e6;function Ns(s){let t=0;return s.replace(/\b(for|while)\s*\([^)]*\)\s*\{/g,e=>{const i=`__lc${t++}`;return`${e} if(++${i}>${ks})throw new Error("Loop limit exceeded");`}).replace(/\b(for|while)\s*\([^)]*\)\s*\{/g,e=>e).replace(/^/,()=>{let e="";for(let i=0;i<t;i++)e+=`let __lc${i}=0;`;return e})}const wt=new Map;for(const s of $e)wt.set(s.toLowerCase(),s);function js(s){const t={value:!1},e=new Set;return new Proxy(s,{get(r,n){if(n==="__dirty")return t.value;if(n==="__resetDirty")return()=>{t.value=!1};if(typeof n!="string")return;if($e.has(n))return r[n];const a=wt.get(n.toLowerCase());if(a)return e.has(n)||(e.add(n),console.warn(`[ParticleScript] config.${n} → did you mean config.${a}?`)),r[a]},set(r,n,a){if(typeof n!="string")return!0;let o=n;if(!$e.has(o)){const c=wt.get(o.toLowerCase());if(c)e.has(n)||(e.add(n),console.warn(`[ParticleScript] config.${n} → did you mean config.${c}?`)),o=c;else return!0}return r[o]=a,t.value=!0,!0}})}class Bt{constructor(t,e,i){this._particles=new Xs,this._configProxy=js(e),this._configSnapshot=null,this._fn=null,this._error=!1,this.compile(t)}compile(t){if(this._fn=null,this._error=!1,!(!t||typeof t!="string"))try{const i=`
|
|
869
869
|
return function(__deltaTime, __time, __currentFrame, __totalFrames, __particles, __config, __math) {
|
|
870
870
|
var window = void 0, document = void 0, globalThis = void 0;
|
|
871
871
|
var Function = void 0, eval = void 0, fetch = void 0;
|
|
@@ -873,8 +873,8 @@ return function(__deltaTime, __time, __currentFrame, __totalFrames, __particles,
|
|
|
873
873
|
var deltaTime = __deltaTime, time = __time;
|
|
874
874
|
var currentFrame = __currentFrame, totalFrames = __totalFrames;
|
|
875
875
|
var particles = __particles, config = __config, math = __math;
|
|
876
|
-
${
|
|
877
|
-
};`,r=new Function(i);this._fn=r()}catch(e){console.warn("[ParticleScript] Compilation error:",e.message),this._fn=null,this._error=!0}}execute(t,e,i,r,n,a,o){if(!this._fn||this._error)return{configDirty:!1,particlesDirty:!1};this._particles._bind(n,a,o),this._configProxy.__resetDirty();try{this._fn(t,e,i,r,this._particles,this._configProxy,Ei)}catch(c){console.warn("[ParticleScript] Runtime error:",c.message)}return{configDirty:this._configProxy.__dirty,particlesDirty:this._particles._dirty}}snapshotConfig(t){const e={};for(const i of qe){const r=t[i];r!==void 0&&(e[i]=Array.isArray(r)?[...r]:r)}this._configSnapshot=e}restoreConfig(t){if(this._configSnapshot){for(const e of qe)if(e in this._configSnapshot){const i=this._configSnapshot[e];t[e]=Array.isArray(i)?[...i]:i}}}destroy(){this._fn=null,this._particles=null,this._configProxy=null,this._configSnapshot=null}}async function Ci(s){const t=new DataView(s);if(t.getUint32(0,!0)!==1179937895)throw new Error("Invalid GLB file: incorrect magic number");const i=t.getUint32(4,!0);if(i!==2)throw new Error(`Unsupported GLB version: ${i} (only version 2 is supported)`);const r=t.getUint32(8,!0);let n=12,a=null,o=null;for(;n<r;){const P=t.getUint32(n,!0),B=t.getUint32(n+4,!0),M=s.slice(n+8,n+8+P);if(B===1313821514){const k=new TextDecoder("utf-8").decode(M);a=JSON.parse(k)}else B===5130562&&(o=M);n+=8+P}if(!a)throw new Error("GLB file missing JSON chunk");if(!a.meshes||a.meshes.length===0)throw new Error("GLB file contains no meshes");const l=a.meshes[0].primitives[0];if(!l)throw new Error("First mesh has no primitives");const u=l.attributes.POSITION;if(u===void 0)throw new Error("Mesh primitive missing POSITION attribute");const h=St(a,o,u,3,5126);let p;if(l.attributes.NORMAL!==void 0)p=St(a,o,l.attributes.NORMAL,3,5126);else{const P=l.indices;if(P===void 0)throw new Error("Cannot generate normals without indices");const B=di(a,o,P);p=ks(h,B)}const d=l.indices;if(d===void 0)throw new Error("Mesh primitive missing indices");const S=di(a,o,d),R=h.length/3,E=S.length;let T=null;l.attributes.TEXCOORD_0!==void 0&&(T=St(a,o,l.attributes.TEXCOORD_0,2,5126));let x=!1;if(a.materials&&a.materials.length>0){const P=a.materials[0];P.pbrMetallicRoughness&&P.pbrMetallicRoughness.baseColorTexture!==void 0&&(x=!0)}let L=null;if(a.skins&&a.skins.length>0)try{L=qs(a,o,l),globalThis.__HZFX_DEBUG&&console.log("Animation data extracted:",L)}catch(P){console.warn("Failed to extract animation data:",P)}return{positions:h,normals:p,indices:S,texCoords:T,vertexCount:R,indexCount:E,animationData:L,hasBaseColorTexture:x}}function St(s,t,e,i,r){const n=s.accessors[e],o={SCALAR:1,VEC2:2,VEC3:3,VEC4:4}[n.type];if(o!==i)throw new Error(`Attribute accessor type mismatch: expected ${i} components, got ${o}`);if(n.componentType!==r)throw new Error(`Attribute component type mismatch: expected ${r}, got ${n.componentType}`);const l=(s.bufferViews[n.bufferView].byteOffset||0)+(n.byteOffset||0),u=n.count,h=new DataView(t,l,u*i*4),p=new Float32Array(u*i);for(let d=0;d<u*i;d++)p[d]=h.getFloat32(d*4,!0);return p}function di(s,t,e){const i=s.accessors[e];if(i.type!=="SCALAR")throw new Error(`Indices accessor must be SCALAR, got ${i.type}`);const n=(s.bufferViews[i.bufferView].byteOffset||0)+(i.byteOffset||0),a=i.count;if(i.componentType===5123){const o=new DataView(t,n,a*2),c=new Uint16Array(a);for(let l=0;l<a;l++)c[l]=o.getUint16(l*2,!0);return c}else if(i.componentType===5125){const o=new DataView(t,n,a*4),c=new Uint32Array(a);for(let l=0;l<a;l++)c[l]=o.getUint32(l*4,!0);return c}else throw new Error(`Unsupported index component type: ${i.componentType}`)}function ks(s,t){const e=new Float32Array(s.length);for(let i=0;i<t.length;i+=3){const r=t[i]*3,n=t[i+1]*3,a=t[i+2]*3,o=[s[r],s[r+1],s[r+2]],c=[s[n],s[n+1],s[n+2]],l=[s[a],s[a+1],s[a+2]],u=[c[0]-o[0],c[1]-o[1],c[2]-o[2]],h=[l[0]-o[0],l[1]-o[1],l[2]-o[2]],p=[u[1]*h[2]-u[2]*h[1],u[2]*h[0]-u[0]*h[2],u[0]*h[1]-u[1]*h[0]],d=Math.sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]);d>0&&(p[0]/=d,p[1]/=d,p[2]/=d),e[r]=e[n]=e[a]=p[0],e[r+1]=e[n+1]=e[a+1]=p[1],e[r+2]=e[n+2]=e[a+2]=p[2]}return e}function Ns(s,t,e){const i=s.accessors[e];if(i.type!=="VEC4")throw new Error(`JOINTS_0 must be VEC4, got ${i.type}`);const n=(s.bufferViews[i.bufferView].byteOffset||0)+(i.byteOffset||0),a=i.count;if(i.componentType===5121){const o=new DataView(t,n,a*4),c=new Uint8Array(a*4);for(let l=0;l<a*4;l++)c[l]=o.getUint8(l);return c}else if(i.componentType===5123){const o=new DataView(t,n,a*8),c=new Uint8Array(a*4);for(let l=0;l<a*4;l++)c[l]=o.getUint16(l*2,!0);return c}else throw new Error(`Unsupported JOINTS_0 component type: ${i.componentType}`)}function js(s,t,e){const i=s.accessors[e];if(i.type!=="VEC4")throw new Error(`WEIGHTS_0 must be VEC4, got ${i.type}`);const n=(s.bufferViews[i.bufferView].byteOffset||0)+(i.byteOffset||0),a=i.count;if(i.componentType===5126){const o=new DataView(t,n,a*16),c=new Float32Array(a*4);for(let l=0;l<a*4;l++)c[l]=o.getFloat32(l*4,!0);return c}else if(i.componentType===5121){const o=new DataView(t,n,a*4),c=new Float32Array(a*4);for(let l=0;l<a*4;l++)c[l]=o.getUint8(l)/255;return c}else throw new Error(`Unsupported WEIGHTS_0 component type: ${i.componentType}`)}function Ys(s,t,e){const i=s.accessors[e];if(i.type!=="MAT4")throw new Error(`Expected MAT4, got ${i.type}`);if(i.componentType!==5126)throw new Error(`Expected FLOAT component type for MAT4, got ${i.componentType}`);const n=(s.bufferViews[i.bufferView].byteOffset||0)+(i.byteOffset||0),a=i.count,o=new DataView(t,n,a*64),c=new Float32Array(a*16);for(let l=0;l<a*16;l++)c[l]=o.getFloat32(l*4,!0);return c}function Hs(s,t,e){const i=s.accessors[e];if(i.type!=="SCALAR")throw new Error(`Expected SCALAR, got ${i.type}`);if(i.componentType!==5126)throw new Error(`Expected FLOAT component type for SCALAR, got ${i.componentType}`);const n=(s.bufferViews[i.bufferView].byteOffset||0)+(i.byteOffset||0),a=i.count,o=new DataView(t,n,a*4),c=new Float32Array(a);for(let l=0;l<a;l++)c[l]=o.getFloat32(l*4,!0);return c}function Zs(s,t,e){const i=s.accessors[e],n={VEC3:3,VEC4:4}[i.type];if(!n)throw new Error(`Expected VEC3 or VEC4, got ${i.type}`);if(i.componentType!==5126)throw new Error(`Expected FLOAT component type, got ${i.componentType}`);const o=(s.bufferViews[i.bufferView].byteOffset||0)+(i.byteOffset||0),c=i.count,l=new DataView(t,o,c*n*4),u=new Float32Array(c*n);for(let h=0;h<c*n;h++)u[h]=l.getFloat32(h*4,!0);return u}function qs(s,t,e){const i=s.skins[0],r=i.joints,n=Ys(s,t,i.inverseBindMatrices),a=e.attributes.JOINTS_0!==void 0?Ns(s,t,e.attributes.JOINTS_0):null,o=e.attributes.WEIGHTS_0!==void 0?js(s,t,e.attributes.WEIGHTS_0):null;if(!a||!o)throw new Error("Mesh missing JOINTS_0 or WEIGHTS_0 attributes");const c=s.nodes.map(u=>({translation:u.translation||[0,0,0],rotation:u.rotation||[0,0,0,1],scale:u.scale||[1,1,1],children:u.children||[],name:u.name||""})),l=[];if(s.animations&&s.animations.length>0)for(const u of s.animations){const h=[];let p=0;for(const d of u.channels){const S=u.samplers[d.sampler],R=Hs(s,t,S.input),E=Zs(s,t,S.output),T=R[R.length-1];T>p&&(p=T),h.push({targetNode:d.target.node,targetPath:d.target.path,interpolation:S.interpolation||"LINEAR",timestamps:R,values:E})}l.push({name:u.name||`Animation ${l.length}`,duration:p,channels:h})}return{joints:r,inverseBindMatrices:n,jointIndices:a,jointWeights:o,nodes:c,animations:l}}async function _t(s){const t=new DataView(s);if(t.getUint32(0,!0)!==1179937895)throw new Error("Invalid GLB file: incorrect magic number");const i=t.getUint32(4,!0);if(i!==2)throw new Error(`Unsupported GLB version: ${i}`);const r=t.getUint32(8,!0);let n=12,a=null,o=null;for(;n<r;){const L=t.getUint32(n,!0),P=t.getUint32(n+4,!0),B=s.slice(n+8,n+8+L);if(P===1313821514){const F=new TextDecoder("utf-8").decode(B);a=JSON.parse(F)}else P===5130562&&(o=B);n+=8+L}if(!a)throw new Error("GLB file missing JSON chunk");if(!a.materials||a.materials.length===0)return null;const c=a.materials[0];if(!c.pbrMetallicRoughness||c.pbrMetallicRoughness.baseColorTexture===void 0)return null;const l=c.pbrMetallicRoughness.baseColorTexture.index;if(!a.textures||!a.textures[l])return null;const h=a.textures[l].source;if(h===void 0||!a.images||!a.images[h])return null;const p=a.images[h],d=p.mimeType||"image/png";if(p.bufferView===void 0)return null;if(!o)throw new Error("GLB file missing BIN chunk (required for embedded textures)");const S=a.bufferViews[p.bufferView],R=S.byteOffset||0,E=S.byteLength,T=o.slice(R,R+E);return{imageBlob:new Blob([T],{type:d}),mimeType:d}}function fi(s,t,e){return[s[0]+(t[0]-s[0])*e,s[1]+(t[1]-s[1])*e,s[2]+(t[2]-s[2])*e]}function pi(s,t,e){let i=s[0]*t[0]+s[1]*t[1]+s[2]*t[2]+s[3]*t[3],r=t;if(i<0&&(i=-i,r=[-t[0],-t[1],-t[2],-t[3]]),i>.9995){const l=[s[0]+(r[0]-s[0])*e,s[1]+(r[1]-s[1])*e,s[2]+(r[2]-s[2])*e,s[3]+(r[3]-s[3])*e];return $s(l)}const n=Math.acos(i),a=Math.sin(n),o=Math.sin((1-e)*n)/a,c=Math.sin(e*n)/a;return[s[0]*o+r[0]*c,s[1]*o+r[1]*c,s[2]*o+r[2]*c,s[3]*o+r[3]*c]}function $s(s){const t=Math.sqrt(s[0]*s[0]+s[1]*s[1]+s[2]*s[2]+s[3]*s[3]);return t>1e-4?[s[0]/t,s[1]/t,s[2]/t,s[3]/t]:[0,0,0,1]}function Ws(s,t){const e=s[0],i=s[1],r=s[2],n=s[3],a=e+e,o=i+i,c=r+r,l=e*a,u=e*o,h=e*c,p=i*o,d=i*c,S=r*c,R=n*a,E=n*o,T=n*c,x=t||new Float32Array(16);return x[0]=1-(p+S),x[1]=u+T,x[2]=h-E,x[3]=0,x[4]=u-T,x[5]=1-(l+S),x[6]=d+R,x[7]=0,x[8]=h+E,x[9]=d-R,x[10]=1-(l+p),x[11]=0,x[12]=0,x[13]=0,x[14]=0,x[15]=1,x}const Js=new Float32Array(16);function Qs(s,t,e,i){const r=Ws(t,Js),n=i||new Float32Array(16);return n[0]=r[0]*e[0],n[1]=r[1]*e[0],n[2]=r[2]*e[0],n[3]=0,n[4]=r[4]*e[1],n[5]=r[5]*e[1],n[6]=r[6]*e[1],n[7]=0,n[8]=r[8]*e[2],n[9]=r[9]*e[2],n[10]=r[10]*e[2],n[11]=0,n[12]=s[0],n[13]=s[1],n[14]=s[2],n[15]=1,n}function hi(s,t,e){const i=e||new Float32Array(16);for(let r=0;r<4;r++)for(let n=0;n<4;n++)i[r*4+n]=s[0+n]*t[r*4+0]+s[4+n]*t[r*4+1]+s[8+n]*t[r*4+2]+s[12+n]*t[r*4+3];return i}class Ai{constructor(t){this.joints=t.joints,this.inverseBindMatrices=t.inverseBindMatrices,this.jointWeights=t.jointWeights,this.jointIndices=t.jointIndices,this.nodes=t.nodes,this.animations=t.animations,this.restPositions=null,this.restNormals=null,this.currentAnimIndex=0,this.currentTime=0,this.playing=!0,this.speed=1,this.loop=!0,this.jointLocalTransforms=new Array(this.nodes.length),this.jointGlobalTransforms=new Array(this.nodes.length),this.jointFinalMatrices=new Array(this.joints.length);for(let e=0;e<this.nodes.length;e++)this.jointLocalTransforms[e]=new Float32Array(16),this.jointGlobalTransforms[e]=new Float32Array(16);for(let e=0;e<this.joints.length;e++)this.jointFinalMatrices[e]=new Float32Array(16);this.skinnedPositions=null,this.skinnedNormals=null,this._gpuSkinningReady=!1,this._buildTopologicalOrder(),this._parentMap=new Array(this.nodes.length).fill(-1);for(let e=0;e<this.nodes.length;e++)for(const i of this.nodes[e].children)this._parentMap[i]=e;this._invBindViews=new Array(this.joints.length);for(let e=0;e<this.joints.length;e++)this._invBindViews[e]=this.inverseBindMatrices.subarray(e*16,e*16+16)}setRestPose(t,e){this.restPositions=new Float32Array(t),this.restNormals=new Float32Array(e),this.skinnedPositions=new Float32Array(t.length),this.skinnedNormals=new Float32Array(e.length)}async initGPUSkinning(t,e,i){try{this._gpuDevice=t,this._gpuOutputBuffer=e;const r=this.restPositions.length/3,n=new Float32Array(r*8);for(let c=0;c<r;c++){const l=c*8,u=c*3,h=c*2;n[l]=this.restPositions[u],n[l+1]=this.restPositions[u+1],n[l+2]=this.restPositions[u+2],n[l+3]=this.restNormals[u],n[l+4]=this.restNormals[u+1],n[l+5]=this.restNormals[u+2],n[l+6]=i?i[h]:0,n[l+7]=i?i[h+1]:0}this._gpuRestDataBuffer=t.createBuffer({size:n.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,label:"skinning_restData"}),t.queue.writeBuffer(this._gpuRestDataBuffer,0,n),this._gpuJointWeightsBuffer=t.createBuffer({size:this.jointWeights.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,label:"skinning_jointWeights"}),t.queue.writeBuffer(this._gpuJointWeightsBuffer,0,this.jointWeights);const a=new Uint32Array(this.jointIndices.length);for(let c=0;c<this.jointIndices.length;c++)a[c]=this.jointIndices[c];this._gpuJointIndicesBuffer=t.createBuffer({size:a.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,label:"skinning_jointIndices"}),t.queue.writeBuffer(this._gpuJointIndicesBuffer,0,a),this._gpuJointMatricesBuffer=t.createBuffer({size:this.joints.length*16*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,label:"skinning_jointMatrices"}),this._gpuJointMatricesData=new Float32Array(this.joints.length*16);const o=t.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]});this._gpuSkinningPipeline=t.createComputePipeline({layout:t.createPipelineLayout({bindGroupLayouts:[o]}),compute:{module:t.createShaderModule({code:Ds}),entryPoint:"main"}}),this._gpuSkinningBindGroup=t.createBindGroup({layout:o,entries:[{binding:0,resource:{buffer:this._gpuRestDataBuffer}},{binding:1,resource:{buffer:this._gpuJointWeightsBuffer}},{binding:2,resource:{buffer:this._gpuJointIndicesBuffer}},{binding:3,resource:{buffer:this._gpuJointMatricesBuffer}},{binding:4,resource:{buffer:this._gpuOutputBuffer}}]}),this._gpuVertexCount=r,this._gpuSkinningReady=!0,globalThis.__HZFX_DEBUG&&console.log(`GPU skinning initialized: ${r} vertices, ${this.joints.length} joints`)}catch(r){console.warn("GPU skinning init failed, using CPU fallback:",r),this._gpuSkinningReady=!1}}_applySkinningGPU(){for(let i=0;i<this.joints.length;i++)this._gpuJointMatricesData.set(this.jointFinalMatrices[i],i*16);this._gpuDevice.queue.writeBuffer(this._gpuJointMatricesBuffer,0,this._gpuJointMatricesData);const t=this._gpuDevice.createCommandEncoder({label:"SkinningComputeEncoder"}),e=t.beginComputePass({label:"SkinningComputePass"});e.setPipeline(this._gpuSkinningPipeline),e.setBindGroup(0,this._gpuSkinningBindGroup),e.dispatchWorkgroups(Math.ceil(this._gpuVertexCount/64),1,1),e.end(),this._gpuDevice.queue.submit([t.finish()])}update(t){if(!this.playing||this.animations.length===0)return{positions:this.skinnedPositions,normals:this.skinnedNormals,changed:!1};this.currentTime+=t*this.speed;const e=this.animations[this.currentAnimIndex];return this.loop?this.currentTime=this.currentTime%e.duration:this.currentTime>e.duration&&(this.currentTime=e.duration,this.playing=!1),this._computeLocalTransforms(this.currentTime),this._computeGlobalTransforms(),this._computeFinalMatrices(),this._gpuSkinningReady?(this._applySkinningGPU(),{gpuSkinned:!0,changed:!0}):(this._applySkinning(),{positions:this.skinnedPositions,normals:this.skinnedNormals,changed:!0})}getCurrentAnimation(){return this.animations[this.currentAnimIndex]}setAnimation(t){t>=0&&t<this.animations.length&&(this.currentAnimIndex=t,this.currentTime=0)}getAnimationNames(){return this.animations.map(t=>t.name)}_buildTopologicalOrder(){const t=new Set,e=[],i=n=>{if(t.has(n))return;t.add(n);const a=this.nodes[n];for(const o of a.children)i(o);e.push(n)},r=new Set;for(const n of this.nodes)for(const a of n.children)r.add(a);for(let n=0;n<this.nodes.length;n++)r.has(n)||i(n);this.topologicalOrder=e.reverse()}_sampleChannel(t,e){const{timestamps:i,values:r,interpolation:n,targetPath:a}=t;if(e<=i[0])return this._extractValue(r,0,a);if(e>=i[i.length-1])return this._extractValue(r,i.length-1,a);let o=0,c=i.length-1;for(;c-o>1;){const S=Math.floor((o+c)/2);i[S]<=e?o=S:c=S}const l=i[o],u=i[c],h=(e-l)/(u-l),p=this._extractValue(r,o,a),d=this._extractValue(r,c,a);return n==="STEP"?p:a==="rotation"?pi(p,d,h):fi(p,d,h)}_extractValue(t,e,i){if(i==="rotation"){const r=e*4;return[t[r],t[r+1],t[r+2],t[r+3]]}else{const r=e*3;return[t[r],t[r+1],t[r+2]]}}_computeLocalTransforms(t){const e=this.animations[this.currentAnimIndex];for(let i=0;i<this.nodes.length;i++){const r=this.nodes[i];let n=r.translation,a=r.rotation,o=r.scale;for(const c of e.channels)if(c.targetNode===i){const l=this._sampleChannel(c,t);c.targetPath==="translation"?n=l:c.targetPath==="rotation"?a=l:c.targetPath==="scale"&&(o=l)}Qs(n,a,o,this.jointLocalTransforms[i])}}_computeGlobalTransforms(){const t=this._parentMap;for(const e of this.topologicalOrder){const i=t[e];i===-1?this.jointGlobalTransforms[e].set(this.jointLocalTransforms[e]):hi(this.jointGlobalTransforms[i],this.jointLocalTransforms[e],this.jointGlobalTransforms[e])}}_computeFinalMatrices(){for(let t=0;t<this.joints.length;t++){const e=this.joints[t],i=this.jointGlobalTransforms[e];hi(i,this._invBindViews[t],this.jointFinalMatrices[t])}}_applySkinning(){const t=this.restPositions.length/3,e=this.restPositions,i=this.restNormals,r=this.skinnedPositions,n=this.skinnedNormals,a=this.jointWeights,o=this.jointIndices,c=this.jointFinalMatrices;for(let l=0;l<t;l++){const u=l*3,h=l*4,p=e[u],d=e[u+1],S=e[u+2],R=i[u],E=i[u+1],T=i[u+2];let x=0,L=0,P=0,B=0,M=0,F=0;for(let Y=0;Y<4;Y++){const N=a[h+Y];if(N===0)continue;const G=c[o[h+Y]];x+=(G[0]*p+G[4]*d+G[8]*S+G[12])*N,L+=(G[1]*p+G[5]*d+G[9]*S+G[13])*N,P+=(G[2]*p+G[6]*d+G[10]*S+G[14])*N,B+=(G[0]*R+G[4]*E+G[8]*T)*N,M+=(G[1]*R+G[5]*E+G[9]*T)*N,F+=(G[2]*R+G[6]*E+G[10]*T)*N}const k=Math.sqrt(B*B+M*M+F*F);k>1e-4&&(n[u]=B/k,n[u+1]=M/k,n[u+2]=F/k),r[u]=x,r[u+1]=L,r[u+2]=P}}}class Ui{constructor({duration:t=0,loop:e=!1,playbackRate:i=1}={}){this.currentTime=0,this.duration=t,this.loop=e,this.playbackRate=i,this.paused=!1,this._justLooped=!1}tick(t){if(this.paused)return 0;const e=t*this.playbackRate;return this.currentTime+=e,this._justLooped=!1,this.loop&&this.duration>0&&isFinite(this.duration)&&this.currentTime>=this.duration&&(this.currentTime=0,this._justLooped=!0),e}get justLooped(){return this._justLooped}reset(){this.currentTime=0,this._justLooped=!1}seek(t){this.currentTime=Math.max(0,t||0),this._justLooped=!1}}const mi={linear:s=>s,easeInQuad:s=>s*s,easeOutQuad:s=>1-(1-s)*(1-s),easeInOutQuad:s=>s<.5?2*s*s:1-Math.pow(-2*s+2,2)/2,easeInCubic:s=>s*s*s,easeOutCubic:s=>1-Math.pow(1-s,3),easeInOutCubic:s=>s<.5?4*s*s*s:1-Math.pow(-2*s+2,3)/2,easeInQuart:s=>s*s*s*s,easeOutQuart:s=>1-Math.pow(1-s,4),easeInOutQuart:s=>s<.5?8*s*s*s*s:1-Math.pow(-2*s+2,4)/2,easeOutBack:s=>1+2.70158*Math.pow(s-1,3)+1.70158*Math.pow(s-1,2),easeOutElastic:s=>{if(s===0||s===1)return s;const t=2*Math.PI/3;return Math.pow(2,-10*s)*Math.sin((s*10-.75)*t)+1}};function Ks(s,t,e,i){const r=3*s,n=3*(e-s)-r,a=1-r-n,o=3*t,c=3*(i-t)-o,l=1-o-c,u=d=>((a*d+n)*d+r)*d,h=d=>((l*d+c)*d+o)*d,p=d=>(3*a*d+2*n)*d+r;return d=>{if(d<=0)return 0;if(d>=1)return 1;let S=d;for(let R=0;R<8;R++){const E=u(S)-d;if(Math.abs(E)<1e-5)break;const T=p(S);if(Math.abs(T)<1e-6)break;S-=E/T}return h(S)}}function Ii(s,t){return typeof s=="function"?s(t):Array.isArray(s)&&s.length===4?Ks(s[0],s[1],s[2],s[3])(t):(mi[s]||mi.linear)(t)}function er(s,t){if(!Array.isArray(s)||s.length===0)return;if(s.length===1||t<=s[0].t)return s[0].v;const e=s[s.length-1];if(t>=e.t)return e.v;for(let i=0;i<s.length-1;i++){const r=s[i],n=s[i+1];if(t>=r.t&&t<=n.t){const a=n.t-r.t,o=a>0?(t-r.t)/a:0;return r.v+(n.v-r.v)*Ii(r.ease,o)}}return e.v}function tr(s,t){if(!Array.isArray(s)||s.length===0)return;const e=(r,n,a)=>[r[0]+(n[0]-r[0])*a,r[1]+(n[1]-r[1])*a,r[2]+(n[2]-r[2])*a];if(s.length===1||t<=s[0].t)return s[0].v.slice();const i=s[s.length-1];if(t>=i.t)return i.v.slice();for(let r=0;r<s.length-1;r++){const n=s[r],a=s[r+1];if(t>=n.t&&t<=a.t){const o=a.t-n.t,c=o>0?(t-n.t)/o:0;return e(n.v,a.v,Ii(n.ease,c))}}return i.v.slice()}const ir=["gravityStrength","emissionRate","damping","particleSize","particleSpeed"],sr={square:0,circle:1,triangle:2,diamond:3,star:4,hexagon:5,ring:6,heart:7,cross:8,spark:9,leaf:10,capsule:11,crescent:12,line:13,"curved-line":14};function yi(s){const t=atob(s),e=new Uint8Array(t.length);for(let i=0;i<t.length;i++)e[i]=t.charCodeAt(i);return e.buffer}class at{constructor(t,e){this.device=t,this.config=e,this.MAX_PARTICLES=e.maxParticles||1e4,this.particleCount=e.particleCount||100,this.activeParticles=0,this.emitting=!1,this.currentEmissionTime=0,this.destroyed=!1,this.particleData=new Float32Array(this.MAX_PARTICLES*8),this.particleVelocities=new Float32Array(this.MAX_PARTICLES*4),this.instanceBuffer=t.createBuffer({size:this.MAX_PARTICLES*8*4,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC,label:"particleInstanceBuffer"}),this.velocityBuffer=t.createBuffer({size:this.MAX_PARTICLES*4*4,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,label:"particleVelocityBuffer"}),this.trailBuffer=t.createBuffer({size:this.MAX_PARTICLES*4*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,label:"particleTrailBuffer"}),this._trailResetData=new Float32Array(this.MAX_PARTICLES*4),this.appearanceUniformBuffer=t.createBuffer({size:224,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,label:"appearanceUniformBuffer"}),this.bloomIntensityBuffer=t.createBuffer({size:64,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,label:"systemBloomIntensityBuffer"}),e.overrideXVelocity===void 0&&(e.overrideXVelocity=!1),e.overrideYVelocity===void 0&&(e.overrideYVelocity=!1),e.overrideZVelocity===void 0&&(e.overrideZVelocity=!1),e.xVelocity===void 0&&(e.xVelocity=0),e.yVelocity===void 0&&(e.yVelocity=0),e.zVelocity===void 0&&(e.zVelocity=0),e.textureEnabled===void 0&&(e.textureEnabled=!1),e.glbModelEnabled===void 0&&(e.glbModelEnabled=!1),e.textureType===void 0&&(e.textureType="image"),e.glbFileName===void 0&&(e.glbFileName=null),e.animationIndex===void 0&&(e.animationIndex=0),e.animationSpeed===void 0&&(e.animationSpeed=1),e.animationLoop===void 0&&(e.animationLoop=!0),e.useGlbTexture===void 0&&(e.useGlbTexture=!1),e.glbHasTexture===void 0&&(e.glbHasTexture=!1),e.particleShape===void 0&&(e.particleShape="square"),e.particleShapeRotation!==void 0&&(e.rotation=(e.rotation||0)+e.particleShapeRotation,delete e.particleShapeRotation),e.particleShapeRotationX===void 0&&(e.particleShapeRotationX=0),e.particleShapeRotationY===void 0&&(e.particleShapeRotationY=0),e.particleShapeRotationZ===void 0&&(e.particleShapeRotationZ=0),e.particleColor===void 0&&(e.particleColor=[1,1,1]),e.startColor===void 0&&(e.startColor=[1,0,0]),e.endColor===void 0&&(e.endColor=[0,0,1]),e.fadeEnabled===void 0&&(e.fadeEnabled=!0),e.colorTransitionEnabled===void 0&&(e.colorTransitionEnabled=!1),e.randomColorEnabled===void 0&&(e.randomColorEnabled=!1),e.randomColors===void 0&&(e.randomColors=[]),e.particleSize===void 0&&(e.particleSize=.1),e.particleSpeed===void 0&&(e.particleSpeed=1),e.opacity===void 0&&(e.opacity=1),e.aspectRatio===void 0&&(e.aspectRatio=1),e.rotation===void 0&&(e.rotation=0),e.rotationMode===void 0&&(e.rotationMode="fixed"),e.minRotation===void 0&&(e.minRotation=0),e.maxRotation===void 0&&(e.maxRotation=90),e.orientX===void 0&&(e.orientX=0),e.orientY===void 0&&(e.orientY=0),e.orientZ===void 0&&(e.orientZ=0),e.randomSize===void 0&&(e.randomSize=!1),e.minSize===void 0&&(e.minSize=.05),e.maxSize===void 0&&(e.maxSize=.15),e.randomSpeed===void 0&&(e.randomSpeed=!1),e.minSpeed===void 0&&(e.minSpeed=.1),e.maxSpeed===void 0&&(e.maxSpeed=1),e.fadeSizeEnabled===void 0&&(e.fadeSizeEnabled=!1),e.increaseSizeEnabled===void 0&&(e.increaseSizeEnabled=!1),e.sizeLifetimeSpeed===void 0&&(e.sizeLifetimeSpeed=1),e.bloomEnabled===void 0&&(e.bloomEnabled=!0),e.bloomIntensity===void 0&&(e.bloomIntensity=1),e.bloomColor===void 0&&(e.bloomColor=[1,1,1]),e.gravityEnabled===void 0&&(e.gravityEnabled=!1),e.gravityStrength===void 0&&(e.gravityStrength=2),e.dampingEnabled===void 0&&(e.dampingEnabled=!1),e.dampingStrength===void 0&&(e.dampingStrength=1),e.attractorEnabled===void 0&&(e.attractorEnabled=!1),e.attractorStrength===void 0&&(e.attractorStrength=1),e.attractorPosition===void 0&&(e.attractorPosition=[0,0,0]),e.burstMode===void 0&&(e.burstMode=!1),e.emissionShape===void 0&&(e.emissionShape="cube"),e.lifetime===void 0&&(e.lifetime=5),e.emissionRate===void 0&&(e.emissionRate=10),e.startAt===void 0&&(e.startAt=0),e.emissionDuration===void 0&&(e.emissionDuration=10),e.emissionDurationInfinite===void 0&&(e.emissionDurationInfinite=!1),e.emissionDuration>300&&(e.emissionDurationInfinite=!0,e.emissionDuration=10),e.outerLength===void 0&&(e.outerLength=e.cubeLength??2),e.innerLength===void 0&&(e.innerLength=0),e.outerRadius===void 0&&(e.outerRadius=2),e.innerRadius===void 0&&(e.innerRadius=0),e.squareSize===void 0&&(e.squareSize=2),e.squareInnerSize===void 0&&(e.squareInnerSize=0),e.circleInnerRadius===void 0&&(e.circleInnerRadius=0),e.circleOuterRadius===void 0&&(e.circleOuterRadius=2),e.circleVelocityDirection===void 0&&(e.circleVelocityDirection="outward"),e.cylinderInnerRadius===void 0&&(e.cylinderInnerRadius=0),e.cylinderOuterRadius===void 0&&(e.cylinderOuterRadius=2),e.cylinderHeight===void 0&&(e.cylinderHeight=4),e.cylinderVelocityDirection===void 0&&(e.cylinderVelocityDirection="outward"),e.planeWidth===void 0&&(e.planeWidth=2),e.planeDepth===void 0&&(e.planeDepth=2),e.coneOuterRadius===void 0&&(e.coneOuterRadius=2),e.coneInnerRadius===void 0&&(e.coneInnerRadius=0),e.coneHeight===void 0&&(e.coneHeight=4),e.torusMajorRadius===void 0&&(e.torusMajorRadius=2),e.torusMinorRadius===void 0&&(e.torusMinorRadius=.5),e.lineLength===void 0&&(e.lineLength=4),e.hemisphereOuterRadius===void 0&&(e.hemisphereOuterRadius=2),e.hemisphereInnerRadius===void 0&&(e.hemisphereInnerRadius=0),e.discRadius===void 0&&(e.discRadius=2),e.annulusInnerRadius===void 0&&(e.annulusInnerRadius=1),e.annulusOuterRadius===void 0&&(e.annulusOuterRadius=2),e.capsuleRadius===void 0&&(e.capsuleRadius=.5),e.capsuleHeight===void 0&&(e.capsuleHeight=4),e.arcStartAngle===void 0&&(e.arcStartAngle=0),e.arcEndAngle===void 0&&(e.arcEndAngle=180),e.arcInnerRadius===void 0&&(e.arcInnerRadius=0),e.arcOuterRadius===void 0&&(e.arcOuterRadius=2),e.spiralTurns===void 0&&(e.spiralTurns=3),e.spiralRadiusStart===void 0&&(e.spiralRadiusStart=.5),e.spiralRadiusEnd===void 0&&(e.spiralRadiusEnd=2),e.spiralHeight===void 0&&(e.spiralHeight=4),e.frustumRadiusNear===void 0&&(e.frustumRadiusNear=.5),e.frustumRadiusFar===void 0&&(e.frustumRadiusFar=2),e.frustumHeight===void 0&&(e.frustumHeight=4),e.cubeSurfaceSize===void 0&&(e.cubeSurfaceSize=2),e.sphereSurfaceRadius===void 0&&(e.sphereSurfaceRadius=2),e.boxFrameSize===void 0&&(e.boxFrameSize=2),e.polygonSides===void 0&&(e.polygonSides=6),e.polygonRadius===void 0&&(e.polygonRadius=2),e.emissionRotationX===void 0&&(e.emissionRotationX=0),e.emissionRotationY===void 0&&(e.emissionRotationY=0),e.emissionRotationZ===void 0&&(e.emissionRotationZ=0),e.emissionPositionX===void 0&&(e.emissionPositionX=e.emissionTranslationX??0),e.emissionPositionY===void 0&&(e.emissionPositionY=e.emissionTranslationY??0),e.emissionPositionZ===void 0&&(e.emissionPositionZ=e.emissionTranslationZ??0),e.pulseEnabled===void 0&&(e.pulseEnabled=!1),e.pulseAmplitude===void 0&&(e.pulseAmplitude=.5),e.pulseFrequency===void 0&&(e.pulseFrequency=1),e.pulsePhaseRandom===void 0&&(e.pulsePhaseRandom=0),e.pulseOpacity===void 0&&(e.pulseOpacity=!1),e.confinementEnabled===void 0&&(e.confinementEnabled=!1),e.confinementShape===void 0&&(e.confinementShape="box"),e.confinementMode===void 0&&(e.confinementMode="bounce"),e.confinementSpace===void 0&&(e.confinementSpace="world"),e.confinementBoxHalfSize===void 0&&(e.confinementBoxHalfSize=[2,2,2]),e.confinementSphereRadius===void 0&&(e.confinementSphereRadius=3),e.confinementRestitution===void 0&&(e.confinementRestitution=.8),e.confinementFriction===void 0&&(e.confinementFriction=.1),e.softBoundaryEnabled===void 0&&(e.softBoundaryEnabled=!1),e.softBoundaryStrength===void 0&&(e.softBoundaryStrength=5),e.softBoundaryFalloff===void 0&&(e.softBoundaryFalloff=.5),e.depthWriteEnabled===void 0&&(e.depthWriteEnabled=!1),e.velocityStretchEnabled===void 0&&(e.velocityStretchEnabled=!1),e.velocityStretchFactor===void 0&&(e.velocityStretchFactor=1),e.blendMode===void 0&&(e.blendMode="normal"),e.noiseDistortEnabled===void 0&&(e.noiseDistortEnabled=!1),e.noiseTilingX===void 0&&(e.noiseTilingX=3),e.noiseTilingY===void 0&&(e.noiseTilingY=3),e.noiseSpeed===void 0&&(e.noiseSpeed=-1.5),e.noiseAmplitude===void 0&&(e.noiseAmplitude=.08),e.emissionTrailEnabled===void 0&&(e.emissionTrailEnabled=!1),e.emissionTrailDuration===void 0&&(e.emissionTrailDuration=1),e.emissionTrailWidth===void 0&&(e.emissionTrailWidth=.3),e.emissionTrailMinDistance===void 0&&(e.emissionTrailMinDistance=.05),e.emissionTrailMaxPoints===void 0&&(e.emissionTrailMaxPoints=256),e.emissionTrailSegments===void 0&&(e.emissionTrailSegments=8),e.emissionTrailMode===void 0&&(e.emissionTrailMode="ribbon"),e.emissionTrailShape===void 0&&(e.emissionTrailShape="straight"),e.emissionTrailShapeAmplitude===void 0&&(e.emissionTrailShapeAmplitude=.1),e.emissionTrailShapeFrequency===void 0&&(e.emissionTrailShapeFrequency=4),e.emissionTrailShapeSpeed===void 0&&(e.emissionTrailShapeSpeed=0),e.shapeDisplay===void 0&&(e.shapeDisplay=!0),e.followSystemTranslation===void 0&&(e.followSystemTranslation=!0),e.followSystemId===void 0&&(e.followSystemId=null),this._newEmissions=[],this._emptyEmissions=[],this._pendingFollowEmissions=this._emptyEmissions,this.glbVertexBuffer=null,this.glbIndexBuffer=null,this.glbIndexCount=0,this.glbIndexFormat="uint16",this.glbMeshData=null,this.glbRawArrayBuffer=null,this.glbAnimator=null,this.glbAnimated=!1,this._glbInterleavedData=null,this._appearanceData=new Float32Array(56),this._bloomIntensityData=new Float32Array(16),this._simPosition=[0,0,0],this._simVelocity=[0,0,0],this._simRotMatrix=null,this._simRotX=0,this._simRotZ=0,this._emitSimRotY=0,this.emitter=new vi(e),this.physics=new Ri(t,this.MAX_PARTICLES),this.textureManager=new Ti(t),e.gravityEnabled&&this.setGravity(e.gravityStrength||0),e.dampingEnabled&&this.physics.setDamping(e.dampingStrength||0),e.attractorEnabled&&e.attractorPosition&&this.setAttractor(e.attractorStrength||0,e.attractorPosition),e.confinementEnabled&&this.setConfinement({enabled:!0,shape:e.confinementShape,mode:e.confinementMode,space:e.confinementSpace,boxSize:e.confinementBoxHalfSize,sphereRadius:e.confinementSphereRadius,restitution:e.confinementRestitution,friction:e.confinementFriction}),e.softBoundaryEnabled&&this.setSoftBoundary({enabled:!0,strength:e.softBoundaryStrength,falloff:e.softBoundaryFalloff}),this.particleTexture=this.textureManager.getDefaultTexture(),this.updateBloomIntensity(),this.updateAppearanceUniform(),this.frameCount=0,this.shouldReset=!1,this._scriptParticleData=new Float32Array(this.MAX_PARTICLES*8),this._scriptVelocityData=new Float32Array(this.MAX_PARTICLES*4),this._scriptReadbackPending=!1,this._scriptReadbackReady=!1,this._scriptFrame=0,this._scriptTime=0,this._scriptConfigRestored=!1,this._particleScript=null,e.script&&(this._particleScript=new Pt(e.script,e,this.MAX_PARTICLES)),this.initComputePipeline(t)}async initComputePipeline(t){this.computeReady=await this.physics.initComputePipeline(this.instanceBuffer,this.velocityBuffer,this.trailBuffer)}setScript(t){this._particleScript&&(this._particleScript.destroy(),this._particleScript=null),this._scriptReadbackPending=!1,this._scriptReadbackReady=!1,this._scriptFrame=0,this._scriptTime=0,this._scriptConfigRestored=!1,t?(this.config.script=t,this._particleScript=new Pt(t,this.config,this.MAX_PARTICLES),this._particleScript.snapshotConfig(this.config)):delete this.config.script}async setTexture(t){this.destroyed||(this.textureManager.destroyTexture(this.particleTexture),this.particleTexture=await this.textureManager.loadTexture(t),this.config.textureEnabled=!0,this.updateAppearanceUniform(),this.updateBuffers())}resetTexture(){this.destroyed||(this.textureManager.destroyTexture(this.particleTexture),this.particleTexture=this.textureManager.getDefaultTexture(),this.config.textureEnabled=!1,this.updateAppearanceUniform(),this.updateBuffers())}async setGLBModel(t){try{this.glbRawArrayBuffer=t;const e=await Ci(t);this.glbMeshData=e,this.config.glbHasTexture=e.hasBaseColorTexture||!1;const i=new Float32Array(e.vertexCount*8);for(let r=0;r<e.vertexCount;r++){const n=r*8,a=r*3,o=r*2;i[n+0]=e.positions[a+0],i[n+1]=e.positions[a+1],i[n+2]=e.positions[a+2],i[n+3]=e.normals[a+0],i[n+4]=e.normals[a+1],i[n+5]=e.normals[a+2],e.texCoords?(i[n+6]=e.texCoords[o+0],i[n+7]=e.texCoords[o+1]):(i[n+6]=0,i[n+7]=0)}if(this.glbVertexBuffer&&this.glbVertexBuffer.destroy(),this.glbIndexBuffer&&this.glbIndexBuffer.destroy(),this.glbVertexBuffer=this.device.createBuffer({size:i.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST|GPUBufferUsage.STORAGE,label:"glbVertexBuffer"}),this.device.queue.writeBuffer(this.glbVertexBuffer,0,i),this.glbIndexBuffer=this.device.createBuffer({size:e.indices.byteLength,usage:GPUBufferUsage.INDEX|GPUBufferUsage.COPY_DST,label:"glbIndexBuffer"}),this.device.queue.writeBuffer(this.glbIndexBuffer,0,e.indices),this.glbIndexCount=e.indexCount,this.glbIndexFormat=e.indices instanceof Uint32Array?"uint32":"uint16",this.config.glbModelEnabled=!0,this.config.textureType="glb",e.animationData){this.glbAnimator=new Ai(e.animationData),this.glbAnimator.setRestPose(e.positions,e.normals),this.glbAnimated=!0,this.config.glbAnimated=!0,this.glbAnimator.loop=this.config.animationLoop,this._glbInterleavedData=new Float32Array(e.vertexCount*8);try{await this.glbAnimator.initGPUSkinning(this.device,this.glbVertexBuffer,e.texCoords)}catch(r){console.warn("GPU skinning init failed, using CPU fallback:",r)}globalThis.__HZFX_DEBUG&&console.log(`GLB animated model loaded: ${e.animationData.animations.length} animations`)}else this.glbAnimator=null,this.glbAnimated=!1,this.config.glbAnimated=!1,this._glbInterleavedData=null;globalThis.__HZFX_DEBUG&&console.log(`GLB model loaded: ${e.vertexCount} vertices, ${e.indexCount} indices`)}catch(e){throw console.error("Failed to load GLB model:",e),e}}resetGLBModel(){this.glbVertexBuffer&&(this.glbVertexBuffer.destroy(),this.glbVertexBuffer=null),this.glbIndexBuffer&&(this.glbIndexBuffer.destroy(),this.glbIndexBuffer=null),this.glbIndexCount=0,this.glbIndexFormat="uint16",this.glbMeshData=null,this.glbRawArrayBuffer=null,this.glbAnimator=null,this.glbAnimated=!1,this.config.glbAnimated=!1,this._glbInterleavedData=null,this.config.glbFileName=null,this.config.glbHasTexture=!1,this.config.useGlbTexture=!1,this.config.glbModelEnabled=!1,this.config.textureType="image"}setSimulationTransform(t){if(t.position&&(this._simPosition[0]=t.position[0],this._simPosition[1]=t.position[1],this._simPosition[2]=t.position[2]),t.rotation){this._simRotX=t.rotation[0]||0,this._simRotZ=t.rotation[1]||0,this._simRotY=t.rotation[2]||0;const e=Math.cos(this._simRotX),i=Math.sin(this._simRotX),r=Math.cos(this._simRotZ),n=Math.sin(this._simRotZ),a=Math.cos(this._simRotY),o=Math.sin(this._simRotY);this._simRotMatrix=[a*r,-a*n*e+o*i,a*n*i+o*e,n,r*e,-r*i,-o*r,o*n*e+a*i,-o*n*i+a*e]}else this._simRotMatrix=null,this._simRotX=0,this._simRotZ=0,this._simRotY=0;t.velocity&&(this._simVelocity[0]=t.velocity[0],this._simVelocity[1]=t.velocity[1],this._simVelocity[2]=t.velocity[2])}clearSimulationTransform(){this._simPosition[0]=this._simPosition[1]=this._simPosition[2]=0,this._simVelocity[0]=this._simVelocity[1]=this._simVelocity[2]=0,this._simRotMatrix=null,this._simRotX=0,this._simRotZ=0}updateAnimatedGLBBuffer(){if(!this.glbAnimator||!this.glbAnimator.playing)return!1;if(this.glbAnimator._gpuSkinningReady)return!0;const t=this.glbAnimator.skinnedPositions,e=this.glbAnimator.skinnedNormals,i=this.glbMeshData.texCoords;for(let r=0;r<this.glbMeshData.vertexCount;r++){const n=r*8,a=r*3,o=r*2;this._glbInterleavedData[n]=t[a],this._glbInterleavedData[n+1]=t[a+1],this._glbInterleavedData[n+2]=t[a+2],this._glbInterleavedData[n+3]=e[a],this._glbInterleavedData[n+4]=e[a+1],this._glbInterleavedData[n+5]=e[a+2],i?(this._glbInterleavedData[n+6]=i[o],this._glbInterleavedData[n+7]=i[o+1]):(this._glbInterleavedData[n+6]=0,this._glbInterleavedData[n+7]=0)}return this.device.queue.writeBuffer(this.glbVertexBuffer,0,this._glbInterleavedData),!0}updateAppearanceUniform(){if(this.destroyed)return;let t=0;this.config.rotationMode==="random"?t=1:this.config.rotationMode==="velocity"?t=2:this.config.rotationMode==="oriented"?t=3:this.config.rotationMode==="cylindrical"&&(t=4);const e=sr[this.config.particleShape]??0,i=this._appearanceData;i[0]=this.config.fadeEnabled?1:0,i[1]=this.config.randomColorEnabled?2:this.config.colorTransitionEnabled?1:0,i[2]=this.config.particleSize,i[3]=this.config.textureEnabled?1:0,i[4]=this.config.particleColor[0],i[5]=this.config.particleColor[1],i[6]=this.config.particleColor[2],i[7]=this.config.rotation||0,i[8]=this.config.startColor[0],i[9]=this.config.startColor[1],i[10]=this.config.startColor[2],i[11]=t,i[12]=this.config.endColor[0],i[13]=this.config.endColor[1],i[14]=this.config.endColor[2],i[15]=this.config.minRotation||0,i[16]=this.config.maxRotation||90,i[17]=this.config.aspectRatio||1,i[18]=this.config.randomSize?1:0,i[19]=this.config.minSize||.1,i[20]=this.config.maxSize||.5,i[21]=this.config.fadeSizeEnabled?1:0,i[22]=this.config.opacity!==void 0?this.config.opacity:1,i[23]=this.config.increaseSizeEnabled?1:0,i[24]=this.config.sizeLifetimeSpeed??1,i[25]=e,i[26]=0,i[27]=this.config.pulseEnabled?1:0,i[28]=this.config.pulseAmplitude??.5,i[29]=this.config.pulseFrequency??1,i[30]=this.config.pulsePhaseRandom??0,i[31]=this.config.pulseOpacity?1:0,i[32]=this.config.particleShapeRotationX||0,i[33]=this.config.particleShapeRotationY||0,i[34]=this.config.particleShapeRotationZ||0,i[35]=0;const r=this.config.followSystemTranslation??!0;i[36]=r?this._simPosition[0]:0,i[37]=r?this._simPosition[1]:0,i[38]=r?this._simPosition[2]:0,i[39]=0,i[40]=this._simRotX,i[41]=this._simRotZ,i[42]=this.config.velocityStretchEnabled?1:0,i[43]=this.config.velocityStretchFactor??1,i[44]=this.config.noiseDistortEnabled?1:0,i[45]=this.config.noiseTilingX??3,i[46]=this.config.noiseTilingY??3,i[47]=this.config.noiseSpeed??-1.5,i[48]=this.config.noiseAmplitude??.08,i[49]=r?this._simVelocity[0]:0,i[50]=r?this._simVelocity[1]:0,i[51]=r?this._simVelocity[2]:0,i[52]=this.config.orientX??0,i[53]=this.config.orientY??0,i[54]=this.config.orientZ??0,i[55]=0,this.device.queue.writeBuffer(this.appearanceUniformBuffer,0,i)}updateBloomIntensity(){const t=this._bloomIntensityData;t[0]=this.config.bloomIntensity||1;const e=this.config.bloomColor||[1,1,1];t[4]=e[0],t[5]=e[1],t[6]=e[2],this.device.queue.writeBuffer(this.bloomIntensityBuffer,0,t)}spawnParticles(){if(this.activeParticles=0,this.currentEmissionTime=0,this._newEmissions.length=0,this._pendingFollowEmissions=this._emptyEmissions,this._scriptFrame=0,this._scriptTime=0,this._scriptReadbackPending=!1,this._scriptReadbackReady=!1,this._scriptConfigRestored=!1,this._particleScript&&(this._particleScript._configSnapshot?(this._particleScript.restoreConfig(this.config),this.config.gravityEnabled&&this.setGravity(this.config.gravityStrength),this.config.dampingEnabled&&this.physics.setDamping(this.config.dampingStrength),this.config.attractorEnabled&&this.setAttractor(this.config.attractorStrength,this.config.attractorPosition),this.updateAppearanceUniform(),this.updateBloomIntensity()):this._particleScript.snapshotConfig(this.config)),this.device.queue.writeBuffer(this.trailBuffer,0,this._trailResetData,0,this.MAX_PARTICLES*4),this.glbAnimator&&(this.glbAnimator.currentTime=0,this.glbAnimator.playing=!0),this.config.followSystemId){this.emitting=!0,this.particleCount=this.MAX_PARTICLES;return}if(this.config.burstMode){const t=this.config.particleCount;this.particleCount=t;let e=0;const i=500;for(let r=0;r<t;r++)if(this.emitParticle(),e++,e>=i||r===t-1){const n=r-e+1,a=n*8,o=n*4;this.device.queue.writeBuffer(this.instanceBuffer,a*4,this.particleData,a,e*8),this.device.queue.writeBuffer(this.velocityBuffer,o*4,this.particleVelocities,o,e*4),e=0}this.emitting=!1}else{this.emitting=!0;const t=this.config.lifetime||5,e=this.config.emissionDurationInfinite?t:Math.min(this.config.emissionDuration||10,t);this.particleCount=Math.min(Math.ceil((this.config.emissionRate||10)*e),this.MAX_PARTICLES)}}get effectiveEmissionDuration(){return this.config.emissionDurationInfinite?1/0:this.config.emissionDuration??10}_applySimTransformToParticle(t){this._emitSimRotY=this._simRotY||0;const e=t*8,i=t*4;if(this._simRotMatrix){const r=this._simRotMatrix,n=this.particleData[e],a=this.particleData[e+1],o=this.particleData[e+2],c=this.particleVelocities[i],l=this.particleVelocities[i+1],u=this.particleVelocities[i+2];this.particleData[e]=r[0]*n+r[1]*a+r[2]*o,this.particleData[e+1]=r[3]*n+r[4]*a+r[5]*o,this.particleData[e+2]=r[6]*n+r[7]*a+r[8]*o,this.particleVelocities[i]=r[0]*c+r[1]*l+r[2]*u,this.particleVelocities[i+1]=r[3]*c+r[4]*l+r[5]*u,this.particleVelocities[i+2]=r[6]*c+r[7]*l+r[8]*u}(this.config.followSystemTranslation??!0)||(this.particleData[e]+=this._simPosition[0],this.particleData[e+1]+=this._simPosition[1],this.particleData[e+2]+=this._simPosition[2])}emitParticle(){if(this.activeParticles>=this.particleCount)return!1;this.emitter.emitParticle(this.particleData,this.activeParticles,this.particleVelocities);const t=this.activeParticles*8,e=this.activeParticles*4;return this._applySimTransformToParticle(this.activeParticles),this._newEmissions.push(this.particleData[t],this.particleData[t+1],this.particleData[t+2],this.particleVelocities[e],this.particleVelocities[e+1],this.particleVelocities[e+2]),this.activeParticles++,!0}emitFollowerParticle(t,e,i){if(this.activeParticles>=this.particleCount)return!1;const r=this.activeParticles*8,n=t+(this.config.emissionPositionX||0),a=e+(this.config.emissionPositionY||0),o=i+(this.config.emissionPositionZ||0);this.particleData[r]=n,this.particleData[r+1]=a,this.particleData[r+2]=o;const c=this.activeParticles*4;return this.emitter.calculateVelocity(n,a,o,this.particleVelocities,c),this.emitter.setParticleColor(this.particleData,r),this.emitter.setParticleLifetime(this.particleData,r),this.activeParticles++,!0}updateParticles(t,e,i=0){const r=this.config.startAt||0,n=r>0&&i<r;if(this._particleScript&&this._scriptReadbackReady){this._scriptReadbackReady=!1,this._scriptTime+=t,this._scriptFrame++;const u=this.config.emissionDurationInfinite?1/0:(this.config.emissionDuration||0)+(this.config.lifetime||0);if(u>0&&this._scriptTime>=u&&!this._scriptConfigRestored)this._scriptConfigRestored=!0,this._particleScript._configSnapshot&&(this._particleScript.restoreConfig(this.config),this.updateAppearanceUniform(),this.updateBloomIntensity(),this.config.gravityEnabled&&this.setGravity(this.config.gravityStrength),this.config.dampingEnabled&&this.physics.setDamping(this.config.dampingStrength),this.config.attractorEnabled&&this.setAttractor(this.config.attractorStrength,this.config.attractorPosition));else if(!this._scriptConfigRestored){const h=u>0?Math.ceil(u/.016666666666666666):0,{configDirty:p,particlesDirty:d}=this._particleScript.execute(t,this._scriptTime,this._scriptFrame,h,this._scriptParticleData,this._scriptVelocityData,this.activeParticles);d&&this.activeParticles>0&&(this.device.queue.writeBuffer(this.instanceBuffer,0,this._scriptParticleData,0,this.activeParticles*8),this.device.queue.writeBuffer(this.velocityBuffer,0,this._scriptVelocityData,0,this.activeParticles*4)),p&&(this.updateAppearanceUniform(),this.updateBloomIntensity(),this.config.gravityEnabled&&this.setGravity(this.config.gravityStrength),this.config.dampingEnabled&&this.physics.setDamping(this.config.dampingStrength),this.config.attractorEnabled&&this.setAttractor(this.config.attractorStrength,this.config.attractorPosition))}}this.physics.physicsAccumulator+=t;const a=performance.now()/1e3,c=a-this.physics.lastUpdateTime>1/this.physics.minUpdatesPerSecond,l=this.activeParticles;if(!n&&!this.emitting&&!this.config.burstMode&&!this.config.followSystemId&&this.currentEmissionTime<this.effectiveEmissionDuration&&(this.emitting=!0),!n&&this.emitting)if(this.currentEmissionTime+=t,this.currentEmissionTime<this.effectiveEmissionDuration){const u=this.activeParticles;let h=!1;if(this.config.followSystemId){if(this._pendingFollowEmissions.length>0){const p=this._pendingFollowEmissions.length/6;for(let d=0;d<p;d++){const S=d*6;if(this.emitFollowerParticle(this._pendingFollowEmissions[S],this._pendingFollowEmissions[S+1],this._pendingFollowEmissions[S+2]))h=!0;else break}}}else{let p=0;if(this.config.emissionRate>=1){p=Math.floor(this.config.emissionRate*t);const d=this.config.emissionRate*t-p;Math.random()<d&&(p+=1)}else{const d=this.config.emissionRate*t;Math.random()<d&&(p=1)}p===0&&c&&this.config.emissionRate>0&&this.activeParticles<this.particleCount&&(p=1);for(let d=0;d<p&&this.emitParticle();d++)h=!0}if(h){const p=this.activeParticles-u,d=u*8,S=u*4;this.device.queue.writeBuffer(this.instanceBuffer,d*4,this.particleData,d,p*8),this.device.queue.writeBuffer(this.velocityBuffer,S*4,this.particleVelocities,S,p*4)}}else this.emitting=!1,this.currentEmissionTime=this.config.emissionDuration;for(;this.physics.physicsAccumulator>=this.physics.fixedDeltaTime;)this.physics.updatePhysics(this.physics.fixedDeltaTime,l,this.config,this.instanceBuffer,this.velocityBuffer,e),this.physics.physicsAccumulator-=this.physics.fixedDeltaTime,this.physics.physicsClock+=this.physics.fixedDeltaTime;c&&l>0&&(this.physics.updatePhysics(this.physics.fixedDeltaTime,l,this.config,this.instanceBuffer,this.velocityBuffer,e),this.physics.lastUpdateTime=a),this.frameCount++,(this.activeParticles>=this.particleCount||this.frameCount%300===0)&&this.readbackAndProcessParticles(),this._particleScript&&this.activeParticles>0&&!this._scriptReadbackPending&&(this._scriptReadbackPending=!0,this.physics.readbackForScript(this.activeParticles,this._scriptParticleData,this._scriptVelocityData,this.instanceBuffer,this.velocityBuffer).then(u=>{this._scriptReadbackPending=!1,u.shouldUpdate&&(this._scriptReadbackReady=!0)}).catch(()=>{this._scriptReadbackPending=!1}))}async readbackAndProcessParticles(){if(!(this.activeParticles<=0))try{if(!(await this.physics.readbackAndProcessParticles(this.activeParticles,this.particleData,this.particleVelocities,this.instanceBuffer,this.velocityBuffer)).shouldUpdate)return;let e=0,i=!1;for(let r=0;r<this.activeParticles;r++){const n=this.particleData[r*8+6],a=this.particleData[r*8+7];if(n>=a){if(this.emitting&&this.currentEmissionTime<this.effectiveEmissionDuration&&e<this.particleCount){this.respawnParticle(r,e),e++,i=!0;continue}continue}if(e!==r){const o=r*8,c=e*8;this.particleData.copyWithin(c,o,o+8);const l=r*4,u=e*4;this.particleVelocities.copyWithin(u,l,l+4),i=!0}e++}(e!==this.activeParticles||i)&&(this.activeParticles=e,this.device.queue.writeBuffer(this.instanceBuffer,0,this.particleData,0,this.activeParticles*8),this.device.queue.writeBuffer(this.velocityBuffer,0,this.particleVelocities,0,this.activeParticles*4))}catch(t){t&&t.name==="AbortError"||console.error("Error reading back particle data:",t)}}respawnParticle(t,e){!this.emitting||this.currentEmissionTime>=this.effectiveEmissionDuration||this.config.followSystemId||(this.emitter.emitParticle(this.particleData,e,this.particleVelocities),this._applySimTransformToParticle(e))}updateBuffers(){this.destroyed||!this.particleData||this.activeParticles>0&&this.device.queue.writeBuffer(this.instanceBuffer,0,this.particleData,0,this.activeParticles*8)}updateParticleColors(){if(!(this.destroyed||!this.particleData)){for(let t=0;t<this.activeParticles;t++){const e=t*8;if(this.config.randomColorEnabled&&this.config.randomColors.length>0){const i=this.config.randomColors,r=i[Math.floor(Math.random()*i.length)];this.particleData[e+3]=r[0],this.particleData[e+4]=r[1],this.particleData[e+5]=r[2]}else this.config.colorTransitionEnabled?(this.particleData[e+3]=this.config.startColor[0],this.particleData[e+4]=this.config.startColor[1],this.particleData[e+5]=this.config.startColor[2]):(this.particleData[e+3]=this.config.particleColor[0],this.particleData[e+4]=this.config.particleColor[1],this.particleData[e+5]=this.config.particleColor[2])}this.activeParticles>0&&this.device.queue.writeBuffer(this.instanceBuffer,0,this.particleData,0,this.activeParticles*8)}}updateParticleVelocities(){for(let t=0;t<this.activeParticles;t++){const e=t*8,i=t*4,r=this.particleData[e],n=this.particleData[e+1],a=this.particleData[e+2],o=this.particleVelocities[i],c=this.particleVelocities[i+1],l=this.particleVelocities[i+2],u=Math.sqrt(o*o+c*c+l*l);if(u>.001){const h=this.config.particleSpeed*2;this.particleVelocities[i]=o/u*h,this.particleVelocities[i+1]=c/u*h,this.particleVelocities[i+2]=l/u*h}else{const h=Math.sqrt(r*r+n*n+a*a);if(h>.001){const p=this.config.particleSpeed*2;this.particleVelocities[i]=r/h*p,this.particleVelocities[i+1]=n/h*p,this.particleVelocities[i+2]=a/h*p}else this.particleVelocities[i]=0,this.particleVelocities[i+1]=this.config.particleSpeed*2,this.particleVelocities[i+2]=0}}this.activeParticles>0&&this.device.queue.writeBuffer(this.velocityBuffer,0,this.particleVelocities,0,this.activeParticles*4)}async readbackForRendering(t,e){return this.physics.readbackForRendering(this.activeParticles,t,e,this.instanceBuffer,this.velocityBuffer)}destroy(){this.destroyed=!0,this.instanceBuffer.destroy(),this.velocityBuffer.destroy(),this.trailBuffer.destroy(),this.appearanceUniformBuffer.destroy(),this.bloomIntensityBuffer.destroy(),this.physics.destroy(),this.glbVertexBuffer&&(this.glbVertexBuffer.destroy(),this.glbVertexBuffer=null),this.glbIndexBuffer&&(this.glbIndexBuffer.destroy(),this.glbIndexBuffer=null),this.textureManager.destroyTexture(this.particleTexture),this._particleScript&&(this._particleScript.destroy(),this._particleScript=null),this.glbAnimator=null,this.glbMeshData=null,this.glbRawArrayBuffer=null,this.particleData=null,this.particleVelocities=null,this._scriptParticleData=null,this._scriptVelocityData=null}setGravity(t){this.physics.setGravity(t)}setAttractor(t,e){this.physics.setAttractor(t,e)}setConfinement(t){const e=t.center||this.config.confinementCenter||[0,0,0],i=t.space==="local"?[this.config.emissionPositionX||0,this.config.emissionPositionY||0,this.config.emissionPositionZ||0]:[0,0,0],r=[i[0]+(e[0]||0),i[1]+(e[1]||0),i[2]+(e[2]||0)];this.physics.setConfinement({...t,center:r})}setSoftBoundary(t){this.physics.setSoftBoundary(t)}}class zi{constructor(t){this.device=t,this.particleSystems=[],this.activeSystemIndex=0,this.systemCounter=1,this.onSystemCreated=null,this.loop=void 0,this.clock=new Ui({loop:!!this.loop}),this.ready=!0}createParticleSystem(t={}){const e=this.systemCounter++,i=t.name||`System ${e+1}`,r={...t,name:i,id:e},n=new at(this.device,r);return this.particleSystems.push({system:n,config:r}),this.particleSystems.length===1&&(this.activeSystemIndex=0),this.onSystemCreated&&typeof this.onSystemCreated=="function"&&this.onSystemCreated(e,r),e}getActiveSystem(){return this.particleSystems.length===0?null:this.particleSystems[this.activeSystemIndex].system}getActiveConfig(){return this.particleSystems.length===0?null:this.particleSystems[this.activeSystemIndex].config}setActiveSystem(t){return t>=0&&t<this.particleSystems.length?(this.activeSystemIndex=t,!0):!1}getSystemById(t){return this.particleSystems.find(({config:e})=>e.id===t)||null}destroy(){for(const{system:t}of this.particleSystems)t.destroy();this.particleSystems=[],this.activeSystemIndex=0}removeSystem(t){if(t>=0&&t<this.particleSystems.length){const e=this.particleSystems[t].config;this.particleSystems[t].system.destroy(),this.particleSystems.splice(t,1);const i=e.id;for(const{config:r}of this.particleSystems)r.followSystemId===i&&(r.followSystemId=null);return this.particleSystems.length===0?this.activeSystemIndex=0:t<=this.activeSystemIndex&&(this.activeSystemIndex=Math.max(0,this.activeSystemIndex-1)),!0}return!1}respawnAllSystems(){var t;for(const{system:e}of this.particleSystems)e.spawnParticles();(t=this.clock)==null||t.reset()}getTotalDuration(){let t=0;for(const{config:e}of this.particleSystems){if(e.emissionDurationInfinite)return 1/0;const i=e.lifetime||5,r=(e.burstMode||e.oneOnlyMode?i:(e.emissionDuration||10)+i)+(e.startAt||0);r>t&&(t=r)}return t||1}updateAllSystems(t){const e=this.device.createCommandEncoder({label:"BatchedPhysicsEncoder"});let i=!1;const r=this.clock?this.clock.currentTime:0,n=this.clock?this.clock.duration:0;if(this.clock&&n>0&&isFinite(n)){const a=Math.min(1,this.clock.currentTime/n);for(const{system:o,config:c}of this.particleSystems){const l=c.keyframes;if(!(!l||c.keyframesEnabled===!1)){for(const u of ir){const h=l[u];if(h&&h.length){const p=er(h,a);p!==void 0&&(c[u]=p)}}if(l.particleColor&&l.particleColor.length){const u=tr(l.particleColor,a);u&&(c.particleColor=u,o.updateAppearanceUniform())}}}}for(const{system:a,config:o}of this.particleSystems){if(o.hidden||o.followSystemId)continue;const c=a.activeParticles>0;a.updateParticles(t,e,r),(c||a.activeParticles>0)&&(i=!0)}for(const{system:a,config:o}of this.particleSystems){if(o.hidden||!o.followSystemId)continue;const c=this.getSystemById(o.followSystemId);c&&(a._pendingFollowEmissions=c.system._newEmissions);const l=a.activeParticles>0;a.updateParticles(t,e,r),(l||a.activeParticles>0)&&(i=!0)}i&&this.device.queue.submit([e.finish()]);for(const{system:a}of this.particleSystems)a._newEmissions.length=0,a._pendingFollowEmissions=a._emptyEmissions}getSystemsList(){return this.particleSystems.map(({config:t},e)=>({name:t.name,id:t.id,index:e,isActive:e===this.activeSystemIndex,hidden:t.hidden||!1}))}duplicateActiveSystem(){if(this.particleSystems.length===0)return-1;const t=this.getActiveConfig(),e=JSON.parse(JSON.stringify(t));return e.name=`${t.name} (Copy)`,e.onAppearanceChange=null,e.onColorChange=null,e.onSizeChange=null,e.onSpeedChange=null,e.onPhysicsChange=null,e.onBloomIntensityChange=null,e.onRespawn=null,e.getActiveSystem=null,delete e.id,this.createParticleSystem(e)}async replaceSystems(t){var e;if(!t||!t.systems||!Array.isArray(t.systems))return console.error("Invalid scene data provided"),!1;this.ready=!1;try{this.particleSystems=[],this.systemCounter=1;for(const r of t.systems){const n=this.systemCounter++,a={...r,id:n},o=new at(this.device,a);this.particleSystems.push({system:o,config:a})}const i={};t.systems.forEach((r,n)=>{i[r.id]=this.particleSystems[n].config.id});for(const{config:r}of this.particleSystems)r.followSystemId&&i[r.followSystemId]!==void 0&&(r.followSystemId=i[r.followSystemId]);t.activeSystemIndex!==void 0&&t.activeSystemIndex>=0&&t.activeSystemIndex<this.particleSystems.length?this.activeSystemIndex=t.activeSystemIndex:this.activeSystemIndex=0,this.loop=t.loop;for(const{system:r,config:n}of this.particleSystems)if(n.glbModelEnabled)try{let a=null;if(n.glbModelData)a=yi(n.glbModelData);else if(n.glbFileName){const o=await fetch(`/${n.glbFileName}`);o.ok?a=await o.arrayBuffer():console.warn(`GLB file not found: ${n.glbFileName}`)}if(a){if(await r.setGLBModel(a),n.animationIndex!==void 0&&r.glbAnimator&&r.glbAnimator.setAnimation(n.animationIndex),n.animationSpeed!==void 0&&r.glbAnimator&&(r.glbAnimator.speed=n.animationSpeed),n.animationLoop!==void 0&&r.glbAnimator&&(r.glbAnimator.loop=n.animationLoop),n.useGlbTexture&&(n.textureEnabled=!0),n.useGlbTexture&&((e=r.glbMeshData)!=null&&e.hasBaseColorTexture))try{const o=await _t(a);if(o){const c=await createImageBitmap(o.imageBlob);await r.setTexture(c),globalThis.__HZFX_DEBUG&&console.log(`GLB embedded texture restored for ${n.name}`)}}catch(o){console.warn(`Failed to restore GLB texture for ${n.name}:`,o),n.useGlbTexture=!1}}else n.glbModelEnabled=!1}catch(a){console.warn(`Failed to load GLB for ${n.name}:`,a),n.glbModelEnabled=!1}for(const{system:r,config:n}of this.particleSystems)if(n.textureEnabled&&!n.glbModelEnabled&&n.textureImageData)try{const a=new Image;await new Promise((c,l)=>{a.onload=c,a.onerror=l,a.src=n.textureImageData});const o=await createImageBitmap(a);await r.setTexture(o)}catch(a){console.warn(`Failed to restore texture for ${n.name}:`,a),n.textureEnabled=!1}for(const{system:r,config:n}of this.particleSystems)r.updateAppearanceUniform();return this.respawnAllSystems(),!0}catch(i){return console.error("Error replacing systems:",i),!1}finally{this.ready=!0}}async addSystems(t,e=[0,0,0]){var r;if(!t||!t.systems||!Array.isArray(t.systems))return console.error("Invalid scene data provided"),!1;this.ready=!1;const i=[];try{for(const o of t.systems){const c=this.systemCounter++;i.push(c);const l={...o,id:c,emissionPositionX:(o.emissionPositionX||0)+e[0],emissionPositionY:(o.emissionPositionY||0)+e[1],emissionPositionZ:(o.emissionPositionZ||0)+e[2]};o.attractorEnabled&&o.attractorPosition&&(l.attractorPosition=[o.attractorPosition[0]+e[0],o.attractorPosition[1]+e[1],o.attractorPosition[2]+e[2]]);const u=new at(this.device,l);this.particleSystems.push({system:u,config:l}),this.onSystemCreated&&typeof this.onSystemCreated=="function"&&this.onSystemCreated(c,l)}const n=this.particleSystems.length-t.systems.length,a={};t.systems.forEach((o,c)=>{a[o.id]=this.particleSystems[n+c].config.id});for(let o=n;o<this.particleSystems.length;o++){const{config:c}=this.particleSystems[o];c.followSystemId&&a[c.followSystemId]!==void 0&&(c.followSystemId=a[c.followSystemId])}for(const{system:o,config:c}of this.particleSystems)if(c.glbModelEnabled&&!o.glbMeshData)try{let l=null;if(c.glbModelData)l=yi(c.glbModelData);else if(c.glbFileName){const u=await fetch(`/${c.glbFileName}`);u.ok?l=await u.arrayBuffer():console.warn(`GLB file not found: ${c.glbFileName}`)}if(l){if(await o.setGLBModel(l),c.animationIndex!==void 0&&o.glbAnimator&&o.glbAnimator.setAnimation(c.animationIndex),c.animationSpeed!==void 0&&o.glbAnimator&&(o.glbAnimator.speed=c.animationSpeed),c.animationLoop!==void 0&&o.glbAnimator&&(o.glbAnimator.loop=c.animationLoop),c.useGlbTexture&&(c.textureEnabled=!0),c.useGlbTexture&&((r=o.glbMeshData)!=null&&r.hasBaseColorTexture))try{const u=await _t(l);if(u){const h=await createImageBitmap(u.imageBlob);await o.setTexture(h),globalThis.__HZFX_DEBUG&&console.log(`GLB embedded texture restored for ${c.name}`)}}catch(u){console.warn(`Failed to restore GLB texture for ${c.name}:`,u),c.useGlbTexture=!1}}else c.glbModelEnabled=!1}catch(l){console.warn(`Failed to load GLB for ${c.name}:`,l),c.glbModelEnabled=!1}for(const{system:o,config:c}of this.particleSystems)if(c.textureEnabled&&!c.glbModelEnabled&&c.textureImageData&&!o._textureRestored)try{const l=new Image;await new Promise((h,p)=>{l.onload=h,l.onerror=p,l.src=c.textureImageData});const u=await createImageBitmap(l);await o.setTexture(u),o._textureRestored=!0}catch(l){console.warn(`Failed to restore texture for ${c.name}:`,l),c.textureEnabled=!1}return i}catch(n){return console.error("Error adding systems:",n),!1}finally{this.ready=!0}}}async function Gi(s){if(!s)throw new Error("canvas is required for initWebGPU()");if(!navigator.gpu)throw new Error("WebGPU not supported on this browser.");const t=s.getContext("webgpu"),i=await(await navigator.gpu.requestAdapter()).requestDevice(),r=navigator.gpu.getPreferredCanvasFormat();return t.configure({device:i,format:r,alphaMode:"premultiplied"}),{device:i,context:t,format:r,canvas:s}}const le="rgba16float";function wt(s,t,e,i){const r=s.createTexture({size:[e,i],format:le,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,mipLevelCount:1,sampleCount:1}),n=s.createTexture({size:[e,i],format:le,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,mipLevelCount:1,sampleCount:1}),a=s.createTexture({size:[e,i],format:le,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,mipLevelCount:1,sampleCount:1});return{sceneTexture:r,bloomTexA:n,bloomTexB:a}}function Bt(s,t,e){return s.createTexture({size:[t,e],format:"depth24plus",usage:GPUTextureUsage.RENDER_ATTACHMENT})}function Ee(s,t,e){const i=s.createBuffer({size:t.byteLength,usage:e,mappedAtCreation:!0});return new t.constructor(i.getMappedRange()).set(t),i.unmap(),i}const Di=`
|
|
876
|
+
${Ns(t)}
|
|
877
|
+
};`,r=new Function(i);this._fn=r()}catch(e){console.warn("[ParticleScript] Compilation error:",e.message),this._fn=null,this._error=!0}}execute(t,e,i,r,n,a,o){if(!this._fn||this._error)return{configDirty:!1,particlesDirty:!1};this._particles._bind(n,a,o),this._configProxy.__resetDirty();try{this._fn(t,e,i,r,this._particles,this._configProxy,Ui)}catch(c){console.warn("[ParticleScript] Runtime error:",c.message)}return{configDirty:this._configProxy.__dirty,particlesDirty:this._particles._dirty}}snapshotConfig(t){const e={};for(const i of $e){const r=t[i];r!==void 0&&(e[i]=Array.isArray(r)?[...r]:r)}this._configSnapshot=e}restoreConfig(t){if(this._configSnapshot){for(const e of $e)if(e in this._configSnapshot){const i=this._configSnapshot[e];t[e]=Array.isArray(i)?[...i]:i}}}destroy(){this._fn=null,this._particles=null,this._configProxy=null,this._configSnapshot=null}}async function Ii(s){const t=new DataView(s);if(t.getUint32(0,!0)!==1179937895)throw new Error("Invalid GLB file: incorrect magic number");const i=t.getUint32(4,!0);if(i!==2)throw new Error(`Unsupported GLB version: ${i} (only version 2 is supported)`);const r=t.getUint32(8,!0);let n=12,a=null,o=null;for(;n<r;){const P=t.getUint32(n,!0),T=t.getUint32(n+4,!0),E=s.slice(n+8,n+8+P);if(T===1313821514){const k=new TextDecoder("utf-8").decode(E);a=JSON.parse(k)}else T===5130562&&(o=E);n+=8+P}if(!a)throw new Error("GLB file missing JSON chunk");if(!a.meshes||a.meshes.length===0)throw new Error("GLB file contains no meshes");const l=a.meshes[0].primitives[0];if(!l)throw new Error("First mesh has no primitives");const u=l.attributes.POSITION;if(u===void 0)throw new Error("Mesh primitive missing POSITION attribute");const m=Pt(a,o,u,3,5126);let p;if(l.attributes.NORMAL!==void 0)p=Pt(a,o,l.attributes.NORMAL,3,5126);else{const P=l.indices;if(P===void 0)throw new Error("Cannot generate normals without indices");const T=yi(a,o,P);p=Ys(m,T)}const d=l.indices;if(d===void 0)throw new Error("Mesh primitive missing indices");const b=yi(a,o,d),w=m.length/3,M=b.length;let R=null;l.attributes.TEXCOORD_0!==void 0&&(R=Pt(a,o,l.attributes.TEXCOORD_0,2,5126));let x=!1;if(a.materials&&a.materials.length>0){const P=a.materials[0];P.pbrMetallicRoughness&&P.pbrMetallicRoughness.baseColorTexture!==void 0&&(x=!0)}let L=null;if(a.skins&&a.skins.length>0)try{L=Js(a,o,l),globalThis.__HZFX_DEBUG&&console.log("Animation data extracted:",L)}catch(P){console.warn("Failed to extract animation data:",P)}return{positions:m,normals:p,indices:b,texCoords:R,vertexCount:w,indexCount:M,animationData:L,hasBaseColorTexture:x}}function Pt(s,t,e,i,r){const n=s.accessors[e],o={SCALAR:1,VEC2:2,VEC3:3,VEC4:4}[n.type];if(o!==i)throw new Error(`Attribute accessor type mismatch: expected ${i} components, got ${o}`);if(n.componentType!==r)throw new Error(`Attribute component type mismatch: expected ${r}, got ${n.componentType}`);const l=(s.bufferViews[n.bufferView].byteOffset||0)+(n.byteOffset||0),u=n.count,m=new DataView(t,l,u*i*4),p=new Float32Array(u*i);for(let d=0;d<u*i;d++)p[d]=m.getFloat32(d*4,!0);return p}function yi(s,t,e){const i=s.accessors[e];if(i.type!=="SCALAR")throw new Error(`Indices accessor must be SCALAR, got ${i.type}`);const n=(s.bufferViews[i.bufferView].byteOffset||0)+(i.byteOffset||0),a=i.count;if(i.componentType===5123){const o=new DataView(t,n,a*2),c=new Uint16Array(a);for(let l=0;l<a;l++)c[l]=o.getUint16(l*2,!0);return c}else if(i.componentType===5125){const o=new DataView(t,n,a*4),c=new Uint32Array(a);for(let l=0;l<a;l++)c[l]=o.getUint32(l*4,!0);return c}else throw new Error(`Unsupported index component type: ${i.componentType}`)}function Ys(s,t){const e=new Float32Array(s.length);for(let i=0;i<t.length;i+=3){const r=t[i]*3,n=t[i+1]*3,a=t[i+2]*3,o=[s[r],s[r+1],s[r+2]],c=[s[n],s[n+1],s[n+2]],l=[s[a],s[a+1],s[a+2]],u=[c[0]-o[0],c[1]-o[1],c[2]-o[2]],m=[l[0]-o[0],l[1]-o[1],l[2]-o[2]],p=[u[1]*m[2]-u[2]*m[1],u[2]*m[0]-u[0]*m[2],u[0]*m[1]-u[1]*m[0]],d=Math.sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]);d>0&&(p[0]/=d,p[1]/=d,p[2]/=d),e[r]=e[n]=e[a]=p[0],e[r+1]=e[n+1]=e[a+1]=p[1],e[r+2]=e[n+2]=e[a+2]=p[2]}return e}function Hs(s,t,e){const i=s.accessors[e];if(i.type!=="VEC4")throw new Error(`JOINTS_0 must be VEC4, got ${i.type}`);const n=(s.bufferViews[i.bufferView].byteOffset||0)+(i.byteOffset||0),a=i.count;if(i.componentType===5121){const o=new DataView(t,n,a*4),c=new Uint8Array(a*4);for(let l=0;l<a*4;l++)c[l]=o.getUint8(l);return c}else if(i.componentType===5123){const o=new DataView(t,n,a*8),c=new Uint8Array(a*4);for(let l=0;l<a*4;l++)c[l]=o.getUint16(l*2,!0);return c}else throw new Error(`Unsupported JOINTS_0 component type: ${i.componentType}`)}function qs(s,t,e){const i=s.accessors[e];if(i.type!=="VEC4")throw new Error(`WEIGHTS_0 must be VEC4, got ${i.type}`);const n=(s.bufferViews[i.bufferView].byteOffset||0)+(i.byteOffset||0),a=i.count;if(i.componentType===5126){const o=new DataView(t,n,a*16),c=new Float32Array(a*4);for(let l=0;l<a*4;l++)c[l]=o.getFloat32(l*4,!0);return c}else if(i.componentType===5121){const o=new DataView(t,n,a*4),c=new Float32Array(a*4);for(let l=0;l<a*4;l++)c[l]=o.getUint8(l)/255;return c}else throw new Error(`Unsupported WEIGHTS_0 component type: ${i.componentType}`)}function Zs(s,t,e){const i=s.accessors[e];if(i.type!=="MAT4")throw new Error(`Expected MAT4, got ${i.type}`);if(i.componentType!==5126)throw new Error(`Expected FLOAT component type for MAT4, got ${i.componentType}`);const n=(s.bufferViews[i.bufferView].byteOffset||0)+(i.byteOffset||0),a=i.count,o=new DataView(t,n,a*64),c=new Float32Array(a*16);for(let l=0;l<a*16;l++)c[l]=o.getFloat32(l*4,!0);return c}function $s(s,t,e){const i=s.accessors[e];if(i.type!=="SCALAR")throw new Error(`Expected SCALAR, got ${i.type}`);if(i.componentType!==5126)throw new Error(`Expected FLOAT component type for SCALAR, got ${i.componentType}`);const n=(s.bufferViews[i.bufferView].byteOffset||0)+(i.byteOffset||0),a=i.count,o=new DataView(t,n,a*4),c=new Float32Array(a);for(let l=0;l<a;l++)c[l]=o.getFloat32(l*4,!0);return c}function Ws(s,t,e){const i=s.accessors[e],n={VEC3:3,VEC4:4}[i.type];if(!n)throw new Error(`Expected VEC3 or VEC4, got ${i.type}`);if(i.componentType!==5126)throw new Error(`Expected FLOAT component type, got ${i.componentType}`);const o=(s.bufferViews[i.bufferView].byteOffset||0)+(i.byteOffset||0),c=i.count,l=new DataView(t,o,c*n*4),u=new Float32Array(c*n);for(let m=0;m<c*n;m++)u[m]=l.getFloat32(m*4,!0);return u}function Js(s,t,e){const i=s.skins[0],r=i.joints,n=Zs(s,t,i.inverseBindMatrices),a=e.attributes.JOINTS_0!==void 0?Hs(s,t,e.attributes.JOINTS_0):null,o=e.attributes.WEIGHTS_0!==void 0?qs(s,t,e.attributes.WEIGHTS_0):null;if(!a||!o)throw new Error("Mesh missing JOINTS_0 or WEIGHTS_0 attributes");const c=s.nodes.map(u=>({translation:u.translation||[0,0,0],rotation:u.rotation||[0,0,0,1],scale:u.scale||[1,1,1],children:u.children||[],name:u.name||""})),l=[];if(s.animations&&s.animations.length>0)for(const u of s.animations){const m=[];let p=0;for(const d of u.channels){const b=u.samplers[d.sampler],w=$s(s,t,b.input),M=Ws(s,t,b.output),R=w[w.length-1];R>p&&(p=R),m.push({targetNode:d.target.node,targetPath:d.target.path,interpolation:b.interpolation||"LINEAR",timestamps:w,values:M})}l.push({name:u.name||`Animation ${l.length}`,duration:p,channels:m})}return{joints:r,inverseBindMatrices:n,jointIndices:a,jointWeights:o,nodes:c,animations:l}}async function Mt(s){const t=new DataView(s);if(t.getUint32(0,!0)!==1179937895)throw new Error("Invalid GLB file: incorrect magic number");const i=t.getUint32(4,!0);if(i!==2)throw new Error(`Unsupported GLB version: ${i}`);const r=t.getUint32(8,!0);let n=12,a=null,o=null;for(;n<r;){const L=t.getUint32(n,!0),P=t.getUint32(n+4,!0),T=s.slice(n+8,n+8+L);if(P===1313821514){const F=new TextDecoder("utf-8").decode(T);a=JSON.parse(F)}else P===5130562&&(o=T);n+=8+L}if(!a)throw new Error("GLB file missing JSON chunk");if(!a.materials||a.materials.length===0)return null;const c=a.materials[0];if(!c.pbrMetallicRoughness||c.pbrMetallicRoughness.baseColorTexture===void 0)return null;const l=c.pbrMetallicRoughness.baseColorTexture.index;if(!a.textures||!a.textures[l])return null;const m=a.textures[l].source;if(m===void 0||!a.images||!a.images[m])return null;const p=a.images[m],d=p.mimeType||"image/png";if(p.bufferView===void 0)return null;if(!o)throw new Error("GLB file missing BIN chunk (required for embedded textures)");const b=a.bufferViews[p.bufferView],w=b.byteOffset||0,M=b.byteLength,R=o.slice(w,w+M);return{imageBlob:new Blob([R],{type:d}),mimeType:d}}function Qs(s,t,e,i){return i=i||[0,0,0],i[0]=s[0]+(t[0]-s[0])*e,i[1]=s[1]+(t[1]-s[1])*e,i[2]=s[2]+(t[2]-s[2])*e,i}function Ks(s,t,e,i){i=i||[0,0,0,0];let r=s[0]*t[0]+s[1]*t[1]+s[2]*t[2]+s[3]*t[3],n=1;if(r<0&&(r=-r,n=-1),r>.9995){i[0]=s[0]+(n*t[0]-s[0])*e,i[1]=s[1]+(n*t[1]-s[1])*e,i[2]=s[2]+(n*t[2]-s[2])*e,i[3]=s[3]+(n*t[3]-s[3])*e;const u=Math.sqrt(i[0]*i[0]+i[1]*i[1]+i[2]*i[2]+i[3]*i[3]);return u>1e-4?(i[0]/=u,i[1]/=u,i[2]/=u,i[3]/=u):(i[0]=0,i[1]=0,i[2]=0,i[3]=1),i}const a=Math.acos(r),o=Math.sin(a),c=Math.sin((1-e)*a)/o,l=Math.sin(e*a)/o;return i[0]=s[0]*c+n*t[0]*l,i[1]=s[1]*c+n*t[1]*l,i[2]=s[2]*c+n*t[2]*l,i[3]=s[3]*c+n*t[3]*l,i}function er(s,t){const e=s[0],i=s[1],r=s[2],n=s[3],a=e+e,o=i+i,c=r+r,l=e*a,u=e*o,m=e*c,p=i*o,d=i*c,b=r*c,w=n*a,M=n*o,R=n*c,x=t||new Float32Array(16);return x[0]=1-(p+b),x[1]=u+R,x[2]=m-M,x[3]=0,x[4]=u-R,x[5]=1-(l+b),x[6]=d+w,x[7]=0,x[8]=m+M,x[9]=d-w,x[10]=1-(l+p),x[11]=0,x[12]=0,x[13]=0,x[14]=0,x[15]=1,x}const tr=new Float32Array(16);function ir(s,t,e,i){const r=er(t,tr),n=i||new Float32Array(16);return n[0]=r[0]*e[0],n[1]=r[1]*e[0],n[2]=r[2]*e[0],n[3]=0,n[4]=r[4]*e[1],n[5]=r[5]*e[1],n[6]=r[6]*e[1],n[7]=0,n[8]=r[8]*e[2],n[9]=r[9]*e[2],n[10]=r[10]*e[2],n[11]=0,n[12]=s[0],n[13]=s[1],n[14]=s[2],n[15]=1,n}function gi(s,t,e){const i=e||new Float32Array(16);for(let r=0;r<4;r++)for(let n=0;n<4;n++)i[r*4+n]=s[0+n]*t[r*4+0]+s[4+n]*t[r*4+1]+s[8+n]*t[r*4+2]+s[12+n]*t[r*4+3];return i}class Gi{constructor(t){this.joints=t.joints,this.inverseBindMatrices=t.inverseBindMatrices,this.jointWeights=t.jointWeights,this.jointIndices=t.jointIndices,this.nodes=t.nodes,this.animations=t.animations,this.restPositions=null,this.restNormals=null,this.currentAnimIndex=0,this.currentTime=0,this.playing=!0,this.speed=1,this.loop=!0,this.jointLocalTransforms=new Array(this.nodes.length),this.jointGlobalTransforms=new Array(this.nodes.length),this.jointFinalMatrices=new Array(this.joints.length);for(let e=0;e<this.nodes.length;e++)this.jointLocalTransforms[e]=new Float32Array(16),this.jointGlobalTransforms[e]=new Float32Array(16);for(let e=0;e<this.joints.length;e++)this.jointFinalMatrices[e]=new Float32Array(16);this.skinnedPositions=null,this.skinnedNormals=null,this._gpuSkinningReady=!1,this._sV0=new Float64Array(4),this._sV1=new Float64Array(4),this._scrT=new Float64Array(3),this._scrR=new Float64Array(4),this._scrS=new Float64Array(3),this._buildTopologicalOrder(),this._parentMap=new Array(this.nodes.length).fill(-1);for(let e=0;e<this.nodes.length;e++)for(const i of this.nodes[e].children)this._parentMap[i]=e;this._invBindViews=new Array(this.joints.length);for(let e=0;e<this.joints.length;e++)this._invBindViews[e]=this.inverseBindMatrices.subarray(e*16,e*16+16)}setRestPose(t,e){this.restPositions=new Float32Array(t),this.restNormals=new Float32Array(e),this.skinnedPositions=new Float32Array(t.length),this.skinnedNormals=new Float32Array(e.length)}async initGPUSkinning(t,e,i){try{this._gpuDevice=t,this._gpuOutputBuffer=e;const r=this.restPositions.length/3,n=new Float32Array(r*8);for(let c=0;c<r;c++){const l=c*8,u=c*3,m=c*2;n[l]=this.restPositions[u],n[l+1]=this.restPositions[u+1],n[l+2]=this.restPositions[u+2],n[l+3]=this.restNormals[u],n[l+4]=this.restNormals[u+1],n[l+5]=this.restNormals[u+2],n[l+6]=i?i[m]:0,n[l+7]=i?i[m+1]:0}this._gpuRestDataBuffer=t.createBuffer({size:n.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,label:"skinning_restData"}),t.queue.writeBuffer(this._gpuRestDataBuffer,0,n),this._gpuJointWeightsBuffer=t.createBuffer({size:this.jointWeights.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,label:"skinning_jointWeights"}),t.queue.writeBuffer(this._gpuJointWeightsBuffer,0,this.jointWeights);const a=new Uint32Array(this.jointIndices.length);for(let c=0;c<this.jointIndices.length;c++)a[c]=this.jointIndices[c];this._gpuJointIndicesBuffer=t.createBuffer({size:a.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,label:"skinning_jointIndices"}),t.queue.writeBuffer(this._gpuJointIndicesBuffer,0,a),this._gpuJointMatricesBuffer=t.createBuffer({size:this.joints.length*16*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,label:"skinning_jointMatrices"}),this._gpuJointMatricesData=new Float32Array(this.joints.length*16);const o=t.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]});this._gpuSkinningPipeline=t.createComputePipeline({layout:t.createPipelineLayout({bindGroupLayouts:[o]}),compute:{module:t.createShaderModule({code:Os}),entryPoint:"main"}}),this._gpuSkinningBindGroup=t.createBindGroup({layout:o,entries:[{binding:0,resource:{buffer:this._gpuRestDataBuffer}},{binding:1,resource:{buffer:this._gpuJointWeightsBuffer}},{binding:2,resource:{buffer:this._gpuJointIndicesBuffer}},{binding:3,resource:{buffer:this._gpuJointMatricesBuffer}},{binding:4,resource:{buffer:this._gpuOutputBuffer}}]}),this._gpuVertexCount=r,this._gpuSkinningReady=!0,globalThis.__HZFX_DEBUG&&console.log(`GPU skinning initialized: ${r} vertices, ${this.joints.length} joints`)}catch(r){console.warn("GPU skinning init failed, using CPU fallback:",r),this._gpuSkinningReady=!1}}_applySkinningGPU(){for(let i=0;i<this.joints.length;i++)this._gpuJointMatricesData.set(this.jointFinalMatrices[i],i*16);this._gpuDevice.queue.writeBuffer(this._gpuJointMatricesBuffer,0,this._gpuJointMatricesData);const t=this._gpuDevice.createCommandEncoder({label:"SkinningComputeEncoder"}),e=t.beginComputePass({label:"SkinningComputePass"});e.setPipeline(this._gpuSkinningPipeline),e.setBindGroup(0,this._gpuSkinningBindGroup),e.dispatchWorkgroups(Math.ceil(this._gpuVertexCount/64),1,1),e.end(),this._gpuDevice.queue.submit([t.finish()])}update(t){if(!this.playing||this.animations.length===0)return{positions:this.skinnedPositions,normals:this.skinnedNormals,changed:!1};this.currentTime+=t*this.speed;const e=this.animations[this.currentAnimIndex];return this.loop?this.currentTime=this.currentTime%e.duration:this.currentTime>e.duration&&(this.currentTime=e.duration,this.playing=!1),this._computeLocalTransforms(this.currentTime),this._computeGlobalTransforms(),this._computeFinalMatrices(),this._gpuSkinningReady?(this._applySkinningGPU(),{gpuSkinned:!0,changed:!0}):(this._applySkinning(),{positions:this.skinnedPositions,normals:this.skinnedNormals,changed:!0})}getCurrentAnimation(){return this.animations[this.currentAnimIndex]}setAnimation(t){t>=0&&t<this.animations.length&&(this.currentAnimIndex=t,this.currentTime=0)}getAnimationNames(){return this.animations.map(t=>t.name)}_buildTopologicalOrder(){const t=new Set,e=[],i=n=>{if(t.has(n))return;t.add(n);const a=this.nodes[n];for(const o of a.children)i(o);e.push(n)},r=new Set;for(const n of this.nodes)for(const a of n.children)r.add(a);for(let n=0;n<this.nodes.length;n++)r.has(n)||i(n);this.topologicalOrder=e.reverse()}_sampleChannel(t,e,i){const{timestamps:r,values:n,interpolation:a,targetPath:o}=t;if(e<=r[0])return this._extractValue(n,0,o,i);if(e>=r[r.length-1])return this._extractValue(n,r.length-1,o,i);let c=0,l=r.length-1;for(;l-c>1;){const w=Math.floor((c+l)/2);r[w]<=e?c=w:l=w}const u=r[c],m=r[l],p=(e-u)/(m-u),d=this._extractValue(n,c,o,this._sV0),b=this._extractValue(n,l,o,this._sV1);return a==="STEP"?(i[0]=d[0],i[1]=d[1],i[2]=d[2],o==="rotation"&&(i[3]=d[3]),i):o==="rotation"?Ks(d,b,p,i):Qs(d,b,p,i)}_extractValue(t,e,i,r){if(i==="rotation"){const n=e*4;r[0]=t[n],r[1]=t[n+1],r[2]=t[n+2],r[3]=t[n+3]}else{const n=e*3;r[0]=t[n],r[1]=t[n+1],r[2]=t[n+2]}return r}_computeLocalTransforms(t){const e=this.animations[this.currentAnimIndex];for(let i=0;i<this.nodes.length;i++){const r=this.nodes[i];let n=r.translation,a=r.rotation,o=r.scale;for(const c of e.channels)c.targetNode===i&&(c.targetPath==="translation"?n=this._sampleChannel(c,t,this._scrT):c.targetPath==="rotation"?a=this._sampleChannel(c,t,this._scrR):c.targetPath==="scale"&&(o=this._sampleChannel(c,t,this._scrS)));ir(n,a,o,this.jointLocalTransforms[i])}}_computeGlobalTransforms(){const t=this._parentMap;for(const e of this.topologicalOrder){const i=t[e];i===-1?this.jointGlobalTransforms[e].set(this.jointLocalTransforms[e]):gi(this.jointGlobalTransforms[i],this.jointLocalTransforms[e],this.jointGlobalTransforms[e])}}_computeFinalMatrices(){for(let t=0;t<this.joints.length;t++){const e=this.joints[t],i=this.jointGlobalTransforms[e];gi(i,this._invBindViews[t],this.jointFinalMatrices[t])}}_applySkinning(){const t=this.restPositions.length/3,e=this.restPositions,i=this.restNormals,r=this.skinnedPositions,n=this.skinnedNormals,a=this.jointWeights,o=this.jointIndices,c=this.jointFinalMatrices;for(let l=0;l<t;l++){const u=l*3,m=l*4,p=e[u],d=e[u+1],b=e[u+2],w=i[u],M=i[u+1],R=i[u+2];let x=0,L=0,P=0,T=0,E=0,F=0;for(let Y=0;Y<4;Y++){const N=a[m+Y];if(N===0)continue;const z=c[o[m+Y]];x+=(z[0]*p+z[4]*d+z[8]*b+z[12])*N,L+=(z[1]*p+z[5]*d+z[9]*b+z[13])*N,P+=(z[2]*p+z[6]*d+z[10]*b+z[14])*N,T+=(z[0]*w+z[4]*M+z[8]*R)*N,E+=(z[1]*w+z[5]*M+z[9]*R)*N,F+=(z[2]*w+z[6]*M+z[10]*R)*N}const k=Math.sqrt(T*T+E*E+F*F);k>1e-4&&(n[u]=T/k,n[u+1]=E/k,n[u+2]=F/k),r[u]=x,r[u+1]=L,r[u+2]=P}}}class zi{constructor({duration:t=0,loop:e=!1,playbackRate:i=1}={}){this.currentTime=0,this.duration=t,this.loop=e,this.playbackRate=i,this.paused=!1,this._justLooped=!1}tick(t){if(this.paused)return 0;const e=t*this.playbackRate;return this.currentTime+=e,this._justLooped=!1,this.loop&&this.duration>0&&isFinite(this.duration)&&this.currentTime>=this.duration&&(this.currentTime=0,this._justLooped=!0),e}get justLooped(){return this._justLooped}reset(){this.currentTime=0,this._justLooped=!1}seek(t){this.currentTime=Math.max(0,t||0),this._justLooped=!1}}const bi={linear:s=>s,easeInQuad:s=>s*s,easeOutQuad:s=>1-(1-s)*(1-s),easeInOutQuad:s=>s<.5?2*s*s:1-Math.pow(-2*s+2,2)/2,easeInCubic:s=>s*s*s,easeOutCubic:s=>1-Math.pow(1-s,3),easeInOutCubic:s=>s<.5?4*s*s*s:1-Math.pow(-2*s+2,3)/2,easeInQuart:s=>s*s*s*s,easeOutQuart:s=>1-Math.pow(1-s,4),easeInOutQuart:s=>s<.5?8*s*s*s*s:1-Math.pow(-2*s+2,4)/2,easeOutBack:s=>1+2.70158*Math.pow(s-1,3)+1.70158*Math.pow(s-1,2),easeOutElastic:s=>{if(s===0||s===1)return s;const t=2*Math.PI/3;return Math.pow(2,-10*s)*Math.sin((s*10-.75)*t)+1}};function sr(s,t,e,i){const r=3*s,n=3*(e-s)-r,a=1-r-n,o=3*t,c=3*(i-t)-o,l=1-o-c,u=d=>((a*d+n)*d+r)*d,m=d=>((l*d+c)*d+o)*d,p=d=>(3*a*d+2*n)*d+r;return d=>{if(d<=0)return 0;if(d>=1)return 1;let b=d;for(let w=0;w<8;w++){const M=u(b)-d;if(Math.abs(M)<1e-5)break;const R=p(b);if(Math.abs(R)<1e-6)break;b-=M/R}return m(b)}}function Di(s,t){return typeof s=="function"?s(t):Array.isArray(s)&&s.length===4?sr(s[0],s[1],s[2],s[3])(t):(bi[s]||bi.linear)(t)}function rr(s,t){if(!Array.isArray(s)||s.length===0)return;if(s.length===1||t<=s[0].t)return s[0].v;const e=s[s.length-1];if(t>=e.t)return e.v;for(let i=0;i<s.length-1;i++){const r=s[i],n=s[i+1];if(t>=r.t&&t<=n.t){const a=n.t-r.t,o=a>0?(t-r.t)/a:0;return r.v+(n.v-r.v)*Di(r.ease,o)}}return e.v}function nr(s,t,e){if(!Array.isArray(s)||s.length===0)return;const i=s.length,r=s[i-1];let n,a,o;if(i===1||t<=s[0].t)n=a=s[0].v,o=0;else if(t>=r.t)n=a=r.v,o=0;else{n=a=r.v,o=0;for(let m=0;m<i-1;m++){const p=s[m],d=s[m+1];if(t>=p.t&&t<=d.t){const b=d.t-p.t;n=p.v,a=d.v,o=Di(p.ease,b>0?(t-p.t)/b:0);break}}}const c=n[0]+(a[0]-n[0])*o,l=n[1]+(a[1]-n[1])*o,u=n[2]+(a[2]-n[2])*o;return e?(e[0]=c,e[1]=l,e[2]=u,e):[c,l,u]}const ar=["gravityStrength","emissionRate","damping","particleSize","particleSpeed"],or={square:0,circle:1,triangle:2,diamond:3,star:4,hexagon:5,ring:6,heart:7,cross:8,spark:9,leaf:10,capsule:11,crescent:12,line:13,"curved-line":14};function Si(s){const t=atob(s),e=new Uint8Array(t.length);for(let i=0;i<t.length;i++)e[i]=t.charCodeAt(i);return e.buffer}class ct{constructor(t,e){this.device=t,this.config=e,this.MAX_PARTICLES=e.maxParticles||1e4,this.particleCount=e.particleCount||100,this.activeParticles=0,this.emitting=!1,this.currentEmissionTime=0,this.destroyed=!1,this.particleData=new Float32Array(this.MAX_PARTICLES*8),this.particleVelocities=new Float32Array(this.MAX_PARTICLES*4),this.instanceBuffer=t.createBuffer({size:this.MAX_PARTICLES*8*4,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC,label:"particleInstanceBuffer"}),this.velocityBuffer=t.createBuffer({size:this.MAX_PARTICLES*4*4,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,label:"particleVelocityBuffer"}),this.trailBuffer=t.createBuffer({size:this.MAX_PARTICLES*4*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,label:"particleTrailBuffer"}),this._trailResetData=new Float32Array(this.MAX_PARTICLES*4),this.appearanceUniformBuffer=t.createBuffer({size:224,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,label:"appearanceUniformBuffer"}),this.bloomIntensityBuffer=t.createBuffer({size:64,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,label:"systemBloomIntensityBuffer"}),e.overrideXVelocity===void 0&&(e.overrideXVelocity=!1),e.overrideYVelocity===void 0&&(e.overrideYVelocity=!1),e.overrideZVelocity===void 0&&(e.overrideZVelocity=!1),e.xVelocity===void 0&&(e.xVelocity=0),e.yVelocity===void 0&&(e.yVelocity=0),e.zVelocity===void 0&&(e.zVelocity=0),e.textureEnabled===void 0&&(e.textureEnabled=!1),e.glbModelEnabled===void 0&&(e.glbModelEnabled=!1),e.textureType===void 0&&(e.textureType="image"),e.glbFileName===void 0&&(e.glbFileName=null),e.animationIndex===void 0&&(e.animationIndex=0),e.animationSpeed===void 0&&(e.animationSpeed=1),e.animationLoop===void 0&&(e.animationLoop=!0),e.useGlbTexture===void 0&&(e.useGlbTexture=!1),e.glbHasTexture===void 0&&(e.glbHasTexture=!1),e.particleShape===void 0&&(e.particleShape="square"),e.particleShapeRotation!==void 0&&(e.rotation=(e.rotation||0)+e.particleShapeRotation,delete e.particleShapeRotation),e.particleShapeRotationX===void 0&&(e.particleShapeRotationX=0),e.particleShapeRotationY===void 0&&(e.particleShapeRotationY=0),e.particleShapeRotationZ===void 0&&(e.particleShapeRotationZ=0),e.particleColor===void 0&&(e.particleColor=[1,1,1]),e.startColor===void 0&&(e.startColor=[1,0,0]),e.endColor===void 0&&(e.endColor=[0,0,1]),e.fadeEnabled===void 0&&(e.fadeEnabled=!0),e.colorTransitionEnabled===void 0&&(e.colorTransitionEnabled=!1),e.randomColorEnabled===void 0&&(e.randomColorEnabled=!1),e.randomColors===void 0&&(e.randomColors=[]),e.particleSize===void 0&&(e.particleSize=.1),e.particleSpeed===void 0&&(e.particleSpeed=1),e.opacity===void 0&&(e.opacity=1),e.aspectRatio===void 0&&(e.aspectRatio=1),e.rotation===void 0&&(e.rotation=0),e.rotationMode===void 0&&(e.rotationMode="fixed"),e.minRotation===void 0&&(e.minRotation=0),e.maxRotation===void 0&&(e.maxRotation=90),e.orientX===void 0&&(e.orientX=0),e.orientY===void 0&&(e.orientY=0),e.orientZ===void 0&&(e.orientZ=0),e.randomSize===void 0&&(e.randomSize=!1),e.minSize===void 0&&(e.minSize=.05),e.maxSize===void 0&&(e.maxSize=.15),e.randomSpeed===void 0&&(e.randomSpeed=!1),e.minSpeed===void 0&&(e.minSpeed=.1),e.maxSpeed===void 0&&(e.maxSpeed=1),e.fadeSizeEnabled===void 0&&(e.fadeSizeEnabled=!1),e.increaseSizeEnabled===void 0&&(e.increaseSizeEnabled=!1),e.sizeLifetimeSpeed===void 0&&(e.sizeLifetimeSpeed=1),e.bloomEnabled===void 0&&(e.bloomEnabled=!0),e.bloomIntensity===void 0&&(e.bloomIntensity=1),e.bloomColor===void 0&&(e.bloomColor=[1,1,1]),e.gravityEnabled===void 0&&(e.gravityEnabled=!1),e.gravityStrength===void 0&&(e.gravityStrength=2),e.dampingEnabled===void 0&&(e.dampingEnabled=!1),e.dampingStrength===void 0&&(e.dampingStrength=1),e.attractorEnabled===void 0&&(e.attractorEnabled=!1),e.attractorStrength===void 0&&(e.attractorStrength=1),e.attractorPosition===void 0&&(e.attractorPosition=[0,0,0]),e.burstMode===void 0&&(e.burstMode=!1),e.emissionShape===void 0&&(e.emissionShape="cube"),e.lifetime===void 0&&(e.lifetime=5),e.emissionRate===void 0&&(e.emissionRate=10),e.startAt===void 0&&(e.startAt=0),e.emissionDuration===void 0&&(e.emissionDuration=10),e.emissionDurationInfinite===void 0&&(e.emissionDurationInfinite=!1),e.emissionDuration>300&&(e.emissionDurationInfinite=!0,e.emissionDuration=10),e.outerLength===void 0&&(e.outerLength=e.cubeLength??2),e.innerLength===void 0&&(e.innerLength=0),e.outerRadius===void 0&&(e.outerRadius=2),e.innerRadius===void 0&&(e.innerRadius=0),e.squareSize===void 0&&(e.squareSize=2),e.squareInnerSize===void 0&&(e.squareInnerSize=0),e.circleInnerRadius===void 0&&(e.circleInnerRadius=0),e.circleOuterRadius===void 0&&(e.circleOuterRadius=2),e.circleVelocityDirection===void 0&&(e.circleVelocityDirection="outward"),e.cylinderInnerRadius===void 0&&(e.cylinderInnerRadius=0),e.cylinderOuterRadius===void 0&&(e.cylinderOuterRadius=2),e.cylinderHeight===void 0&&(e.cylinderHeight=4),e.cylinderVelocityDirection===void 0&&(e.cylinderVelocityDirection="outward"),e.planeWidth===void 0&&(e.planeWidth=2),e.planeDepth===void 0&&(e.planeDepth=2),e.coneOuterRadius===void 0&&(e.coneOuterRadius=2),e.coneInnerRadius===void 0&&(e.coneInnerRadius=0),e.coneHeight===void 0&&(e.coneHeight=4),e.torusMajorRadius===void 0&&(e.torusMajorRadius=2),e.torusMinorRadius===void 0&&(e.torusMinorRadius=.5),e.lineLength===void 0&&(e.lineLength=4),e.hemisphereOuterRadius===void 0&&(e.hemisphereOuterRadius=2),e.hemisphereInnerRadius===void 0&&(e.hemisphereInnerRadius=0),e.discRadius===void 0&&(e.discRadius=2),e.annulusInnerRadius===void 0&&(e.annulusInnerRadius=1),e.annulusOuterRadius===void 0&&(e.annulusOuterRadius=2),e.capsuleRadius===void 0&&(e.capsuleRadius=.5),e.capsuleHeight===void 0&&(e.capsuleHeight=4),e.arcStartAngle===void 0&&(e.arcStartAngle=0),e.arcEndAngle===void 0&&(e.arcEndAngle=180),e.arcInnerRadius===void 0&&(e.arcInnerRadius=0),e.arcOuterRadius===void 0&&(e.arcOuterRadius=2),e.spiralTurns===void 0&&(e.spiralTurns=3),e.spiralRadiusStart===void 0&&(e.spiralRadiusStart=.5),e.spiralRadiusEnd===void 0&&(e.spiralRadiusEnd=2),e.spiralHeight===void 0&&(e.spiralHeight=4),e.frustumRadiusNear===void 0&&(e.frustumRadiusNear=.5),e.frustumRadiusFar===void 0&&(e.frustumRadiusFar=2),e.frustumHeight===void 0&&(e.frustumHeight=4),e.cubeSurfaceSize===void 0&&(e.cubeSurfaceSize=2),e.sphereSurfaceRadius===void 0&&(e.sphereSurfaceRadius=2),e.boxFrameSize===void 0&&(e.boxFrameSize=2),e.polygonSides===void 0&&(e.polygonSides=6),e.polygonRadius===void 0&&(e.polygonRadius=2),e.emissionRotationX===void 0&&(e.emissionRotationX=0),e.emissionRotationY===void 0&&(e.emissionRotationY=0),e.emissionRotationZ===void 0&&(e.emissionRotationZ=0),e.emissionPositionX===void 0&&(e.emissionPositionX=e.emissionTranslationX??0),e.emissionPositionY===void 0&&(e.emissionPositionY=e.emissionTranslationY??0),e.emissionPositionZ===void 0&&(e.emissionPositionZ=e.emissionTranslationZ??0),e.pulseEnabled===void 0&&(e.pulseEnabled=!1),e.pulseAmplitude===void 0&&(e.pulseAmplitude=.5),e.pulseFrequency===void 0&&(e.pulseFrequency=1),e.pulsePhaseRandom===void 0&&(e.pulsePhaseRandom=0),e.pulseOpacity===void 0&&(e.pulseOpacity=!1),e.confinementEnabled===void 0&&(e.confinementEnabled=!1),e.confinementShape===void 0&&(e.confinementShape="box"),e.confinementMode===void 0&&(e.confinementMode="bounce"),e.confinementSpace===void 0&&(e.confinementSpace="world"),e.confinementBoxHalfSize===void 0&&(e.confinementBoxHalfSize=[2,2,2]),e.confinementSphereRadius===void 0&&(e.confinementSphereRadius=3),e.confinementRestitution===void 0&&(e.confinementRestitution=.8),e.confinementFriction===void 0&&(e.confinementFriction=.1),e.softBoundaryEnabled===void 0&&(e.softBoundaryEnabled=!1),e.softBoundaryStrength===void 0&&(e.softBoundaryStrength=5),e.softBoundaryFalloff===void 0&&(e.softBoundaryFalloff=.5),e.depthWriteEnabled===void 0&&(e.depthWriteEnabled=!1),e.velocityStretchEnabled===void 0&&(e.velocityStretchEnabled=!1),e.velocityStretchFactor===void 0&&(e.velocityStretchFactor=1),e.blendMode===void 0&&(e.blendMode="normal"),e.noiseDistortEnabled===void 0&&(e.noiseDistortEnabled=!1),e.noiseTilingX===void 0&&(e.noiseTilingX=3),e.noiseTilingY===void 0&&(e.noiseTilingY=3),e.noiseSpeed===void 0&&(e.noiseSpeed=-1.5),e.noiseAmplitude===void 0&&(e.noiseAmplitude=.08),e.emissionTrailEnabled===void 0&&(e.emissionTrailEnabled=!1),e.emissionTrailDuration===void 0&&(e.emissionTrailDuration=1),e.emissionTrailWidth===void 0&&(e.emissionTrailWidth=.3),e.emissionTrailMinDistance===void 0&&(e.emissionTrailMinDistance=.05),e.emissionTrailMaxPoints===void 0&&(e.emissionTrailMaxPoints=256),e.emissionTrailSegments===void 0&&(e.emissionTrailSegments=8),e.emissionTrailMode===void 0&&(e.emissionTrailMode="ribbon"),e.emissionTrailShape===void 0&&(e.emissionTrailShape="straight"),e.emissionTrailShapeAmplitude===void 0&&(e.emissionTrailShapeAmplitude=.1),e.emissionTrailShapeFrequency===void 0&&(e.emissionTrailShapeFrequency=4),e.emissionTrailShapeSpeed===void 0&&(e.emissionTrailShapeSpeed=0),e.shapeDisplay===void 0&&(e.shapeDisplay=!0),e.followSystemTranslation===void 0&&(e.followSystemTranslation=!0),e.followSystemId===void 0&&(e.followSystemId=null),this._newEmissions=[],this._emptyEmissions=[],this._pendingFollowEmissions=this._emptyEmissions,this.glbVertexBuffer=null,this.glbIndexBuffer=null,this.glbIndexCount=0,this.glbIndexFormat="uint16",this.glbMeshData=null,this.glbRawArrayBuffer=null,this.glbAnimator=null,this.glbAnimated=!1,this._glbInterleavedData=null,this._appearanceData=new Float32Array(56),this._bloomIntensityData=new Float32Array(16),this._simPosition=[0,0,0],this._simVelocity=[0,0,0],this._simRotMatrix=null,this._simRotX=0,this._simRotZ=0,this._emitSimRotY=0,this.emitter=new wi(e),this.physics=new Ci(t,this.MAX_PARTICLES),this.textureManager=new Ai(t),e.gravityEnabled&&this.setGravity(e.gravityStrength||0),e.dampingEnabled&&this.physics.setDamping(e.dampingStrength||0),e.attractorEnabled&&e.attractorPosition&&this.setAttractor(e.attractorStrength||0,e.attractorPosition),e.confinementEnabled&&this.setConfinement({enabled:!0,shape:e.confinementShape,mode:e.confinementMode,space:e.confinementSpace,boxSize:e.confinementBoxHalfSize,sphereRadius:e.confinementSphereRadius,restitution:e.confinementRestitution,friction:e.confinementFriction}),e.softBoundaryEnabled&&this.setSoftBoundary({enabled:!0,strength:e.softBoundaryStrength,falloff:e.softBoundaryFalloff}),this.particleTexture=this.textureManager.getDefaultTexture(),this.updateBloomIntensity(),this.updateAppearanceUniform(),this.frameCount=0,this.shouldReset=!1,this._scriptParticleData=new Float32Array(this.MAX_PARTICLES*8),this._scriptVelocityData=new Float32Array(this.MAX_PARTICLES*4),this._scriptReadbackPending=!1,this._scriptReadbackReady=!1,this._scriptFrame=0,this._scriptTime=0,this._scriptConfigRestored=!1,this._particleScript=null,e.script&&(this._particleScript=new Bt(e.script,e,this.MAX_PARTICLES)),this.initComputePipeline(t)}async initComputePipeline(t){this.computeReady=await this.physics.initComputePipeline(this.instanceBuffer,this.velocityBuffer,this.trailBuffer)}setScript(t){this._particleScript&&(this._particleScript.destroy(),this._particleScript=null),this._scriptReadbackPending=!1,this._scriptReadbackReady=!1,this._scriptFrame=0,this._scriptTime=0,this._scriptConfigRestored=!1,t?(this.config.script=t,this._particleScript=new Bt(t,this.config,this.MAX_PARTICLES),this._particleScript.snapshotConfig(this.config)):delete this.config.script}async setTexture(t){this.destroyed||(this.textureManager.destroyTexture(this.particleTexture),this.particleTexture=await this.textureManager.loadTexture(t),this.config.textureEnabled=!0,this.updateAppearanceUniform(),this.updateBuffers())}resetTexture(){this.destroyed||(this.textureManager.destroyTexture(this.particleTexture),this.particleTexture=this.textureManager.getDefaultTexture(),this.config.textureEnabled=!1,this.updateAppearanceUniform(),this.updateBuffers())}async setGLBModel(t){try{this.glbRawArrayBuffer=t;const e=await Ii(t);this.glbMeshData=e,this.config.glbHasTexture=e.hasBaseColorTexture||!1;const i=new Float32Array(e.vertexCount*8);for(let r=0;r<e.vertexCount;r++){const n=r*8,a=r*3,o=r*2;i[n+0]=e.positions[a+0],i[n+1]=e.positions[a+1],i[n+2]=e.positions[a+2],i[n+3]=e.normals[a+0],i[n+4]=e.normals[a+1],i[n+5]=e.normals[a+2],e.texCoords?(i[n+6]=e.texCoords[o+0],i[n+7]=e.texCoords[o+1]):(i[n+6]=0,i[n+7]=0)}if(this.glbVertexBuffer&&this.glbVertexBuffer.destroy(),this.glbIndexBuffer&&this.glbIndexBuffer.destroy(),this.glbVertexBuffer=this.device.createBuffer({size:i.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST|GPUBufferUsage.STORAGE,label:"glbVertexBuffer"}),this.device.queue.writeBuffer(this.glbVertexBuffer,0,i),this.glbIndexBuffer=this.device.createBuffer({size:e.indices.byteLength,usage:GPUBufferUsage.INDEX|GPUBufferUsage.COPY_DST,label:"glbIndexBuffer"}),this.device.queue.writeBuffer(this.glbIndexBuffer,0,e.indices),this.glbIndexCount=e.indexCount,this.glbIndexFormat=e.indices instanceof Uint32Array?"uint32":"uint16",this.config.glbModelEnabled=!0,this.config.textureType="glb",e.animationData){this.glbAnimator=new Gi(e.animationData),this.glbAnimator.setRestPose(e.positions,e.normals),this.glbAnimated=!0,this.config.glbAnimated=!0,this.glbAnimator.loop=this.config.animationLoop,this._glbInterleavedData=new Float32Array(e.vertexCount*8);try{await this.glbAnimator.initGPUSkinning(this.device,this.glbVertexBuffer,e.texCoords)}catch(r){console.warn("GPU skinning init failed, using CPU fallback:",r)}globalThis.__HZFX_DEBUG&&console.log(`GLB animated model loaded: ${e.animationData.animations.length} animations`)}else this.glbAnimator=null,this.glbAnimated=!1,this.config.glbAnimated=!1,this._glbInterleavedData=null;globalThis.__HZFX_DEBUG&&console.log(`GLB model loaded: ${e.vertexCount} vertices, ${e.indexCount} indices`)}catch(e){throw console.error("Failed to load GLB model:",e),e}}resetGLBModel(){this.glbVertexBuffer&&(this.glbVertexBuffer.destroy(),this.glbVertexBuffer=null),this.glbIndexBuffer&&(this.glbIndexBuffer.destroy(),this.glbIndexBuffer=null),this.glbIndexCount=0,this.glbIndexFormat="uint16",this.glbMeshData=null,this.glbRawArrayBuffer=null,this.glbAnimator=null,this.glbAnimated=!1,this.config.glbAnimated=!1,this._glbInterleavedData=null,this.config.glbFileName=null,this.config.glbHasTexture=!1,this.config.useGlbTexture=!1,this.config.glbModelEnabled=!1,this.config.textureType="image"}setSimulationTransform(t){if(t.position&&(this._simPosition[0]=t.position[0],this._simPosition[1]=t.position[1],this._simPosition[2]=t.position[2]),t.rotation){this._simRotX=t.rotation[0]||0,this._simRotZ=t.rotation[1]||0,this._simRotY=t.rotation[2]||0;const e=Math.cos(this._simRotX),i=Math.sin(this._simRotX),r=Math.cos(this._simRotZ),n=Math.sin(this._simRotZ),a=Math.cos(this._simRotY),o=Math.sin(this._simRotY);this._simRotMatrix=[a*r,-a*n*e+o*i,a*n*i+o*e,n,r*e,-r*i,-o*r,o*n*e+a*i,-o*n*i+a*e]}else this._simRotMatrix=null,this._simRotX=0,this._simRotZ=0,this._simRotY=0;t.velocity&&(this._simVelocity[0]=t.velocity[0],this._simVelocity[1]=t.velocity[1],this._simVelocity[2]=t.velocity[2])}clearSimulationTransform(){this._simPosition[0]=this._simPosition[1]=this._simPosition[2]=0,this._simVelocity[0]=this._simVelocity[1]=this._simVelocity[2]=0,this._simRotMatrix=null,this._simRotX=0,this._simRotZ=0}updateAnimatedGLBBuffer(){if(!this.glbAnimator||!this.glbAnimator.playing)return!1;if(this.glbAnimator._gpuSkinningReady)return!0;const t=this.glbAnimator.skinnedPositions,e=this.glbAnimator.skinnedNormals,i=this.glbMeshData.texCoords;for(let r=0;r<this.glbMeshData.vertexCount;r++){const n=r*8,a=r*3,o=r*2;this._glbInterleavedData[n]=t[a],this._glbInterleavedData[n+1]=t[a+1],this._glbInterleavedData[n+2]=t[a+2],this._glbInterleavedData[n+3]=e[a],this._glbInterleavedData[n+4]=e[a+1],this._glbInterleavedData[n+5]=e[a+2],i?(this._glbInterleavedData[n+6]=i[o],this._glbInterleavedData[n+7]=i[o+1]):(this._glbInterleavedData[n+6]=0,this._glbInterleavedData[n+7]=0)}return this.device.queue.writeBuffer(this.glbVertexBuffer,0,this._glbInterleavedData),!0}updateAppearanceUniform(){if(this.destroyed)return;let t=0;this.config.rotationMode==="random"?t=1:this.config.rotationMode==="velocity"?t=2:this.config.rotationMode==="oriented"?t=3:this.config.rotationMode==="cylindrical"&&(t=4);const e=or[this.config.particleShape]??0,i=this._appearanceData;i[0]=this.config.fadeEnabled?1:0,i[1]=this.config.randomColorEnabled?2:this.config.colorTransitionEnabled?1:0,i[2]=this.config.particleSize,i[3]=this.config.textureEnabled?1:0,i[4]=this.config.particleColor[0],i[5]=this.config.particleColor[1],i[6]=this.config.particleColor[2],i[7]=this.config.rotation||0,i[8]=this.config.startColor[0],i[9]=this.config.startColor[1],i[10]=this.config.startColor[2],i[11]=t,i[12]=this.config.endColor[0],i[13]=this.config.endColor[1],i[14]=this.config.endColor[2],i[15]=this.config.minRotation||0,i[16]=this.config.maxRotation||90,i[17]=this.config.aspectRatio||1,i[18]=this.config.randomSize?1:0,i[19]=this.config.minSize||.1,i[20]=this.config.maxSize||.5,i[21]=this.config.fadeSizeEnabled?1:0,i[22]=this.config.opacity!==void 0?this.config.opacity:1,i[23]=this.config.increaseSizeEnabled?1:0,i[24]=this.config.sizeLifetimeSpeed??1,i[25]=e,i[26]=0,i[27]=this.config.pulseEnabled?1:0,i[28]=this.config.pulseAmplitude??.5,i[29]=this.config.pulseFrequency??1,i[30]=this.config.pulsePhaseRandom??0,i[31]=this.config.pulseOpacity?1:0,i[32]=this.config.particleShapeRotationX||0,i[33]=this.config.particleShapeRotationY||0,i[34]=this.config.particleShapeRotationZ||0,i[35]=0;const r=this.config.followSystemTranslation??!0;i[36]=r?this._simPosition[0]:0,i[37]=r?this._simPosition[1]:0,i[38]=r?this._simPosition[2]:0,i[39]=0,i[40]=this._simRotX,i[41]=this._simRotZ,i[42]=this.config.velocityStretchEnabled?1:0,i[43]=this.config.velocityStretchFactor??1,i[44]=this.config.noiseDistortEnabled?1:0,i[45]=this.config.noiseTilingX??3,i[46]=this.config.noiseTilingY??3,i[47]=this.config.noiseSpeed??-1.5,i[48]=this.config.noiseAmplitude??.08,i[49]=r?this._simVelocity[0]:0,i[50]=r?this._simVelocity[1]:0,i[51]=r?this._simVelocity[2]:0,i[52]=this.config.orientX??0,i[53]=this.config.orientY??0,i[54]=this.config.orientZ??0,i[55]=0,this.device.queue.writeBuffer(this.appearanceUniformBuffer,0,i)}updateBloomIntensity(){const t=this._bloomIntensityData;t[0]=this.config.bloomIntensity||1;const e=this.config.bloomColor||[1,1,1];t[4]=e[0],t[5]=e[1],t[6]=e[2],this.device.queue.writeBuffer(this.bloomIntensityBuffer,0,t)}spawnParticles(){if(this.activeParticles=0,this.currentEmissionTime=0,this._newEmissions.length=0,this._pendingFollowEmissions=this._emptyEmissions,this._scriptFrame=0,this._scriptTime=0,this._scriptReadbackPending=!1,this._scriptReadbackReady=!1,this._scriptConfigRestored=!1,this._particleScript&&(this._particleScript._configSnapshot?(this._particleScript.restoreConfig(this.config),this.config.gravityEnabled&&this.setGravity(this.config.gravityStrength),this.config.dampingEnabled&&this.physics.setDamping(this.config.dampingStrength),this.config.attractorEnabled&&this.setAttractor(this.config.attractorStrength,this.config.attractorPosition),this.updateAppearanceUniform(),this.updateBloomIntensity()):this._particleScript.snapshotConfig(this.config)),this.device.queue.writeBuffer(this.trailBuffer,0,this._trailResetData,0,this.MAX_PARTICLES*4),this.glbAnimator&&(this.glbAnimator.currentTime=0,this.glbAnimator.playing=!0),this.config.followSystemId){this.emitting=!0,this.particleCount=this.MAX_PARTICLES;return}if(this.config.burstMode){const t=this.config.particleCount;this.particleCount=t;let e=0;const i=500;for(let r=0;r<t;r++)if(this.emitParticle(),e++,e>=i||r===t-1){const n=r-e+1,a=n*8,o=n*4;this.device.queue.writeBuffer(this.instanceBuffer,a*4,this.particleData,a,e*8),this.device.queue.writeBuffer(this.velocityBuffer,o*4,this.particleVelocities,o,e*4),e=0}this.emitting=!1}else{this.emitting=!0;const t=this.config.lifetime||5,e=this.config.emissionDurationInfinite?t:Math.min(this.config.emissionDuration||10,t);this.particleCount=Math.min(Math.ceil((this.config.emissionRate||10)*e),this.MAX_PARTICLES)}}get effectiveEmissionDuration(){return this.config.emissionDurationInfinite?1/0:this.config.emissionDuration??10}_applySimTransformToParticle(t){this._emitSimRotY=this._simRotY||0;const e=t*8,i=t*4;if(this._simRotMatrix){const r=this._simRotMatrix,n=this.particleData[e],a=this.particleData[e+1],o=this.particleData[e+2],c=this.particleVelocities[i],l=this.particleVelocities[i+1],u=this.particleVelocities[i+2];this.particleData[e]=r[0]*n+r[1]*a+r[2]*o,this.particleData[e+1]=r[3]*n+r[4]*a+r[5]*o,this.particleData[e+2]=r[6]*n+r[7]*a+r[8]*o,this.particleVelocities[i]=r[0]*c+r[1]*l+r[2]*u,this.particleVelocities[i+1]=r[3]*c+r[4]*l+r[5]*u,this.particleVelocities[i+2]=r[6]*c+r[7]*l+r[8]*u}(this.config.followSystemTranslation??!0)||(this.particleData[e]+=this._simPosition[0],this.particleData[e+1]+=this._simPosition[1],this.particleData[e+2]+=this._simPosition[2])}emitParticle(){if(this.activeParticles>=this.particleCount)return!1;this.emitter.emitParticle(this.particleData,this.activeParticles,this.particleVelocities);const t=this.activeParticles*8,e=this.activeParticles*4;return this._applySimTransformToParticle(this.activeParticles),this._newEmissions.push(this.particleData[t],this.particleData[t+1],this.particleData[t+2],this.particleVelocities[e],this.particleVelocities[e+1],this.particleVelocities[e+2]),this.activeParticles++,!0}emitFollowerParticle(t,e,i){if(this.activeParticles>=this.particleCount)return!1;const r=this.activeParticles*8,n=t+(this.config.emissionPositionX||0),a=e+(this.config.emissionPositionY||0),o=i+(this.config.emissionPositionZ||0);this.particleData[r]=n,this.particleData[r+1]=a,this.particleData[r+2]=o;const c=this.activeParticles*4;return this.emitter.calculateVelocity(n,a,o,this.particleVelocities,c),this.emitter.setParticleColor(this.particleData,r),this.emitter.setParticleLifetime(this.particleData,r),this.activeParticles++,!0}updateParticles(t,e,i=0){const r=this.config.startAt||0,n=r>0&&i<r;if(this._particleScript&&this._scriptReadbackReady){this._scriptReadbackReady=!1,this._scriptTime+=t,this._scriptFrame++;const u=this.config.emissionDurationInfinite?1/0:(this.config.emissionDuration||0)+(this.config.lifetime||0);if(u>0&&this._scriptTime>=u&&!this._scriptConfigRestored)this._scriptConfigRestored=!0,this._particleScript._configSnapshot&&(this._particleScript.restoreConfig(this.config),this.updateAppearanceUniform(),this.updateBloomIntensity(),this.config.gravityEnabled&&this.setGravity(this.config.gravityStrength),this.config.dampingEnabled&&this.physics.setDamping(this.config.dampingStrength),this.config.attractorEnabled&&this.setAttractor(this.config.attractorStrength,this.config.attractorPosition));else if(!this._scriptConfigRestored){const m=u>0?Math.ceil(u/.016666666666666666):0,{configDirty:p,particlesDirty:d}=this._particleScript.execute(t,this._scriptTime,this._scriptFrame,m,this._scriptParticleData,this._scriptVelocityData,this.activeParticles);d&&this.activeParticles>0&&(this.device.queue.writeBuffer(this.instanceBuffer,0,this._scriptParticleData,0,this.activeParticles*8),this.device.queue.writeBuffer(this.velocityBuffer,0,this._scriptVelocityData,0,this.activeParticles*4)),p&&(this.updateAppearanceUniform(),this.updateBloomIntensity(),this.config.gravityEnabled&&this.setGravity(this.config.gravityStrength),this.config.dampingEnabled&&this.physics.setDamping(this.config.dampingStrength),this.config.attractorEnabled&&this.setAttractor(this.config.attractorStrength,this.config.attractorPosition))}}this.physics.physicsAccumulator+=t;const a=performance.now()/1e3,c=a-this.physics.lastUpdateTime>1/this.physics.minUpdatesPerSecond,l=this.activeParticles;if(!n&&!this.emitting&&!this.config.burstMode&&!this.config.followSystemId&&this.currentEmissionTime<this.effectiveEmissionDuration&&(this.emitting=!0),!n&&this.emitting)if(this.currentEmissionTime+=t,this.currentEmissionTime<this.effectiveEmissionDuration){const u=this.activeParticles;let m=!1;if(this.config.followSystemId){if(this._pendingFollowEmissions.length>0){const p=this._pendingFollowEmissions.length/6;for(let d=0;d<p;d++){const b=d*6;if(this.emitFollowerParticle(this._pendingFollowEmissions[b],this._pendingFollowEmissions[b+1],this._pendingFollowEmissions[b+2]))m=!0;else break}}}else{let p=0;if(this.config.emissionRate>=1){p=Math.floor(this.config.emissionRate*t);const d=this.config.emissionRate*t-p;Math.random()<d&&(p+=1)}else{const d=this.config.emissionRate*t;Math.random()<d&&(p=1)}p===0&&c&&this.config.emissionRate>0&&this.activeParticles<this.particleCount&&(p=1);for(let d=0;d<p&&this.emitParticle();d++)m=!0}if(m){const p=this.activeParticles-u,d=u*8,b=u*4;this.device.queue.writeBuffer(this.instanceBuffer,d*4,this.particleData,d,p*8),this.device.queue.writeBuffer(this.velocityBuffer,b*4,this.particleVelocities,b,p*4)}}else this.emitting=!1,this.currentEmissionTime=this.config.emissionDuration;for(;this.physics.physicsAccumulator>=this.physics.fixedDeltaTime;)this.physics.updatePhysics(this.physics.fixedDeltaTime,l,this.config,this.instanceBuffer,this.velocityBuffer,e),this.physics.physicsAccumulator-=this.physics.fixedDeltaTime,this.physics.physicsClock+=this.physics.fixedDeltaTime;c&&l>0&&(this.physics.updatePhysics(this.physics.fixedDeltaTime,l,this.config,this.instanceBuffer,this.velocityBuffer,e),this.physics.lastUpdateTime=a),this.frameCount++,(this.activeParticles>=this.particleCount||this.frameCount%300===0)&&this.readbackAndProcessParticles(),this._particleScript&&this.activeParticles>0&&!this._scriptReadbackPending&&(this._scriptReadbackPending=!0,this.physics.readbackForScript(this.activeParticles,this._scriptParticleData,this._scriptVelocityData,this.instanceBuffer,this.velocityBuffer).then(u=>{this._scriptReadbackPending=!1,u.shouldUpdate&&(this._scriptReadbackReady=!0)}).catch(()=>{this._scriptReadbackPending=!1}))}async readbackAndProcessParticles(){if(!(this.activeParticles<=0))try{if(!(await this.physics.readbackAndProcessParticles(this.activeParticles,this.particleData,this.particleVelocities,this.instanceBuffer,this.velocityBuffer)).shouldUpdate)return;let e=0,i=!1;for(let r=0;r<this.activeParticles;r++){const n=this.particleData[r*8+6],a=this.particleData[r*8+7];if(n>=a){if(this.emitting&&this.currentEmissionTime<this.effectiveEmissionDuration&&e<this.particleCount){this.respawnParticle(r,e),e++,i=!0;continue}continue}if(e!==r){const o=r*8,c=e*8;this.particleData.copyWithin(c,o,o+8);const l=r*4,u=e*4;this.particleVelocities.copyWithin(u,l,l+4),i=!0}e++}(e!==this.activeParticles||i)&&(this.activeParticles=e,this.device.queue.writeBuffer(this.instanceBuffer,0,this.particleData,0,this.activeParticles*8),this.device.queue.writeBuffer(this.velocityBuffer,0,this.particleVelocities,0,this.activeParticles*4))}catch(t){t&&t.name==="AbortError"||console.error("Error reading back particle data:",t)}}respawnParticle(t,e){!this.emitting||this.currentEmissionTime>=this.effectiveEmissionDuration||this.config.followSystemId||(this.emitter.emitParticle(this.particleData,e,this.particleVelocities),this._applySimTransformToParticle(e))}updateBuffers(){this.destroyed||!this.particleData||this.activeParticles>0&&this.device.queue.writeBuffer(this.instanceBuffer,0,this.particleData,0,this.activeParticles*8)}updateParticleColors(){if(!(this.destroyed||!this.particleData)){for(let t=0;t<this.activeParticles;t++){const e=t*8;if(this.config.randomColorEnabled&&this.config.randomColors.length>0){const i=this.config.randomColors,r=i[Math.floor(Math.random()*i.length)];this.particleData[e+3]=r[0],this.particleData[e+4]=r[1],this.particleData[e+5]=r[2]}else this.config.colorTransitionEnabled?(this.particleData[e+3]=this.config.startColor[0],this.particleData[e+4]=this.config.startColor[1],this.particleData[e+5]=this.config.startColor[2]):(this.particleData[e+3]=this.config.particleColor[0],this.particleData[e+4]=this.config.particleColor[1],this.particleData[e+5]=this.config.particleColor[2])}this.activeParticles>0&&this.device.queue.writeBuffer(this.instanceBuffer,0,this.particleData,0,this.activeParticles*8)}}updateParticleVelocities(){for(let t=0;t<this.activeParticles;t++){const e=t*8,i=t*4,r=this.particleData[e],n=this.particleData[e+1],a=this.particleData[e+2],o=this.particleVelocities[i],c=this.particleVelocities[i+1],l=this.particleVelocities[i+2],u=Math.sqrt(o*o+c*c+l*l);if(u>.001){const m=this.config.particleSpeed*2;this.particleVelocities[i]=o/u*m,this.particleVelocities[i+1]=c/u*m,this.particleVelocities[i+2]=l/u*m}else{const m=Math.sqrt(r*r+n*n+a*a);if(m>.001){const p=this.config.particleSpeed*2;this.particleVelocities[i]=r/m*p,this.particleVelocities[i+1]=n/m*p,this.particleVelocities[i+2]=a/m*p}else this.particleVelocities[i]=0,this.particleVelocities[i+1]=this.config.particleSpeed*2,this.particleVelocities[i+2]=0}}this.activeParticles>0&&this.device.queue.writeBuffer(this.velocityBuffer,0,this.particleVelocities,0,this.activeParticles*4)}async readbackForRendering(t,e){return this.physics.readbackForRendering(this.activeParticles,t,e,this.instanceBuffer,this.velocityBuffer)}destroy(){this.destroyed=!0,this.instanceBuffer.destroy(),this.velocityBuffer.destroy(),this.trailBuffer.destroy(),this.appearanceUniformBuffer.destroy(),this.bloomIntensityBuffer.destroy(),this.physics.destroy(),this.glbVertexBuffer&&(this.glbVertexBuffer.destroy(),this.glbVertexBuffer=null),this.glbIndexBuffer&&(this.glbIndexBuffer.destroy(),this.glbIndexBuffer=null),this.textureManager.destroyTexture(this.particleTexture),this._particleScript&&(this._particleScript.destroy(),this._particleScript=null),this.glbAnimator=null,this.glbMeshData=null,this.glbRawArrayBuffer=null,this.particleData=null,this.particleVelocities=null,this._scriptParticleData=null,this._scriptVelocityData=null}setGravity(t){this.physics.setGravity(t)}setAttractor(t,e){this.physics.setAttractor(t,e)}setConfinement(t){const e=t.center||this.config.confinementCenter||[0,0,0],i=t.space==="local"?[this.config.emissionPositionX||0,this.config.emissionPositionY||0,this.config.emissionPositionZ||0]:[0,0,0],r=[i[0]+(e[0]||0),i[1]+(e[1]||0),i[2]+(e[2]||0)];this.physics.setConfinement({...t,center:r})}setSoftBoundary(t){this.physics.setSoftBoundary(t)}}class Fi{constructor(t){this.device=t,this.particleSystems=[],this.activeSystemIndex=0,this.systemCounter=1,this.onSystemCreated=null,this.loop=void 0,this.clock=new zi({loop:!!this.loop}),this.ready=!0}createParticleSystem(t={}){const e=this.systemCounter++,i=t.name||`System ${e+1}`,r={...t,name:i,id:e},n=new ct(this.device,r);return this.particleSystems.push({system:n,config:r}),this.particleSystems.length===1&&(this.activeSystemIndex=0),this.onSystemCreated&&typeof this.onSystemCreated=="function"&&this.onSystemCreated(e,r),e}getActiveSystem(){return this.particleSystems.length===0?null:this.particleSystems[this.activeSystemIndex].system}getActiveConfig(){return this.particleSystems.length===0?null:this.particleSystems[this.activeSystemIndex].config}setActiveSystem(t){return t>=0&&t<this.particleSystems.length?(this.activeSystemIndex=t,!0):!1}getSystemById(t){return this.particleSystems.find(({config:e})=>e.id===t)||null}destroy(){for(const{system:t}of this.particleSystems)t.destroy();this.particleSystems=[],this.activeSystemIndex=0}removeSystem(t){if(t>=0&&t<this.particleSystems.length){const e=this.particleSystems[t].config;this.particleSystems[t].system.destroy(),this.particleSystems.splice(t,1);const i=e.id;for(const{config:r}of this.particleSystems)r.followSystemId===i&&(r.followSystemId=null);return this.particleSystems.length===0?this.activeSystemIndex=0:t<=this.activeSystemIndex&&(this.activeSystemIndex=Math.max(0,this.activeSystemIndex-1)),!0}return!1}respawnAllSystems(){var t;for(const{system:e}of this.particleSystems)e.spawnParticles();(t=this.clock)==null||t.reset()}getTotalDuration(){let t=0;for(const{config:e}of this.particleSystems){if(e.emissionDurationInfinite)return 1/0;const i=e.lifetime||5,r=(e.burstMode||e.oneOnlyMode?i:(e.emissionDuration||10)+i)+(e.startAt||0);r>t&&(t=r)}return t||1}updateAllSystems(t){const e=this.device.createCommandEncoder({label:"BatchedPhysicsEncoder"});let i=!1;const r=this.clock?this.clock.currentTime:0,n=this.clock?this.clock.duration:0;if(this.clock&&n>0&&isFinite(n)){const a=Math.min(1,this.clock.currentTime/n);for(const{system:o,config:c}of this.particleSystems){const l=c.keyframes;if(!(!l||c.keyframesEnabled===!1)){for(const u of ar){const m=l[u];if(m&&m.length){const p=rr(m,a);p!==void 0&&(c[u]=p)}}if(l.particleColor&&l.particleColor.length){const u=c.particleColor,m=u&&typeof u.length=="number"&&u.length>=3?u:void 0,p=nr(l.particleColor,a,m);p&&(c.particleColor=p,o.updateAppearanceUniform())}}}}for(const{system:a,config:o}of this.particleSystems){if(o.hidden||o.followSystemId)continue;const c=a.activeParticles>0;a.updateParticles(t,e,r),(c||a.activeParticles>0)&&(i=!0)}for(const{system:a,config:o}of this.particleSystems){if(o.hidden||!o.followSystemId)continue;const c=this.getSystemById(o.followSystemId);c&&(a._pendingFollowEmissions=c.system._newEmissions);const l=a.activeParticles>0;a.updateParticles(t,e,r),(l||a.activeParticles>0)&&(i=!0)}i&&this.device.queue.submit([e.finish()]);for(const{system:a}of this.particleSystems)a._newEmissions.length=0,a._pendingFollowEmissions=a._emptyEmissions}getSystemsList(){return this.particleSystems.map(({config:t},e)=>({name:t.name,id:t.id,index:e,isActive:e===this.activeSystemIndex,hidden:t.hidden||!1}))}duplicateActiveSystem(){if(this.particleSystems.length===0)return-1;const t=this.getActiveConfig(),e=JSON.parse(JSON.stringify(t));return e.name=`${t.name} (Copy)`,e.onAppearanceChange=null,e.onColorChange=null,e.onSizeChange=null,e.onSpeedChange=null,e.onPhysicsChange=null,e.onBloomIntensityChange=null,e.onRespawn=null,e.getActiveSystem=null,delete e.id,this.createParticleSystem(e)}async replaceSystems(t){var e;if(!t||!t.systems||!Array.isArray(t.systems))return console.error("Invalid scene data provided"),!1;this.ready=!1;try{this.particleSystems=[],this.systemCounter=1;for(const r of t.systems){const n=this.systemCounter++,a={...r,id:n},o=new ct(this.device,a);this.particleSystems.push({system:o,config:a})}const i={};t.systems.forEach((r,n)=>{i[r.id]=this.particleSystems[n].config.id});for(const{config:r}of this.particleSystems)r.followSystemId&&i[r.followSystemId]!==void 0&&(r.followSystemId=i[r.followSystemId]);t.activeSystemIndex!==void 0&&t.activeSystemIndex>=0&&t.activeSystemIndex<this.particleSystems.length?this.activeSystemIndex=t.activeSystemIndex:this.activeSystemIndex=0,this.loop=t.loop;for(const{system:r,config:n}of this.particleSystems)if(n.glbModelEnabled)try{let a=null;if(n.glbModelData)a=Si(n.glbModelData);else if(n.glbFileName){const o=await fetch(`/${n.glbFileName}`);o.ok?a=await o.arrayBuffer():console.warn(`GLB file not found: ${n.glbFileName}`)}if(a){if(await r.setGLBModel(a),n.animationIndex!==void 0&&r.glbAnimator&&r.glbAnimator.setAnimation(n.animationIndex),n.animationSpeed!==void 0&&r.glbAnimator&&(r.glbAnimator.speed=n.animationSpeed),n.animationLoop!==void 0&&r.glbAnimator&&(r.glbAnimator.loop=n.animationLoop),n.useGlbTexture&&(n.textureEnabled=!0),n.useGlbTexture&&((e=r.glbMeshData)!=null&&e.hasBaseColorTexture))try{const o=await Mt(a);if(o){const c=await createImageBitmap(o.imageBlob);await r.setTexture(c),globalThis.__HZFX_DEBUG&&console.log(`GLB embedded texture restored for ${n.name}`)}}catch(o){console.warn(`Failed to restore GLB texture for ${n.name}:`,o),n.useGlbTexture=!1}}else n.glbModelEnabled=!1}catch(a){console.warn(`Failed to load GLB for ${n.name}:`,a),n.glbModelEnabled=!1}for(const{system:r,config:n}of this.particleSystems)if(n.textureEnabled&&!n.glbModelEnabled&&n.textureImageData)try{const a=new Image;await new Promise((c,l)=>{a.onload=c,a.onerror=l,a.src=n.textureImageData});const o=await createImageBitmap(a);await r.setTexture(o)}catch(a){console.warn(`Failed to restore texture for ${n.name}:`,a),n.textureEnabled=!1}for(const{system:r,config:n}of this.particleSystems)r.updateAppearanceUniform();return this.respawnAllSystems(),!0}catch(i){return console.error("Error replacing systems:",i),!1}finally{this.ready=!0}}async addSystems(t,e=[0,0,0]){var r;if(!t||!t.systems||!Array.isArray(t.systems))return console.error("Invalid scene data provided"),!1;this.ready=!1;const i=[];try{for(const o of t.systems){const c=this.systemCounter++;i.push(c);const l={...o,id:c,emissionPositionX:(o.emissionPositionX||0)+e[0],emissionPositionY:(o.emissionPositionY||0)+e[1],emissionPositionZ:(o.emissionPositionZ||0)+e[2]};o.attractorEnabled&&o.attractorPosition&&(l.attractorPosition=[o.attractorPosition[0]+e[0],o.attractorPosition[1]+e[1],o.attractorPosition[2]+e[2]]),o.confinementEnabled&&o.confinementSpace==="world"&&Array.isArray(o.confinementCenter)&&(l.confinementCenter=[(o.confinementCenter[0]||0)+e[0],(o.confinementCenter[1]||0)+e[1],(o.confinementCenter[2]||0)+e[2]]);const u=new ct(this.device,l);this.particleSystems.push({system:u,config:l}),this.onSystemCreated&&typeof this.onSystemCreated=="function"&&this.onSystemCreated(c,l)}const n=this.particleSystems.length-t.systems.length,a={};t.systems.forEach((o,c)=>{a[o.id]=this.particleSystems[n+c].config.id});for(let o=n;o<this.particleSystems.length;o++){const{config:c}=this.particleSystems[o];c.followSystemId&&a[c.followSystemId]!==void 0&&(c.followSystemId=a[c.followSystemId])}for(const{system:o,config:c}of this.particleSystems)if(c.glbModelEnabled&&!o.glbMeshData)try{let l=null;if(c.glbModelData)l=Si(c.glbModelData);else if(c.glbFileName){const u=await fetch(`/${c.glbFileName}`);u.ok?l=await u.arrayBuffer():console.warn(`GLB file not found: ${c.glbFileName}`)}if(l){if(await o.setGLBModel(l),c.animationIndex!==void 0&&o.glbAnimator&&o.glbAnimator.setAnimation(c.animationIndex),c.animationSpeed!==void 0&&o.glbAnimator&&(o.glbAnimator.speed=c.animationSpeed),c.animationLoop!==void 0&&o.glbAnimator&&(o.glbAnimator.loop=c.animationLoop),c.useGlbTexture&&(c.textureEnabled=!0),c.useGlbTexture&&((r=o.glbMeshData)!=null&&r.hasBaseColorTexture))try{const u=await Mt(l);if(u){const m=await createImageBitmap(u.imageBlob);await o.setTexture(m),globalThis.__HZFX_DEBUG&&console.log(`GLB embedded texture restored for ${c.name}`)}}catch(u){console.warn(`Failed to restore GLB texture for ${c.name}:`,u),c.useGlbTexture=!1}}else c.glbModelEnabled=!1}catch(l){console.warn(`Failed to load GLB for ${c.name}:`,l),c.glbModelEnabled=!1}for(const{system:o,config:c}of this.particleSystems)if(c.textureEnabled&&!c.glbModelEnabled&&c.textureImageData&&!o._textureRestored)try{const l=new Image;await new Promise((m,p)=>{l.onload=m,l.onerror=p,l.src=c.textureImageData});const u=await createImageBitmap(l);await o.setTexture(u),o._textureRestored=!0}catch(l){console.warn(`Failed to restore texture for ${c.name}:`,l),c.textureEnabled=!1}return i}catch(n){return console.error("Error adding systems:",n),!1}finally{this.ready=!0}}}async function Vi(s){if(!s)throw new Error("canvas is required for initWebGPU()");if(!navigator.gpu)throw new Error("WebGPU not supported on this browser.");const t=s.getContext("webgpu"),i=await(await navigator.gpu.requestAdapter()).requestDevice(),r=navigator.gpu.getPreferredCanvasFormat();return t.configure({device:i,format:r,alphaMode:"premultiplied"}),{device:i,context:t,format:r,canvas:s}}const oe="rgba16float";function Rt(s,t,e,i){const r=s.createTexture({size:[e,i],format:oe,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,mipLevelCount:1,sampleCount:1}),n=s.createTexture({size:[e,i],format:oe,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,mipLevelCount:1,sampleCount:1}),a=s.createTexture({size:[e,i],format:oe,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,mipLevelCount:1,sampleCount:1});return{sceneTexture:r,bloomTexA:n,bloomTexB:a}}function Tt(s,t,e){return s.createTexture({size:[t,e],format:"depth24plus",usage:GPUTextureUsage.RENDER_ATTACHMENT})}function Te(s,t,e){const i=s.createBuffer({size:t.byteLength,usage:e,mappedAtCreation:!0});return new t.constructor(i.getMappedRange()).set(t),i.unmap(),i}const Oi=`
|
|
878
878
|
struct Uniforms {
|
|
879
879
|
transform: mat4x4<f32>,
|
|
880
880
|
cameraPosition: vec3<f32>,
|
|
@@ -936,7 +936,7 @@ return function(__deltaTime, __time, __currentFrame, __totalFrames, __particles,
|
|
|
936
936
|
|
|
937
937
|
return finalColor;
|
|
938
938
|
}
|
|
939
|
-
`,
|
|
939
|
+
`,Li=`
|
|
940
940
|
struct Uniforms {
|
|
941
941
|
transform: mat4x4<f32>,
|
|
942
942
|
cameraPosition: vec3<f32>,
|
|
@@ -1171,7 +1171,7 @@ return function(__deltaTime, __time, __currentFrame, __totalFrames, __particles,
|
|
|
1171
1171
|
|
|
1172
1172
|
return finalColor;
|
|
1173
1173
|
}
|
|
1174
|
-
`;function Vi(s){const t=s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:3,visibility:GPUShaderStage.FRAGMENT,sampler:{}}]}),e=s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),i=s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:3,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),r=s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]});return{particleBindGroupLayout:t,bloomBindGroupLayout:e,compositeBindGroupLayout:i,object3dBindGroupLayout:r}}function Oi(s,t,e,i={}){const{depthCompare:r}=i,n=r||"less",{particleBindGroupLayout:a,bloomBindGroupLayout:o,compositeBindGroupLayout:c,object3dBindGroupLayout:l}=e,u=s.createPipelineLayout({bindGroupLayouts:[a]}),h=s.createPipelineLayout({bindGroupLayouts:[o]}),p=s.createPipelineLayout({bindGroupLayouts:[c]}),d=s.createShaderModule({code:Pi}),S=s.createShaderModule({code:_i}),R=s.createShaderModule({code:wi}),E=s.createShaderModule({code:Bi}),T=s.createShaderModule({code:Di}),x=s.createShaderModule({code:Fi}),L=W=>s.createRenderPipeline({layout:u,vertex:{module:d,entryPoint:"vs_main",buffers:[{arrayStride:12,stepMode:"vertex",attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]},{arrayStride:32,stepMode:"instance",attributes:[{shaderLocation:1,offset:0,format:"float32x3"},{shaderLocation:2,offset:12,format:"float32x3"},{shaderLocation:3,offset:24,format:"float32x2"}]},{arrayStride:16,stepMode:"instance",attributes:[{shaderLocation:4,offset:0,format:"float32x3"}]},{arrayStride:16,stepMode:"instance",attributes:[{shaderLocation:5,offset:0,format:"float32x3"}]}]},fragment:{module:d,entryPoint:"fs_main",targets:[{format:le,blend:W}]},primitive:{topology:"triangle-list",cullMode:"none"},depthStencil:{depthWriteEnabled:!1,depthCompare:n,format:"depth24plus"}}),P=L({color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}),B=L({color:{srcFactor:"src-alpha",dstFactor:"one",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}),M=s.createRenderPipeline({layout:u,vertex:{module:d,entryPoint:"vs_main",buffers:[{arrayStride:12,stepMode:"vertex",attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]},{arrayStride:32,stepMode:"instance",attributes:[{shaderLocation:1,offset:0,format:"float32x3"},{shaderLocation:2,offset:12,format:"float32x3"},{shaderLocation:3,offset:24,format:"float32x2"}]},{arrayStride:16,stepMode:"instance",attributes:[{shaderLocation:4,offset:0,format:"float32x3"}]},{arrayStride:16,stepMode:"instance",attributes:[{shaderLocation:5,offset:0,format:"float32x3"}]}]},fragment:{module:d,entryPoint:"fs_main",targets:[{format:le,writeMask:0}]},primitive:{topology:"triangle-list",cullMode:"none"},depthStencil:{depthWriteEnabled:!0,depthCompare:"always",format:"depth24plus"}}),F=s.createRenderPipeline({layout:h,vertex:{module:S,entryPoint:"vs_main"},fragment:{module:S,entryPoint:"fs_main",targets:[{format:le}]},primitive:{topology:"triangle-list"}}),k=s.createRenderPipeline({layout:p,vertex:{module:R,entryPoint:"vs_main"},fragment:{module:R,entryPoint:"fs_main",targets:[{format:le,blend:{color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}}),Y=s.createRenderPipeline({layout:p,vertex:{module:E,entryPoint:"vs_main"},fragment:{module:E,entryPoint:"fs_main",targets:[{format:le,blend:{color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}}),N=s.createShaderModule({code:Gs}),G=s.createRenderPipeline({layout:p,vertex:{module:N,entryPoint:"vs_main"},fragment:{module:N,entryPoint:"fs_main",targets:[{format:t,blend:{color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}}),pe=s.createPipelineLayout({bindGroupLayouts:[l]}),De=s.createRenderPipeline({layout:pe,vertex:{module:T,entryPoint:"vs_main",buffers:[{arrayStride:24,stepMode:"vertex",attributes:[{shaderLocation:0,offset:0,format:"float32x3"},{shaderLocation:1,offset:12,format:"float32x3"}]}]},fragment:{module:T,entryPoint:"fs_main",targets:[{format:le,blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list",cullMode:"back"},depthStencil:{depthWriteEnabled:!0,depthCompare:n,format:"depth24plus"}}),lt=s.createRenderPipeline({layout:u,vertex:{module:x,entryPoint:"vs_main",buffers:[{arrayStride:32,stepMode:"vertex",attributes:[{shaderLocation:0,offset:0,format:"float32x3"},{shaderLocation:1,offset:12,format:"float32x3"},{shaderLocation:2,offset:24,format:"float32x2"}]},{arrayStride:32,stepMode:"instance",attributes:[{shaderLocation:3,offset:0,format:"float32x3"},{shaderLocation:4,offset:12,format:"float32x3"},{shaderLocation:5,offset:24,format:"float32x2"}]},{arrayStride:16,stepMode:"instance",attributes:[{shaderLocation:6,offset:0,format:"float32x3"}]}]},fragment:{module:x,entryPoint:"fs_main",targets:[{format:le,blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list",cullMode:"back"},depthStencil:{depthWriteEnabled:!0,depthCompare:n,format:"depth24plus"}});return{particlePipeline:P,particleAdditivePipeline:B,particleDepthWritePipeline:M,blurPipeline:F,compositePipeline:k,directRenderPipeline:Y,finalCompositePipeline:G,object3dPipeline:De,glbMeshPipeline:lt}}function ot(s,t,e,i){const{uniformBuffer:r,appearanceUniformBuffer:n,horizontalBlurUniformBuffer:a,verticalBlurUniformBuffer:o,bloomIntensityBuffer:c}=e,{sceneTexture:l,bloomTexA:u,bloomTexB:h}=i,p=s.createBindGroup({layout:s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:n}}]}),d=s.createBindGroup({layout:s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),entries:[{binding:0,resource:t},{binding:1,resource:l.createView()},{binding:2,resource:{buffer:a}}]}),S=s.createBindGroup({layout:s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),entries:[{binding:0,resource:t},{binding:1,resource:u.createView()},{binding:2,resource:{buffer:o}}]}),R=s.createBindGroup({layout:s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:3,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),entries:[{binding:0,resource:t},{binding:1,resource:l.createView()},{binding:2,resource:h.createView()},{binding:3,resource:{buffer:c}}]}),E=s.createBindGroup({layout:s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:3,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),entries:[{binding:0,resource:t},{binding:1,resource:l.createView()},{binding:2,resource:h.createView()},{binding:3,resource:{buffer:c}}]});return{particleBindGroup:p,horizontalBlurBindGroup:d,verticalBlurBindGroup:S,compositeBindGroup:R,directRenderBindGroup:E}}function Li(s){return s.createSampler({magFilter:"linear",minFilter:"linear",mipmapFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",maxAnisotropy:16})}function Xi(){const s=new Float32Array([-.5,-.5,.5,0,0,1,.5,-.5,.5,0,0,1,.5,.5,.5,0,0,1,-.5,.5,.5,0,0,1,.5,-.5,-.5,0,0,-1,-.5,-.5,-.5,0,0,-1,-.5,.5,-.5,0,0,-1,.5,.5,-.5,0,0,-1,-.5,.5,.5,0,1,0,.5,.5,.5,0,1,0,.5,.5,-.5,0,1,0,-.5,.5,-.5,0,1,0,-.5,-.5,-.5,0,-1,0,.5,-.5,-.5,0,-1,0,.5,-.5,.5,0,-1,0,-.5,-.5,.5,0,-1,0,.5,-.5,.5,1,0,0,.5,-.5,-.5,1,0,0,.5,.5,-.5,1,0,0,.5,.5,.5,1,0,0,-.5,-.5,-.5,-1,0,0,-.5,-.5,.5,-1,0,0,-.5,.5,.5,-1,0,0,-.5,.5,-.5,-1,0,0]),t=new Uint16Array([0,1,2,0,2,3,4,5,6,4,6,7,8,9,10,8,10,11,12,13,14,12,14,15,16,17,18,16,18,19,20,21,22,20,22,23]);return{vertices:s,indices:t}}function ki(s=16,t=16){const e=[],i=[];for(let r=0;r<=s;r++){const n=r*Math.PI/s,a=Math.sin(n),o=Math.cos(n);for(let c=0;c<=t;c++){const l=c*2*Math.PI/t,u=Math.sin(l),p=Math.cos(l)*a,d=o,S=u*a;e.push(p*.5,d*.5,S*.5),e.push(p,d,S)}}for(let r=0;r<s;r++)for(let n=0;n<t;n++){const a=r*(t+1)+n,o=a+t+1;i.push(a),i.push(o),i.push(a+1),i.push(o),i.push(o+1),i.push(a+1)}return{vertices:new Float32Array(e),indices:new Uint16Array(i)}}class rr{constructor(t,e,i,r,n){this.id=t,this.type=e,this.position=i,this.scale=r,this.color=n,this.rotation=[0,0,0]}getModelMatrix(){const{position:t,scale:e,rotation:i}=this,r=this.createTranslationMatrix(t),n=this.createRotationMatrixX(i[0]),a=this.createRotationMatrixY(i[1]),o=this.createRotationMatrixZ(i[2]),c=this.createScaleMatrix(e);let l=r;return l=this.multiplyMatrices(l,o),l=this.multiplyMatrices(l,a),l=this.multiplyMatrices(l,n),l=this.multiplyMatrices(l,c),l}getNormalMatrix(){return this.getModelMatrix()}createTranslationMatrix([t,e,i]){return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1])}createScaleMatrix([t,e,i]){return new Float32Array([t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1])}createRotationMatrixX(t){const e=Math.cos(t),i=Math.sin(t);return new Float32Array([1,0,0,0,0,e,i,0,0,-i,e,0,0,0,0,1])}createRotationMatrixY(t){const e=Math.cos(t),i=Math.sin(t);return new Float32Array([e,0,-i,0,0,1,0,0,i,0,e,0,0,0,0,1])}createRotationMatrixZ(t){const e=Math.cos(t),i=Math.sin(t);return new Float32Array([e,i,0,0,-i,e,0,0,0,0,1,0,0,0,0,1])}multiplyMatrices(t,e){const i=new Float32Array(16);for(let r=0;r<4;r++)for(let n=0;n<4;n++){let a=0;for(let o=0;o<4;o++)a+=t[r*4+o]*e[o*4+n];i[r*4+n]=a}return i}}class nr{constructor(t){this.device=t,this.objects=[],this.nextId=0,this.initializeGeometry(),this.onObjectAdded=null,this.onObjectRemoved=null,this.onObjectUpdated=null}initializeGeometry(){const t=Xi(),e=ki(16,16);this.cubeVertexBuffer=Ee(this.device,t.vertices,GPUBufferUsage.VERTEX),this.cubeIndexBuffer=Ee(this.device,t.indices,GPUBufferUsage.INDEX),this.cubeIndexCount=t.indices.length,this.sphereVertexBuffer=Ee(this.device,e.vertices,GPUBufferUsage.VERTEX),this.sphereIndexBuffer=Ee(this.device,e.indices,GPUBufferUsage.INDEX),this.sphereIndexCount=e.indices.length}addObject(t,e=[0,0,0],i=[1,1,1],r=[1,1,1,1]){const n=new rr(this.nextId++,t,e,i,r);return n.uniformBuffer=this.device.createBuffer({size:192,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.objects.push(n),this.onObjectAdded&&this.onObjectAdded(n),n}removeObject(t){const e=this.objects.findIndex(i=>i.id===t);e!==-1&&(this.objects[e].uniformBuffer.destroy(),this.objects.splice(e,1),this.onObjectRemoved&&this.onObjectRemoved(t))}updateObjectPosition(t,e){const i=this.objects.find(r=>r.id===t);i&&(i.position=e,this.onObjectUpdated&&this.onObjectUpdated(i))}updateObjectScale(t,e){const i=this.objects.find(r=>r.id===t);i&&(i.scale=e,this.onObjectUpdated&&this.onObjectUpdated(i))}updateObjectColor(t,e){const i=this.objects.find(r=>r.id===t);i&&(i.color=e,this.onObjectUpdated&&this.onObjectUpdated(i))}getAllObjects(){return this.objects}getObject(t){return this.objects.find(e=>e.id===t)}updateObjectUniforms(t){const e=t.getModelMatrix(),i=t.getNormalMatrix(),r=new Float32Array(t.color);this.device.queue.writeBuffer(t.uniformBuffer,0,e),this.device.queue.writeBuffer(t.uniformBuffer,64,i),this.device.queue.writeBuffer(t.uniformBuffer,128,r)}renderObjects(t,e,i,r){for(const n of this.objects){this.updateObjectUniforms(n);const a=this.device.createBindGroup({layout:i,entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:n.uniformBuffer}}]});let o,c,l;if(n.type==="cube")o=this.cubeVertexBuffer,c=this.cubeIndexBuffer,l=this.cubeIndexCount;else if(n.type==="sphere")o=this.sphereVertexBuffer,c=this.sphereIndexBuffer,l=this.sphereIndexCount;else continue;t.setPipeline(e),t.setBindGroup(0,a),t.setVertexBuffer(0,o),t.setIndexBuffer(c,"uint16"),t.drawIndexed(l)}}}function ar(s){const t=parseInt(s.slice(1,3),16)/255,e=parseInt(s.slice(3,5),16)/255,i=parseInt(s.slice(5,7),16)/255;return[t,e,i]}function or(s){if(!s)return"#ffffff";const t=Math.round(s[0]*255).toString(16).padStart(2,"0"),e=Math.round(s[1]*255).toString(16).padStart(2,"0"),i=Math.round(s[2]*255).toString(16).padStart(2,"0");return`#${t}${e}${i}`}function lr(s,t,e){const i=gi([s[0]-t[0],s[1]-t[1],s[2]-t[2]]),r=gi(bi(e,i)),n=bi(i,r);return new Float32Array([r[0],n[0],i[0],0,r[1],n[1],i[1],0,r[2],n[2],i[2],0,-xt(r,s),-xt(n,s),-xt(i,s),1])}function cr(s,t=Math.PI/4){const r=1/Math.tan(t/2);return new Float32Array([r*s,0,0,0,0,r,0,0,0,0,(100+.1)/(.1-100),-1,0,0,200*.1/(.1-100),0])}function gi(s){const t=Math.sqrt(s[0]*s[0]+s[1]*s[1]+s[2]*s[2]);return[s[0]/t,s[1]/t,s[2]/t]}function bi(s,t){return[s[1]*t[2]-s[2]*t[1],s[2]*t[0]-s[0]*t[2],s[0]*t[1]-s[1]*t[0]]}function xt(s,t){return s[0]*t[0]+s[1]*t[1]+s[2]*t[2]}function Ni(s,t){const e=new Float32Array(16);for(let i=0;i<4;i++)for(let r=0;r<4;r++){let n=0;for(let a=0;a<4;a++)n+=s[i+a*4]*t[a+r*4];e[i+r*4]=n}return e}const Mt=1481005640,ji=1,Yi=1313821514,Hi=5130562,Ze="$hzfxAsset",Zi=s=>typeof atob=="function"?Uint8Array.from(atob(s),t=>t.charCodeAt(0)):new Uint8Array(Buffer.from(s,"base64")),Si=s=>{if(typeof btoa=="function"){let t="";for(let e=0;e<s.length;e++)t+=String.fromCharCode(s[e]);return btoa(t)}return Buffer.from(s).toString("base64")};function ur(s){const t=s.indexOf(","),e=s.slice(5,t),i=e.split(";")[0]||"application/octet-stream",r=s.slice(t+1),a=/;base64/i.test(e)?Zi(r):new TextEncoder().encode(decodeURIComponent(r));return{mime:i,bytes:a}}function xi(s){return(4-s%4)%4}async function qi(s,t={}){const{textureFormat:e="keep",quality:i=.85}=t,r=[],n=[];let a=0;const o=(B,M,F)=>{const k=a,Y=B.length;r.push({offset:k,length:Y,mime:M,kind:F}),n.push(B),a+=Y;const N=xi(Y);return N&&(n.push(new Uint8Array(N)),a+=N),r.length-1},c=e==="webp"&&typeof OffscreenCanvas<"u"&&typeof createImageBitmap=="function",l=[];for(const B of s.systems||[]){const M={...B};if(typeof M.textureImageData=="string"&&M.textureImageData.startsWith("data:")){let{mime:F,bytes:k}=ur(M.textureImageData);if(c&&F!=="image/webp")try{const Y=await createImageBitmap(new Blob([k],{type:F})),N=new OffscreenCanvas(Y.width,Y.height);N.getContext("2d").drawImage(Y,0,0);const G=await N.convertToBlob({type:"image/webp",quality:i}),pe=new Uint8Array(await G.arrayBuffer());pe.length<k.length&&(k=pe,F="image/webp")}catch{}M.textureImageData={[Ze]:o(k,F,"texture")}}if(typeof M.glbModelData=="string"&&M.glbModelData.length>0){const F=Zi(M.glbModelData);M.glbModelData={[Ze]:o(F,"model/gltf-binary","glb")}}l.push(M)}const u={...s,systems:l,assets:r},h=new TextEncoder().encode(JSON.stringify(u)),p=xi(h.length),d=new Uint8Array(a);let S=0;for(const B of n)d.set(B,S),S+=B.length;const R=h.length+p,E=20+R+8+a,T=new ArrayBuffer(E),x=new DataView(T),L=new Uint8Array(T);let P=0;x.setUint32(P,Mt,!0),P+=4,x.setUint32(P,ji,!0),P+=4,x.setUint32(P,E,!0),P+=4,x.setUint32(P,R,!0),P+=4,x.setUint32(P,Yi,!0),P+=4,L.set(h,P),P+=h.length;for(let B=0;B<p;B++)L[P++]=32;return x.setUint32(P,a,!0),P+=4,x.setUint32(P,Hi,!0),P+=4,L.set(d,P),P+=a,T}function Rt(s){return!s||s.byteLength<12?!1:new DataView(s).getUint32(0,!0)===Mt}function Tt(s){const t=new DataView(s);if(t.getUint32(0,!0)!==Mt)throw new Error("[unpackHZFX] bad magic — not an .hzfx file");const e=t.getUint32(4,!0);if(e!==ji)throw new Error(`[unpackHZFX] unsupported version ${e}`);let i=12,r=null,n=-1;const a=new Uint8Array(s);for(;i+8<=s.byteLength;){const p=t.getUint32(i,!0);i+=4;const d=t.getUint32(i,!0);i+=4,d===Yi?r=JSON.parse(new TextDecoder().decode(a.subarray(i,i+p))):d===Hi&&(n=i),i+=p}if(!r)throw new Error("[unpackHZFX] missing JSON chunk");const o=r.assets||[],c=p=>{const d=o[p];return!d||n<0?null:{...d,bytes:a.subarray(n+d.offset,n+d.offset+d.length)}},l=p=>p&&typeof p=="object"&&typeof p[Ze]=="number",u=(r.systems||[]).map(p=>{const d={...p};if(l(d.textureImageData)){const S=c(d.textureImageData[Ze]);d.textureImageData=S?`data:${S.mime};base64,${Si(S.bytes)}`:void 0}if(l(d.glbModelData)){const S=c(d.glbModelData[Ze]);d.glbModelData=S?Si(S.bytes):void 0}return d}),h={...r,systems:u};return delete h.assets,h}function dr(s){const t=new Uint8Array(s);let e="";for(let i=0;i<t.byteLength;i++)e+=String.fromCharCode(t[i]);return btoa(e)}function $i(s){return{name:s.name,id:s.id,particleCount:s.particleCount,lifetime:s.lifetime,emissionRate:s.emissionRate,emissionDuration:s.emissionDuration,emissionDurationInfinite:s.emissionDurationInfinite||!1,startAt:s.startAt||0,keyframes:s.keyframes||null,keyframesEnabled:s.keyframesEnabled!==!1,particleSize:s.particleSize,particleSpeed:s.particleSpeed,emissionShape:s.emissionShape,outerLength:s.outerLength??s.cubeLength,innerLength:s.innerLength,outerRadius:s.outerRadius,innerRadius:s.innerRadius,squareSize:s.squareSize,squareInnerSize:s.squareInnerSize,circleInnerRadius:s.circleInnerRadius,circleOuterRadius:s.circleOuterRadius,fadeEnabled:s.fadeEnabled,colorTransitionEnabled:s.colorTransitionEnabled,particleColor:s.particleColor,startColor:s.startColor,endColor:s.endColor,randomColorEnabled:s.randomColorEnabled||!1,randomColors:s.randomColors||[],particleShape:s.particleShape||"square",particleShapeRotationX:s.particleShapeRotationX||0,particleShapeRotationY:s.particleShapeRotationY||0,particleShapeRotationZ:s.particleShapeRotationZ||0,pulseEnabled:s.pulseEnabled||!1,pulseAmplitude:s.pulseAmplitude??.5,pulseFrequency:s.pulseFrequency??1,pulsePhaseRandom:s.pulsePhaseRandom??0,pulseOpacity:s.pulseOpacity||!1,bloomEnabled:s.bloomEnabled,bloomIntensity:s.bloomIntensity,bloomColor:s.bloomColor,depthWriteEnabled:s.depthWriteEnabled||!1,burstMode:s.burstMode,gravityEnabled:s.gravityEnabled,gravityStrength:s.gravityStrength,dampingEnabled:s.dampingEnabled,dampingStrength:s.dampingStrength,attractorEnabled:s.attractorEnabled,attractorStrength:s.attractorStrength,attractorPosition:s.attractorPosition,emissionRotationX:s.emissionRotationX,emissionRotationY:s.emissionRotationY,emissionRotationZ:s.emissionRotationZ,orientToDirection:s.orientToDirection??!1,emissionPositionX:s.emissionPositionX,emissionPositionY:s.emissionPositionY,emissionPositionZ:s.emissionPositionZ,rotation:s.rotation,rotationMode:s.rotationMode,minRotation:s.minRotation,maxRotation:s.maxRotation,orientX:s.orientX,orientY:s.orientY,orientZ:s.orientZ,overrideXVelocity:s.overrideXVelocity,overrideYVelocity:s.overrideYVelocity,overrideZVelocity:s.overrideZVelocity,xVelocity:s.xVelocity,yVelocity:s.yVelocity,zVelocity:s.zVelocity,circleVelocityDirection:s.circleVelocityDirection,cylinderVelocityDirection:s.cylinderVelocityDirection,cylinderInnerRadius:s.cylinderInnerRadius,cylinderOuterRadius:s.cylinderOuterRadius,cylinderHeight:s.cylinderHeight,planeWidth:s.planeWidth,planeDepth:s.planeDepth,rectangleWidth:s.rectangleWidth,rectangleHeight:s.rectangleHeight,coneOuterRadius:s.coneOuterRadius,coneInnerRadius:s.coneInnerRadius,coneHeight:s.coneHeight,torusMajorRadius:s.torusMajorRadius,torusMinorRadius:s.torusMinorRadius,lineLength:s.lineLength,hemisphereOuterRadius:s.hemisphereOuterRadius,hemisphereInnerRadius:s.hemisphereInnerRadius,discRadius:s.discRadius,annulusInnerRadius:s.annulusInnerRadius,annulusOuterRadius:s.annulusOuterRadius,capsuleRadius:s.capsuleRadius,capsuleHeight:s.capsuleHeight,arcStartAngle:s.arcStartAngle,arcEndAngle:s.arcEndAngle,arcInnerRadius:s.arcInnerRadius,arcOuterRadius:s.arcOuterRadius,spiralTurns:s.spiralTurns,spiralRadiusStart:s.spiralRadiusStart,spiralRadiusEnd:s.spiralRadiusEnd,spiralHeight:s.spiralHeight,frustumRadiusNear:s.frustumRadiusNear,frustumRadiusFar:s.frustumRadiusFar,frustumHeight:s.frustumHeight,cubeSurfaceSize:s.cubeSurfaceSize,sphereSurfaceRadius:s.sphereSurfaceRadius,boxFrameSize:s.boxFrameSize,polygonSides:s.polygonSides,polygonRadius:s.polygonRadius,aspectRatio:s.aspectRatio,randomSize:s.randomSize,minSize:s.minSize,maxSize:s.maxSize,fadeSizeEnabled:s.fadeSizeEnabled,increaseSizeEnabled:s.increaseSizeEnabled,sizeLifetimeSpeed:s.sizeLifetimeSpeed,opacity:s.opacity,randomSpeed:s.randomSpeed,minSpeed:s.minSpeed,maxSpeed:s.maxSpeed,oneOnlyMode:s.oneOnlyMode,confinementEnabled:s.confinementEnabled||!1,confinementShape:s.confinementShape||"box",confinementMode:s.confinementMode||"bounce",confinementSpace:s.confinementSpace||"world",confinementBoxHalfSize:s.confinementBoxHalfSize||[2,2,2],confinementSphereRadius:s.confinementSphereRadius??3,confinementRestitution:s.confinementRestitution??.8,confinementFriction:s.confinementFriction??.1,confinementCenter:s.confinementCenter,softBoundaryEnabled:s.softBoundaryEnabled||!1,softBoundaryStrength:s.softBoundaryStrength??5,softBoundaryFalloff:s.softBoundaryFalloff??.5,followSystemId:s.followSystemId||null,followSystemTranslation:s.followSystemTranslation??!0,hidden:s.hidden||!1,emissionTrailEnabled:s.emissionTrailEnabled||!1,emissionTrailDuration:s.emissionTrailDuration??1,emissionTrailWidth:s.emissionTrailWidth??.5,emissionTrailMinDistance:s.emissionTrailMinDistance??.05,emissionTrailMaxPoints:s.emissionTrailMaxPoints??100,emissionTrailSegments:s.emissionTrailSegments??8,emissionTrailMode:s.emissionTrailMode??"ribbon",emissionTrailShape:s.emissionTrailShape??"straight",emissionTrailShapeAmplitude:s.emissionTrailShapeAmplitude??.1,emissionTrailShapeFrequency:s.emissionTrailShapeFrequency??4,emissionTrailShapeSpeed:s.emissionTrailShapeSpeed??0,shapeDisplay:s.shapeDisplay??!0,blendMode:s.blendMode??"normal",noiseDistortEnabled:s.noiseDistortEnabled||!1,noiseTilingX:s.noiseTilingX??3,noiseTilingY:s.noiseTilingY??3,noiseSpeed:s.noiseSpeed??-1.5,noiseAmplitude:s.noiseAmplitude??.08,velocityStretchEnabled:s.velocityStretchEnabled||!1,velocityStretchFactor:s.velocityStretchFactor??1,textureEnabled:s.textureEnabled||!1,textureType:s.textureType,textureFileName:s.textureFileName,imageDescription:s.imageDescription,glbModelEnabled:s.glbModelEnabled||!1,glbFileName:s.glbFileName,glbHasTexture:s.glbHasTexture||!1,useGlbTexture:s.useGlbTexture||!1,glbAnimated:s.glbAnimated||!1,animationIndex:s.animationIndex,animationSpeed:s.animationSpeed,animationLoop:s.animationLoop,glbDescription:s.glbDescription,script:s.script||void 0,displayUnit:s.displayUnit||"m"}}async function fr(s,t,e="hzfx"){if(!s||!s.particleSystems||s.particleSystems.length===0){alert("No particle systems to save.");return}try{const i={version:"1.0",timestamp:new Date().toISOString(),systems:s.particleSystems.map(({config:u,system:h})=>({...$i(u),textureImageData:u.textureEnabled&&!u.glbModelEnabled&&u.textureImageData?u.textureImageData:void 0,glbModelData:u.glbModelEnabled&&h.glbRawArrayBuffer?dr(h.glbRawArrayBuffer):void 0})),activeSystemIndex:s.activeSystemIndex,loop:s.loop||!1},r=e==="json"?"json":"hzfx";let n;if(r==="hzfx"){const u=await qi(i,{textureFormat:"webp"});n=new Blob([u],{type:"application/octet-stream"})}else n=new Blob([JSON.stringify(i,null,2)],{type:"application/json"});let a;if(t)a=t;else{const u=new Date;a=`particle-scene_${`${u.getFullYear()}-${(u.getMonth()+1).toString().padStart(2,"0")}-${u.getDate().toString().padStart(2,"0")}_${u.getHours().toString().padStart(2,"0")}${u.getMinutes().toString().padStart(2,"0")}`}`}const o=`${a}.${r}`,c=URL.createObjectURL(n),l=document.createElement("a");l.href=c,l.download=o,document.body.appendChild(l),l.click(),document.body.removeChild(l),URL.revokeObjectURL(c)}catch(i){console.error("Error saving scene:",i),alert("Error saving scene. See console for details.")}}function pr(s){return new Promise((t,e)=>{try{const i=s.target.files[0];if(!i){e(new Error("No file selected"));return}const r=new FileReader;r.onload=n=>{try{const a=n.target.result;let o;if(Rt(a)?o=Tt(a):o=JSON.parse(new TextDecoder().decode(a)),!Array.isArray(o.systems)||o.systems.length===0)throw new Error("No valid particle systems found in the file");t({systems:o.systems.slice(),activeSystemIndex:o.activeSystemIndex||0})}catch(a){console.error("Error loading scene:",a),alert("Error loading scene: "+a.message),e(a)}s.target.value=""},r.onerror=()=>{alert("Failed to read the file"),e(new Error("Failed to read the file")),s.target.value=""},r.readAsArrayBuffer(i)}catch(i){console.error("Error in loadScene:",i),e(i)}})}async function hr(s){if(!s||typeof s!="string")throw new Error("[fetchPreset] url must be a non-empty string");const t=await fetch(s);if(!t.ok)throw new Error(`[fetchPreset] HTTP ${t.status}: ${t.statusText}`);const e=await t.arrayBuffer();let i;if(Rt(e)?i=Tt(e):i=JSON.parse(new TextDecoder().decode(e)),!Array.isArray(i.systems)||i.systems.length===0)throw new Error('[fetchPreset] Invalid preset: "systems" must be a non-empty array');return{version:i.version,systems:i.systems,activeSystemIndex:i.activeSystemIndex??0}}const mr=s=>`
|
|
1174
|
+
`;function Xi(s){const t=s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:3,visibility:GPUShaderStage.FRAGMENT,sampler:{}}]}),e=s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),i=s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:3,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),r=s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]});return{particleBindGroupLayout:t,bloomBindGroupLayout:e,compositeBindGroupLayout:i,object3dBindGroupLayout:r}}function ki(s,t,e,i={}){const{depthCompare:r}=i,n=r||"less",{particleBindGroupLayout:a,bloomBindGroupLayout:o,compositeBindGroupLayout:c,object3dBindGroupLayout:l}=e,u=s.createPipelineLayout({bindGroupLayouts:[a]}),m=s.createPipelineLayout({bindGroupLayouts:[o]}),p=s.createPipelineLayout({bindGroupLayouts:[c]}),d=s.createShaderModule({code:Bi}),b=s.createShaderModule({code:Mi}),w=s.createShaderModule({code:Ri}),M=s.createShaderModule({code:Ti}),R=s.createShaderModule({code:Oi}),x=s.createShaderModule({code:Li}),L=W=>s.createRenderPipeline({layout:u,vertex:{module:d,entryPoint:"vs_main",buffers:[{arrayStride:12,stepMode:"vertex",attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]},{arrayStride:32,stepMode:"instance",attributes:[{shaderLocation:1,offset:0,format:"float32x3"},{shaderLocation:2,offset:12,format:"float32x3"},{shaderLocation:3,offset:24,format:"float32x2"}]},{arrayStride:16,stepMode:"instance",attributes:[{shaderLocation:4,offset:0,format:"float32x3"}]},{arrayStride:16,stepMode:"instance",attributes:[{shaderLocation:5,offset:0,format:"float32x3"}]}]},fragment:{module:d,entryPoint:"fs_main",targets:[{format:oe,blend:W}]},primitive:{topology:"triangle-list",cullMode:"none"},depthStencil:{depthWriteEnabled:!1,depthCompare:n,format:"depth24plus"}}),P=L({color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}),T=L({color:{srcFactor:"src-alpha",dstFactor:"one",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}),E=s.createRenderPipeline({layout:u,vertex:{module:d,entryPoint:"vs_main",buffers:[{arrayStride:12,stepMode:"vertex",attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]},{arrayStride:32,stepMode:"instance",attributes:[{shaderLocation:1,offset:0,format:"float32x3"},{shaderLocation:2,offset:12,format:"float32x3"},{shaderLocation:3,offset:24,format:"float32x2"}]},{arrayStride:16,stepMode:"instance",attributes:[{shaderLocation:4,offset:0,format:"float32x3"}]},{arrayStride:16,stepMode:"instance",attributes:[{shaderLocation:5,offset:0,format:"float32x3"}]}]},fragment:{module:d,entryPoint:"fs_main",targets:[{format:oe,writeMask:0}]},primitive:{topology:"triangle-list",cullMode:"none"},depthStencil:{depthWriteEnabled:!0,depthCompare:"always",format:"depth24plus"}}),F=s.createRenderPipeline({layout:m,vertex:{module:b,entryPoint:"vs_main"},fragment:{module:b,entryPoint:"fs_main",targets:[{format:oe}]},primitive:{topology:"triangle-list"}}),k=s.createRenderPipeline({layout:p,vertex:{module:w,entryPoint:"vs_main"},fragment:{module:w,entryPoint:"fs_main",targets:[{format:oe,blend:{color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}}),Y=s.createRenderPipeline({layout:p,vertex:{module:M,entryPoint:"vs_main"},fragment:{module:M,entryPoint:"fs_main",targets:[{format:oe,blend:{color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}}),N=s.createShaderModule({code:Vs}),z=s.createRenderPipeline({layout:p,vertex:{module:N,entryPoint:"vs_main"},fragment:{module:N,entryPoint:"fs_main",targets:[{format:t,blend:{color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}}),de=s.createPipelineLayout({bindGroupLayouts:[l]}),De=s.createRenderPipeline({layout:de,vertex:{module:R,entryPoint:"vs_main",buffers:[{arrayStride:24,stepMode:"vertex",attributes:[{shaderLocation:0,offset:0,format:"float32x3"},{shaderLocation:1,offset:12,format:"float32x3"}]}]},fragment:{module:R,entryPoint:"fs_main",targets:[{format:oe,blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list",cullMode:"back"},depthStencil:{depthWriteEnabled:!0,depthCompare:n,format:"depth24plus"}}),dt=s.createRenderPipeline({layout:u,vertex:{module:x,entryPoint:"vs_main",buffers:[{arrayStride:32,stepMode:"vertex",attributes:[{shaderLocation:0,offset:0,format:"float32x3"},{shaderLocation:1,offset:12,format:"float32x3"},{shaderLocation:2,offset:24,format:"float32x2"}]},{arrayStride:32,stepMode:"instance",attributes:[{shaderLocation:3,offset:0,format:"float32x3"},{shaderLocation:4,offset:12,format:"float32x3"},{shaderLocation:5,offset:24,format:"float32x2"}]},{arrayStride:16,stepMode:"instance",attributes:[{shaderLocation:6,offset:0,format:"float32x3"}]}]},fragment:{module:x,entryPoint:"fs_main",targets:[{format:oe,blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list",cullMode:"back"},depthStencil:{depthWriteEnabled:!0,depthCompare:n,format:"depth24plus"}});return{particlePipeline:P,particleAdditivePipeline:T,particleDepthWritePipeline:E,blurPipeline:F,compositePipeline:k,directRenderPipeline:Y,finalCompositePipeline:z,object3dPipeline:De,glbMeshPipeline:dt}}function ut(s,t,e,i){const{uniformBuffer:r,appearanceUniformBuffer:n,horizontalBlurUniformBuffer:a,verticalBlurUniformBuffer:o,bloomIntensityBuffer:c}=e,{sceneTexture:l,bloomTexA:u,bloomTexB:m}=i,p=s.createBindGroup({layout:s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:n}}]}),d=s.createBindGroup({layout:s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),entries:[{binding:0,resource:t},{binding:1,resource:l.createView()},{binding:2,resource:{buffer:a}}]}),b=s.createBindGroup({layout:s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),entries:[{binding:0,resource:t},{binding:1,resource:u.createView()},{binding:2,resource:{buffer:o}}]}),w=s.createBindGroup({layout:s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:3,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),entries:[{binding:0,resource:t},{binding:1,resource:l.createView()},{binding:2,resource:m.createView()},{binding:3,resource:{buffer:c}}]}),M=s.createBindGroup({layout:s.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:3,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),entries:[{binding:0,resource:t},{binding:1,resource:l.createView()},{binding:2,resource:m.createView()},{binding:3,resource:{buffer:c}}]});return{particleBindGroup:p,horizontalBlurBindGroup:d,verticalBlurBindGroup:b,compositeBindGroup:w,directRenderBindGroup:M}}function Ni(s){return s.createSampler({magFilter:"linear",minFilter:"linear",mipmapFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",maxAnisotropy:16})}function ji(){const s=new Float32Array([-.5,-.5,.5,0,0,1,.5,-.5,.5,0,0,1,.5,.5,.5,0,0,1,-.5,.5,.5,0,0,1,.5,-.5,-.5,0,0,-1,-.5,-.5,-.5,0,0,-1,-.5,.5,-.5,0,0,-1,.5,.5,-.5,0,0,-1,-.5,.5,.5,0,1,0,.5,.5,.5,0,1,0,.5,.5,-.5,0,1,0,-.5,.5,-.5,0,1,0,-.5,-.5,-.5,0,-1,0,.5,-.5,-.5,0,-1,0,.5,-.5,.5,0,-1,0,-.5,-.5,.5,0,-1,0,.5,-.5,.5,1,0,0,.5,-.5,-.5,1,0,0,.5,.5,-.5,1,0,0,.5,.5,.5,1,0,0,-.5,-.5,-.5,-1,0,0,-.5,-.5,.5,-1,0,0,-.5,.5,.5,-1,0,0,-.5,.5,-.5,-1,0,0]),t=new Uint16Array([0,1,2,0,2,3,4,5,6,4,6,7,8,9,10,8,10,11,12,13,14,12,14,15,16,17,18,16,18,19,20,21,22,20,22,23]);return{vertices:s,indices:t}}function Yi(s=16,t=16){const e=[],i=[];for(let r=0;r<=s;r++){const n=r*Math.PI/s,a=Math.sin(n),o=Math.cos(n);for(let c=0;c<=t;c++){const l=c*2*Math.PI/t,u=Math.sin(l),p=Math.cos(l)*a,d=o,b=u*a;e.push(p*.5,d*.5,b*.5),e.push(p,d,b)}}for(let r=0;r<s;r++)for(let n=0;n<t;n++){const a=r*(t+1)+n,o=a+t+1;i.push(a),i.push(o),i.push(a+1),i.push(o),i.push(o+1),i.push(a+1)}return{vertices:new Float32Array(e),indices:new Uint16Array(i)}}class lr{constructor(t,e,i,r,n){this.id=t,this.type=e,this.position=i,this.scale=r,this.color=n,this.rotation=[0,0,0]}getModelMatrix(){const{position:t,scale:e,rotation:i}=this,r=this.createTranslationMatrix(t),n=this.createRotationMatrixX(i[0]),a=this.createRotationMatrixY(i[1]),o=this.createRotationMatrixZ(i[2]),c=this.createScaleMatrix(e);let l=r;return l=this.multiplyMatrices(l,o),l=this.multiplyMatrices(l,a),l=this.multiplyMatrices(l,n),l=this.multiplyMatrices(l,c),l}getNormalMatrix(){return this.getModelMatrix()}createTranslationMatrix([t,e,i]){return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1])}createScaleMatrix([t,e,i]){return new Float32Array([t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1])}createRotationMatrixX(t){const e=Math.cos(t),i=Math.sin(t);return new Float32Array([1,0,0,0,0,e,i,0,0,-i,e,0,0,0,0,1])}createRotationMatrixY(t){const e=Math.cos(t),i=Math.sin(t);return new Float32Array([e,0,-i,0,0,1,0,0,i,0,e,0,0,0,0,1])}createRotationMatrixZ(t){const e=Math.cos(t),i=Math.sin(t);return new Float32Array([e,i,0,0,-i,e,0,0,0,0,1,0,0,0,0,1])}multiplyMatrices(t,e){const i=new Float32Array(16);for(let r=0;r<4;r++)for(let n=0;n<4;n++){let a=0;for(let o=0;o<4;o++)a+=t[r*4+o]*e[o*4+n];i[r*4+n]=a}return i}}class cr{constructor(t){this.device=t,this.objects=[],this.nextId=0,this.initializeGeometry(),this.onObjectAdded=null,this.onObjectRemoved=null,this.onObjectUpdated=null}initializeGeometry(){const t=ji(),e=Yi(16,16);this.cubeVertexBuffer=Te(this.device,t.vertices,GPUBufferUsage.VERTEX),this.cubeIndexBuffer=Te(this.device,t.indices,GPUBufferUsage.INDEX),this.cubeIndexCount=t.indices.length,this.sphereVertexBuffer=Te(this.device,e.vertices,GPUBufferUsage.VERTEX),this.sphereIndexBuffer=Te(this.device,e.indices,GPUBufferUsage.INDEX),this.sphereIndexCount=e.indices.length}addObject(t,e=[0,0,0],i=[1,1,1],r=[1,1,1,1]){const n=new lr(this.nextId++,t,e,i,r);return n.uniformBuffer=this.device.createBuffer({size:192,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.objects.push(n),this.onObjectAdded&&this.onObjectAdded(n),n}removeObject(t){const e=this.objects.findIndex(i=>i.id===t);e!==-1&&(this.objects[e].uniformBuffer.destroy(),this.objects.splice(e,1),this.onObjectRemoved&&this.onObjectRemoved(t))}updateObjectPosition(t,e){const i=this.objects.find(r=>r.id===t);i&&(i.position=e,this.onObjectUpdated&&this.onObjectUpdated(i))}updateObjectScale(t,e){const i=this.objects.find(r=>r.id===t);i&&(i.scale=e,this.onObjectUpdated&&this.onObjectUpdated(i))}updateObjectColor(t,e){const i=this.objects.find(r=>r.id===t);i&&(i.color=e,this.onObjectUpdated&&this.onObjectUpdated(i))}getAllObjects(){return this.objects}getObject(t){return this.objects.find(e=>e.id===t)}updateObjectUniforms(t){const e=t.getModelMatrix(),i=t.getNormalMatrix(),r=new Float32Array(t.color);this.device.queue.writeBuffer(t.uniformBuffer,0,e),this.device.queue.writeBuffer(t.uniformBuffer,64,i),this.device.queue.writeBuffer(t.uniformBuffer,128,r)}renderObjects(t,e,i,r){for(const n of this.objects){this.updateObjectUniforms(n);const a=this.device.createBindGroup({layout:i,entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:n.uniformBuffer}}]});let o,c,l;if(n.type==="cube")o=this.cubeVertexBuffer,c=this.cubeIndexBuffer,l=this.cubeIndexCount;else if(n.type==="sphere")o=this.sphereVertexBuffer,c=this.sphereIndexBuffer,l=this.sphereIndexCount;else continue;t.setPipeline(e),t.setBindGroup(0,a),t.setVertexBuffer(0,o),t.setIndexBuffer(c,"uint16"),t.drawIndexed(l)}}}function ur(s){const t=parseInt(s.slice(1,3),16)/255,e=parseInt(s.slice(3,5),16)/255,i=parseInt(s.slice(5,7),16)/255;return[t,e,i]}function dr(s){if(!s)return"#ffffff";const t=Math.round(s[0]*255).toString(16).padStart(2,"0"),e=Math.round(s[1]*255).toString(16).padStart(2,"0"),i=Math.round(s[2]*255).toString(16).padStart(2,"0");return`#${t}${e}${i}`}function fr(s,t,e){const i=xi([s[0]-t[0],s[1]-t[1],s[2]-t[2]]),r=xi(vi(e,i)),n=vi(i,r);return new Float32Array([r[0],n[0],i[0],0,r[1],n[1],i[1],0,r[2],n[2],i[2],0,-_t(r,s),-_t(n,s),-_t(i,s),1])}function pr(s,t=Math.PI/4){const r=1/Math.tan(t/2);return new Float32Array([r*s,0,0,0,0,r,0,0,0,0,(100+.1)/(.1-100),-1,0,0,200*.1/(.1-100),0])}function xi(s){const t=Math.sqrt(s[0]*s[0]+s[1]*s[1]+s[2]*s[2]);return[s[0]/t,s[1]/t,s[2]/t]}function vi(s,t){return[s[1]*t[2]-s[2]*t[1],s[2]*t[0]-s[0]*t[2],s[0]*t[1]-s[1]*t[0]]}function _t(s,t){return s[0]*t[0]+s[1]*t[1]+s[2]*t[2]}function Hi(s,t){const e=new Float32Array(16);for(let i=0;i<4;i++)for(let r=0;r<4;r++){let n=0;for(let a=0;a<4;a++)n+=s[i+a*4]*t[a+r*4];e[i+r*4]=n}return e}const Et=1481005640,qi=1,Zi=1313821514,$i=5130562,Ze="$hzfxAsset",Wi=s=>typeof atob=="function"?Uint8Array.from(atob(s),t=>t.charCodeAt(0)):new Uint8Array(Buffer.from(s,"base64")),Pi=s=>{if(typeof btoa=="function"){let t="";for(let e=0;e<s.length;e++)t+=String.fromCharCode(s[e]);return btoa(t)}return Buffer.from(s).toString("base64")};function hr(s){const t=s.indexOf(","),e=s.slice(5,t),i=e.split(";")[0]||"application/octet-stream",r=s.slice(t+1),a=/;base64/i.test(e)?Wi(r):new TextEncoder().encode(decodeURIComponent(r));return{mime:i,bytes:a}}function _i(s){return(4-s%4)%4}async function Ji(s,t={}){const{textureFormat:e="keep",quality:i=.85}=t,r=[],n=[];let a=0;const o=(T,E,F)=>{const k=a,Y=T.length;r.push({offset:k,length:Y,mime:E,kind:F}),n.push(T),a+=Y;const N=_i(Y);return N&&(n.push(new Uint8Array(N)),a+=N),r.length-1},c=e==="webp"&&typeof OffscreenCanvas<"u"&&typeof createImageBitmap=="function",l=[];for(const T of s.systems||[]){const E={...T};if(typeof E.textureImageData=="string"&&E.textureImageData.startsWith("data:")){let{mime:F,bytes:k}=hr(E.textureImageData);if(c&&F!=="image/webp")try{const Y=await createImageBitmap(new Blob([k],{type:F})),N=new OffscreenCanvas(Y.width,Y.height);N.getContext("2d").drawImage(Y,0,0);const z=await N.convertToBlob({type:"image/webp",quality:i}),de=new Uint8Array(await z.arrayBuffer());de.length<k.length&&(k=de,F="image/webp")}catch{}E.textureImageData={[Ze]:o(k,F,"texture")}}if(typeof E.glbModelData=="string"&&E.glbModelData.length>0){const F=Wi(E.glbModelData);E.glbModelData={[Ze]:o(F,"model/gltf-binary","glb")}}l.push(E)}const u={...s,systems:l,assets:r},m=new TextEncoder().encode(JSON.stringify(u)),p=_i(m.length),d=new Uint8Array(a);let b=0;for(const T of n)d.set(T,b),b+=T.length;const w=m.length+p,M=20+w+8+a,R=new ArrayBuffer(M),x=new DataView(R),L=new Uint8Array(R);let P=0;x.setUint32(P,Et,!0),P+=4,x.setUint32(P,qi,!0),P+=4,x.setUint32(P,M,!0),P+=4,x.setUint32(P,w,!0),P+=4,x.setUint32(P,Zi,!0),P+=4,L.set(m,P),P+=m.length;for(let T=0;T<p;T++)L[P++]=32;return x.setUint32(P,a,!0),P+=4,x.setUint32(P,$i,!0),P+=4,L.set(d,P),P+=a,R}function Ct(s){return!s||s.byteLength<12?!1:new DataView(s).getUint32(0,!0)===Et}function At(s){const t=new DataView(s);if(t.getUint32(0,!0)!==Et)throw new Error("[unpackHZFX] bad magic — not an .hzfx file");const e=t.getUint32(4,!0);if(e!==qi)throw new Error(`[unpackHZFX] unsupported version ${e}`);let i=12,r=null,n=-1;const a=new Uint8Array(s);for(;i+8<=s.byteLength;){const p=t.getUint32(i,!0);i+=4;const d=t.getUint32(i,!0);i+=4,d===Zi?r=JSON.parse(new TextDecoder().decode(a.subarray(i,i+p))):d===$i&&(n=i),i+=p}if(!r)throw new Error("[unpackHZFX] missing JSON chunk");const o=r.assets||[],c=p=>{const d=o[p];return!d||n<0?null:{...d,bytes:a.subarray(n+d.offset,n+d.offset+d.length)}},l=p=>p&&typeof p=="object"&&typeof p[Ze]=="number",u=(r.systems||[]).map(p=>{const d={...p};if(l(d.textureImageData)){const b=c(d.textureImageData[Ze]);d.textureImageData=b?`data:${b.mime};base64,${Pi(b.bytes)}`:void 0}if(l(d.glbModelData)){const b=c(d.glbModelData[Ze]);d.glbModelData=b?Pi(b.bytes):void 0}return d}),m={...r,systems:u};return delete m.assets,m}function mr(s){const t=new Uint8Array(s);let e="";for(let i=0;i<t.byteLength;i++)e+=String.fromCharCode(t[i]);return btoa(e)}function Qi(s){return{name:s.name,id:s.id,particleCount:s.particleCount,lifetime:s.lifetime,emissionRate:s.emissionRate,emissionDuration:s.emissionDuration,emissionDurationInfinite:s.emissionDurationInfinite||!1,startAt:s.startAt||0,keyframes:s.keyframes||null,keyframesEnabled:s.keyframesEnabled!==!1,particleSize:s.particleSize,particleSpeed:s.particleSpeed,emissionShape:s.emissionShape,outerLength:s.outerLength??s.cubeLength,innerLength:s.innerLength,outerRadius:s.outerRadius,innerRadius:s.innerRadius,squareSize:s.squareSize,squareInnerSize:s.squareInnerSize,circleInnerRadius:s.circleInnerRadius,circleOuterRadius:s.circleOuterRadius,fadeEnabled:s.fadeEnabled,colorTransitionEnabled:s.colorTransitionEnabled,particleColor:s.particleColor,startColor:s.startColor,endColor:s.endColor,randomColorEnabled:s.randomColorEnabled||!1,randomColors:s.randomColors||[],particleShape:s.particleShape||"square",particleShapeRotationX:s.particleShapeRotationX||0,particleShapeRotationY:s.particleShapeRotationY||0,particleShapeRotationZ:s.particleShapeRotationZ||0,pulseEnabled:s.pulseEnabled||!1,pulseAmplitude:s.pulseAmplitude??.5,pulseFrequency:s.pulseFrequency??1,pulsePhaseRandom:s.pulsePhaseRandom??0,pulseOpacity:s.pulseOpacity||!1,bloomEnabled:s.bloomEnabled,bloomIntensity:s.bloomIntensity,bloomColor:s.bloomColor,depthWriteEnabled:s.depthWriteEnabled||!1,burstMode:s.burstMode,gravityEnabled:s.gravityEnabled,gravityStrength:s.gravityStrength,dampingEnabled:s.dampingEnabled,dampingStrength:s.dampingStrength,attractorEnabled:s.attractorEnabled,attractorStrength:s.attractorStrength,attractorPosition:s.attractorPosition,emissionRotationX:s.emissionRotationX,emissionRotationY:s.emissionRotationY,emissionRotationZ:s.emissionRotationZ,orientToDirection:s.orientToDirection??!1,emissionPositionX:s.emissionPositionX,emissionPositionY:s.emissionPositionY,emissionPositionZ:s.emissionPositionZ,rotation:s.rotation,rotationMode:s.rotationMode,minRotation:s.minRotation,maxRotation:s.maxRotation,orientX:s.orientX,orientY:s.orientY,orientZ:s.orientZ,overrideXVelocity:s.overrideXVelocity,overrideYVelocity:s.overrideYVelocity,overrideZVelocity:s.overrideZVelocity,xVelocity:s.xVelocity,yVelocity:s.yVelocity,zVelocity:s.zVelocity,circleVelocityDirection:s.circleVelocityDirection,cylinderVelocityDirection:s.cylinderVelocityDirection,cylinderInnerRadius:s.cylinderInnerRadius,cylinderOuterRadius:s.cylinderOuterRadius,cylinderHeight:s.cylinderHeight,planeWidth:s.planeWidth,planeDepth:s.planeDepth,rectangleWidth:s.rectangleWidth,rectangleHeight:s.rectangleHeight,coneOuterRadius:s.coneOuterRadius,coneInnerRadius:s.coneInnerRadius,coneHeight:s.coneHeight,torusMajorRadius:s.torusMajorRadius,torusMinorRadius:s.torusMinorRadius,lineLength:s.lineLength,hemisphereOuterRadius:s.hemisphereOuterRadius,hemisphereInnerRadius:s.hemisphereInnerRadius,discRadius:s.discRadius,annulusInnerRadius:s.annulusInnerRadius,annulusOuterRadius:s.annulusOuterRadius,capsuleRadius:s.capsuleRadius,capsuleHeight:s.capsuleHeight,arcStartAngle:s.arcStartAngle,arcEndAngle:s.arcEndAngle,arcInnerRadius:s.arcInnerRadius,arcOuterRadius:s.arcOuterRadius,spiralTurns:s.spiralTurns,spiralRadiusStart:s.spiralRadiusStart,spiralRadiusEnd:s.spiralRadiusEnd,spiralHeight:s.spiralHeight,frustumRadiusNear:s.frustumRadiusNear,frustumRadiusFar:s.frustumRadiusFar,frustumHeight:s.frustumHeight,cubeSurfaceSize:s.cubeSurfaceSize,sphereSurfaceRadius:s.sphereSurfaceRadius,boxFrameSize:s.boxFrameSize,polygonSides:s.polygonSides,polygonRadius:s.polygonRadius,aspectRatio:s.aspectRatio,randomSize:s.randomSize,minSize:s.minSize,maxSize:s.maxSize,fadeSizeEnabled:s.fadeSizeEnabled,increaseSizeEnabled:s.increaseSizeEnabled,sizeLifetimeSpeed:s.sizeLifetimeSpeed,opacity:s.opacity,randomSpeed:s.randomSpeed,minSpeed:s.minSpeed,maxSpeed:s.maxSpeed,oneOnlyMode:s.oneOnlyMode,confinementEnabled:s.confinementEnabled||!1,confinementShape:s.confinementShape||"box",confinementMode:s.confinementMode||"bounce",confinementSpace:s.confinementSpace||"world",confinementBoxHalfSize:s.confinementBoxHalfSize||[2,2,2],confinementSphereRadius:s.confinementSphereRadius??3,confinementRestitution:s.confinementRestitution??.8,confinementFriction:s.confinementFriction??.1,confinementCenter:s.confinementCenter,softBoundaryEnabled:s.softBoundaryEnabled||!1,softBoundaryStrength:s.softBoundaryStrength??5,softBoundaryFalloff:s.softBoundaryFalloff??.5,followSystemId:s.followSystemId||null,followSystemTranslation:s.followSystemTranslation??!0,hidden:s.hidden||!1,emissionTrailEnabled:s.emissionTrailEnabled||!1,emissionTrailDuration:s.emissionTrailDuration??1,emissionTrailWidth:s.emissionTrailWidth??.5,emissionTrailMinDistance:s.emissionTrailMinDistance??.05,emissionTrailMaxPoints:s.emissionTrailMaxPoints??100,emissionTrailSegments:s.emissionTrailSegments??8,emissionTrailMode:s.emissionTrailMode??"ribbon",emissionTrailShape:s.emissionTrailShape??"straight",emissionTrailShapeAmplitude:s.emissionTrailShapeAmplitude??.1,emissionTrailShapeFrequency:s.emissionTrailShapeFrequency??4,emissionTrailShapeSpeed:s.emissionTrailShapeSpeed??0,shapeDisplay:s.shapeDisplay??!0,blendMode:s.blendMode??"normal",noiseDistortEnabled:s.noiseDistortEnabled||!1,noiseTilingX:s.noiseTilingX??3,noiseTilingY:s.noiseTilingY??3,noiseSpeed:s.noiseSpeed??-1.5,noiseAmplitude:s.noiseAmplitude??.08,velocityStretchEnabled:s.velocityStretchEnabled||!1,velocityStretchFactor:s.velocityStretchFactor??1,textureEnabled:s.textureEnabled||!1,textureType:s.textureType,textureFileName:s.textureFileName,imageDescription:s.imageDescription,glbModelEnabled:s.glbModelEnabled||!1,glbFileName:s.glbFileName,glbHasTexture:s.glbHasTexture||!1,useGlbTexture:s.useGlbTexture||!1,glbAnimated:s.glbAnimated||!1,animationIndex:s.animationIndex,animationSpeed:s.animationSpeed,animationLoop:s.animationLoop,glbDescription:s.glbDescription,script:s.script||void 0,displayUnit:s.displayUnit||"m"}}async function yr(s,t,e="hzfx"){if(!s||!s.particleSystems||s.particleSystems.length===0){alert("No particle systems to save.");return}try{const i={version:"1.0",timestamp:new Date().toISOString(),systems:s.particleSystems.map(({config:u,system:m})=>({...Qi(u),textureImageData:u.textureEnabled&&!u.glbModelEnabled&&u.textureImageData?u.textureImageData:void 0,glbModelData:u.glbModelEnabled&&m.glbRawArrayBuffer?mr(m.glbRawArrayBuffer):void 0})),activeSystemIndex:s.activeSystemIndex,loop:s.loop||!1},r=e==="json"?"json":"hzfx";let n;if(r==="hzfx"){const u=await Ji(i,{textureFormat:"webp"});n=new Blob([u],{type:"application/octet-stream"})}else n=new Blob([JSON.stringify(i,null,2)],{type:"application/json"});let a;if(t)a=t;else{const u=new Date;a=`particle-scene_${`${u.getFullYear()}-${(u.getMonth()+1).toString().padStart(2,"0")}-${u.getDate().toString().padStart(2,"0")}_${u.getHours().toString().padStart(2,"0")}${u.getMinutes().toString().padStart(2,"0")}`}`}const o=`${a}.${r}`,c=URL.createObjectURL(n),l=document.createElement("a");l.href=c,l.download=o,document.body.appendChild(l),l.click(),document.body.removeChild(l),URL.revokeObjectURL(c)}catch(i){console.error("Error saving scene:",i),alert("Error saving scene. See console for details.")}}function gr(s){return new Promise((t,e)=>{try{const i=s.target.files[0];if(!i){e(new Error("No file selected"));return}const r=new FileReader;r.onload=n=>{try{const a=n.target.result;let o;if(Ct(a)?o=At(a):o=JSON.parse(new TextDecoder().decode(a)),!Array.isArray(o.systems)||o.systems.length===0)throw new Error("No valid particle systems found in the file");t({systems:o.systems.slice(),activeSystemIndex:o.activeSystemIndex||0})}catch(a){console.error("Error loading scene:",a),alert("Error loading scene: "+a.message),e(a)}s.target.value=""},r.onerror=()=>{alert("Failed to read the file"),e(new Error("Failed to read the file")),s.target.value=""},r.readAsArrayBuffer(i)}catch(i){console.error("Error in loadScene:",i),e(i)}})}async function br(s){if(!s||typeof s!="string")throw new Error("[fetchPreset] url must be a non-empty string");const t=await fetch(s);if(!t.ok)throw new Error(`[fetchPreset] HTTP ${t.status}: ${t.statusText}`);const e=await t.arrayBuffer();let i;if(Ct(e)?i=At(e):i=JSON.parse(new TextDecoder().decode(e)),!Array.isArray(i.systems)||i.systems.length===0)throw new Error('[fetchPreset] Invalid preset: "systems" must be a non-empty array');return{version:i.version,systems:i.systems,activeSystemIndex:i.activeSystemIndex??0}}const Sr=s=>`
|
|
1175
1175
|
@vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
|
|
1176
1176
|
var p = array<vec2f, 3>(vec2f(-1.0, -3.0), vec2f(-1.0, 1.0), vec2f(3.0, 1.0));
|
|
1177
1177
|
return vec4f(p[i], 0.0, 1.0);
|
|
@@ -1180,11 +1180,11 @@ return function(__deltaTime, __time, __currentFrame, __totalFrames, __particles,
|
|
|
1180
1180
|
@fragment fn fs(@builtin(position) pos: vec4f) -> @builtin(frag_depth) f32 {
|
|
1181
1181
|
return textureLoad(src, vec2i(pos.xy), 0);
|
|
1182
1182
|
}
|
|
1183
|
-
`;async function
|
|
1183
|
+
`;async function xr(s,t={}){const{getSceneDepth:e=null,autoRespawn:i=!0}=t;let r,n,a;const o=!!(s&&s.device&&s.context);o?({device:r,context:n,canvas:a}=s,a||(a=n.canvas)):(a=s,{device:r,context:n}=await Vi(a));const c=navigator.gpu.getPreferredCanvasFormat(),l=t.manager||new Fi(r),u={layouts:{},pipelines:{}};function m(f){const h=f?"ms":"ss";if(!u.pipelines[h]){const S=r.createShaderModule({code:Sr(f)}),g=r.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",multisampled:f}}]});u.layouts[h]=g,u.pipelines[h]=r.createRenderPipeline({layout:r.createPipelineLayout({bindGroupLayouts:[g]}),vertex:{module:S,entryPoint:"vs"},fragment:{module:S,entryPoint:"fs",targets:[]},primitive:{topology:"triangle-list"},depthStencil:{format:"depth24plus",depthWriteEnabled:!0,depthCompare:"always"}})}return{pipeline:u.pipelines[h],layout:u.layouts[h]}}const p={bloomSourceTextures:{},bloomCompositeTextures:{},combinedTexture:null,getBloomSourceTexture(f,h,S){return this.bloomSourceTextures[f]||(this.bloomSourceTextures[f]=r.createTexture({size:[h,S],format:"rgba16float",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING})),this.bloomSourceTextures[f]},getBloomCompositeTexture(f,h,S){return this.bloomCompositeTextures[f]||(this.bloomCompositeTextures[f]=r.createTexture({size:[h,S],format:"rgba16float",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING})),this.bloomCompositeTextures[f]},getCombinedTexture(f,h){return this.combinedTexture||(this.combinedTexture=r.createTexture({size:[f,h],format:"rgba16float",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING})),this.combinedTexture},resizeTextures(){Object.values(this.bloomSourceTextures).forEach(f=>f==null?void 0:f.destroy()),Object.values(this.bloomCompositeTextures).forEach(f=>f==null?void 0:f.destroy()),this.combinedTexture&&this.combinedTexture.destroy(),this.bloomSourceTextures={},this.bloomCompositeTextures={},this.combinedTexture=null}},d={systemBindGroups:{},systemBloomHorizontalBindGroups:{},secondHorizontalBindGroups:{},systemBloomCompositeBindGroups:{},combinedBloomCompositeBindGroups:{},combinedInitialBindGroup:null,finalBindGroup:null,textureStates:{},textureRefs:{},clear(){this.systemBindGroups={},this.systemBloomHorizontalBindGroups={},this.secondHorizontalBindGroups={},this.systemBloomCompositeBindGroups={},this.combinedBloomCompositeBindGroups={},this.combinedInitialBindGroup=null,this.finalBindGroup=null,this.textureStates={},this.textureRefs={}}},b=r.createBuffer({size:96,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),w=r.createBuffer({size:208,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),M=r.createBuffer({size:32,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),R=r.createBuffer({size:32,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),x=r.createBuffer({size:64,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),L=Te(r,new Uint16Array([0,1,2,0,2,3]),GPUBufferUsage.INDEX),P={},T=()=>Te(r,new Float32Array([-.5,-.5,0,.5,-.5,0,.5,.5,0,-.5,.5,0]),GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST);l.onSystemCreated=f=>{P[f]||(P[f]=T())};const E=4e4,F=new Float32Array(E*8),k=new Float32Array(E*4),Y=new Float32Array(E*4),N=r.createBuffer({size:E*8*4,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),z=r.createBuffer({size:E*4*4,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),de=r.createBuffer({size:E*4*4,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),De=new Map,dt=8,W=[];function Ut(f){for(const h of W)if(h.ids.has(f))return h;return null}function Ki(f,h){if(!f.pos)return;f.hist.push({t:h,x:f.pos[0],y:f.pos[1],z:f.pos[2]});const S=h-dt;for(;f.hist.length>2&&f.hist[0].t<S;)f.hist.shift()}function It(f,h,S){const g=f.hist;if(g.length===0){const H=f.pos;return H&&(S[0]=H[0],S[1]=H[1],S[2]=H[2]),S}let v;if(h>=g[g.length-1].t)return v=g[g.length-1],S[0]=v.x,S[1]=v.y,S[2]=v.z,S;if(h<=g[0].t)return v=g[0],S[0]=v.x,S[1]=v.y,S[2]=v.z,S;for(let H=g.length-1;H>0;H--)if(g[H-1].t<=h){const j=g[H-1],Q=g[H],Z=(h-j.t)/Math.max(1e-6,Q.t-j.t);return S[0]=j.x+(Q.x-j.x)*Z,S[1]=j.y+(Q.y-j.y)*Z,S[2]=j.z+(Q.z-j.z)*Z,S}return v=g[0],S[0]=v.x,S[1]=v.y,S[2]=v.z,S}const es=.41421356;function ts(){De.clear();let f=0,h=0;A.position[0],A.position[1],A.position[2];for(const{system:S,config:g}of l.particleSystems){if(!g.emissionTrailEnabled||g.hidden||g.glbModelEnabled)continue;S.readbackAndProcessParticles();const v=S.particleData,H=S.particleVelocities,j=S.activeParticles;if(!v||!H||j<=0)continue;const Q=g.emissionTrailMode==="particles",Z=f,Ue=g.emissionTrailDuration??1,y=g.opacity??1,B=g.particleSize??.5,U=g.bloomIntensity||1,I=Math.max(1,Math.min(64,g.emissionTrailSegments??8)),D=g.emissionTrailShape||"straight",J=g.followSystemTranslation??!0,K=S._simPosition,X=J&&K?K[0]:0,it=J&&K?K[1]:0,Wt=J&&K?K[2]:0,Ie=S._simVelocity,Jt=Ie?Ie[0]:0,Rs=Ie?Ie[1]:0,Qt=Ie?Ie[2]:0,Oe=Ut(g.id),Kt=!!(J&&Oe&&Oe.hist&&Oe.hist.length>1);for(let st=0;st<j;st++){const he=st*8,rt=v[he],gt=v[he+1],nt=v[he+2],Ts=rt+X,Es=gt+it,Cs=nt+Wt;let Le=v[he+3],Xe=v[he+4],ke=v[he+5];const Ne=v[he+6],Ge=v[he+7];if(Ne>=Ge||Ge<=0)continue;const me=Ne/Ge;if(g.colorTransitionEnabled){const _=g.startColor??[1,0,0],G=g.endColor??[0,0,1];Le=_[0]+(G[0]-_[0])*me,Xe=_[1]+(G[1]-_[1])*me,ke=_[2]+(G[2]-_[2])*me}Le=Math.min(1,Le*U),Xe=Math.min(1,Xe*U),ke=Math.min(1,ke*U);let je=B;if(g.randomSize){const _=Math.sin(Ge*54321.67)*43758.5453%1,G=_<0?_+1:_;je=(g.minSize??.1)+((g.maxSize??.5)-(g.minSize??.1))*G}if(g.fadeSizeEnabled){const _=Math.max(.01,Math.min(10,g.sizeLifetimeSpeed??1));je*=1-Math.pow(me,1/_)}if(g.increaseSizeEnabled){const _=Math.max(.01,Math.min(10,g.sizeLifetimeSpeed??1));je*=1+Math.pow(me,1/_)}if(je<=0||me>.9)continue;const ei=Math.min((.9-me)*(1/.2),1),ti=.75*je*es*ei;let Ye=y;if(g.fadeEnabled&&(Ye*=Math.max(0,1-me)),Ye*=ei,Ye<.01)continue;const bt=st*4,ii=H[bt],si=H[bt+1],ri=H[bt+2],at=ii+Jt,ot=si+Rs,lt=ri+Qt,ni=Math.sqrt(at*at+ot*ot+lt*lt);if(ni<.001)continue;const St=1/ni,ve=at*St,Pe=ot*St,ye=lt*St,ai=A.right[0],oi=A.right[1],li=A.right[2];let xt=ai*ve+oi*Pe+li*ye,re=ai-xt*ve,ne=oi-xt*Pe,ae=li-xt*ye,He=Math.sqrt(re*re+ne*ne+ae*ae);if(He<.2){const _=A.up[0],G=A.up[1],$=A.up[2],V=_*ve+G*Pe+$*ye;re=_-V*ve,ne=G-V*Pe,ae=$-V*ye,He=Math.sqrt(re*re+ne*ne+ae*ae)||1}re/=He,ne/=He,ae/=He;const qe=Math.min(Ue,Ne);if(qe<.001)continue;const ci=g.gravityEnabled&&g.gravityStrength||0,_e=ds,we=fs,Be=ps;if(g.orientToDirection&&g.burstMode&&Kt){const _=S._emitSimRotY||0,G=hs,$=ms,V=ys;for(let C=0;C<=I;C++){const O=It(Oe,pe-C/I*qe,jt);G[C]=O[0],$[C]=O[1],V[C]=O[2]}for(let C=0;C<=I;C++){const O=C>0?C-1:0,q=C<I?C+1:I;let Me=G[O]-G[q],Re=V[O]-V[q];const ge=(Math.hypot(Me,Re)>1e-5?Math.atan2(Me,Re):Math.atan2(Jt,Qt))-_,te=Math.cos(ge),ie=Math.sin(ge),ue=C/I*qe,vt=-.5*ci*ue*ue;_e[C]=te*rt+ie*nt+G[C],we[C]=gt+vt+$[C],Be[C]=-ie*rt+te*nt+V[C]}}else for(let _=0;_<=I;_++){const G=_/I*qe,$=-.5*ci*G*G;if(Kt){const V=It(Oe,pe-G,jt);_e[_]=rt-ii*G+V[0],we[_]=gt-si*G+$+V[1],Be[_]=nt-ri*G+V[2]}else _e[_]=Ts-at*G,we[_]=Es-ot*G+$,Be[_]=Cs-lt*G}if(D!=="straight"){const _=g.emissionTrailShapeAmplitude??.1,G=g.emissionTrailShapeFrequency??4,$=g.emissionTrailShapeSpeed??0;let V=-ye,C=0,O=ve,q=Math.sqrt(V*V+O*O);q<1e-6&&(V=0,C=ye,O=-Pe,q=Math.sqrt(V*V+C*C+O*O)||1),V/=q,C/=q,O/=q;const Me=Pe*O-ye*C,Re=ye*V-ve*O,ce=ve*C-Pe*V;for(let ee=1;ee<=I;ee++){const ge=ee/I*qe,te=2*Math.PI*G*(pe-ge)+$*pe;let ie=0,ue=0;D==="zigzag"?ie=_*Math.sign(Math.sin(te)):D==="sine"?ie=_*Math.sin(te):D==="spiral"&&(ie=_*Math.sin(te),ue=_*Math.cos(te)),_e[ee]+=V*ie+Me*ue,we[ee]+=C*ie+Re*ue,Be[ee]+=O*ie+ce*ue}}if(Q)for(let _=1;_<=I&&f<E;_++){const G=_/I,$=_e[_]-X,V=we[_]-it,C=Be[_]-Wt,O=f*8,q=f*4;F[O]=$,F[O+1]=V,F[O+2]=C,F[O+3]=Le,F[O+4]=Xe,F[O+5]=ke,F[O+6]=Ne+(Ge-Ne)*G,F[O+7]=Ge,k[q]=0,k[q+1]=0,k[q+2]=0,k[q+3]=0,Y[q]=$,Y[q+1]=V,Y[q+2]=C,Y[q+3]=0,f++}else for(let _=0;_<I&&!(h+42>le.length);_++){const G=_/I,$=(_+1)/I,V=_e[_],C=we[_],O=Be[_],q=_e[_+1],Me=we[_+1],Re=Be[_+1],ce=ti*(1-G),ee=ti*(1-$),ge=Ye*(1-G)*(1-G),te=Ye*(1-$)*(1-$),ie=V+re*ce,ue=C+ne*ce,vt=O+ae*ce,ui=V-re*ce,di=C-ne*ce,fi=O-ae*ce,pi=q+re*ee,hi=Me+ne*ee,mi=Re+ae*ee,As=q-re*ee,Us=Me-ne*ee,Is=Re-ae*ee,ze=(Gs,zs,Ds,Fs)=>{le[h++]=Gs,le[h++]=zs,le[h++]=Ds,le[h++]=Le,le[h++]=Xe,le[h++]=ke,le[h++]=Fs};ze(ie,ue,vt,ge),ze(ui,di,fi,ge),ze(pi,hi,mi,te),ze(ui,di,fi,ge),ze(As,Us,Is,te),ze(pi,hi,mi,te)}}Q&&f>Z&&De.set(g.id,{first:Z,count:f-Z})}f>0&&(r.queue.writeBuffer(N,0,F,0,f*8),r.queue.writeBuffer(z,0,k,0,f*4),r.queue.writeBuffer(de,0,Y,0,f*4)),Fe=h/7,Fe>0&&r.queue.writeBuffer(Lt,0,le,0,h)}const Gt=()=>{r.queue.writeBuffer(M,0,new Float32Array([1,0,a.width,a.height,0,0,0,0])),r.queue.writeBuffer(R,0,new Float32Array([0,1,a.width,a.height,0,0,0,0]))};Gt();const zt=new Float32Array(16).fill(0);zt[0]=1,r.queue.writeBuffer(x,0,zt);const se=Ni(r),fe=Xi(r),{particlePipeline:is,particleAdditivePipeline:ss,particleDepthWritePipeline:rs,blurPipeline:We,compositePipeline:ns,directRenderPipeline:Dt,finalCompositePipeline:as,glbMeshPipeline:os}=ki(r,c,fe),Ft=r.createShaderModule({code:`
|
|
1184
1184
|
struct U { mvp: mat4x4<f32> };
|
|
1185
1185
|
@group(0) @binding(0) var<uniform> u: U;
|
|
1186
1186
|
struct VIn { @location(0) pos: vec3<f32>, @location(1) col: vec4<f32> };
|
|
1187
1187
|
struct VOut { @builtin(position) pos: vec4<f32>, @location(0) col: vec4<f32> };
|
|
1188
1188
|
@vertex fn vs(v: VIn) -> VOut { var o: VOut; o.pos = u.mvp * vec4<f32>(v.pos, 1.0); o.col = v.col; return o; }
|
|
1189
1189
|
@fragment fn fs(i: VOut) -> @location(0) vec4<f32> { return i.col; }
|
|
1190
|
-
`}),Gt=r.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),ns=r.createRenderPipeline({layout:r.createPipelineLayout({bindGroupLayouts:[Gt]}),vertex:{module:zt,entryPoint:"vs",buffers:[{arrayStride:28,attributes:[{shaderLocation:0,offset:0,format:"float32x3"},{shaderLocation:1,offset:12,format:"float32x4"}]}]},fragment:{module:zt,entryPoint:"fs",targets:[{format:"rgba16float",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"}}}]},primitive:{topology:"triangle-list"},depthStencil:{format:"depth24plus",depthWriteEnabled:!1,depthCompare:"less-equal"}}),Dt=512*64*6,ce=new Float32Array(Dt*7),Ft=r.createBuffer({size:Dt*7*4,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,label:"ribbonBuffer"}),as=r.createBindGroup({layout:Gt,entries:[{binding:0,resource:{buffer:S}}]});let Fe=0,{sceneTexture:te,bloomTexA:xe,bloomTexB:ue}=wt(r,c,a.width,a.height),ve=Bt(r,a.width,a.height);const ct={uniformBuffer:S,appearanceUniformBuffer:R,horizontalBlurUniformBuffer:E,verticalBlurUniformBuffer:T,bloomIntensityBuffer:x};let We=ot(r,re,ct,{sceneTexture:te,bloomTexA:xe,bloomTexB:ue});const A={mvp:new Float32Array(16),position:new Float32Array([0,0,10]),right:new Float32Array([1,0,0]),up:new Float32Array([0,1,0]),hasCamera:!1};let me=0,os=0;const Ce=new Float32Array(5),Vt=new Float32Array(16),ls=new Array(65),cs=new Array(65),us=new Array(65),ds=new Array(65),fs=new Array(65),ps=new Array(65),Ot=[0,0,0],Ae={key:null,ms:!1,bindGroup:null};let Lt=!1,ut=!0,Je=!1,Qe=null,dt=a.width,ft=a.height;function Xt(){const f=[te,xe,ue,ve],m=wt(r,c,a.width,a.height);te=m.sceneTexture,xe=m.bloomTexA,ue=m.bloomTexB,ve=Bt(r,a.width,a.height),At(),d.clear(),p.resizeTextures(),We=ot(r,re,ct,{sceneTexture:te,bloomTexA:xe,bloomTexB:ue});let b=!1;const g=()=>{if(!b){b=!0,requestAnimationFrame(g);return}f.forEach(v=>v.destroy())};requestAnimationFrame(g)}function hs(f,m,b){A.mvp.set(Ni(f,m)),m&&m.length>=10&&(A.right[0]=m[0],A.right[1]=m[4],A.right[2]=m[8],A.up[0]=m[1],A.up[1]=m[5],A.up[2]=m[9]),b&&(A.position[0]=b.x??b[0],A.position[1]=b.y??b[1],A.position[2]=b.z??b[2]),A.hasCamera=!0}function ms(f,m){A.mvp.set(f),m&&(A.position[0]=m.x??m[0],A.position[1]=m.y??m[1],A.position[2]=m.z??m[2]),A.hasCamera=!0}async function pt(f){if(Je){Qe=f;return}Je=!0;try{for(const m in P)delete P[m];d.clear(),p.resizeTextures(),We=ot(r,re,ct,{sceneTexture:te,bloomTexA:xe,bloomTexB:ue}),await l.replaceSystems({systems:[],activeSystemIndex:0});for(const m of f)await l.addSystems(m.preset,m.position||[0,0,0]);for(const{config:m}of l.particleSystems)P[m.id]||(P[m.id]=B());ut=!0,l.respawnAllSystems()}finally{if(Je=!1,Qe){const m=Qe;Qe=null,pt(m)}}}async function ys(f,m=[0,0,0]){return pt([{preset:f,position:m}])}function gs(f){if(Lt||Je||!l.ready||f<=0||l.particleSystems.length===0)return;const m=l.clock;if(m&&(m.loop=l.loop??i,m.duration=l.getTotalDuration(),f=m.tick(f)),f>.1&&(f=.1),f<=0)return;if((a.width!==dt||a.height!==ft)&&(dt=a.width,ft=a.height,Xt()),me+=f,W.length){for(const y of W){if(y.getPosition){const w=y.getPosition();w?(y.pos||(y.pos=y._posBuf),Array.isArray(w)?(y.pos[0]=w[0],y.pos[1]=w[1],y.pos[2]=w[2]):(y.pos[0]=w.x,y.pos[1]=w.y,y.pos[2]=w.z)):y.pos=null}y.vel=y._velBuf,y.pos&&y.prevPos&&y.wasActive&&f>0?(y.vel[0]=(y.pos[0]-y.prevPos[0])/f,y.vel[1]=(y.pos[1]-y.prevPos[1])/f,y.vel[2]=(y.pos[2]-y.prevPos[2])/f):(y.vel[0]=0,y.vel[1]=0,y.vel[2]=0),y.justResumed=!!y.pos&&!y.wasActive,y.justResumed&&(y.hist.length=0)}for(const{system:y,config:w}of l.particleSystems){const U=Et(w.id);if(!(!U||U.historyOnly)&&(w.hidden=!U.pos,U.pos)){let I=null;if(U.orientToDirection&&U.vel){const D=U.vel[0],J=U.vel[2];Math.hypot(D,J)>1e-4&&(I=[0,0,Math.atan2(D,J)])}y.setSimulationTransform({position:U.pos,velocity:U.vel,rotation:I}),y.updateAppearanceUniform(),(U.justResumed||y.activeParticles===0)&&y.spawnParticles()}}for(const y of W)y.pos?Wi(y,me):y.hist.length=0,y.prevPos=y.pos?y.pos.slice():null,y.wasActive=!!y.pos;if(globalThis.__HZFX_DEBUG&&(os++&63)===0){const y=l.particleSystems.reduce((D,J)=>D+(J.system.activeParticles|0),0),w=W.find(D=>D.pos),U=w?Math.hypot(A.position[0]-w.pos[0],A.position[1]-w.pos[1],A.position[2]-w.pos[2]).toFixed(1):"-",I=W.map(D=>`{ids:[${[...D.ids]}],pos:${D.pos?"1":"0"},hist:${D.hist.length}}`).join(",");console.info(`[HZFX] movingGroups(${W.length})=[${I}] activeParticles=${y} systems=${l.particleSystems.length} ribbonVerts=${Fe} camDist=${U} t=${me.toFixed(1)}`)}}if(l.updateAllSystems(f),m?m.loop:l.loop??i){const y=l.particleSystems.length>0&&l.particleSystems.every(({system:w})=>w.activeParticles===0&&!w.emitting);(m&&m.justLooped||y&&ut)&&l.respawnAllSystems(),ut=!y}for(const{system:y,config:w}of l.particleSystems)w.glbModelEnabled&&y.glbAnimator&&(y.glbAnimator.update(f),y.updateAnimatedGLBBuffer());r.queue.writeBuffer(S,0,A.mvp),Ce[0]=A.position[0],Ce[1]=A.position[1],Ce[2]=A.position[2],Ce[3]=a.height/Math.max(1,a.width),Ce[4]=me,r.queue.writeBuffer(S,64,Ce),Qi();const g=l.particleSystems.some(({config:y})=>y.bloomEnabled),v=r.createCommandEncoder();let H=!1;if(e)try{const y=e();if(y){let w=null,U=null,I=!1;if(y instanceof GPUTexture?y.width===a.width&&y.height===a.height&&(w=y,U=()=>y.createView({aspect:"depth-only"}),I=y.sampleCount>1):y.view&&(w=y.view,U=()=>y.view,I=!!y.multisampled),w){const{pipeline:D,layout:J}=h(I);(Ae.key!==w||Ae.ms!==I)&&(Ae.key=w,Ae.ms=I,Ae.bindGroup=r.createBindGroup({layout:J,entries:[{binding:0,resource:U()}]}));const K=v.beginRenderPass({colorAttachments:[],depthStencilAttachment:{view:ve.createView(),depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});K.setPipeline(D),K.setBindGroup(0,Ae.bindGroup),K.draw(3),K.end(),H=!0}}}catch{}const j=v.beginRenderPass({colorAttachments:[{view:te.createView(),loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}],depthStencilAttachment:H?{view:ve.createView(),depthLoadOp:"load",depthStoreOp:"store"}:{view:ve.createView(),depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});for(const{system:y,config:w}of l.particleSystems)w.bloomEnabled||w.hidden||y.activeParticles===0||kt(j,y,w);if(Fe>0&&(j.setPipeline(ns),j.setBindGroup(0,as),j.setVertexBuffer(0,Ft),j.draw(Fe)),j.end(),g){const y={colorAttachments:[{view:xe.createView(),loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}]},w={colorAttachments:[{view:ue.createView(),loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}]};for(const{system:U,config:I}of l.particleSystems){if(!I.bloomEnabled||I.hidden||U.activeParticles===0)continue;const D=U.config.id,J=p.getBloomSourceTexture(D,a.width,a.height),K=v.beginRenderPass({colorAttachments:[{view:J.createView(),loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}],depthStencilAttachment:{view:ve.createView(),depthClearValue:1,depthLoadOp:"load",depthStoreOp:"store"}});kt(K,U,I),K.end(),Vt[0]=I.bloomIntensity,r.queue.writeBuffer(x,0,Vt),d.systemBloomHorizontalBindGroups[D]||(d.systemBloomHorizontalBindGroups[D]=r.createBindGroup({layout:he.bloomBindGroupLayout,entries:[{binding:0,resource:re},{binding:1,resource:J.createView()},{binding:2,resource:{buffer:E}}]}));let X=v.beginRenderPass(y);X.setPipeline($e),X.setBindGroup(0,d.systemBloomHorizontalBindGroups[D]),X.draw(3),X.end(),X=v.beginRenderPass(w),X.setPipeline($e),X.setBindGroup(0,We.verticalBlurBindGroup),X.draw(3),X.end(),d.secondHorizontalBindGroups[D]||(d.secondHorizontalBindGroups[D]=r.createBindGroup({layout:he.bloomBindGroupLayout,entries:[{binding:0,resource:re},{binding:1,resource:ue.createView()},{binding:2,resource:{buffer:E}}]})),X=v.beginRenderPass(y),X.setPipeline($e),X.setBindGroup(0,d.secondHorizontalBindGroups[D]),X.draw(3),X.end(),X=v.beginRenderPass(w),X.setPipeline($e),X.setBindGroup(0,We.verticalBlurBindGroup),X.draw(3),X.end();const Ke=p.getBloomCompositeTexture(D,a.width,a.height);X=v.beginRenderPass({colorAttachments:[{view:Ke.createView(),loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}]}),X.setPipeline(is),d.systemBloomCompositeBindGroups[D]||(d.systemBloomCompositeBindGroups[D]=r.createBindGroup({layout:he.compositeBindGroupLayout,entries:[{binding:0,resource:re},{binding:1,resource:J.createView()},{binding:2,resource:ue.createView()},{binding:3,resource:{buffer:U.bloomIntensityBuffer}}]})),X.setBindGroup(0,d.systemBloomCompositeBindGroups[D]),X.draw(3),X.end()}}const Q=p.getCombinedTexture(a.width,a.height),q=v.beginRenderPass({colorAttachments:[{view:Q.createView(),loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}]});q.setPipeline(It),d.combinedInitialBindGroup||(d.combinedInitialBindGroup=r.createBindGroup({layout:he.compositeBindGroupLayout,entries:[{binding:0,resource:re},{binding:1,resource:te.createView()},{binding:2,resource:te.createView()},{binding:3,resource:{buffer:x}}]})),q.setBindGroup(0,d.combinedInitialBindGroup),q.draw(3);for(const{config:y,system:w}of l.particleSystems){if(!y.bloomEnabled||y.hidden||w.activeParticles===0)continue;const U=w.config.id;q.setPipeline(It),d.combinedBloomCompositeBindGroups[U]||(d.combinedBloomCompositeBindGroups[U]=r.createBindGroup({layout:he.compositeBindGroupLayout,entries:[{binding:0,resource:re},{binding:1,resource:p.getBloomCompositeTexture(U,a.width,a.height).createView()},{binding:2,resource:te.createView()},{binding:3,resource:{buffer:x}}]})),q.setBindGroup(0,d.combinedBloomCompositeBindGroups[U]),q.draw(3)}q.end();const Ue=v.beginRenderPass({colorAttachments:[{view:n.getCurrentTexture().createView(),loadOp:o?"load":"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}]});Ue.setPipeline(ss),d.finalBindGroup||(d.finalBindGroup=r.createBindGroup({layout:he.compositeBindGroupLayout,entries:[{binding:0,resource:re},{binding:1,resource:Q.createView()},{binding:2,resource:te.createView()},{binding:3,resource:{buffer:x}}]})),Ue.setBindGroup(0,d.finalBindGroup),Ue.draw(3),Ue.end(),r.queue.submit([v.finish()])}function kt(f,m,b){const g=m.config.id,v=b.glbModelEnabled&&m.glbMeshData,H=!d.systemBindGroups[g]||d.textureStates[g]!==b.textureEnabled||d.textureRefs[g]!==m.particleTexture;d.textureStates[g]=b.textureEnabled,d.textureRefs[g]=m.particleTexture,H&&(d.systemBindGroups[g]=r.createBindGroup({layout:he.particleBindGroupLayout,entries:[{binding:0,resource:{buffer:S}},{binding:1,resource:{buffer:m.appearanceUniformBuffer}},{binding:2,resource:m.particleTexture.createView()},{binding:3,resource:re}]}));const j=d.systemBindGroups[g],Q=b.shapeDisplay!==!1;if(v)Q&&(f.setPipeline(rs),f.setBindGroup(0,j),f.setVertexBuffer(0,m.glbVertexBuffer),f.setVertexBuffer(1,m.instanceBuffer),f.setVertexBuffer(2,m.velocityBuffer),f.setIndexBuffer(m.glbIndexBuffer,m.glbIndexFormat),f.drawIndexed(m.glbIndexCount,m.activeParticles));else{f.setPipeline(b.blendMode==="additive"?es:Ki),f.setIndexBuffer(L,"uint16"),P[g]||(P[g]=B()),f.setVertexBuffer(0,P[g]),f.setBindGroup(0,j),Q&&(f.setVertexBuffer(1,m.instanceBuffer),f.setVertexBuffer(2,m.velocityBuffer),f.setVertexBuffer(3,m.trailBuffer),f.drawIndexed(6,m.activeParticles));const q=De.get(g);q&&(f.setVertexBuffer(1,N),f.setVertexBuffer(2,G),f.setVertexBuffer(3,pe),f.drawIndexed(6,q.count,0,0,q.first)),Q&&b.depthWriteEnabled&&(f.setPipeline(ts),f.drawIndexed(6,m.activeParticles))}}function bs(){dt=a.width,ft=a.height,Xt()}function Ss(){d.clear()}function xs(){Lt=!0,l.destroy(),[te,xe,ue,ve].forEach(f=>f==null?void 0:f.destroy()),p.resizeTextures(),[S,R,E,T,x,L,N,G,pe].forEach(f=>f==null?void 0:f.destroy()),Object.values(P).forEach(f=>f==null?void 0:f.destroy())}async function Nt(f,m){const b=await l.addSystems(f,m);for(const{config:g}of l.particleSystems)P[g.id]||(P[g.id]=B());return l.respawnAllSystems(),new Set(Array.isArray(b)?b:[])}function jt(f){for(const m of f){const b=l.particleSystems.findIndex(g=>g.config.id===m);b>=0&&l.removeSystem(b)}}async function vs(f,m=[0,0,0]){const b=await Nt(f,m);return{remove(){jt(b)}}}async function Ps(f,m={}){const b=await Nt(f,[0,0,0]);globalThis.__HZFX_DEBUG&&console.info(`[HZFX] addMovingEmitter: presetSystems=${(f&&f.systems||[]).length} newIds=[${[...b]}]`);const g={ids:b,pos:null,hist:[],getPosition:m.getPosition||null,orientToDirection:!!m.orientToDirection,_posBuf:[0,0,0],_velBuf:[0,0,0]};return W.push(g),{setPosition(v){v&&(g.pos=Array.isArray(v)?[v[0],v[1],v[2]]:[v.x,v.y,v.z])},setOrientToDirection(v){g.orientToDirection=!!v},remove(){jt(b);const v=W.indexOf(g);v>=0&&W.splice(v,1)}}}function _s(f,m){const g={ids:f instanceof Set?f:new Set(f),pos:null,hist:[],getPosition:m,historyOnly:!0,_posBuf:[0,0,0],_velBuf:[0,0,0]};return W.push(g),{remove(){const v=W.indexOf(g);v>=0&&W.splice(v,1)},setIds(v){g.ids=v instanceof Set?v:new Set(v)}}}return{manager:l,device:r,context:n,setCamera:hs,setCameraMVP:ms,setEmitters:pt,loadPreset:ys,addEmitter:vs,addMovingEmitter:Ps,render:gs,resize:bs,clearCaches:Ss,trackHistoryGroup:_s,destroy:xs}}function gr(s){return()=>{var t,e,i,r,n,a;try{const o=s.backend;if(!o)return null;if(s.needsFrameBufferTarget&&s._frameBufferTarget){const u=(i=(e=(t=s._textures)==null?void 0:t.get)==null?void 0:e.call(t,s._frameBufferTarget))==null?void 0:i.depthTexture,h=u?(r=o.get(u))==null?void 0:r.texture:null;if(h&&h.width===s.domElement.width&&h.height===s.domElement.height)return h}const c=s.getCanvasTarget?o.get(s.getCanvasTarget()):null,l=((a=(n=c==null?void 0:c.descriptor)==null?void 0:n.depthStencilAttachment)==null?void 0:a.view)??null;return l?{view:l,multisampled:(s.currentSamples??0)>1}:null}catch{return null}}}exports.GLBAnimator=Ai;exports.HZClock=Ui;exports.Objects3DManager=nr;exports.ParticleEmitter=vi;exports.ParticlePhysics=Ri;exports.ParticleScript=Pt;exports.ParticleSystem=at;exports.ParticleSystemManager=zi;exports.ParticleTextureManager=Ti;exports.blurShader=_i;exports.compositeShader=wi;exports.createBindGroupLayouts=Vi;exports.createBindGroups=ot;exports.createBuffer=Ee;exports.createCubeGeometry=Xi;exports.createDepthTexture=Bt;exports.createLookAtMatrix=lr;exports.createProjectionMatrix=cr;exports.createRenderPipelines=Oi;exports.createRenderTextures=wt;exports.createSampler=Li;exports.createSphereGeometry=ki;exports.directRenderShader=Bi;exports.extractGLBTexture=_t;exports.fetchPreset=hr;exports.glbMeshParticleShader=Fi;exports.hexToRgb=ar;exports.initHzFxOverlay=yr;exports.initWebGPU=Gi;exports.isHZFX=Rt;exports.loadScene=pr;exports.makeThreeSceneDepth=gr;exports.multiplyMatrices=Ni;exports.object3dShader=Di;exports.packHZFX=qi;exports.parseGLB=Ci;exports.particlePhysicsShader=Mi;exports.particleShader=Pi;exports.rgbToHex=or;exports.saveScene=fr;exports.serializeSystemConfig=$i;exports.unpackHZFX=Tt;
|
|
1190
|
+
`}),Vt=r.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),ls=r.createRenderPipeline({layout:r.createPipelineLayout({bindGroupLayouts:[Vt]}),vertex:{module:Ft,entryPoint:"vs",buffers:[{arrayStride:28,attributes:[{shaderLocation:0,offset:0,format:"float32x3"},{shaderLocation:1,offset:12,format:"float32x4"}]}]},fragment:{module:Ft,entryPoint:"fs",targets:[{format:"rgba16float",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"}}}]},primitive:{topology:"triangle-list"},depthStencil:{format:"depth24plus",depthWriteEnabled:!1,depthCompare:"less-equal"}}),Ot=512*64*6,le=new Float32Array(Ot*7),Lt=r.createBuffer({size:Ot*7*4,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,label:"ribbonBuffer"}),cs=r.createBindGroup({layout:Vt,entries:[{binding:0,resource:{buffer:b}}]});let Fe=0,{sceneTexture:be,bloomTexA:Se,bloomTexB:xe}=Rt(r,c,a.width,a.height),Je=Tt(r,a.width,a.height),Ee,Xt,Qe,Ve;const kt=()=>{const f=h=>h.createView();Ee=f(be),Xt=f(Se),Qe=f(xe),Ve=f(Je)};kt();const ft={uniformBuffer:b,appearanceUniformBuffer:w,horizontalBlurUniformBuffer:M,verticalBlurUniformBuffer:R,bloomIntensityBuffer:x};let Ke=ut(r,se,ft,{sceneTexture:be,bloomTexA:Se,bloomTexB:xe});const A={mvp:new Float32Array(16),position:new Float32Array([0,0,10]),right:new Float32Array([1,0,0]),up:new Float32Array([0,1,0]),hasCamera:!1};let pe=0,us=0;const Ce=new Float32Array(5),Nt=new Float32Array(16),ds=new Array(65),fs=new Array(65),ps=new Array(65),hs=new Array(65),ms=new Array(65),ys=new Array(65),jt=[0,0,0],Ae={key:null,ms:!1,bindGroup:null};let Yt=!1,pt=!0,et=!1,tt=null,ht=a.width,mt=a.height;function Ht(){const f=[be,Se,xe,Je],h=Rt(r,c,a.width,a.height);be=h.sceneTexture,Se=h.bloomTexA,xe=h.bloomTexB,Je=Tt(r,a.width,a.height),kt(),Gt(),d.clear(),p.resizeTextures(),Ke=ut(r,se,ft,{sceneTexture:be,bloomTexA:Se,bloomTexB:xe});let S=!1;const g=()=>{if(!S){S=!0,requestAnimationFrame(g);return}f.forEach(v=>v.destroy())};requestAnimationFrame(g)}function gs(f,h,S){A.mvp.set(Hi(f,h)),h&&h.length>=10&&(A.right[0]=h[0],A.right[1]=h[4],A.right[2]=h[8],A.up[0]=h[1],A.up[1]=h[5],A.up[2]=h[9]),S&&(A.position[0]=S.x??S[0],A.position[1]=S.y??S[1],A.position[2]=S.z??S[2]),A.hasCamera=!0}function bs(f,h){A.mvp.set(f),h&&(A.position[0]=h.x??h[0],A.position[1]=h.y??h[1],A.position[2]=h.z??h[2]),A.hasCamera=!0}async function yt(f){if(et){tt=f;return}et=!0;try{for(const h in P)delete P[h];d.clear(),p.resizeTextures(),Ke=ut(r,se,ft,{sceneTexture:be,bloomTexA:Se,bloomTexB:xe}),await l.replaceSystems({systems:[],activeSystemIndex:0});for(const h of f)await l.addSystems(h.preset,h.position||[0,0,0]);for(const{config:h}of l.particleSystems)P[h.id]||(P[h.id]=T());pt=!0,l.respawnAllSystems()}finally{if(et=!1,tt){const h=tt;tt=null,yt(h)}}}async function Ss(f,h=[0,0,0]){return yt([{preset:f,position:h}])}function xs(f){if(Yt||et||!l.ready||f<=0||l.particleSystems.length===0)return;const h=l.clock;if(h&&(h.loop=l.loop??i,h.duration=l.getTotalDuration(),f=h.tick(f)),f>.1&&(f=.1),f<=0)return;if((a.width!==ht||a.height!==mt)&&(ht=a.width,mt=a.height,Ht()),pe+=f,W.length){for(const y of W){if(y.getPosition){const B=y.getPosition();B?(y.pos||(y.pos=y._posBuf),Array.isArray(B)?(y.pos[0]=B[0],y.pos[1]=B[1],y.pos[2]=B[2]):(y.pos[0]=B.x,y.pos[1]=B.y,y.pos[2]=B.z)):y.pos=null}y.vel=y._velBuf,y.pos&&y.prevPos&&y.wasActive&&f>0?(y.vel[0]=(y.pos[0]-y.prevPos[0])/f,y.vel[1]=(y.pos[1]-y.prevPos[1])/f,y.vel[2]=(y.pos[2]-y.prevPos[2])/f):(y.vel[0]=0,y.vel[1]=0,y.vel[2]=0),y.justResumed=!!y.pos&&!y.wasActive,y.justResumed&&(y.hist.length=0)}for(const{system:y,config:B}of l.particleSystems){const U=Ut(B.id);if(!(!U||U.historyOnly)&&(B.hidden=!U.pos,U.pos)){let I=null;if(U.orientToDirection&&U.vel){const D=U.vel[0],J=U.vel[2];Math.hypot(D,J)>1e-4&&(I=[0,0,Math.atan2(D,J)])}y.setSimulationTransform({position:U.pos,velocity:U.vel,rotation:I}),y.updateAppearanceUniform(),(U.justResumed||y.activeParticles===0)&&y.spawnParticles()}}for(const y of W)y.pos?Ki(y,pe):y.hist.length=0,y.pos?(y._prevPosBuf[0]=y.pos[0],y._prevPosBuf[1]=y.pos[1],y._prevPosBuf[2]=y.pos[2],y.prevPos=y._prevPosBuf):y.prevPos=null,y.wasActive=!!y.pos;if(globalThis.__HZFX_DEBUG&&(us++&63)===0){const y=l.particleSystems.reduce((D,J)=>D+(J.system.activeParticles|0),0),B=W.find(D=>D.pos),U=B?Math.hypot(A.position[0]-B.pos[0],A.position[1]-B.pos[1],A.position[2]-B.pos[2]).toFixed(1):"-",I=W.map(D=>`{ids:[${[...D.ids]}],pos:${D.pos?"1":"0"},hist:${D.hist.length}}`).join(",");console.info(`[HZFX] movingGroups(${W.length})=[${I}] activeParticles=${y} systems=${l.particleSystems.length} ribbonVerts=${Fe} camDist=${U} t=${pe.toFixed(1)}`)}}if(l.updateAllSystems(f),h?h.loop:l.loop??i){const y=l.particleSystems.length>0&&l.particleSystems.every(({system:B})=>B.activeParticles===0&&!B.emitting);(h&&h.justLooped||y&&pt)&&l.respawnAllSystems(),pt=!y}for(const{system:y,config:B}of l.particleSystems)B.glbModelEnabled&&y.glbAnimator&&(y.glbAnimator.update(f),y.updateAnimatedGLBBuffer());r.queue.writeBuffer(b,0,A.mvp),Ce[0]=A.position[0],Ce[1]=A.position[1],Ce[2]=A.position[2],Ce[3]=a.height/Math.max(1,a.width),Ce[4]=pe,r.queue.writeBuffer(b,64,Ce),ts();const g=l.particleSystems.some(({config:y})=>y.bloomEnabled),v=r.createCommandEncoder();let H=!1;if(e)try{const y=e();if(y){let B=null,U=null,I=!1;if(y instanceof GPUTexture?y.width===a.width&&y.height===a.height&&(B=y,U=()=>y.createView({aspect:"depth-only"}),I=y.sampleCount>1):y.view&&(B=y.view,U=()=>y.view,I=!!y.multisampled),B){const{pipeline:D,layout:J}=m(I);(Ae.key!==B||Ae.ms!==I)&&(Ae.key=B,Ae.ms=I,Ae.bindGroup=r.createBindGroup({layout:J,entries:[{binding:0,resource:U()}]}));const K=v.beginRenderPass({colorAttachments:[],depthStencilAttachment:{view:Ve,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});K.setPipeline(D),K.setBindGroup(0,Ae.bindGroup),K.draw(3),K.end(),H=!0}}}catch{}const j=v.beginRenderPass({colorAttachments:[{view:Ee,loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}],depthStencilAttachment:H?{view:Ve,depthLoadOp:"load",depthStoreOp:"store"}:{view:Ve,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});for(const{system:y,config:B}of l.particleSystems)B.bloomEnabled||B.hidden||y.activeParticles===0||qt(j,y,B);if(Fe>0&&(j.setPipeline(ls),j.setBindGroup(0,cs),j.setVertexBuffer(0,Lt),j.draw(Fe)),j.end(),g){const y={colorAttachments:[{view:Xt,loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}]},B={colorAttachments:[{view:Qe,loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}]};for(const{system:U,config:I}of l.particleSystems){if(!I.bloomEnabled||I.hidden||U.activeParticles===0)continue;const D=U.config.id,J=p.getBloomSourceTexture(D,a.width,a.height),K=v.beginRenderPass({colorAttachments:[{view:J.createView(),loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}],depthStencilAttachment:{view:Ve,depthClearValue:1,depthLoadOp:"load",depthStoreOp:"store"}});qt(K,U,I),K.end(),Nt[0]=I.bloomIntensity,r.queue.writeBuffer(x,0,Nt),d.systemBloomHorizontalBindGroups[D]||(d.systemBloomHorizontalBindGroups[D]=r.createBindGroup({layout:fe.bloomBindGroupLayout,entries:[{binding:0,resource:se},{binding:1,resource:J.createView()},{binding:2,resource:{buffer:M}}]}));let X=v.beginRenderPass(y);X.setPipeline(We),X.setBindGroup(0,d.systemBloomHorizontalBindGroups[D]),X.draw(3),X.end(),X=v.beginRenderPass(B),X.setPipeline(We),X.setBindGroup(0,Ke.verticalBlurBindGroup),X.draw(3),X.end(),d.secondHorizontalBindGroups[D]||(d.secondHorizontalBindGroups[D]=r.createBindGroup({layout:fe.bloomBindGroupLayout,entries:[{binding:0,resource:se},{binding:1,resource:Qe},{binding:2,resource:{buffer:M}}]})),X=v.beginRenderPass(y),X.setPipeline(We),X.setBindGroup(0,d.secondHorizontalBindGroups[D]),X.draw(3),X.end(),X=v.beginRenderPass(B),X.setPipeline(We),X.setBindGroup(0,Ke.verticalBlurBindGroup),X.draw(3),X.end();const it=p.getBloomCompositeTexture(D,a.width,a.height);X=v.beginRenderPass({colorAttachments:[{view:it.createView(),loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}]}),X.setPipeline(ns),d.systemBloomCompositeBindGroups[D]||(d.systemBloomCompositeBindGroups[D]=r.createBindGroup({layout:fe.compositeBindGroupLayout,entries:[{binding:0,resource:se},{binding:1,resource:J.createView()},{binding:2,resource:Qe},{binding:3,resource:{buffer:U.bloomIntensityBuffer}}]})),X.setBindGroup(0,d.systemBloomCompositeBindGroups[D]),X.draw(3),X.end()}}const Q=p.getCombinedTexture(a.width,a.height),Z=v.beginRenderPass({colorAttachments:[{view:Q.createView(),loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}]});Z.setPipeline(Dt),d.combinedInitialBindGroup||(d.combinedInitialBindGroup=r.createBindGroup({layout:fe.compositeBindGroupLayout,entries:[{binding:0,resource:se},{binding:1,resource:Ee},{binding:2,resource:Ee},{binding:3,resource:{buffer:x}}]})),Z.setBindGroup(0,d.combinedInitialBindGroup),Z.draw(3);for(const{config:y,system:B}of l.particleSystems){if(!y.bloomEnabled||y.hidden||B.activeParticles===0)continue;const U=B.config.id;Z.setPipeline(Dt),d.combinedBloomCompositeBindGroups[U]||(d.combinedBloomCompositeBindGroups[U]=r.createBindGroup({layout:fe.compositeBindGroupLayout,entries:[{binding:0,resource:se},{binding:1,resource:p.getBloomCompositeTexture(U,a.width,a.height).createView()},{binding:2,resource:Ee},{binding:3,resource:{buffer:x}}]})),Z.setBindGroup(0,d.combinedBloomCompositeBindGroups[U]),Z.draw(3)}Z.end();const Ue=v.beginRenderPass({colorAttachments:[{view:n.getCurrentTexture().createView(),loadOp:o?"load":"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}]});Ue.setPipeline(as),d.finalBindGroup||(d.finalBindGroup=r.createBindGroup({layout:fe.compositeBindGroupLayout,entries:[{binding:0,resource:se},{binding:1,resource:Q.createView()},{binding:2,resource:Ee},{binding:3,resource:{buffer:x}}]})),Ue.setBindGroup(0,d.finalBindGroup),Ue.draw(3),Ue.end(),r.queue.submit([v.finish()])}function qt(f,h,S){const g=h.config.id,v=S.glbModelEnabled&&h.glbMeshData,H=!d.systemBindGroups[g]||d.textureStates[g]!==S.textureEnabled||d.textureRefs[g]!==h.particleTexture;d.textureStates[g]=S.textureEnabled,d.textureRefs[g]=h.particleTexture,H&&(d.systemBindGroups[g]=r.createBindGroup({layout:fe.particleBindGroupLayout,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:{buffer:h.appearanceUniformBuffer}},{binding:2,resource:h.particleTexture.createView()},{binding:3,resource:se}]}));const j=d.systemBindGroups[g],Q=S.shapeDisplay!==!1;if(v)Q&&(f.setPipeline(os),f.setBindGroup(0,j),f.setVertexBuffer(0,h.glbVertexBuffer),f.setVertexBuffer(1,h.instanceBuffer),f.setVertexBuffer(2,h.velocityBuffer),f.setIndexBuffer(h.glbIndexBuffer,h.glbIndexFormat),f.drawIndexed(h.glbIndexCount,h.activeParticles));else{f.setPipeline(S.blendMode==="additive"?ss:is),f.setIndexBuffer(L,"uint16"),P[g]||(P[g]=T()),f.setVertexBuffer(0,P[g]),f.setBindGroup(0,j),Q&&(f.setVertexBuffer(1,h.instanceBuffer),f.setVertexBuffer(2,h.velocityBuffer),f.setVertexBuffer(3,h.trailBuffer),f.drawIndexed(6,h.activeParticles));const Z=De.get(g);Z&&(f.setVertexBuffer(1,N),f.setVertexBuffer(2,z),f.setVertexBuffer(3,de),f.drawIndexed(6,Z.count,0,0,Z.first)),Q&&S.depthWriteEnabled&&(f.setPipeline(rs),f.drawIndexed(6,h.activeParticles))}}function vs(){ht=a.width,mt=a.height,Ht()}function Ps(){d.clear()}function _s(){Yt=!0,l.destroy(),[be,Se,xe,Je].forEach(f=>f==null?void 0:f.destroy()),p.resizeTextures(),[b,w,M,R,x,L,N,z,de].forEach(f=>f==null?void 0:f.destroy()),Object.values(P).forEach(f=>f==null?void 0:f.destroy())}async function Zt(f,h){const S=await l.addSystems(f,h);for(const{config:g}of l.particleSystems)P[g.id]||(P[g.id]=T());return l.respawnAllSystems(),new Set(Array.isArray(S)?S:[])}function $t(f){for(const h of f){const S=l.particleSystems.findIndex(g=>g.config.id===h);S>=0&&l.removeSystem(S)}}async function ws(f,h=[0,0,0]){const S=await Zt(f,h);return{remove(){$t(S)}}}async function Bs(f,h={}){const S=await Zt(f,[0,0,0]);globalThis.__HZFX_DEBUG&&console.info(`[HZFX] addMovingEmitter: presetSystems=${(f&&f.systems||[]).length} newIds=[${[...S]}]`);const g={ids:S,pos:null,hist:[],getPosition:h.getPosition||null,orientToDirection:!!h.orientToDirection,_posBuf:[0,0,0],_velBuf:[0,0,0],_prevPosBuf:[0,0,0]};return W.push(g),{setPosition(v){v&&(g.pos=Array.isArray(v)?[v[0],v[1],v[2]]:[v.x,v.y,v.z])},setOrientToDirection(v){g.orientToDirection=!!v},remove(){$t(S);const v=W.indexOf(g);v>=0&&W.splice(v,1)}}}function Ms(f,h){const g={ids:f instanceof Set?f:new Set(f),pos:null,hist:[],getPosition:h,historyOnly:!0,_posBuf:[0,0,0],_velBuf:[0,0,0],_prevPosBuf:[0,0,0]};return W.push(g),{remove(){const v=W.indexOf(g);v>=0&&W.splice(v,1)},setIds(v){g.ids=v instanceof Set?v:new Set(v)}}}return{manager:l,device:r,context:n,setCamera:gs,setCameraMVP:bs,setEmitters:yt,loadPreset:Ss,addEmitter:ws,addMovingEmitter:Bs,render:xs,resize:vs,clearCaches:Ps,trackHistoryGroup:Ms,destroy:_s}}function vr(s){return()=>{var t,e,i,r,n,a,o,c;try{const l=s.backend;if(!l)return null;const u=s.domElement.width,m=s.domElement.height,p=(typeof s._getFrameBufferTarget=="function"?s._getFrameBufferTarget():null)||s._frameBufferTarget||null;if(s.needsFrameBufferTarget&&p){const w=l.get(p),M=((i=(e=(t=s._textures)==null?void 0:t.get)==null?void 0:e.call(t,p))==null?void 0:i.depthTexture)||p.depthTexture,R=[(r=w==null?void 0:w.depthTexture)==null?void 0:r.texture,w==null?void 0:w.depthTexture,(n=w==null?void 0:w.depthBuffer)==null?void 0:n.texture,M?(a=l.get(M))==null?void 0:a.texture:null];for(const x of R)if(x&&typeof x.createView=="function"&&x.width===u&&x.height===m)return x;return null}const d=s.getCanvasTarget?l.get(s.getCanvasTarget()):null,b=((c=(o=d==null?void 0:d.descriptor)==null?void 0:o.depthStencilAttachment)==null?void 0:c.view)??null;return b?{view:b,multisampled:(s.currentSamples??0)>1}:null}catch{return null}}}exports.GLBAnimator=Gi;exports.HZClock=zi;exports.Objects3DManager=cr;exports.ParticleEmitter=wi;exports.ParticlePhysics=Ci;exports.ParticleScript=Bt;exports.ParticleSystem=ct;exports.ParticleSystemManager=Fi;exports.ParticleTextureManager=Ai;exports.blurShader=Mi;exports.compositeShader=Ri;exports.createBindGroupLayouts=Xi;exports.createBindGroups=ut;exports.createBuffer=Te;exports.createCubeGeometry=ji;exports.createDepthTexture=Tt;exports.createLookAtMatrix=fr;exports.createProjectionMatrix=pr;exports.createRenderPipelines=ki;exports.createRenderTextures=Rt;exports.createSampler=Ni;exports.createSphereGeometry=Yi;exports.directRenderShader=Ti;exports.extractGLBTexture=Mt;exports.fetchPreset=br;exports.glbMeshParticleShader=Li;exports.hexToRgb=ur;exports.initHzFxOverlay=xr;exports.initWebGPU=Vi;exports.isHZFX=Ct;exports.loadScene=gr;exports.makeThreeSceneDepth=vr;exports.multiplyMatrices=Hi;exports.object3dShader=Oi;exports.packHZFX=Ji;exports.parseGLB=Ii;exports.particlePhysicsShader=Ei;exports.particleShader=Bi;exports.rgbToHex=dr;exports.saveScene=yr;exports.serializeSystemConfig=Qi;exports.unpackHZFX=At;
|