@neutrinoparticles/js-v1.1-phaser 1.1.0 → 1.1.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.1.1] - 2026-08-04
4
+
5
+ - Fixed particle opacity not dimming particles: the alpha of a particle — whether a fixed value or driven by a graph — did not fade the particle's colour, so effects looked fully opaque. Additive effects ignored alpha completely, normally-blended ones kept full brightness instead of fading out, and multiplied ones brightened the background as they faded (issue #289).
6
+
3
7
  ## [1.1.0] - 2026-08-03
4
8
 
5
9
  - Emitter properties can now be **read** as well as written: `getEmitterPropertyValue()`, `hasEmitterProperty()` and `getEmitterProperties()` (which lists every property an effect exposes, with its live value). `setPropertyInEmitter()`, for addressing a single emitter by name, is now available on the effect too
@@ -1,4 +1,4 @@
1
- "use strict";var K=Object.defineProperty;var z=(s,e,t)=>e in s?K(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var a=(s,e,t)=>z(s,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Phaser=require("phaser"),Neutrino=require("@neutrinoparticles/js-v1.1");function _interopNamespaceDefault(s){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>s[t]})}}return e.default=s,Object.freeze(e)}const Neutrino__namespace=_interopNamespaceDefault(Neutrino),vertexShaderSource=`#version 300 es
1
+ "use strict";var K=Object.defineProperty;var N=(s,e,t)=>e in s?K(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var a=(s,e,t)=>N(s,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Phaser=require("phaser"),Neutrino=require("@neutrinoparticles/js-v1.1");function _interopNamespaceDefault(s){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>s[t]})}}return e.default=s,Object.freeze(e)}const Neutrino__namespace=_interopNamespaceDefault(Neutrino),vertexShaderSource=`#version 300 es
2
2
  precision highp float;
3
3
 
4
4
  uniform sampler2D uDataTexture;
@@ -596,8 +596,16 @@ void main() {
596
596
  // Texture coordinates with grid + atlas remap
597
597
  vec2 baseTexCoord = TEX_COORD[vertexIndex];
598
598
 
599
- float gx = mod(gridIndex, gridWidth);
599
+ // #283: gx must come from the SAME quotient as gy. GLSL mod(x,y) is
600
+ // x - y*floor(x/y), but the driver may evaluate its internal quotient
601
+ // differently from the floor() below (reciprocal-multiply / FMA). At exact
602
+ // multiples of gridWidth the two disagreed — mod(15,15) gave 15 while
603
+ // floor(15/15) gave 0 — addressing column 15 of a 15-column grid, whose U
604
+ // range starts at 1.0 (off the atlas), so the first cell of every row
605
+ // sampled the clamped transparent edge and vanished. The clamp keeps a
606
+ // rounding-induced gx == gridWidth inside the last column.
600
607
  float gy = floor(gridIndex / gridWidth);
608
+ float gx = clamp(gridIndex - gy * gridWidth, 0.0, gridWidth - 1.0);
601
609
  float cellW = 1.0 / gridWidth;
602
610
  float cellH = 1.0 / gridHeight;
603
611
 
@@ -683,6 +691,13 @@ void main() {
683
691
  else texColor = useGrad ? textureGrad(uTextures[7], atlasUV, gradX, gradY) : texture(uTextures[7], atlasUV);
684
692
 
685
693
  fragColor = texColor * vColor;
694
+ // Premultiply the per-particle alpha into RGB. texColor is premultiplied but
695
+ // vColor.a is not, and every blend func expects a premultiplied source:
696
+ // NORMAL (ONE, 1-src.a) would only reduce how much background shows through,
697
+ // ADD (ONE, ONE) would ignore alpha entirely, and MULTIPLY
698
+ // (DST_COLOR, 1-src.a) would brighten the destination as alpha drops instead
699
+ // of leaving it untouched.
700
+ fragColor.rgb *= vColor.a;
686
701
  // Apply host world alpha. texColor is premultiplied and the blend funcs use
687
702
  // a src factor of ONE (NORMAL) / ONE,ONE (ADD), so the whole RGBA must be
688
703
  // scaled — fading RGB, not just the alpha channel — to dim correctly in both
@@ -1222,8 +1237,12 @@ void main() {
1222
1237
  // Texture coordinates with grid + atlas remap
1223
1238
  vec2 baseTexCoord = texCoordOf(corner);
1224
1239
 
1225
- float gx = mod(gridIndex, gridWidth);
1240
+ // #283: gx must come from the SAME quotient as gy — see particle.vert.
1241
+ // mod(x,y) and a separate floor(x/y) can disagree at exact multiples of
1242
+ // gridWidth (mod(15,15) -> 15, floor(15/15) -> 0), which addressed a
1243
+ // column past the grid and blanked the first cell of every row.
1226
1244
  float gy = floor(gridIndex / gridWidth);
1245
+ float gx = clamp(gridIndex - gy * gridWidth, 0.0, gridWidth - 1.0);
1227
1246
  float cellW = 1.0 / gridWidth;
1228
1247
  float cellH = 1.0 / gridHeight;
1229
1248
 
@@ -1291,8 +1310,13 @@ void main() {
1291
1310
  // texColor is premultiplied and blend src factors are ONE-based, so the
1292
1311
  // world alpha scales the whole RGBA (mirror of the ES 3.00 shader).
1293
1312
  gl_FragColor = texColor * vColor * uWorldAlpha;
1313
+ // Premultiply the per-particle alpha into RGB: vColor.a is not premultiplied,
1314
+ // so without this ADD ignores alpha entirely, NORMAL only reduces background
1315
+ // show-through, and MULTIPLY brightens the destination as alpha drops.
1316
+ // Mirror of the ES 3.00 shader.
1317
+ gl_FragColor.rgb *= vColor.a;
1294
1318
  }
1295
- `,A=class A{constructor(e,t){a(this,"neutrino");a(this,"gl");a(this,"_shaderProgram",null);a(this,"_indexBuffer",null);a(this,"_dummyVB",null);a(this,"_indexBufferCapacity",0);a(this,"_vao",null);a(this,"_isWebGL1",!1);a(this,"_maxBatchTextures",A.MAX_BATCH_TEXTURES);a(this,"_hasElementIndexUint",!1);a(this,"_vaoExt",null);a(this,"_aIdBuffer",null);a(this,"_aIdLocation",-1);a(this,"_uDataTexture",null);a(this,"_uDataTextureWidth",null);a(this,"_uMetaTexture",null);a(this,"_uDataTexSize",null);a(this,"_uCameraRight",null);a(this,"_uCameraUp",null);a(this,"_uCameraDir",null);a(this,"_uViewProjMatrix",null);a(this,"_uModelMatrix",null);a(this,"_uViewportAspect",null);a(this,"_uWorldAlpha",null);a(this,"_uTextures",[]);a(this,"_uTexRemaps",[]);a(this,"_noiseInitialized",!1);this.gl=e,this.neutrino=t,this._isWebGL1=typeof e.createVertexArray!="function",this._isWebGL1&&this._probeWebGL1Capabilities(),this._initShader(),this._isWebGL1&&this._smokeTestVertexTextureFetch()}initializeNoise(e,t,n){if(this._noiseInitialized){t&&t();return}this.neutrino.initializeNoise(e,()=>{this._noiseInitialized=!0,t&&t()},n)}generateNoise(){if(this._noiseInitialized)return;const e=new this.neutrino.NoiseGenerator;for(;!e.step(););this._noiseInitialized=!0}get shaderProgram(){return this._shaderProgram}get isWebGL1(){return this._isWebGL1}get maxBatchTextures(){return this._maxBatchTextures}get uDataTexture(){return this._uDataTexture}get uDataTextureWidth(){return this._uDataTextureWidth}get uMetaTexture(){return this._uMetaTexture}get uDataTexSize(){return this._uDataTexSize}get uCameraRight(){return this._uCameraRight}get uCameraUp(){return this._uCameraUp}get uCameraDir(){return this._uCameraDir}get uViewProjMatrix(){return this._uViewProjMatrix}get uModelMatrix(){return this._uModelMatrix}get uViewportAspect(){return this._uViewportAspect}get uWorldAlpha(){return this._uWorldAlpha}get uTextures(){return this._uTextures}get uTexRemaps(){return this._uTexRemaps}ensureIndexBuffer(e){if(e<=this._indexBufferCapacity)return;const t=this.gl,n=this._isWebGL1?null:t.getParameter(t.VERTEX_ARRAY_BINDING),r=t.getParameter(t.ARRAY_BUFFER_BINDING),o=t.getParameter(t.ELEMENT_ARRAY_BUFFER_BINDING);this._indexBuffer&&t.deleteBuffer(this._indexBuffer),this._dummyVB&&(t.deleteBuffer(this._dummyVB),this._dummyVB=null),this._vao&&(t.deleteVertexArray(this._vao),this._vao=null),this._aIdBuffer&&(t.deleteBuffer(this._aIdBuffer),this._aIdBuffer=null);const l=e>16383;if(l&&this._isWebGL1&&!this._hasElementIndexUint)throw new Error(`NeutrinoParticles (js-v1.1): the effect needs 32-bit indices (${e} particles) but this WebGL1 context lacks OES_element_index_uint.`);const c=l?new Uint32Array(e*6):new Uint16Array(e*6);for(let i=0;i<e;i++){const u=i*4,_=i*6;c[_+0]=u+0,c[_+1]=u+1,c[_+2]=u+2,c[_+3]=u+0,c[_+4]=u+2,c[_+5]=u+3}if(this._indexBuffer=t.createBuffer(),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this._indexBuffer),t.bufferData(t.ELEMENT_ARRAY_BUFFER,c,t.STATIC_DRAW),this._isWebGL1){const i=new Float32Array(e*4);for(let u=0;u<i.length;u++)i[u]=u;this._aIdBuffer=t.createBuffer(),t.bindBuffer(t.ARRAY_BUFFER,this._aIdBuffer),t.bufferData(t.ARRAY_BUFFER,i,t.STATIC_DRAW)}else this._dummyVB=t.createBuffer(),t.bindBuffer(t.ARRAY_BUFFER,this._dummyVB),t.bufferData(t.ARRAY_BUFFER,e*4,t.STATIC_DRAW),this._vao=t.createVertexArray(),t.bindVertexArray(this._vao),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this._indexBuffer),t.bindBuffer(t.ARRAY_BUFFER,this._dummyVB),t.enableVertexAttribArray(0),t.vertexAttribPointer(0,1,t.UNSIGNED_BYTE,!1,0,0),t.bindVertexArray(n);t.bindBuffer(t.ARRAY_BUFFER,r),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,o),this._indexBufferCapacity=e}get vao(){return this._vao}get indexBuffer(){return this._indexBuffer}get aIdBuffer(){return this._aIdBuffer}get aIdLocation(){return this._aIdLocation}get indexType(){return this._indexBufferCapacity>16383?this.gl.UNSIGNED_INT:this.gl.UNSIGNED_SHORT}unbindVao(){this._isWebGL1?this._vaoExt&&this._vaoExt.bindVertexArrayOES(null):this.gl.bindVertexArray(null)}destroy(){const e=this.gl;this._shaderProgram&&e.deleteProgram(this._shaderProgram),this._indexBuffer&&e.deleteBuffer(this._indexBuffer),this._dummyVB&&e.deleteBuffer(this._dummyVB),this._vao&&e.deleteVertexArray(this._vao),this._aIdBuffer&&e.deleteBuffer(this._aIdBuffer)}_probeWebGL1Capabilities(){const e=this.gl;if(!e.getExtension("OES_texture_float"))throw new Error("NeutrinoParticles (js-v1.1): WebGL1 context lacks OES_texture_float; WebGL2 or WebGL1 with vertex float textures is required.");const t=e.getParameter(e.MAX_VERTEX_TEXTURE_IMAGE_UNITS);if(t<2)throw new Error("NeutrinoParticles (js-v1.1): WebGL1 context has "+t+" vertex texture units (2 required); WebGL2 or WebGL1 with vertex float textures is required.");const n=e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT);if(!n||n.precision===0)throw new Error("NeutrinoParticles (js-v1.1): WebGL1 context lacks highp float in fragment shaders; WebGL2 or WebGL1 with fragment highp is required.");this._hasElementIndexUint=!!e.getExtension("OES_element_index_uint"),this._vaoExt=e.getExtension("OES_vertex_array_object");const r=e.getParameter(e.MAX_COMBINED_TEXTURE_IMAGE_UNITS),o=e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS);this._maxBatchTextures=Math.max(1,Math.min(A.MAX_BATCH_TEXTURES,r-2,o))}_smokeTestVertexTextureFetch(){const e=this.gl,t=`precision highp float;
1319
+ `,A=class A{constructor(e,t){a(this,"neutrino");a(this,"gl");a(this,"_shaderProgram",null);a(this,"_indexBuffer",null);a(this,"_dummyVB",null);a(this,"_indexBufferCapacity",0);a(this,"_vao",null);a(this,"_isWebGL1",!1);a(this,"_maxBatchTextures",A.MAX_BATCH_TEXTURES);a(this,"_hasElementIndexUint",!1);a(this,"_vaoExt",null);a(this,"_aIdBuffer",null);a(this,"_aIdLocation",-1);a(this,"_uDataTexture",null);a(this,"_uDataTextureWidth",null);a(this,"_uMetaTexture",null);a(this,"_uDataTexSize",null);a(this,"_uCameraRight",null);a(this,"_uCameraUp",null);a(this,"_uCameraDir",null);a(this,"_uViewProjMatrix",null);a(this,"_uModelMatrix",null);a(this,"_uViewportAspect",null);a(this,"_uWorldAlpha",null);a(this,"_uTextures",[]);a(this,"_uTexRemaps",[]);a(this,"_noiseInitialized",!1);this.gl=e,this.neutrino=t,this._isWebGL1=typeof e.createVertexArray!="function",this._isWebGL1&&this._probeWebGL1Capabilities(),this._initShader(),this._isWebGL1&&this._smokeTestVertexTextureFetch()}initializeNoise(e,t,n){if(this._noiseInitialized){t&&t();return}this.neutrino.initializeNoise(e,()=>{this._noiseInitialized=!0,t&&t()},n)}generateNoise(){if(this._noiseInitialized)return;const e=new this.neutrino.NoiseGenerator;for(;!e.step(););this._noiseInitialized=!0}get shaderProgram(){return this._shaderProgram}get isWebGL1(){return this._isWebGL1}get maxBatchTextures(){return this._maxBatchTextures}get uDataTexture(){return this._uDataTexture}get uDataTextureWidth(){return this._uDataTextureWidth}get uMetaTexture(){return this._uMetaTexture}get uDataTexSize(){return this._uDataTexSize}get uCameraRight(){return this._uCameraRight}get uCameraUp(){return this._uCameraUp}get uCameraDir(){return this._uCameraDir}get uViewProjMatrix(){return this._uViewProjMatrix}get uModelMatrix(){return this._uModelMatrix}get uViewportAspect(){return this._uViewportAspect}get uWorldAlpha(){return this._uWorldAlpha}get uTextures(){return this._uTextures}get uTexRemaps(){return this._uTexRemaps}ensureIndexBuffer(e){if(e<=this._indexBufferCapacity)return;const t=this.gl,n=this._isWebGL1?null:t.getParameter(t.VERTEX_ARRAY_BINDING),r=t.getParameter(t.ARRAY_BUFFER_BINDING),o=t.getParameter(t.ELEMENT_ARRAY_BUFFER_BINDING);this._indexBuffer&&t.deleteBuffer(this._indexBuffer),this._dummyVB&&(t.deleteBuffer(this._dummyVB),this._dummyVB=null),this._vao&&(t.deleteVertexArray(this._vao),this._vao=null),this._aIdBuffer&&(t.deleteBuffer(this._aIdBuffer),this._aIdBuffer=null);const l=e>16383;if(l&&this._isWebGL1&&!this._hasElementIndexUint)throw new Error(`NeutrinoParticles (js-v1.1): the effect needs 32-bit indices (${e} particles) but this WebGL1 context lacks OES_element_index_uint.`);const d=l?new Uint32Array(e*6):new Uint16Array(e*6);for(let i=0;i<e;i++){const u=i*4,_=i*6;d[_+0]=u+0,d[_+1]=u+1,d[_+2]=u+2,d[_+3]=u+0,d[_+4]=u+2,d[_+5]=u+3}if(this._indexBuffer=t.createBuffer(),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this._indexBuffer),t.bufferData(t.ELEMENT_ARRAY_BUFFER,d,t.STATIC_DRAW),this._isWebGL1){const i=new Float32Array(e*4);for(let u=0;u<i.length;u++)i[u]=u;this._aIdBuffer=t.createBuffer(),t.bindBuffer(t.ARRAY_BUFFER,this._aIdBuffer),t.bufferData(t.ARRAY_BUFFER,i,t.STATIC_DRAW)}else this._dummyVB=t.createBuffer(),t.bindBuffer(t.ARRAY_BUFFER,this._dummyVB),t.bufferData(t.ARRAY_BUFFER,e*4,t.STATIC_DRAW),this._vao=t.createVertexArray(),t.bindVertexArray(this._vao),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this._indexBuffer),t.bindBuffer(t.ARRAY_BUFFER,this._dummyVB),t.enableVertexAttribArray(0),t.vertexAttribPointer(0,1,t.UNSIGNED_BYTE,!1,0,0),t.bindVertexArray(n);t.bindBuffer(t.ARRAY_BUFFER,r),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,o),this._indexBufferCapacity=e}get vao(){return this._vao}get indexBuffer(){return this._indexBuffer}get aIdBuffer(){return this._aIdBuffer}get aIdLocation(){return this._aIdLocation}get indexType(){return this._indexBufferCapacity>16383?this.gl.UNSIGNED_INT:this.gl.UNSIGNED_SHORT}unbindVao(){this._isWebGL1?this._vaoExt&&this._vaoExt.bindVertexArrayOES(null):this.gl.bindVertexArray(null)}destroy(){const e=this.gl;this._shaderProgram&&e.deleteProgram(this._shaderProgram),this._indexBuffer&&e.deleteBuffer(this._indexBuffer),this._dummyVB&&e.deleteBuffer(this._dummyVB),this._vao&&e.deleteVertexArray(this._vao),this._aIdBuffer&&e.deleteBuffer(this._aIdBuffer)}_probeWebGL1Capabilities(){const e=this.gl;if(!e.getExtension("OES_texture_float"))throw new Error("NeutrinoParticles (js-v1.1): WebGL1 context lacks OES_texture_float; WebGL2 or WebGL1 with vertex float textures is required.");const t=e.getParameter(e.MAX_VERTEX_TEXTURE_IMAGE_UNITS);if(t<2)throw new Error("NeutrinoParticles (js-v1.1): WebGL1 context has "+t+" vertex texture units (2 required); WebGL2 or WebGL1 with vertex float textures is required.");const n=e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT);if(!n||n.precision===0)throw new Error("NeutrinoParticles (js-v1.1): WebGL1 context lacks highp float in fragment shaders; WebGL2 or WebGL1 with fragment highp is required.");this._hasElementIndexUint=!!e.getExtension("OES_element_index_uint"),this._vaoExt=e.getExtension("OES_vertex_array_object");const r=e.getParameter(e.MAX_COMBINED_TEXTURE_IMAGE_UNITS),o=e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS);this._maxBatchTextures=Math.max(1,Math.min(A.MAX_BATCH_TEXTURES,r-2,o))}_smokeTestVertexTextureFetch(){const e=this.gl,t=`precision highp float;
1296
1320
  attribute float aId;
1297
1321
  uniform sampler2D uF;
1298
1322
  uniform sampler2D uB;
@@ -1307,8 +1331,8 @@ void main() {
1307
1331
  `,n=`precision mediump float;
1308
1332
  varying vec4 vC;
1309
1333
  void main() { gl_FragColor = vC; }
1310
- `,r=e.getParameter(e.VIEWPORT),o=e.getParameter(e.CURRENT_PROGRAM),l=e.getParameter(e.ARRAY_BUFFER_BINDING),c=e.getParameter(e.FRAMEBUFFER_BINDING),i=e.getParameter(e.ACTIVE_TEXTURE);e.activeTexture(e.TEXTURE0);const u=e.getParameter(e.TEXTURE_BINDING_2D);e.activeTexture(e.TEXTURE1);const _=e.getParameter(e.TEXTURE_BINDING_2D),y=e.isEnabled(e.BLEND),E=e.isEnabled(e.DEPTH_TEST),I=e.isEnabled(e.SCISSOR_TEST);let m=null,b=null,B=null,f=null,v=null,g=null,d=-1,w=!1,x=null,h=4,U=0,p=0,P=0,D=!1,S=!1;const T=new Uint8Array(4);try{m=e.createProgram(),e.attachShader(m,this._compileShader(e.VERTEX_SHADER,t)),e.attachShader(m,this._compileShader(e.FRAGMENT_SHADER,n)),e.linkProgram(m);const C=(R,F)=>{const M=e.createTexture();return e.bindTexture(e.TEXTURE_2D,M),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,1,1,0,e.RGBA,R,F),M};e.activeTexture(e.TEXTURE0),b=C(e.FLOAT,new Float32Array([1,.5,.25,1])),B=C(e.UNSIGNED_BYTE,new Uint8Array([51,102,153,255])),f=e.createTexture(),e.bindTexture(e.TEXTURE_2D,f),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,1,1,0,e.RGBA,e.UNSIGNED_BYTE,null),v=e.createFramebuffer(),e.bindFramebuffer(e.FRAMEBUFFER,v),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,f,0),g=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,g),e.bufferData(e.ARRAY_BUFFER,new Float32Array([0]),e.STATIC_DRAW),S=e.getProgramParameter(m,e.LINK_STATUS),S&&(e.useProgram(m),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,b),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,B),e.uniform1i(e.getUniformLocation(m,"uF"),0),e.uniform1i(e.getUniformLocation(m,"uB"),1),d=e.getAttribLocation(m,"aId"),w=e.getVertexAttrib(d,e.VERTEX_ATTRIB_ARRAY_ENABLED),x=e.getVertexAttrib(d,e.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING),h=e.getVertexAttrib(d,e.VERTEX_ATTRIB_ARRAY_SIZE),U=e.getVertexAttrib(d,e.VERTEX_ATTRIB_ARRAY_TYPE),D=e.getVertexAttrib(d,e.VERTEX_ATTRIB_ARRAY_NORMALIZED),p=e.getVertexAttrib(d,e.VERTEX_ATTRIB_ARRAY_STRIDE),P=e.getVertexAttribOffset(d,e.VERTEX_ATTRIB_ARRAY_POINTER),e.enableVertexAttribArray(d),e.vertexAttribPointer(d,1,e.FLOAT,!1,0,0),e.viewport(0,0,1,1),e.disable(e.BLEND),e.disable(e.DEPTH_TEST),e.disable(e.SCISSOR_TEST),e.drawArrays(e.POINTS,0,1),e.readPixels(0,0,1,1,e.RGBA,e.UNSIGNED_BYTE,T),S=Math.abs(T[0]-51)<=2&&Math.abs(T[1]-51)<=2&&Math.abs(T[2]-38)<=2)}finally{d>=0&&(x&&(e.bindBuffer(e.ARRAY_BUFFER,x),e.vertexAttribPointer(d,h,U,D,p,P)),w?e.enableVertexAttribArray(d):e.disableVertexAttribArray(d)),v&&e.deleteFramebuffer(v),f&&e.deleteTexture(f),b&&e.deleteTexture(b),B&&e.deleteTexture(B),g&&e.deleteBuffer(g),m&&e.deleteProgram(m),e.bindFramebuffer(e.FRAMEBUFFER,c),e.bindBuffer(e.ARRAY_BUFFER,l),e.useProgram(o),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,u),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,_),e.activeTexture(i),y&&e.enable(e.BLEND),E&&e.enable(e.DEPTH_TEST),I&&e.enable(e.SCISSOR_TEST),e.viewport(r[0],r[1],r[2],r[3])}if(!S)throw new Error(`NeutrinoParticles (js-v1.1): WebGL1 vertex texture fetch smoke test failed (got ${T[0]},${T[1]},${T[2]}); WebGL2 or WebGL1 with working vertex float textures is required.`)}_initShader(){const e=this.gl,t=this._isWebGL1?vertexShaderSourceGL1:vertexShaderSource,n=this._isWebGL1?fragmentShaderSourceGL1:fragmentShaderSource,r=this._compileShader(e.VERTEX_SHADER,t),o=this._compileShader(e.FRAGMENT_SHADER,n);if(this._shaderProgram=e.createProgram(),e.attachShader(this._shaderProgram,r),e.attachShader(this._shaderProgram,o),e.linkProgram(this._shaderProgram),!e.getProgramParameter(this._shaderProgram,e.LINK_STATUS))throw new Error("Shader link error: "+e.getProgramInfoLog(this._shaderProgram));e.deleteShader(r),e.deleteShader(o),this._uDataTexture=e.getUniformLocation(this._shaderProgram,"uDataTexture"),this._uCameraRight=e.getUniformLocation(this._shaderProgram,"uCameraRight"),this._uCameraUp=e.getUniformLocation(this._shaderProgram,"uCameraUp"),this._uCameraDir=e.getUniformLocation(this._shaderProgram,"uCameraDir"),this._uViewProjMatrix=e.getUniformLocation(this._shaderProgram,"uViewProjMatrix"),this._uModelMatrix=e.getUniformLocation(this._shaderProgram,"uModelMatrix"),this._uViewportAspect=e.getUniformLocation(this._shaderProgram,"uViewportAspect"),this._uWorldAlpha=e.getUniformLocation(this._shaderProgram,"uWorldAlpha"),this._isWebGL1?(this._uMetaTexture=e.getUniformLocation(this._shaderProgram,"uMetaTexture"),this._uDataTexSize=e.getUniformLocation(this._shaderProgram,"uDataTexSize"),this._aIdLocation=e.getAttribLocation(this._shaderProgram,"aId")):this._uDataTextureWidth=e.getUniformLocation(this._shaderProgram,"uDataTextureWidth"),this._uTextures=[],this._uTexRemaps=[];for(let l=0;l<A.MAX_BATCH_TEXTURES;l++)this._uTextures.push(e.getUniformLocation(this._shaderProgram,`uTextures[${l}]`)),this._uTexRemaps.push(e.getUniformLocation(this._shaderProgram,`uTexRemaps[${l}]`))}_compileShader(e,t){const n=this.gl,r=n.createShader(e);if(n.shaderSource(r,t),n.compileShader(r),!n.getShaderParameter(r,n.COMPILE_STATUS)){const o=n.getShaderInfoLog(r);throw n.deleteShader(r),new Error("Shader compile error: "+o)}return r}};a(A,"MAX_BATCH_TEXTURES",8);let NeutrinoContext=A;class GamePlugin extends Phaser.Plugins.BasePlugin{constructor(){super(...arguments);a(this,"neutrino");a(this,"ctx");a(this,"texturesBasePath","")}init(t){if(t=Object.assign({texturesBasePath:"",generateNoise:!1},t),this.game.renderer.type!==Phaser.WEBGL)throw new Error("NeutrinoParticles (js-v1.1): a WebGL renderer is required (Canvas not supported).");const r=this.game.renderer.gl;this.texturesBasePath=t.texturesBasePath,this.neutrino=new Neutrino__namespace.Context,this.ctx=new NeutrinoContext(r,this.neutrino),t.generateNoise&&this.generateNoise()}start(){}stop(){}destroy(){this.ctx&&this.ctx.destroy(),this.neutrino=null,super.destroy()}loadNoise(t,n,r){this.ctx.initializeNoise(t,n||(()=>{}),r||(()=>{}))}generateNoise(){this.ctx.generateNoise()}}function noext(s){return s.replace(/\.[^/.]+$/,"")}class EffectModel{constructor(scene,scriptText,options){a(this,"gamePlugin");a(this,"scene");a(this,"effectModel");a(this,"textureFrames",[]);a(this,"texturesRemap",[]);a(this,"_numTexturesToLoadLeft",0);options=Object.assign({atlases:[]},options),this.gamePlugin=scene.plugins.get("neutrino"),this.scene=scene;const evalScript=`(function(ctx) {
1334
+ `,r=e.getParameter(e.VIEWPORT),o=e.getParameter(e.CURRENT_PROGRAM),l=e.getParameter(e.ARRAY_BUFFER_BINDING),d=e.getParameter(e.FRAMEBUFFER_BINDING),i=e.getParameter(e.ACTIVE_TEXTURE);e.activeTexture(e.TEXTURE0);const u=e.getParameter(e.TEXTURE_BINDING_2D);e.activeTexture(e.TEXTURE1);const _=e.getParameter(e.TEXTURE_BINDING_2D),y=e.isEnabled(e.BLEND),E=e.isEnabled(e.DEPTH_TEST),I=e.isEnabled(e.SCISSOR_TEST);let m=null,b=null,U=null,f=null,v=null,g=null,c=-1,w=!1,x=null,h=4,B=0,p=0,P=0,D=!1,S=!1;const T=new Uint8Array(4);try{m=e.createProgram(),e.attachShader(m,this._compileShader(e.VERTEX_SHADER,t)),e.attachShader(m,this._compileShader(e.FRAGMENT_SHADER,n)),e.linkProgram(m);const C=(R,F)=>{const M=e.createTexture();return e.bindTexture(e.TEXTURE_2D,M),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,1,1,0,e.RGBA,R,F),M};e.activeTexture(e.TEXTURE0),b=C(e.FLOAT,new Float32Array([1,.5,.25,1])),U=C(e.UNSIGNED_BYTE,new Uint8Array([51,102,153,255])),f=e.createTexture(),e.bindTexture(e.TEXTURE_2D,f),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,1,1,0,e.RGBA,e.UNSIGNED_BYTE,null),v=e.createFramebuffer(),e.bindFramebuffer(e.FRAMEBUFFER,v),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,f,0),g=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,g),e.bufferData(e.ARRAY_BUFFER,new Float32Array([0]),e.STATIC_DRAW),S=e.getProgramParameter(m,e.LINK_STATUS),S&&(e.useProgram(m),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,b),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,U),e.uniform1i(e.getUniformLocation(m,"uF"),0),e.uniform1i(e.getUniformLocation(m,"uB"),1),c=e.getAttribLocation(m,"aId"),w=e.getVertexAttrib(c,e.VERTEX_ATTRIB_ARRAY_ENABLED),x=e.getVertexAttrib(c,e.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING),h=e.getVertexAttrib(c,e.VERTEX_ATTRIB_ARRAY_SIZE),B=e.getVertexAttrib(c,e.VERTEX_ATTRIB_ARRAY_TYPE),D=e.getVertexAttrib(c,e.VERTEX_ATTRIB_ARRAY_NORMALIZED),p=e.getVertexAttrib(c,e.VERTEX_ATTRIB_ARRAY_STRIDE),P=e.getVertexAttribOffset(c,e.VERTEX_ATTRIB_ARRAY_POINTER),e.enableVertexAttribArray(c),e.vertexAttribPointer(c,1,e.FLOAT,!1,0,0),e.viewport(0,0,1,1),e.disable(e.BLEND),e.disable(e.DEPTH_TEST),e.disable(e.SCISSOR_TEST),e.drawArrays(e.POINTS,0,1),e.readPixels(0,0,1,1,e.RGBA,e.UNSIGNED_BYTE,T),S=Math.abs(T[0]-51)<=2&&Math.abs(T[1]-51)<=2&&Math.abs(T[2]-38)<=2)}finally{c>=0&&(x&&(e.bindBuffer(e.ARRAY_BUFFER,x),e.vertexAttribPointer(c,h,B,D,p,P)),w?e.enableVertexAttribArray(c):e.disableVertexAttribArray(c)),v&&e.deleteFramebuffer(v),f&&e.deleteTexture(f),b&&e.deleteTexture(b),U&&e.deleteTexture(U),g&&e.deleteBuffer(g),m&&e.deleteProgram(m),e.bindFramebuffer(e.FRAMEBUFFER,d),e.bindBuffer(e.ARRAY_BUFFER,l),e.useProgram(o),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,u),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,_),e.activeTexture(i),y&&e.enable(e.BLEND),E&&e.enable(e.DEPTH_TEST),I&&e.enable(e.SCISSOR_TEST),e.viewport(r[0],r[1],r[2],r[3])}if(!S)throw new Error(`NeutrinoParticles (js-v1.1): WebGL1 vertex texture fetch smoke test failed (got ${T[0]},${T[1]},${T[2]}); WebGL2 or WebGL1 with working vertex float textures is required.`)}_initShader(){const e=this.gl,t=this._isWebGL1?vertexShaderSourceGL1:vertexShaderSource,n=this._isWebGL1?fragmentShaderSourceGL1:fragmentShaderSource,r=this._compileShader(e.VERTEX_SHADER,t),o=this._compileShader(e.FRAGMENT_SHADER,n);if(this._shaderProgram=e.createProgram(),e.attachShader(this._shaderProgram,r),e.attachShader(this._shaderProgram,o),e.linkProgram(this._shaderProgram),!e.getProgramParameter(this._shaderProgram,e.LINK_STATUS))throw new Error("Shader link error: "+e.getProgramInfoLog(this._shaderProgram));e.deleteShader(r),e.deleteShader(o),this._uDataTexture=e.getUniformLocation(this._shaderProgram,"uDataTexture"),this._uCameraRight=e.getUniformLocation(this._shaderProgram,"uCameraRight"),this._uCameraUp=e.getUniformLocation(this._shaderProgram,"uCameraUp"),this._uCameraDir=e.getUniformLocation(this._shaderProgram,"uCameraDir"),this._uViewProjMatrix=e.getUniformLocation(this._shaderProgram,"uViewProjMatrix"),this._uModelMatrix=e.getUniformLocation(this._shaderProgram,"uModelMatrix"),this._uViewportAspect=e.getUniformLocation(this._shaderProgram,"uViewportAspect"),this._uWorldAlpha=e.getUniformLocation(this._shaderProgram,"uWorldAlpha"),this._isWebGL1?(this._uMetaTexture=e.getUniformLocation(this._shaderProgram,"uMetaTexture"),this._uDataTexSize=e.getUniformLocation(this._shaderProgram,"uDataTexSize"),this._aIdLocation=e.getAttribLocation(this._shaderProgram,"aId")):this._uDataTextureWidth=e.getUniformLocation(this._shaderProgram,"uDataTextureWidth"),this._uTextures=[],this._uTexRemaps=[];for(let l=0;l<A.MAX_BATCH_TEXTURES;l++)this._uTextures.push(e.getUniformLocation(this._shaderProgram,`uTextures[${l}]`)),this._uTexRemaps.push(e.getUniformLocation(this._shaderProgram,`uTexRemaps[${l}]`))}_compileShader(e,t){const n=this.gl,r=n.createShader(e);if(n.shaderSource(r,t),n.compileShader(r),!n.getShaderParameter(r,n.COMPILE_STATUS)){const o=n.getShaderInfoLog(r);throw n.deleteShader(r),new Error("Shader compile error: "+o)}return r}};a(A,"MAX_BATCH_TEXTURES",8);let NeutrinoContext=A;class GamePlugin extends Phaser.Plugins.BasePlugin{constructor(){super(...arguments);a(this,"neutrino");a(this,"ctx");a(this,"texturesBasePath","")}init(t){if(t=Object.assign({texturesBasePath:"",generateNoise:!1},t),this.game.renderer.type!==Phaser.WEBGL)throw new Error("NeutrinoParticles (js-v1.1): a WebGL renderer is required (Canvas not supported).");const r=this.game.renderer.gl;this.texturesBasePath=t.texturesBasePath,this.neutrino=new Neutrino__namespace.Context,this.ctx=new NeutrinoContext(r,this.neutrino),t.generateNoise&&this.generateNoise()}start(){}stop(){}destroy(){this.ctx&&this.ctx.destroy(),this.neutrino=null,super.destroy()}loadNoise(t,n,r){this.ctx.initializeNoise(t,n||(()=>{}),r||(()=>{}))}generateNoise(){this.ctx.generateNoise()}}function noext(s){return s.replace(/\.[^/.]+$/,"")}class EffectModel{constructor(scene,scriptText,options){a(this,"gamePlugin");a(this,"scene");a(this,"effectModel");a(this,"textureFrames",[]);a(this,"texturesRemap",[]);a(this,"_numTexturesToLoadLeft",0);options=Object.assign({atlases:[]},options),this.gamePlugin=scene.plugins.get("neutrino"),this.scene=scene;const evalScript=`(function(ctx) {
1311
1335
  `+scriptText+`
1312
1336
  return new NeutrinoEffect(ctx);
1313
- })(this.gamePlugin.neutrino);`;this.effectModel=eval(evalScript),this._startLoadTextures(options.atlases)}get ready(){return this._numTexturesToLoadLeft===0}glTexture(s){const e=this.textureFrames[s];return e?e.glTexture.webGLTexture:null}_startLoadTextures(s){const e=this.effectModel.textures.length;this._numTexturesToLoadLeft=e;for(let t=0;t<e;++t){const n=this.effectModel.textures[t],r=this.gamePlugin.texturesBasePath+n,o=noext(r);let l=this._findFrameInAtlases(s,n);if(l||(l=this._findFrameInAtlases(s,noext(n))),!l&&this.scene.sys.textures.exists(o)){const c=this.scene.sys.textures.get(o);l=c.get(c.firstFrame)}l?this._onTextureLoaded(t,l):(this.scene.load.once("filecomplete-image-"+o,((c,i)=>()=>{const u=this.scene.sys.textures.get(i);this._onTextureLoaded(c,u.get(u.firstFrame))})(t,o)),this.scene.load.image(o,r))}}_findFrameInAtlases(s,e){for(let t=0;t<s.length;++t){const n=s[t];if(!this.scene.sys.textures.exists(n))continue;const r=this.scene.sys.textures.get(n);if(r.has(e))return r.get(e)}return null}_onTextureLoaded(s,e){this.textureFrames[s]=e,this._numTexturesToLoadLeft--,this._numTexturesToLoadLeft===0&&this._initTexturesRemapIfNeeded()}_fullCover(s){return s.width===s.source.width&&s.height===s.source.height}_initTexturesRemapIfNeeded(){let s=!1;for(let e=0;e<this.textureFrames.length;++e)if(!this._fullCover(this.textureFrames[e])){s=!0;break}if(s)for(let e=0;e<this.textureFrames.length;++e){const t=this.textureFrames[e];this.texturesRemap[e]={x:t.u0,y:1-t.v1,width:t.u1-t.u0,height:t.v1-t.v0}}}}class NeutrinoFile extends Phaser.Loader.File{constructor(t,n){const{key:r,url:o,options:l,xhrSettings:c}=n;super(t,{type:"binary",extension:"js",responseType:"text",key:r,url:o,xhrSettings:c});a(this,"_options");this.cache=t.cacheManager.binary,this._options=l}onProcess(){this.state=Phaser.Loader.FILE_PROCESSING;const t=this.xhrLoader.response;this.data=new EffectModel(this.loader.scene,t,this._options),this.onProcessComplete()}}var Pause=(s=>(s[s.NO=0]="NO",s[s.BEFORE_UPDATE_OR_RENDER=1]="BEFORE_UPDATE_OR_RENDER",s[s.YES=2]="YES",s))(Pause||{});const RING_BUFFER_SIZE$1=3;class DataTextureManager{constructor(e,t,n,r){a(this,"textureWidth");a(this,"textureHeight");a(this,"_gl");a(this,"_floatView");a(this,"_textures",[]);a(this,"_currentIndex",0);const o=e.getParameter(e.MAX_TEXTURE_SIZE);if(n>o||r>o)throw new Error(`NeutrinoParticles: data texture ${n}x${r} exceeds GL MAX_TEXTURE_SIZE (${o}). Reduce effect particle capacity.`);this._gl=e,this.textureWidth=n,this.textureHeight=r,this._floatView=new Float32Array(t.buffer,t.byteOffset,t.length);for(let l=0;l<RING_BUFFER_SIZE$1;l++){const c=e.createTexture();e.bindTexture(e.TEXTURE_2D,c),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.RGBA32F,n,r,0,e.RGBA,e.FLOAT,null),this._textures.push(c)}e.bindTexture(e.TEXTURE_2D,null)}get currentTexture(){return this._textures[this._currentIndex]}uploadAndBind(e){const t=this._gl;t.activeTexture(t.TEXTURE0+e),t.bindTexture(t.TEXTURE_2D,this._textures[this._currentIndex]),t.pixelStorei(t.UNPACK_ALIGNMENT,4),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texSubImage2D(t.TEXTURE_2D,0,0,0,this.textureWidth,this.textureHeight,t.RGBA,t.FLOAT,this._floatView)}advance(){this._currentIndex=(this._currentIndex+1)%RING_BUFFER_SIZE$1}destroy(){const e=this._gl;for(const t of this._textures)t&&e.deleteTexture(t);this._textures=[]}}class MetaTextureManager{constructor(e,t){a(this,"bytes");a(this,"_u32");this.bytes=new Uint8Array(e*t*4),this._u32=new Uint32Array(this.bytes.buffer)}build(e,t){const n=this._u32;for(let r=0;r<t;r++){const o=r*16,l=r*4;n[l]=e[o],n[l+1]=e[o+12],n[l+2]=e[o+13],n[l+3]=e[o+14]}}patchSlot(e,t,n){const r=this.bytes;let o=e*16;for(let l=0;l<t;l++)r[o]=n,o+=16}}const RING_BUFFER_SIZE=3;class DataTextureManagerGL1{constructor(e,t,n,r){a(this,"textureWidth");a(this,"textureHeight");a(this,"meta");a(this,"_gl");a(this,"_floatView");a(this,"_dataTextures",[]);a(this,"_metaTextures",[]);a(this,"_currentIndex",0);const o=e.getParameter(e.MAX_TEXTURE_SIZE);if(n>o||r>o)throw new Error(`NeutrinoParticles: data texture ${n}x${r} exceeds GL MAX_TEXTURE_SIZE (${o}). Reduce effect particle capacity.`);if(n*r>16777216)throw new Error(`NeutrinoParticles: data texture ${n}x${r} exceeds the WebGL1 render path texel cap (2^24). Reduce effect particle capacity.`);this._gl=e,this.textureWidth=n,this.textureHeight=r,this._floatView=new Float32Array(t.buffer,t.byteOffset,t.length),this.meta=new MetaTextureManager(n,r);const l=e.getParameter(e.ACTIVE_TEXTURE);e.activeTexture(e.TEXTURE0);const c=e.getParameter(e.TEXTURE_BINDING_2D);for(let i=0;i<RING_BUFFER_SIZE;i++)this._dataTextures.push(this._createTexture(e.FLOAT)),this._metaTextures.push(this._createTexture(e.UNSIGNED_BYTE));e.bindTexture(e.TEXTURE_2D,c),e.activeTexture(l)}get currentDataTexture(){return this._dataTextures[this._currentIndex]}get currentMetaTexture(){return this._metaTextures[this._currentIndex]}upload(e,t,n){const r=this._gl,o=this.textureWidth,l=Math.min(this.textureHeight,Math.ceil(e*4/o));if(l===0)return;const c=l*o*4;r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,!1),r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),r.pixelStorei(r.UNPACK_ALIGNMENT,4),r.activeTexture(r.TEXTURE0+t),r.bindTexture(r.TEXTURE_2D,this.currentDataTexture),r.texSubImage2D(r.TEXTURE_2D,0,0,0,o,l,r.RGBA,r.FLOAT,this._floatView.subarray(0,c)),r.activeTexture(r.TEXTURE0+n),r.bindTexture(r.TEXTURE_2D,this.currentMetaTexture),r.texSubImage2D(r.TEXTURE_2D,0,0,0,o,l,r.RGBA,r.UNSIGNED_BYTE,this.meta.bytes.subarray(0,c))}advance(){this._currentIndex=(this._currentIndex+1)%RING_BUFFER_SIZE}destroy(){const e=this._gl;for(const t of this._dataTextures)e.deleteTexture(t);for(const t of this._metaTextures)e.deleteTexture(t);this._dataTextures=[],this._metaTextures=[]}_createTexture(e){const t=this._gl,n=t.createTexture();return t.bindTexture(t.TEXTURE_2D,n),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureWidth,this.textureHeight,0,t.RGBA,e,null),n}}const DATA_TEXTURE_UNIT=0,META_TEXTURE_UNIT=1,PARTICLE_TEXTURE_START_UNIT=1,PARTICLE_TEXTURE_START_UNIT_GL1=2,FLOATS_PER_PARTICLE=16,BYTES_PER_PARTICLE=FLOATS_PER_PARTICLE*4,MAX_BATCHES=64;class DrawBatch{constructor(){a(this,"blendMode",0);a(this,"startParticle",0);a(this,"numParticles",0);a(this,"numTextures",0);a(this,"glTextures",new Array(NeutrinoContext.MAX_BATCH_TEXTURES).fill(null));a(this,"remaps",new Array(NeutrinoContext.MAX_BATCH_TEXTURES).fill(null))}reset(){this.blendMode=0,this.startParticle=0,this.numParticles=0,this.numTextures=0}}class NeutrinoRenderer{constructor(){a(this,"_orthoMatrix",new Float32Array(16));a(this,"_perspMatrix",new Float32Array(16));a(this,"_vpMatrix",new Float32Array(16));a(this,"_projFrame",{x:0,y:0,width:0,height:0});a(this,"_modelMatrix",new Float32Array(16));a(this,"_texSlotMap",new Map);a(this,"_batchPool");a(this,"_batchCount",0);this._batchPool=[];for(let e=0;e<MAX_BATCHES;e++)this._batchPool.push(new DrawBatch)}render(e,t,n,r,o,l,c){if(l===0)return;const i=e.gl,u=e.isWebGL1,_=e.maxBatchTextures,y=c.renderStyles,E=c.materials,I=u?t.meta:null;I&&I.build(r,l),this._batchCount=0;const m=this._texSlotMap;for(;this._batchPool.length<o.length;)this._batchPool.push(new DrawBatch);let b=0;for(;b<o.length;){const f=this._batchPool[this._batchCount];f.reset(),f.blendMode=this._resolveBlend(o[b].blendMode,E),f.startParticle=o[b].startParticleIndex,m.clear();let v=b;for(;v<o.length&&this._resolveBlend(o[v].blendMode,E)===f.blendMode;){const g=y[o[v].renderStyleIndex].textureIndices[0];if(!m.has(g)){if(m.size>=_)break;const x=m.size;m.set(g,x),f.glTextures[x]=c.glTextures[g]||null,f.remaps[x]=c.remaps[g]||null,f.numTextures=x+1}const d=m.get(g),w=o[v];if(I)I.patchSlot(w.startParticleIndex,w.numParticles,d);else if(d!==0)for(let x=0;x<w.numParticles;x++){const h=(w.startParticleIndex+x)*BYTES_PER_PARTICLE,U=n.getUint32(h,!0);n.setUint32(h,U&4294967040|d,!0)}f.numParticles+=w.numParticles,v++}this._batchCount++,b=v}const B=i.isEnabled(i.SCISSOR_TEST);try{if(i.disable(i.DEPTH_TEST),i.disable(i.STENCIL_TEST),i.disable(i.SCISSOR_TEST),i.disable(i.CULL_FACE),i.depthMask(!1),i.colorMask(!0,!0,!0,!0),i.useProgram(e.shaderProgram),u){const p=t;p.upload(l,DATA_TEXTURE_UNIT,META_TEXTURE_UNIT),i.uniform1i(e.uDataTexture,DATA_TEXTURE_UNIT),i.uniform1i(e.uMetaTexture,META_TEXTURE_UNIT),i.uniform2f(e.uDataTexSize,p.textureWidth,p.textureHeight)}else{const p=t;p.uploadAndBind(DATA_TEXTURE_UNIT),i.uniform1i(e.uDataTexture,DATA_TEXTURE_UNIT),i.uniform1i(e.uDataTextureWidth,p.textureWidth)}i.uniform3f(e.uCameraRight,1,0,0),i.uniform3f(e.uCameraUp,0,-1,0),i.uniform3f(e.uCameraDir,0,0,-1);const f=c.viewportWidth,v=c.viewportHeight,g=c.zoom||1,d=this._orthoMatrix;if(d.fill(0),d[0]=2/f*g,d[5]=-2/v*g,d[10]=0,d[15]=1,d[12]=-1-2/f*g*c.scrollX,d[13]=1+2/v*g*c.scrollY,c.projection){const p=this._projFrame;p.x=0,p.y=0,p.width=f,p.height=v,c.projection.setScreenFrame(p),c.projection.writeMatrix(this._perspMatrix),this._mulMatrix(this._vpMatrix,d,this._perspMatrix),i.uniformMatrix4fv(e.uViewProjMatrix,!1,this._vpMatrix)}else i.uniformMatrix4fv(e.uViewProjMatrix,!1,d);const w=v>0?f/v:1;e.uViewportAspect&&i.uniform1f(e.uViewportAspect,w),e.uWorldAlpha&&i.uniform1f(e.uWorldAlpha,c.worldAlpha);const x=c.model,h=this._modelMatrix;h[0]=x.a,h[1]=x.b,h[2]=0,h[3]=0,h[4]=x.c,h[5]=x.d,h[6]=0,h[7]=0,h[8]=0,h[9]=0,h[10]=1,h[11]=0,h[12]=x.tx,h[13]=x.ty,h[14]=0,h[15]=1,i.uniformMatrix4fv(e.uModelMatrix,!1,h),u?(e.unbindVao(),i.bindBuffer(i.ARRAY_BUFFER,e.aIdBuffer),i.enableVertexAttribArray(e.aIdLocation),i.vertexAttribPointer(e.aIdLocation,1,i.FLOAT,!1,0,0),i.bindBuffer(i.ELEMENT_ARRAY_BUFFER,e.indexBuffer)):i.bindVertexArray(e.vao);const U=u?PARTICLE_TEXTURE_START_UNIT_GL1:PARTICLE_TEXTURE_START_UNIT;i.enable(i.BLEND);for(let p=0;p<this._batchCount;p++){const P=this._batchPool[p];this._applyBlendMode(i,P.blendMode);for(let T=0;T<P.numTextures;T++){const C=U+T;i.activeTexture(i.TEXTURE0+C),i.bindTexture(i.TEXTURE_2D,P.glTextures[T]),i.uniform1i(e.uTextures[T],C);const R=P.remaps[T];R?i.uniform4f(e.uTexRemaps[T],R.x,R.y,R.width,R.height):i.uniform4f(e.uTexRemaps[T],0,0,1,1)}const D=P.startParticle*6,S=P.numParticles*6;i.drawElements(i.TRIANGLES,S,e.indexType,D*(e.indexType===i.UNSIGNED_INT?4:2))}}finally{u?(i.disableVertexAttribArray(e.aIdLocation),i.bindBuffer(i.ARRAY_BUFFER,null),i.bindBuffer(i.ELEMENT_ARRAY_BUFFER,null)):i.bindVertexArray(null),i.useProgram(null),B&&i.enable(i.SCISSOR_TEST)}}_mulMatrix(e,t,n){for(let r=0;r<16;r+=4){const o=n[r],l=n[r+1],c=n[r+2],i=n[r+3];e[r]=t[0]*o+t[4]*l+t[8]*c+t[12]*i,e[r+1]=t[1]*o+t[5]*l+t[9]*c+t[13]*i,e[r+2]=t[2]*o+t[6]*l+t[10]*c+t[14]*i,e[r+3]=t[3]*o+t[7]*l+t[11]*c+t[15]*i}}_resolveBlend(e,t){return t&&e>=0&&e<t.length?t[e]:e}_applyBlendMode(e,t){switch(t){default:case 0:e.blendFuncSeparate(e.ONE,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 1:e.blendFunc(e.ONE,e.ONE);break;case 2:e.blendFunc(e.DST_COLOR,e.ONE_MINUS_SRC_ALPHA);break}}}const sharedRenderer=new NeutrinoRenderer;class Effect extends Phaser.GameObjects.GameObject{constructor(t,n,r){r=Object.assign({position:[0,0,0],angle:0,scale:1,pause:Pause.BEFORE_UPDATE_OR_RENDER,generatorsPaused:!1},r||{});super(n,"Neutrino");a(this,"gamePlugin");a(this,"effectModel");a(this,"effect",null);a(this,"x",0);a(this,"y",0);a(this,"z",0);a(this,"angle",0);a(this,"rotation",0);a(this,"scaleX",1);a(this,"scaleY",1);a(this,"scrollFactorX",1);a(this,"scrollFactorY",1);a(this,"alpha",1);a(this,"depth",0);a(this,"blendMode",Phaser.BlendModes.NORMAL);a(this,"projection");a(this,"_dataTextureManager",null);a(this,"_worldPosition");a(this,"_worldScaledPosition");a(this,"_worldRotation",[0,0,0,1]);a(this,"_worldScale");a(this,"_tempMatrix1");a(this,"_tempMatrix2");a(this,"_unpauseOnUpdateRender");a(this,"_glTexturesScratch",[]);this.gamePlugin=n.plugins.get("neutrino"),this.effectModel=t,this.x=r.position[0],this.y=r.position[1],this.z=r.position[2],this.angle=r.angle,this.scaleX=r.scale,this.scaleY=r.scale,this.projection=r.projection,this._worldPosition=new Phaser.Math.Vector2,this._worldScaledPosition=[0,0,0],this._worldScale=1,this._tempMatrix1=new Phaser.GameObjects.Components.TransformMatrix,this._tempMatrix2=new Phaser.GameObjects.Components.TransformMatrix,this._unpauseOnUpdateRender=r.pause===Pause.BEFORE_UPDATE_OR_RENDER,this._updateWorldTransform();const o={paused:r.pause!==Pause.NO,generatorsPaused:r.generatorsPaused};this.effectModel&&(this.effect=this.effectModel.effectModel.createInstance(this._renderPosition(),this._renderRotation(),o),this._dataTextureManager=this.gamePlugin.ctx.isWebGL1?new DataTextureManagerGL1(this.gamePlugin.ctx.gl,this.effect.particleDataUint32,this.effect.dataTextureWidth,this.effect.dataTextureHeight):new DataTextureManager(this.gamePlugin.ctx.gl,this.effect.particleDataUint32,this.effect.dataTextureWidth,this.effect.dataTextureHeight),this.gamePlugin.ctx.ensureIndexBuffer(this.effectModel.effectModel.totalParticles))}get ready(){return this.effectModel!=null&&this.effectModel.ready&&this.effect!=null}preUpdate(t,n){this.ready&&(this._checkUnpauseOnUpdateRender()||this._updateWorldTransform(),this.effect.update(n/1e3,this._renderPosition(),this._renderRotation()))}renderWebGL(t,n,r){if(!this.ready||this.alpha<=0)return;this._checkUnpauseOnUpdateRender();const o=this.gamePlugin.ctx,l=this._dataTextureManager;this.effect.construct([0,0,-1]);const c=this.effect.renderInstructions,i=c._totalParticles;if(i===0)return;t.flush();const u=this.effectModel.effectModel.textures.length,_=this._glTexturesScratch;_.length=u;for(let E=0;E<u;++E)_[E]=this.effectModel.glTexture(E);const y=this._worldScale;try{sharedRenderer.render(o,l,this.effect.particleDataView,this.effect.particleDataUint32,c,i,{model:{a:y,b:0,c:0,d:y,tx:0,ty:0},viewportWidth:t.width,viewportHeight:t.height,scrollX:r.scrollX*this.scrollFactorX,scrollY:r.scrollY*this.scrollFactorY,zoom:r.zoom,worldAlpha:this.alpha,projection:this.projection,glTextures:_,remaps:this.effectModel.texturesRemap,renderStyles:this.effect.model.renderStyles,materials:this.effect.model.materials}),l.advance()}finally{t.pipelines.rebind()}}restart(t){this.ready&&(this._applyTransformOptions(t),this._updateWorldTransform(),this.effect.restart(this._renderPosition(),this._renderRotation()))}resetPosition(t){this.ready&&(this._applyTransformOptions(t),this._updateWorldTransform(),this.effect.resetPosition(this._renderPosition(),this._renderRotation()))}pause(){this.ready&&this.effect.pauseAllEmitters()}unpause(){this.ready&&this.effect.unpauseAllEmitters()}get paused(){return this.ready?this.effect.areAllEmittersPaused():!1}pauseGenerators(){this.ready&&this.effect.pauseGeneratorsInAllEmitters()}unpauseGenerators(){this.ready&&this.effect.unpauseGeneratorsInAllEmitters()}get generatorsPaused(){return this.ready?this.effect.areGeneratorsInAllEmittersPaused():!1}setPropertyInAllEmitters(t,n){this.ready&&this.effect.setPropertyInAllEmitters(t,n)}setPropertyInEmitter(t,n,r){this.ready&&this.effect.setPropertyInEmitter(t,n,r)}getEmitterPropertyValue(t,n){if(this.ready)return n===void 0?this.effect.getEmitterPropertyValue(t):this.effect.getEmitterPropertyValue(t,n)}hasEmitterProperty(t,n){return this.ready?n===void 0?this.effect.hasEmitterProperty(t):this.effect.hasEmitterProperty(t,n):!1}getEmitterProperties(){return this.ready?this.effect.getEmitterProperties():[]}getNumParticles(){return this.ready?this.effect.getNumParticles():0}setScrollFactor(t,n){return this.scrollFactorX=t,this.scrollFactorY=n===void 0?t:n,this}setAlpha(t,n,r,o){return this.alpha=t===void 0?1:t,this}destroy(t){this._dataTextureManager&&(this._dataTextureManager.destroy(),this._dataTextureManager=null),super.destroy(t)}_applyTransformOptions(t){t&&(t.position&&(this.x=t.position[0],this.y=t.position[1],this.z=t.position[2]),t.angle!==void 0?(this.angle=t.angle,this.rotation=Phaser.Math.DegToRad(t.angle)):t.rotation!==void 0&&(this.rotation=t.rotation,this.angle=Phaser.Math.RadToDeg(t.rotation)))}_updateWorldTransform(){const t=(o,l)=>{if(!o)return;const c=this._tempMatrix2;c.applyITRS(o.x,o.y,o.rotation,o.scaleX,o.scaleY),c.multiply(l.matrix,l.matrix),l.angle+=o.angle,l.scale*=(o.scaleX+o.scaleY)*.5,t(o.parentContainer,l)},n={matrix:this._tempMatrix1.loadIdentity(),angle:this.angle,scale:(this.scaleX+this.scaleY)*.5};t(this.parentContainer,n),n.matrix.transformPoint(this.x,this.y,this._worldPosition),this._worldRotation=this.gamePlugin.neutrino.axisangle2quat_([0,0,1],n.angle),this._worldScale=n.scale;const r=this._worldScale!==0?1/this._worldScale:0;this._worldScaledPosition[0]=this._worldPosition.x*r,this._worldScaledPosition[1]=this._worldPosition.y*r,this._worldScaledPosition[2]=this.z*r}_renderPosition(){return this._worldScaledPosition}_renderRotation(){return this._worldRotation}_checkUnpauseOnUpdateRender(){return this._unpauseOnUpdateRender?(this.resetPosition(),this.unpause(),this._unpauseOnUpdateRender=!1,!0):!1}}class PerspectiveProjection{constructor(e){a(this,"_angleTan",0);a(this,"_screenWidth",0);a(this,"_screenPosX",0);a(this,"_screenPosY",0);a(this,"_z",0);a(this,"_near",0);this.horizontalAngle=e}set horizontalAngle(e){this._angleTan=Math.tan(e*.5/180*Math.PI)}setScreenFrame(e){this._screenWidth=e.width,this._screenPosX=e.x+e.width*.5,this._screenPosY=e.y+e.height*.5,this._z=this._screenWidth*.5/this._angleTan,this._near=this._z*.99}transformPosition(e,t){if(t[2]>this._near)return!1;const n=this._getScale(t);return e[0]=(t[0]-this._screenPosX)*n+this._screenPosX,e[1]=(t[1]-this._screenPosY)*n+this._screenPosY,!0}transformSize(e,t,n){const r=this._getScale(t);e[0]=n[0]*r,e[1]=n[1]*r}_getScale(e){return this._z/(this._z-e[2])}writeMatrix(e){const t=this._z,n=Number.isFinite(t)&&t>0?1/t:0;e.fill(0),e[0]=1,e[5]=1,e[8]=-this._screenPosX*n,e[9]=-this._screenPosY*n,e[11]=-n,e[15]=1}}let _installed=!1;function installPlugin(){_installed||(_installed=!0,Phaser.Loader.FileTypesManager.register("neutrino",function(s,e,t,n){if(Array.isArray(s))for(const r of s)this.addFile(new NeutrinoFile(this,r));else typeof s=="object"?this.addFile(new NeutrinoFile(this,s)):this.addFile(new NeutrinoFile(this,{key:s,url:e,options:t,xhrSettings:n}));return this}),Phaser.GameObjects.GameObjectFactory.register("neutrino",function(s,e){const t=new Effect(s,this.scene,e);return this.displayList.add(t),this.updateList.add(t),t}),Phaser.GameObjects.GameObjectCreator.register("neutrino",function(s){const e=new Effect(s.effectModel,this.scene,s);return s.add!==!1&&(this.scene.sys.displayList.add(e),this.scene.sys.updateList.add(e)),e}))}installPlugin();exports.DataTextureManager=DataTextureManager;exports.Effect=Effect;exports.EffectModel=EffectModel;exports.GamePlugin=GamePlugin;exports.NeutrinoContext=NeutrinoContext;exports.NeutrinoFile=NeutrinoFile;exports.NeutrinoRenderer=NeutrinoRenderer;exports.Pause=Pause;exports.PerspectiveProjection=PerspectiveProjection;exports.installPlugin=installPlugin;
1337
+ })(this.gamePlugin.neutrino);`;this.effectModel=eval(evalScript),this._startLoadTextures(options.atlases)}get ready(){return this._numTexturesToLoadLeft===0}glTexture(s){const e=this.textureFrames[s];return e?e.glTexture.webGLTexture:null}_startLoadTextures(s){const e=this.effectModel.textures.length;this._numTexturesToLoadLeft=e;for(let t=0;t<e;++t){const n=this.effectModel.textures[t],r=this.gamePlugin.texturesBasePath+n,o=noext(r);let l=this._findFrameInAtlases(s,n);if(l||(l=this._findFrameInAtlases(s,noext(n))),!l&&this.scene.sys.textures.exists(o)){const d=this.scene.sys.textures.get(o);l=d.get(d.firstFrame)}l?this._onTextureLoaded(t,l):(this.scene.load.once("filecomplete-image-"+o,((d,i)=>()=>{const u=this.scene.sys.textures.get(i);this._onTextureLoaded(d,u.get(u.firstFrame))})(t,o)),this.scene.load.image(o,r))}}_findFrameInAtlases(s,e){for(let t=0;t<s.length;++t){const n=s[t];if(!this.scene.sys.textures.exists(n))continue;const r=this.scene.sys.textures.get(n);if(r.has(e))return r.get(e)}return null}_onTextureLoaded(s,e){this.textureFrames[s]=e,this._numTexturesToLoadLeft--,this._numTexturesToLoadLeft===0&&this._initTexturesRemapIfNeeded()}_fullCover(s){return s.width===s.source.width&&s.height===s.source.height}_initTexturesRemapIfNeeded(){let s=!1;for(let e=0;e<this.textureFrames.length;++e)if(!this._fullCover(this.textureFrames[e])){s=!0;break}if(s)for(let e=0;e<this.textureFrames.length;++e){const t=this.textureFrames[e];this.texturesRemap[e]={x:t.u0,y:1-t.v1,width:t.u1-t.u0,height:t.v1-t.v0}}}}class NeutrinoFile extends Phaser.Loader.File{constructor(t,n){const{key:r,url:o,options:l,xhrSettings:d}=n;super(t,{type:"binary",extension:"js",responseType:"text",key:r,url:o,xhrSettings:d});a(this,"_options");this.cache=t.cacheManager.binary,this._options=l}onProcess(){this.state=Phaser.Loader.FILE_PROCESSING;const t=this.xhrLoader.response;this.data=new EffectModel(this.loader.scene,t,this._options),this.onProcessComplete()}}var Pause=(s=>(s[s.NO=0]="NO",s[s.BEFORE_UPDATE_OR_RENDER=1]="BEFORE_UPDATE_OR_RENDER",s[s.YES=2]="YES",s))(Pause||{});const RING_BUFFER_SIZE$1=3;class DataTextureManager{constructor(e,t,n,r){a(this,"textureWidth");a(this,"textureHeight");a(this,"_gl");a(this,"_floatView");a(this,"_textures",[]);a(this,"_currentIndex",0);const o=e.getParameter(e.MAX_TEXTURE_SIZE);if(n>o||r>o)throw new Error(`NeutrinoParticles: data texture ${n}x${r} exceeds GL MAX_TEXTURE_SIZE (${o}). Reduce effect particle capacity.`);this._gl=e,this.textureWidth=n,this.textureHeight=r,this._floatView=new Float32Array(t.buffer,t.byteOffset,t.length);for(let l=0;l<RING_BUFFER_SIZE$1;l++){const d=e.createTexture();e.bindTexture(e.TEXTURE_2D,d),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.RGBA32F,n,r,0,e.RGBA,e.FLOAT,null),this._textures.push(d)}e.bindTexture(e.TEXTURE_2D,null)}get currentTexture(){return this._textures[this._currentIndex]}uploadAndBind(e){const t=this._gl;t.activeTexture(t.TEXTURE0+e),t.bindTexture(t.TEXTURE_2D,this._textures[this._currentIndex]),t.pixelStorei(t.UNPACK_ALIGNMENT,4),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texSubImage2D(t.TEXTURE_2D,0,0,0,this.textureWidth,this.textureHeight,t.RGBA,t.FLOAT,this._floatView)}advance(){this._currentIndex=(this._currentIndex+1)%RING_BUFFER_SIZE$1}destroy(){const e=this._gl;for(const t of this._textures)t&&e.deleteTexture(t);this._textures=[]}}class MetaTextureManager{constructor(e,t){a(this,"bytes");a(this,"_u32");this.bytes=new Uint8Array(e*t*4),this._u32=new Uint32Array(this.bytes.buffer)}build(e,t){const n=this._u32;for(let r=0;r<t;r++){const o=r*16,l=r*4;n[l]=e[o],n[l+1]=e[o+12],n[l+2]=e[o+13],n[l+3]=e[o+14]}}patchSlot(e,t,n){const r=this.bytes;let o=e*16;for(let l=0;l<t;l++)r[o]=n,o+=16}}const RING_BUFFER_SIZE=3;class DataTextureManagerGL1{constructor(e,t,n,r){a(this,"textureWidth");a(this,"textureHeight");a(this,"meta");a(this,"_gl");a(this,"_floatView");a(this,"_dataTextures",[]);a(this,"_metaTextures",[]);a(this,"_currentIndex",0);const o=e.getParameter(e.MAX_TEXTURE_SIZE);if(n>o||r>o)throw new Error(`NeutrinoParticles: data texture ${n}x${r} exceeds GL MAX_TEXTURE_SIZE (${o}). Reduce effect particle capacity.`);if(n*r>16777216)throw new Error(`NeutrinoParticles: data texture ${n}x${r} exceeds the WebGL1 render path texel cap (2^24). Reduce effect particle capacity.`);this._gl=e,this.textureWidth=n,this.textureHeight=r,this._floatView=new Float32Array(t.buffer,t.byteOffset,t.length),this.meta=new MetaTextureManager(n,r);const l=e.getParameter(e.ACTIVE_TEXTURE);e.activeTexture(e.TEXTURE0);const d=e.getParameter(e.TEXTURE_BINDING_2D);for(let i=0;i<RING_BUFFER_SIZE;i++)this._dataTextures.push(this._createTexture(e.FLOAT)),this._metaTextures.push(this._createTexture(e.UNSIGNED_BYTE));e.bindTexture(e.TEXTURE_2D,d),e.activeTexture(l)}get currentDataTexture(){return this._dataTextures[this._currentIndex]}get currentMetaTexture(){return this._metaTextures[this._currentIndex]}upload(e,t,n){const r=this._gl,o=this.textureWidth,l=Math.min(this.textureHeight,Math.ceil(e*4/o));if(l===0)return;const d=l*o*4;r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,!1),r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),r.pixelStorei(r.UNPACK_ALIGNMENT,4),r.activeTexture(r.TEXTURE0+t),r.bindTexture(r.TEXTURE_2D,this.currentDataTexture),r.texSubImage2D(r.TEXTURE_2D,0,0,0,o,l,r.RGBA,r.FLOAT,this._floatView.subarray(0,d)),r.activeTexture(r.TEXTURE0+n),r.bindTexture(r.TEXTURE_2D,this.currentMetaTexture),r.texSubImage2D(r.TEXTURE_2D,0,0,0,o,l,r.RGBA,r.UNSIGNED_BYTE,this.meta.bytes.subarray(0,d))}advance(){this._currentIndex=(this._currentIndex+1)%RING_BUFFER_SIZE}destroy(){const e=this._gl;for(const t of this._dataTextures)e.deleteTexture(t);for(const t of this._metaTextures)e.deleteTexture(t);this._dataTextures=[],this._metaTextures=[]}_createTexture(e){const t=this._gl,n=t.createTexture();return t.bindTexture(t.TEXTURE_2D,n),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureWidth,this.textureHeight,0,t.RGBA,e,null),n}}const DATA_TEXTURE_UNIT=0,META_TEXTURE_UNIT=1,PARTICLE_TEXTURE_START_UNIT=1,PARTICLE_TEXTURE_START_UNIT_GL1=2,FLOATS_PER_PARTICLE=16,BYTES_PER_PARTICLE=FLOATS_PER_PARTICLE*4,MAX_BATCHES=64;class DrawBatch{constructor(){a(this,"blendMode",0);a(this,"startParticle",0);a(this,"numParticles",0);a(this,"numTextures",0);a(this,"glTextures",new Array(NeutrinoContext.MAX_BATCH_TEXTURES).fill(null));a(this,"remaps",new Array(NeutrinoContext.MAX_BATCH_TEXTURES).fill(null))}reset(){this.blendMode=0,this.startParticle=0,this.numParticles=0,this.numTextures=0}}class NeutrinoRenderer{constructor(){a(this,"_orthoMatrix",new Float32Array(16));a(this,"_perspMatrix",new Float32Array(16));a(this,"_vpMatrix",new Float32Array(16));a(this,"_projFrame",{x:0,y:0,width:0,height:0});a(this,"_modelMatrix",new Float32Array(16));a(this,"_texSlotMap",new Map);a(this,"_batchPool");a(this,"_batchCount",0);this._batchPool=[];for(let e=0;e<MAX_BATCHES;e++)this._batchPool.push(new DrawBatch)}render(e,t,n,r,o,l,d){if(l===0)return;const i=e.gl,u=e.isWebGL1,_=e.maxBatchTextures,y=d.renderStyles,E=d.materials,I=u?t.meta:null;I&&I.build(r,l),this._batchCount=0;const m=this._texSlotMap;for(;this._batchPool.length<o.length;)this._batchPool.push(new DrawBatch);let b=0;for(;b<o.length;){const f=this._batchPool[this._batchCount];f.reset(),f.blendMode=this._resolveBlend(o[b].blendMode,E),f.startParticle=o[b].startParticleIndex,m.clear();let v=b;for(;v<o.length&&this._resolveBlend(o[v].blendMode,E)===f.blendMode;){const g=y[o[v].renderStyleIndex].textureIndices[0];if(!m.has(g)){if(m.size>=_)break;const x=m.size;m.set(g,x),f.glTextures[x]=d.glTextures[g]||null,f.remaps[x]=d.remaps[g]||null,f.numTextures=x+1}const c=m.get(g),w=o[v];if(I)I.patchSlot(w.startParticleIndex,w.numParticles,c);else if(c!==0)for(let x=0;x<w.numParticles;x++){const h=(w.startParticleIndex+x)*BYTES_PER_PARTICLE,B=n.getUint32(h,!0);n.setUint32(h,B&4294967040|c,!0)}f.numParticles+=w.numParticles,v++}this._batchCount++,b=v}const U=i.isEnabled(i.SCISSOR_TEST);try{if(i.disable(i.DEPTH_TEST),i.disable(i.STENCIL_TEST),i.disable(i.SCISSOR_TEST),i.disable(i.CULL_FACE),i.depthMask(!1),i.colorMask(!0,!0,!0,!0),i.useProgram(e.shaderProgram),u){const p=t;p.upload(l,DATA_TEXTURE_UNIT,META_TEXTURE_UNIT),i.uniform1i(e.uDataTexture,DATA_TEXTURE_UNIT),i.uniform1i(e.uMetaTexture,META_TEXTURE_UNIT),i.uniform2f(e.uDataTexSize,p.textureWidth,p.textureHeight)}else{const p=t;p.uploadAndBind(DATA_TEXTURE_UNIT),i.uniform1i(e.uDataTexture,DATA_TEXTURE_UNIT),i.uniform1i(e.uDataTextureWidth,p.textureWidth)}i.uniform3f(e.uCameraRight,1,0,0),i.uniform3f(e.uCameraUp,0,-1,0),i.uniform3f(e.uCameraDir,0,0,-1);const f=d.viewportWidth,v=d.viewportHeight,g=d.zoom||1,c=this._orthoMatrix;if(c.fill(0),c[0]=2/f*g,c[5]=-2/v*g,c[10]=0,c[15]=1,c[12]=-1-2/f*g*d.scrollX,c[13]=1+2/v*g*d.scrollY,d.projection){const p=this._projFrame;p.x=0,p.y=0,p.width=f,p.height=v,d.projection.setScreenFrame(p),d.projection.writeMatrix(this._perspMatrix),this._mulMatrix(this._vpMatrix,c,this._perspMatrix),i.uniformMatrix4fv(e.uViewProjMatrix,!1,this._vpMatrix)}else i.uniformMatrix4fv(e.uViewProjMatrix,!1,c);const w=v>0?f/v:1;e.uViewportAspect&&i.uniform1f(e.uViewportAspect,w),e.uWorldAlpha&&i.uniform1f(e.uWorldAlpha,d.worldAlpha);const x=d.model,h=this._modelMatrix;h[0]=x.a,h[1]=x.b,h[2]=0,h[3]=0,h[4]=x.c,h[5]=x.d,h[6]=0,h[7]=0,h[8]=0,h[9]=0,h[10]=1,h[11]=0,h[12]=x.tx,h[13]=x.ty,h[14]=0,h[15]=1,i.uniformMatrix4fv(e.uModelMatrix,!1,h),u?(e.unbindVao(),i.bindBuffer(i.ARRAY_BUFFER,e.aIdBuffer),i.enableVertexAttribArray(e.aIdLocation),i.vertexAttribPointer(e.aIdLocation,1,i.FLOAT,!1,0,0),i.bindBuffer(i.ELEMENT_ARRAY_BUFFER,e.indexBuffer)):i.bindVertexArray(e.vao);const B=u?PARTICLE_TEXTURE_START_UNIT_GL1:PARTICLE_TEXTURE_START_UNIT;i.enable(i.BLEND);for(let p=0;p<this._batchCount;p++){const P=this._batchPool[p];this._applyBlendMode(i,P.blendMode);for(let T=0;T<P.numTextures;T++){const C=B+T;i.activeTexture(i.TEXTURE0+C),i.bindTexture(i.TEXTURE_2D,P.glTextures[T]),i.uniform1i(e.uTextures[T],C);const R=P.remaps[T];R?i.uniform4f(e.uTexRemaps[T],R.x,R.y,R.width,R.height):i.uniform4f(e.uTexRemaps[T],0,0,1,1)}const D=P.startParticle*6,S=P.numParticles*6;i.drawElements(i.TRIANGLES,S,e.indexType,D*(e.indexType===i.UNSIGNED_INT?4:2))}}finally{u?(i.disableVertexAttribArray(e.aIdLocation),i.bindBuffer(i.ARRAY_BUFFER,null),i.bindBuffer(i.ELEMENT_ARRAY_BUFFER,null)):i.bindVertexArray(null),i.useProgram(null),U&&i.enable(i.SCISSOR_TEST)}}_mulMatrix(e,t,n){for(let r=0;r<16;r+=4){const o=n[r],l=n[r+1],d=n[r+2],i=n[r+3];e[r]=t[0]*o+t[4]*l+t[8]*d+t[12]*i,e[r+1]=t[1]*o+t[5]*l+t[9]*d+t[13]*i,e[r+2]=t[2]*o+t[6]*l+t[10]*d+t[14]*i,e[r+3]=t[3]*o+t[7]*l+t[11]*d+t[15]*i}}_resolveBlend(e,t){return t&&e>=0&&e<t.length?t[e]:e}_applyBlendMode(e,t){switch(t){default:case 0:e.blendFuncSeparate(e.ONE,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 1:e.blendFunc(e.ONE,e.ONE);break;case 2:e.blendFunc(e.DST_COLOR,e.ONE_MINUS_SRC_ALPHA);break}}}const sharedRenderer=new NeutrinoRenderer;class Effect extends Phaser.GameObjects.GameObject{constructor(t,n,r){r=Object.assign({position:[0,0,0],angle:0,scale:1,pause:Pause.BEFORE_UPDATE_OR_RENDER,generatorsPaused:!1},r||{});super(n,"Neutrino");a(this,"gamePlugin");a(this,"effectModel");a(this,"effect",null);a(this,"x",0);a(this,"y",0);a(this,"z",0);a(this,"angle",0);a(this,"rotation",0);a(this,"scaleX",1);a(this,"scaleY",1);a(this,"scrollFactorX",1);a(this,"scrollFactorY",1);a(this,"alpha",1);a(this,"depth",0);a(this,"blendMode",Phaser.BlendModes.NORMAL);a(this,"projection");a(this,"_dataTextureManager",null);a(this,"_worldPosition");a(this,"_worldScaledPosition");a(this,"_worldRotation",[0,0,0,1]);a(this,"_worldScale");a(this,"_tempMatrix1");a(this,"_tempMatrix2");a(this,"_unpauseOnUpdateRender");a(this,"_glTexturesScratch",[]);this.gamePlugin=n.plugins.get("neutrino"),this.effectModel=t,this.x=r.position[0],this.y=r.position[1],this.z=r.position[2],this.angle=r.angle,this.scaleX=r.scale,this.scaleY=r.scale,this.projection=r.projection,this._worldPosition=new Phaser.Math.Vector2,this._worldScaledPosition=[0,0,0],this._worldScale=1,this._tempMatrix1=new Phaser.GameObjects.Components.TransformMatrix,this._tempMatrix2=new Phaser.GameObjects.Components.TransformMatrix,this._unpauseOnUpdateRender=r.pause===Pause.BEFORE_UPDATE_OR_RENDER,this._updateWorldTransform();const o={paused:r.pause!==Pause.NO,generatorsPaused:r.generatorsPaused};this.effectModel&&(this.effect=this.effectModel.effectModel.createInstance(this._renderPosition(),this._renderRotation(),o),this._dataTextureManager=this.gamePlugin.ctx.isWebGL1?new DataTextureManagerGL1(this.gamePlugin.ctx.gl,this.effect.particleDataUint32,this.effect.dataTextureWidth,this.effect.dataTextureHeight):new DataTextureManager(this.gamePlugin.ctx.gl,this.effect.particleDataUint32,this.effect.dataTextureWidth,this.effect.dataTextureHeight),this.gamePlugin.ctx.ensureIndexBuffer(this.effectModel.effectModel.totalParticles))}get ready(){return this.effectModel!=null&&this.effectModel.ready&&this.effect!=null}preUpdate(t,n){this.ready&&(this._checkUnpauseOnUpdateRender()||this._updateWorldTransform(),this.effect.update(n/1e3,this._renderPosition(),this._renderRotation()))}renderWebGL(t,n,r){if(!this.ready||this.alpha<=0)return;this._checkUnpauseOnUpdateRender();const o=this.gamePlugin.ctx,l=this._dataTextureManager;this.effect.construct([0,0,-1]);const d=this.effect.renderInstructions,i=d._totalParticles;if(i===0)return;t.flush();const u=this.effectModel.effectModel.textures.length,_=this._glTexturesScratch;_.length=u;for(let E=0;E<u;++E)_[E]=this.effectModel.glTexture(E);const y=this._worldScale;try{sharedRenderer.render(o,l,this.effect.particleDataView,this.effect.particleDataUint32,d,i,{model:{a:y,b:0,c:0,d:y,tx:0,ty:0},viewportWidth:t.width,viewportHeight:t.height,scrollX:r.scrollX*this.scrollFactorX,scrollY:r.scrollY*this.scrollFactorY,zoom:r.zoom,worldAlpha:this.alpha,projection:this.projection,glTextures:_,remaps:this.effectModel.texturesRemap,renderStyles:this.effect.model.renderStyles,materials:this.effect.model.materials}),l.advance()}finally{t.pipelines.rebind()}}restart(t){this.ready&&(this._applyTransformOptions(t),this._updateWorldTransform(),this.effect.restart(this._renderPosition(),this._renderRotation()))}resetPosition(t){this.ready&&(this._applyTransformOptions(t),this._updateWorldTransform(),this.effect.resetPosition(this._renderPosition(),this._renderRotation()))}pause(){this.ready&&this.effect.pauseAllEmitters()}unpause(){this.ready&&this.effect.unpauseAllEmitters()}get paused(){return this.ready?this.effect.areAllEmittersPaused():!1}pauseGenerators(){this.ready&&this.effect.pauseGeneratorsInAllEmitters()}unpauseGenerators(){this.ready&&this.effect.unpauseGeneratorsInAllEmitters()}get generatorsPaused(){return this.ready?this.effect.areGeneratorsInAllEmittersPaused():!1}setPropertyInAllEmitters(t,n){this.ready&&this.effect.setPropertyInAllEmitters(t,n)}setPropertyInEmitter(t,n,r){this.ready&&this.effect.setPropertyInEmitter(t,n,r)}getEmitterPropertyValue(t,n){if(this.ready)return n===void 0?this.effect.getEmitterPropertyValue(t):this.effect.getEmitterPropertyValue(t,n)}hasEmitterProperty(t,n){return this.ready?n===void 0?this.effect.hasEmitterProperty(t):this.effect.hasEmitterProperty(t,n):!1}getEmitterProperties(){return this.ready?this.effect.getEmitterProperties():[]}getNumParticles(){return this.ready?this.effect.getNumParticles():0}setScrollFactor(t,n){return this.scrollFactorX=t,this.scrollFactorY=n===void 0?t:n,this}setAlpha(t,n,r,o){return this.alpha=t===void 0?1:t,this}destroy(t){this._dataTextureManager&&(this._dataTextureManager.destroy(),this._dataTextureManager=null),super.destroy(t)}_applyTransformOptions(t){t&&(t.position&&(this.x=t.position[0],this.y=t.position[1],this.z=t.position[2]),t.angle!==void 0?(this.angle=t.angle,this.rotation=Phaser.Math.DegToRad(t.angle)):t.rotation!==void 0&&(this.rotation=t.rotation,this.angle=Phaser.Math.RadToDeg(t.rotation)))}_updateWorldTransform(){const t=(o,l)=>{if(!o)return;const d=this._tempMatrix2;d.applyITRS(o.x,o.y,o.rotation,o.scaleX,o.scaleY),d.multiply(l.matrix,l.matrix),l.angle+=o.angle,l.scale*=(o.scaleX+o.scaleY)*.5,t(o.parentContainer,l)},n={matrix:this._tempMatrix1.loadIdentity(),angle:this.angle,scale:(this.scaleX+this.scaleY)*.5};t(this.parentContainer,n),n.matrix.transformPoint(this.x,this.y,this._worldPosition),this._worldRotation=this.gamePlugin.neutrino.axisangle2quat_([0,0,1],n.angle),this._worldScale=n.scale;const r=this._worldScale!==0?1/this._worldScale:0;this._worldScaledPosition[0]=this._worldPosition.x*r,this._worldScaledPosition[1]=this._worldPosition.y*r,this._worldScaledPosition[2]=this.z*r}_renderPosition(){return this._worldScaledPosition}_renderRotation(){return this._worldRotation}_checkUnpauseOnUpdateRender(){return this._unpauseOnUpdateRender?(this.resetPosition(),this.unpause(),this._unpauseOnUpdateRender=!1,!0):!1}}class PerspectiveProjection{constructor(e){a(this,"_angleTan",0);a(this,"_screenWidth",0);a(this,"_screenPosX",0);a(this,"_screenPosY",0);a(this,"_z",0);a(this,"_near",0);this.horizontalAngle=e}set horizontalAngle(e){this._angleTan=Math.tan(e*.5/180*Math.PI)}setScreenFrame(e){this._screenWidth=e.width,this._screenPosX=e.x+e.width*.5,this._screenPosY=e.y+e.height*.5,this._z=this._screenWidth*.5/this._angleTan,this._near=this._z*.99}transformPosition(e,t){if(t[2]>this._near)return!1;const n=this._getScale(t);return e[0]=(t[0]-this._screenPosX)*n+this._screenPosX,e[1]=(t[1]-this._screenPosY)*n+this._screenPosY,!0}transformSize(e,t,n){const r=this._getScale(t);e[0]=n[0]*r,e[1]=n[1]*r}_getScale(e){return this._z/(this._z-e[2])}writeMatrix(e){const t=this._z,n=Number.isFinite(t)&&t>0?1/t:0;e.fill(0),e[0]=1,e[5]=1,e[8]=-this._screenPosX*n,e[9]=-this._screenPosY*n,e[11]=-n,e[15]=1}}let _installed=!1;function installPlugin(){_installed||(_installed=!0,Phaser.Loader.FileTypesManager.register("neutrino",function(s,e,t,n){if(Array.isArray(s))for(const r of s)this.addFile(new NeutrinoFile(this,r));else typeof s=="object"?this.addFile(new NeutrinoFile(this,s)):this.addFile(new NeutrinoFile(this,{key:s,url:e,options:t,xhrSettings:n}));return this}),Phaser.GameObjects.GameObjectFactory.register("neutrino",function(s,e){const t=new Effect(s,this.scene,e);return this.displayList.add(t),this.updateList.add(t),t}),Phaser.GameObjects.GameObjectCreator.register("neutrino",function(s){const e=new Effect(s.effectModel,this.scene,s);return s.add!==!1&&(this.scene.sys.displayList.add(e),this.scene.sys.updateList.add(e)),e}))}installPlugin();exports.DataTextureManager=DataTextureManager;exports.Effect=Effect;exports.EffectModel=EffectModel;exports.GamePlugin=GamePlugin;exports.NeutrinoContext=NeutrinoContext;exports.NeutrinoFile=NeutrinoFile;exports.NeutrinoRenderer=NeutrinoRenderer;exports.Pause=Pause;exports.PerspectiveProjection=PerspectiveProjection;exports.installPlugin=installPlugin;
1314
1338
  //# sourceMappingURL=neutrinoparticles.js-v1.1-phaser.cjs.js.map