rapid-render 1.0.24 → 1.0.27

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/README.md CHANGED
@@ -101,37 +101,46 @@ stack.restore(); // 1.root
101
101
  rapid.drawSprite(ui);
102
102
  ```
103
103
 
104
- ## Use Saved World Matrices
104
+ ## Reuse MatrixStack Transforms
105
105
 
106
- `save()` returns the current `parent`, `local`, and `world` matrix IDs. The IDs can be used with `customMatrix` after their stack scope has been restored, as long as they belong to the current frame.
106
+ `save()` returns `parent`, `local`, and `world` matrix IDs. Saved world IDs can be used with `customMatrix` within the current frame. Use `retainMatrix()` to cache transforms across frames and reuse them with `save(cached)`:
107
107
 
108
108
  ```ts
109
- rapid.clear();
110
-
111
109
  const stack = rapid.matrixStack;
112
- // Build the hierarchy for this frame.
113
- const world = stack.save();
114
- stack.translate(200, 200);
115
-
116
- const enemyNode = stack.save();
117
- stack.translate(80, 0);
118
-
119
- stack.restore(); // enemyNode
120
- stack.restore(); // world
110
+ const matrix = rapid.matrix;
111
+
112
+ const cached = stack.retainMatrix(stack.save());
113
+ matrix.translate(cached.local, 100, 80);
114
+ matrix.multiplyOut(cached.world, cached.parent, cached.local);
115
+ stack.restore();
116
+
117
+ function drawFrame() {
118
+ rapid.clear();
119
+ stack.save(cached);
120
+ rapid.drawSprite({ texture });
121
+ stack.restore();
122
+ rapid.flush();
123
+ }
124
+ ```
121
125
 
122
- // The stack has been restored, but enemyNode.world is still available during
123
- // this frame. Build the hierarchy again next frame with the latest game state.
124
- rapid.drawSprite({
125
- texture: enemy,
126
- customMatrix: enemyNode.world,
127
- });
126
+ `save()` accepts a saved state or individual matrix IDs:
128
127
 
129
- rapid.flush();
128
+ ```ts
129
+ stack.save(); // Identity local; inherit parent world.
130
+ stack.save(cached); // Reuse the saved world and local IDs.
131
+ stack.save(cached.world, cached.local); // Pass both IDs explicitly.
132
+ stack.save(cached.world); // Create an identity local.
133
+ stack.save(undefined, cached.local); // Calculate world = parent world * local.
130
134
  ```
131
135
 
132
- `MatrixStack` is immediate-mode: rebuild transform hierarchies each frame. For retained scene graphs, keep transforms in your own game objects and feed them into the stack while traversing the scene.
136
+ Matrices retained with `stack.retainMatrix()` or created with `rapid.matrix.alloc()` are managed by you. Release them when no longer needed:
133
137
 
134
- With this flexible matrix stack, you can build your own architecture with minimal friction. It doesn't care how you organize your game logic. You can use ECS, scene graphs, components, or any hybrid approach you prefer.
138
+ ```ts
139
+ rapid.matrix.free(cached);
140
+
141
+ const m = rapid.matrix.alloc();
142
+ rapid.matrix.free(m);
143
+ ```
135
144
 
136
145
  For more information about matrix transformations, see the [Transformations](https://nightre.github.io/Rapid.js/docs.html#transformations).
137
146
 
@@ -48,7 +48,7 @@ export declare class MatrixStore {
48
48
  */
49
49
  allocDirty(): number;
50
50
  /** Releases a matrix index so it can be reused by a later allocation. */
51
- free(index: number): void;
51
+ free(index: number | MatrixSaveState): void;
52
52
  /**
53
53
  * Resets the store, clearing all allocated matrices.
54
54
  */
@@ -240,12 +240,13 @@ export declare class MatrixStack {
240
240
  /**
241
241
  * Saves the current matrix state and pushes it onto the stack.
242
242
  * Equivalent to context.save().
243
- * Provided matrix IDs are used directly and recycled by reset() unless retained.
244
- * @param matrixWorld Optional world matrix ID from this store; defaults to parent * local.
243
+ * Provided matrix IDs are used directly and remain caller-owned; only matrices
244
+ * created by this call are queued for recycling by reset().
245
+ * @param matrixWorld Optional world matrix ID or saved state from this store; defaults to parent * local.
245
246
  * @param matrixLocal Optional local matrix ID from this store; defaults to identity.
246
247
  * @returns Matrix IDs for the saved parent, local, and world transforms.
247
248
  */
248
- save(matrixWorld?: number, matrixLocal?: number): MatrixSaveState;
249
+ save(matrixWorld?: number | MatrixSaveState, matrixLocal?: number): MatrixSaveState;
249
250
  /**
250
251
  * Restores the matrix state from the top of the stack.
251
252
  * Equivalent to context.restore().
@@ -253,7 +254,7 @@ export declare class MatrixStack {
253
254
  restore(): void;
254
255
  restoreAll(): void;
255
256
  /**
256
- * Removes a matrix from the current and previous frame recycle queues so
257
+ * Removes a matrix from the frame recycle queue so
257
258
  * it remains valid across `reset()` calls.
258
259
  *
259
260
  * Passing a `MatrixSaveState` retains its `local` and `world` matrices;
@@ -261,8 +262,9 @@ export declare class MatrixStack {
261
262
  * Retained matrices must eventually be released with `matrix.free()`.
262
263
  *
263
264
  * @param matrix A matrix ID or the state returned by `save()`.
265
+ * @returns The supplied ID or state, preserving its input type.
264
266
  */
265
- retainMatrix(matrix: number | MatrixSaveState): void;
267
+ retainMatrix<T extends number | MatrixSaveState>(matrix: T): T;
266
268
  /**
267
269
  * Translates the current local and world matrices by x and y.
268
270
  * @param x - Translation along the x-axis.
@@ -176,19 +176,19 @@ class Ct {
176
176
  async load(t, e) {
177
177
  let r = this.cache.get(t);
178
178
  if (r)
179
- return this.addTexture(new W(r));
179
+ return this.addTexture(new k(r));
180
180
  try {
181
181
  const i = await this._fetchImage(t);
182
- return r = z.fromSource(this.render, i, e), r.uid = t, this.cache.set(t, r), this.addTexture(new W(r));
182
+ return r = z.fromSource(this.render, i, e), r.uid = t, this.cache.set(t, r), this.addTexture(new k(r));
183
183
  } catch (i) {
184
184
  throw console.error(`[TextureManager] Failed to load: ${t}`, i), i;
185
185
  }
186
186
  }
187
187
  create(t, e) {
188
188
  if (e?.key && this.cache.has(e.key))
189
- return this.addTexture(new W(this.cache.get(e.key)));
189
+ return this.addTexture(new k(this.cache.get(e.key)));
190
190
  const r = z.fromSource(this.render, t, e);
191
- return e?.key && (r.uid = e.key, this.cache.set(e.key, r)), this.addTexture(new W(r));
191
+ return e?.key && (r.uid = e.key, this.cache.set(e.key, r)), this.addTexture(new k(r));
192
192
  }
193
193
  createRenderTexture(t) {
194
194
  return this.addTexture(new _t(this.render, t));
@@ -198,7 +198,7 @@ class Ct {
198
198
  }
199
199
  destroy(t, e = !1) {
200
200
  let r, i;
201
- typeof t == "string" ? (i = t, r = this.cache.get(i)) : t instanceof W ? (r = t.base, i = r?.uid, this.removeTexture(t), t.destroy()) : (r = t, i = r.uid), r && (r.refCount <= 0 || e) && (r.destroy(this.render.gl), i && this.cache.delete(i));
201
+ typeof t == "string" ? (i = t, r = this.cache.get(i)) : t instanceof k ? (r = t.base, i = r?.uid, this.removeTexture(t), t.destroy()) : (r = t, i = r.uid), r && (r.refCount <= 0 || e) && (r.destroy(this.render.gl), i && this.cache.delete(i));
202
202
  }
203
203
  destroyAll() {
204
204
  for (const t of this.cache.values())
@@ -238,7 +238,7 @@ class z {
238
238
  this.glTexture && (t.deleteTexture(this.glTexture), this.glTexture = null);
239
239
  }
240
240
  }
241
- class W {
241
+ class k {
242
242
  base;
243
243
  uvX = 0;
244
244
  uvY = 0;
@@ -274,12 +274,12 @@ class W {
274
274
  return this.base ? (this._px = t, this._py = e, this.isAtlas = t !== 0 || e !== 0 || r !== this.base.width || i !== this.base.height, this.uvX = t / this.base.width, this.uvY = e / this.base.height, this.uvW = this.uvX + r / this.base.width, this.uvH = this.uvY + i / this.base.height, this.rawWidth = r * this.scale, this.rawHeight = i * this.scale, this) : this;
275
275
  }
276
276
  getSubTexture(t, e, r, i) {
277
- if (!this.base) return new W();
277
+ if (!this.base) return new k();
278
278
  const s = this.clone(), a = this._px, o = this._py;
279
279
  return s.setRegion(a + t, o + e, r, i), s;
280
280
  }
281
281
  clone(t) {
282
- const e = t ?? new W(this.base);
282
+ const e = t ?? new k(this.base);
283
283
  return t && this.base && t.setBase(this.base), e.scale = this.scale, e.uvX = this.uvX, e.uvY = this.uvY, e.uvW = this.uvW, e.uvH = this.uvH, e.rawWidth = this.rawWidth, e.rawHeight = this.rawHeight, e.offsetX = this.offsetX, e.offsetY = this.offsetY, e.flipY = this.flipY, e.isRotated = this.isRotated, e.isAtlas = this.isAtlas, e._px = this._px, e._py = this._py, e;
284
284
  }
285
285
  splitGrid(t, e, r, i, s = 0) {
@@ -292,13 +292,13 @@ class W {
292
292
  }
293
293
  static fromImageSource(t, e, r = {}) {
294
294
  const i = nt(t, e, r);
295
- return new W(new z(i, e.width, e.height));
295
+ return new k(new z(i, e.width, e.height));
296
296
  }
297
297
  destroy() {
298
298
  this.base && (this.base.refCount--, this.base = void 0), this.glTexture = null;
299
299
  }
300
300
  }
301
- class _t extends W {
301
+ class _t extends k {
302
302
  framebuffer;
303
303
  renderbuffer;
304
304
  gl;
@@ -362,7 +362,7 @@ const Pt = {
362
362
  align: "left",
363
363
  lineHeight: 1
364
364
  };
365
- class Lt extends W {
365
+ class Lt extends k {
366
366
  canvas;
367
367
  ctx;
368
368
  render;
@@ -421,7 +421,7 @@ class Lt extends W {
421
421
  t.textBaseline = "alphabetic";
422
422
  const L = t.measureText(w).fontBoundingBoxDescent * c;
423
423
  t.textBaseline = f;
424
- const S = t.measureText(w).fontBoundingBoxDescent * c, E = r * a, b = P + O + (v.length - 1) * E, I = x / 2 + 2 / d, k = U + I * 2, G = b + I * 2, N = Math.max(1, Math.ceil(k * d)), F = Math.max(1, Math.ceil(G * d)), V = N / d;
424
+ const S = t.measureText(w).fontBoundingBoxDescent * c, E = r * a, b = P + O + (v.length - 1) * E, I = x / 2 + 2 / d, W = U + I * 2, G = b + I * 2, N = Math.max(1, Math.ceil(W * d)), F = Math.max(1, Math.ceil(G * d)), V = N / d;
425
425
  (this.canvas.width !== N || this.canvas.height !== F) && (this.canvas.width = N, this.canvas.height = F), t.setTransform(d, 0, 0, -d, 0, F), t.clearRect(
426
426
  0,
427
427
  0,
@@ -617,10 +617,10 @@ function Dt(n, t, e, r, i = !1) {
617
617
  return n.uniformMatrix3x2fv(t, !1, r);
618
618
  // fallback: guess by value shape
619
619
  default:
620
- return Wt(n, t, r);
620
+ return kt(n, t, r);
621
621
  }
622
622
  }
623
- function Wt(n, t, e) {
623
+ function kt(n, t, e) {
624
624
  if (typeof e == "number")
625
625
  return n.uniform1f(t, e);
626
626
  const r = e;
@@ -1014,7 +1014,7 @@ void main(void) {\r
1014
1014
  \r
1015
1015
  // CUSTOM_CODE_CALL\r
1016
1016
  }\r
1017
- `, j = 48, kt = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
1017
+ `, j = 48, Wt = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
1018
1018
  class dt extends Rt {
1019
1019
  instanceBuffer;
1020
1020
  quadBuffer;
@@ -1028,7 +1028,7 @@ class dt extends Rt {
1028
1028
  createBuffer() {
1029
1029
  const t = this.gl;
1030
1030
  this.quadBuffer = new lt(t, C.Float32, t.ARRAY_BUFFER, t.STATIC_DRAW), this.quadBuffer.bindBuffer();
1031
- for (const e of kt) this.quadBuffer.pushFloat32(e);
1031
+ for (const e of Wt) this.quadBuffer.pushFloat32(e);
1032
1032
  this.quadBuffer.makeDirty(), this.quadBuffer.bufferData(), this.instanceBuffer = new lt(t, C.Uint32, t.ARRAY_BUFFER, t.DYNAMIC_DRAW);
1033
1033
  }
1034
1034
  createDefaultShader() {
@@ -1075,7 +1075,7 @@ class dt extends Rt {
1075
1075
  m / T.height
1076
1076
  ), S = this.instanceBuffer, E = S.usedElemNum;
1077
1077
  S.resize(12);
1078
- const b = S.float32, I = S.uint32, k = v ? U : w, G = v ? w : U, N = k + 2 * f, F = G + 2 * m, V = P - f, H = O - m, R = this.localSpriteMatrix;
1078
+ const b = S.float32, I = S.uint32, W = v ? U : w, G = v ? w : U, N = W + 2 * f, F = G + 2 * m, V = P - f, H = O - m, R = this.localSpriteMatrix;
1079
1079
  v ? (R[0] = 0, R[1] = y ? F : -F, R[2] = x ? -N : N, R[3] = 0, R[4] = V + (x ? N : 0), R[5] = H + (y ? 0 : F)) : (R[0] = x ? -N : N, R[1] = 0, R[2] = 0, R[3] = y ? -F : F, R[4] = V + (x ? N : 0), R[5] = H + (y ? F : 0));
1080
1080
  const A = this.worldSpriteMatrix;
1081
1081
  A[0] = e * R[0] + i * R[1], A[1] = r * R[0] + s * R[1], A[2] = e * R[2] + i * R[3], A[3] = r * R[2] + s * R[3], A[4] = a + e * R[4] + i * R[5], A[5] = o + r * R[4] + s * R[5], b[E + 6] = h, b[E + 7] = c, b[E + 8] = u, b[E + 9] = l, I[E + 10] = d, I[E + 11] = L, this.rapid.roundPixels && (A[4] = Math.round(A[4]), A[5] = Math.round(A[5])), b[E] = A[0], b[E + 1] = A[2], b[E + 2] = A[4], b[E + 3] = A[1], b[E + 4] = A[3], b[E + 5] = A[5], S.usedElemNum += 12, S.makeDirty(), this.instanceCount++;
@@ -1119,6 +1119,10 @@ class Gt {
1119
1119
  return this.freeFlag.typedArray[this.freeFlag.usedElemNum++] = 1, t;
1120
1120
  }
1121
1121
  free(t) {
1122
+ if (typeof t != "number") {
1123
+ this.free(t.local), this.free(t.world);
1124
+ return;
1125
+ }
1122
1126
  !Number.isInteger(t) || t < 0 || t >= this.matrixCount || this.freeFlag.typedArray[t] !== 0 && (this.freeFlag.typedArray[t] = 0, this.freeMatrixStack.push(t));
1123
1127
  }
1124
1128
  reset() {
@@ -1257,7 +1261,7 @@ class Ht {
1257
1261
  save(t, e) {
1258
1262
  this.stack.push(this.curLocalM), this.stack.push(this.curWorldM);
1259
1263
  const r = this.curWorldM;
1260
- return this.curLocalM = e ?? this.matrix.alloc(), this.curWorldM = t ?? this.matrix.allocDirty(), t === void 0 && (e === void 0 ? this.matrix.copy(this.curWorldM, r) : this.matrix.multiplyOut(this.curWorldM, r, this.curLocalM)), this.currStack.push(this.curLocalM), this.currStack.push(this.curWorldM), { parent: r, world: this.curWorldM, local: this.curLocalM };
1264
+ return t !== void 0 && typeof t != "number" && ([t, e] = [t?.world, t?.local]), this.curLocalM = e ?? this.matrix.alloc(), this.curWorldM = t ?? this.matrix.allocDirty(), t === void 0 && (e === void 0 ? this.matrix.copy(this.curWorldM, r) : this.matrix.multiplyOut(this.curWorldM, r, this.curLocalM)), e === void 0 && this.currStack.push(this.curLocalM), t === void 0 && this.currStack.push(this.curWorldM), { parent: r, world: this.curWorldM, local: this.curLocalM };
1261
1265
  }
1262
1266
  restore() {
1263
1267
  this.stack.length != 0 && (this.curWorldM = this.stack.pop(), this.curLocalM = this.stack.pop());
@@ -1272,7 +1276,7 @@ class Ht {
1272
1276
  ), r = [];
1273
1277
  for (let i = 0; i < this.currStack.length; i++)
1274
1278
  e.has(this.currStack.get(i)) && r.push(i);
1275
- _.removeAtIndices(r, [this.currStack]);
1279
+ return _.removeAtIndices(r, [this.currStack]), t;
1276
1280
  }
1277
1281
  translate(t, e) {
1278
1282
  this.matrix.translate(this.curLocalM, t, e), this.matrix.translate(this.curWorldM, t, e);
@@ -1745,8 +1749,8 @@ const at = 10, xt = (n, t, e, r, i, s) => {
1745
1749
  const f = t[d], m = e[d].normal, x = e[d].miters, y = (d + 1) % t.length, v = t[y], T = e[y].normal, w = e[y].miters, U = f.add(m.multiply(x * i)), P = f.subtract(m.multiply(x * i)), O = v.add(T.multiply(w * i)), L = v.subtract(T.multiply(w * i)), S = f.distanceTo(v);
1746
1750
  let E = 0, b = 0;
1747
1751
  h === 0 ? (E = c / r, b = (c + S) / r) : (E = c / u, b = E + S / u);
1748
- const I = new p(E, 0), k = new p(E, 1), G = new p(b, 0), N = new p(b, 1);
1749
- s.push(U), a.push(I), s.push(P), a.push(k), s.push(O), a.push(G), s.push(O), a.push(G), s.push(L), a.push(N), s.push(P), a.push(k), c += S;
1752
+ const I = new p(E, 0), W = new p(E, 1), G = new p(b, 0), N = new p(b, 1);
1753
+ s.push(U), a.push(I), s.push(P), a.push(W), s.push(O), a.push(G), s.push(O), a.push(G), s.push(L), a.push(N), s.push(P), a.push(W), c += S;
1750
1754
  }
1751
1755
  if (o && !n.closed) {
1752
1756
  const d = t[0], f = e[0].normal, m = h === 0 ? r > 0 ? 1 / r : 0 : 1 / u, x = xt(d, f, i, !0, 0, m);
@@ -2032,7 +2036,7 @@ class le extends dt {
2032
2036
  drawParticles(t, e, r, i = 0, s = 4294967295, a, o = 1, h = 1, c = 0, u = 0, l = 1, d = 1, f = !1, m = !1, x = !1, y = 0.5, v = 0.5, T, w = !1, U) {
2033
2037
  if (!t.glTexture || a <= 0) return;
2034
2038
  this.texture && t !== this.texture && this.flush();
2035
- const P = typeof o == "number", O = typeof h == "number", L = typeof i == "number", S = typeof s == "number", E = typeof c == "number", b = !S && typeof s[0] == "number", I = t.uvW - t.uvX, k = t.uvH - t.uvY, G = I === 0 ? 0 : 1 / I, N = k === 0 ? 0 : 1 / k;
2039
+ const P = typeof o == "number", O = typeof h == "number", L = typeof i == "number", S = typeof s == "number", E = typeof c == "number", b = !S && typeof s[0] == "number", I = t.uvW - t.uvX, W = t.uvH - t.uvY, G = I === 0 ? 0 : 1 / I, N = W === 0 ? 0 : 1 / W;
2036
2040
  let F = t.rawWidth * (f ? -1 : 1);
2037
2041
  P && (F *= o);
2038
2042
  let V = t.rawHeight * (m ? -1 : 1);
@@ -2151,7 +2155,7 @@ const fe = {
2151
2155
  2: new p(0.5, 0.5)
2152
2156
  };
2153
2157
  class me {
2154
- constructor(t, e) {
2158
+ constructor(t, e = {}) {
2155
2159
  this.rapid = t, this.updateWindowOption(e);
2156
2160
  }
2157
2161
  viewLeft = 0;
@@ -2191,12 +2195,12 @@ class me {
2191
2195
  s.physicsHeight / e
2192
2196
  ), P = s.physicsWidth / U, O = s.physicsHeight / U, L = P - t, S = O - e;
2193
2197
  if (u = -L * T.x, l = t + L * (1 - T.x), f = -S * T.y, d = e + S * (1 - T.y), !w.x && L > 0 || !w.y && S > 0) {
2194
- const E = w.x && L > 0 ? u : 0, b = w.x && L > 0 ? l : t, I = w.y && S > 0 ? f : 0, k = w.y && S > 0 ? d : e;
2198
+ const E = w.x && L > 0 ? u : 0, b = w.x && L > 0 ? l : t, I = w.y && S > 0 ? f : 0, W = w.y && S > 0 ? d : e;
2195
2199
  this.scissorViewport = {
2196
2200
  x: E,
2197
2201
  y: I,
2198
2202
  width: b - E,
2199
- height: k - I
2203
+ height: W - I
2200
2204
  };
2201
2205
  }
2202
2206
  break;
@@ -2308,7 +2312,7 @@ class we {
2308
2312
  textureFilter;
2309
2313
  viewport;
2310
2314
  _filterRT = [null, null];
2311
- _filterInput = new W();
2315
+ _filterInput = new k();
2312
2316
  get height() {
2313
2317
  return this.logicHeight;
2314
2318
  }
@@ -2978,7 +2982,7 @@ export {
2978
2982
  we as Rapid,
2979
2983
  _t as RenderTexture,
2980
2984
  Lt as TextTexture,
2981
- W as Texture,
2985
+ k as Texture,
2982
2986
  it as TextureFilterMode,
2983
2987
  Ct as TextureManager,
2984
2988
  J as TextureWrapMode,
@@ -1,4 +1,4 @@
1
- (function(v,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(v=typeof globalThis<"u"?globalThis:v||self,p(v.RapidRender={}))})(this,(function(v){"use strict";class p{_r;_g;_b;_a;uint32;premultipliedUint32;static clampByte(t){return t<=0?0:t>=255?255:Math.round(t)}constructor(t,e,r,i=255){this._r=t,this._g=e,this._b=r,this._a=i,this.updateUint()}setClearColor(t,e=!0){const r=e?this.premultipliedUint32:this.uint32;t.clearColor((r&255)/255,(r>>>8&255)/255,(r>>>16&255)/255,(r>>>24)/255)}get r(){return this._r}set r(t){this._r=t,this.updateUint()}get g(){return this._g}set g(t){this._g=t,this.updateUint()}get b(){return this._b}set b(t){this._b=t,this.updateUint()}get a(){return this._a}set a(t){this._a=t,this.updateUint()}updateUint(){this.uint32=(this._a<<24|this._b<<16|this._g<<8|this._r)>>>0;const t=p.clampByte(this._a),e=p.clampByte(this._r*t/255),r=p.clampByte(this._g*t/255),i=p.clampByte(this._b*t/255);this.premultipliedUint32=(t<<24|i<<16|r<<8|e)>>>0}reset(){this._r=0,this._g=0,this._b=0,this._a=255,this.updateUint()}setRGBA(t,e,r,i){this._r=t,this._g=e,this._b=r,this._a=i,this.updateUint()}setHSL(t,e,r){t=(t%360+360)%360,e=Math.max(0,Math.min(100,e))/100,r=Math.max(0,Math.min(100,r))/100;const i=(1-Math.abs(2*r-1))*e,s=i*(1-Math.abs(t/60%2-1)),a=r-i/2;let o=0,h=0,c=0;return t<60?[o,h,c]=[i,s,0]:t<120?[o,h,c]=[s,i,0]:t<180?[o,h,c]=[0,i,s]:t<240?[o,h,c]=[0,s,i]:t<300?[o,h,c]=[s,0,i]:[o,h,c]=[i,0,s],this.setRGBA((o+a)*255,(h+a)*255,(c+a)*255,255),this}copy(t){this.setRGBA(t.r,t.g,t.b,t.a)}clone(){return new p(this._r,this._g,this._b,this._a)}toHexString(t=!0){const e=this.r.toString(16).padStart(2,"0"),r=this.g.toString(16).padStart(2,"0"),i=this.b.toString(16).padStart(2,"0"),s=this.a.toString(16).padStart(2,"0");return`#${e}${r}${i}${t?s:""}`}equals(t){return t.r===this.r&&t.g===this.g&&t.b===this.b&&t.a===this.a}static FromHSL(t,e,r){return new p(0,0,0).setHSL(t,e,r)}static FromRGB(t,e,r){return new p(t,e,r)}static fromNorm(t,e,r,i=1){return new p(Math.round(t*255),Math.round(e*255),Math.round(r*255),Math.round(i*255))}static packColor(t,e,r,i,s){const a=p.clampByte(i),o=s?a/255:1,h=p.clampByte(t*o),c=p.clampByte(e*o),u=p.clampByte(r*o);return(a<<24|u<<16|c<<8|h)>>>0}static fromHex(t){t.startsWith("#")&&(t=t.slice(1));const e=parseInt(t.slice(0,2),16),r=parseInt(t.slice(2,4),16),i=parseInt(t.slice(4,6),16);let s=255;return t.length>=8&&(s=parseInt(t.slice(6,8),16)),new p(e,r,i,s)}add(t){return new p(Math.min(this.r+t.r,255),Math.min(this.g+t.g,255),Math.min(this.b+t.b,255),Math.min(this.a+t.a,255))}subtract(t){return new p(this.r-t.r,this.g-t.g,this.b-t.b,this.a-t.a)}divide(t){return t instanceof p?new p(this.r/t.r,this.g/t.g,this.b/t.b,this.a/t.a):new p(this.r/t,this.g/t,this.b/t,this.a/t)}multiply(t){return t instanceof p?new p(this.r*t.r,this.g*t.g,this.b*t.b,this.a*t.a):new p(this.r*t,this.g*t,this.b*t,this.a*t)}clamp(){this._r=Math.max(0,Math.min(255,this._r)),this._g=Math.max(0,Math.min(255,this._g)),this._b=Math.max(0,Math.min(255,this._b)),this._a=Math.max(0,Math.min(255,this._a)),this.updateUint()}static Red=new p(255,0,0,255);static Green=new p(0,255,0,255);static Blue=new p(0,0,255,255);static Yellow=new p(255,255,0,255);static Purple=new p(128,0,128,255);static Orange=new p(255,165,0,255);static Pink=new p(255,192,203,255);static Gray=new p(128,128,128,255);static Brown=new p(139,69,19,255);static Cyan=new p(0,255,255,255);static Magenta=new p(255,0,255,255);static Lime=new p(192,255,0,255);static White=new p(255,255,255,255);static Black=new p(0,0,0,255);static Transparent=new p(0,0,0,0)}var q=(n=>(n[n.LINEAR=0]="LINEAR",n[n.NEAREST=1]="NEAREST",n))(q||{}),j=(n=>(n[n.REPEAT=0]="REPEAT",n[n.CLAMP=1]="CLAMP",n[n.MIRRORED_REPEAT=2]="MIRRORED_REPEAT",n))(j||{});class vt{render;cache=new Map;texture=new Set;constructor(t){this.render=t}addTexture(t){return this.texture.add(t),t}removeTexture(t){return this.texture.delete(t),t}async load(t,e){let r=this.cache.get(t);if(r)return this.addTexture(new W(r));try{const i=await this._fetchImage(t);return r=X.fromSource(this.render,i,e),r.uid=t,this.cache.set(t,r),this.addTexture(new W(r))}catch(i){throw console.error(`[TextureManager] Failed to load: ${t}`,i),i}}create(t,e){if(e?.key&&this.cache.has(e.key))return this.addTexture(new W(this.cache.get(e.key)));const r=X.fromSource(this.render,t,e);return e?.key&&(r.uid=e.key,this.cache.set(e.key,r)),this.addTexture(new W(r))}createRenderTexture(t){return this.addTexture(new yt(this.render,t))}createTextTexture(t){return this.addTexture(new Tt(this.render,t))}destroy(t,e=!1){let r,i;typeof t=="string"?(i=t,r=this.cache.get(i)):t instanceof W?(r=t.base,i=r?.uid,this.removeTexture(t),t.destroy()):(r=t,i=r.uid),r&&(r.refCount<=0||e)&&(r.destroy(this.render.gl),i&&this.cache.delete(i))}destroyAll(){for(const t of this.cache.values())t.destroy(this.render.gl);this.cache.clear()}_fetchImage(t){return new Promise((e,r)=>{const i=new Image;i.crossOrigin="anonymous",i.onload=()=>e(i),i.onerror=()=>r(new Error(`Failed to load image resource: ${t}`)),i.src=t})}}class X{glTexture=null;width;height;uid;refCount=0;constructor(t,e,r){this.glTexture=t,this.width=e,this.height=r}static fromSource(t,e,r={}){const i=st(t,e,r);return new X(i,e.width,e.height)}updateSource(t,e,r={}){this.glTexture&&(t.bindTexture(t.TEXTURE_2D,this.glTexture),r.textureFilter!==void 0&&ct(t,r.textureFilter),r.wrap!==void 0&&ht(t,r.wrap),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,1),t.pixelStorei(t.UNPACK_ALIGNMENT,1),r.premultipliedAlpha!==void 0&&t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,r.premultipliedAlpha),this.width===e.width&&this.height===e.height?t.texSubImage2D(t.TEXTURE_2D,0,0,0,t.RGBA,t.UNSIGNED_BYTE,e):(t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),this.width=e.width,this.height=e.height),r.premultipliedAlpha!==void 0&&t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1))}setFilterMode(t,e){this.glTexture&&(t.bindTexture(t.TEXTURE_2D,this.glTexture),ct(t,e),t.bindTexture(t.TEXTURE_2D,null))}setWrapMode(t,e){this.glTexture&&(t.bindTexture(t.TEXTURE_2D,this.glTexture),ht(t,e),t.bindTexture(t.TEXTURE_2D,null))}destroy(t){this.glTexture&&(t.deleteTexture(this.glTexture),this.glTexture=null)}}class W{base;uvX=0;uvY=0;uvW=1;uvH=1;rawWidth=0;rawHeight=0;offsetX=0;offsetY=0;scale=1;isAtlas=!1;flipY=!1;isRotated=!1;glTexture=null;get width(){return this.isRotated?this.rawHeight:this.rawWidth}get height(){return this.isRotated?this.rawWidth:this.rawHeight}_px=0;_py=0;constructor(t){t&&this.setBase(t)}updateResolution(){}setBase(t){return this.base===t?this:(this.base&&this.base.refCount--,this.base=t,this.base.refCount++,this.setRegion(0,0,t.width,t.height),this.glTexture=t.glTexture,this)}setRegion(t,e,r,i){return this.base?(this._px=t,this._py=e,this.isAtlas=t!==0||e!==0||r!==this.base.width||i!==this.base.height,this.uvX=t/this.base.width,this.uvY=e/this.base.height,this.uvW=this.uvX+r/this.base.width,this.uvH=this.uvY+i/this.base.height,this.rawWidth=r*this.scale,this.rawHeight=i*this.scale,this):this}getSubTexture(t,e,r,i){if(!this.base)return new W;const s=this.clone(),a=this._px,o=this._py;return s.setRegion(a+t,o+e,r,i),s}clone(t){const e=t??new W(this.base);return t&&this.base&&t.setBase(this.base),e.scale=this.scale,e.uvX=this.uvX,e.uvY=this.uvY,e.uvW=this.uvW,e.uvH=this.uvH,e.rawWidth=this.rawWidth,e.rawHeight=this.rawHeight,e.offsetX=this.offsetX,e.offsetY=this.offsetY,e.flipY=this.flipY,e.isRotated=this.isRotated,e.isAtlas=this.isAtlas,e._px=this._px,e._py=this._py,e}splitGrid(t,e,r,i,s=0){if(!this.base)return[];const a=[],o=this.rawWidth,h=this.rawHeight,c=Math.max(0,s),u=t+c,l=e+c,d=r??Math.floor((o+c)/u),f=i??Math.floor((h+c)/l);for(let m=0;m<f;m++)for(let x=0;x<d;x++)a.push(this.getSubTexture(x*u,m*l,t,e));return a}static fromImageSource(t,e,r={}){const i=st(t,e,r);return new W(new X(i,e.width,e.height))}destroy(){this.base&&(this.base.refCount--,this.base=void 0),this.glTexture=null}}class yt extends W{framebuffer;renderbuffer;gl;premultipliedAlpha;clearColor;_allocW=0;_allocH=0;constructor(t,e){super(),this.gl=t.gl,this.premultipliedAlpha=t.premultipliedAlpha,this.clearColor=e.clearColor??p.Black;const r=Math.max(Math.round(e.width),1),i=Math.max(Math.round(e.height),1),a=st(t,{width:r,height:i},{...e,onlySize:!0});if(this.setBase(new X(a,r,i)),this.framebuffer=this.gl.createFramebuffer(),this.renderbuffer=this.gl.createRenderbuffer(),!this.framebuffer||!this.renderbuffer)throw new Error("Failed to create Framebuffer or Renderbuffer");this.resize(r,i,!0)}resize(t,e,r=!1){t=Math.max(Math.round(t),1),e=Math.max(Math.round(e),1);const i=this.rawWidth===t&&this.rawHeight===e;if(!r&&i)return;const s=this.gl;(r||t>this._allocW||e>this._allocH)&&this.base&&(this._allocW=Math.max(this._allocW,t),this._allocH=Math.max(this._allocH,e),this.base.width=this._allocW,this.base.height=this._allocH,s.bindTexture(s.TEXTURE_2D,this.base.glTexture),s.texImage2D(s.TEXTURE_2D,0,s.RGBA,this._allocW,this._allocH,0,s.RGBA,s.UNSIGNED_BYTE,null),s.bindRenderbuffer(s.RENDERBUFFER,this.renderbuffer),s.renderbufferStorage(s.RENDERBUFFER,s.STENCIL_INDEX8,this._allocW,this._allocH),s.bindFramebuffer(s.FRAMEBUFFER,this.framebuffer),s.framebufferTexture2D(s.FRAMEBUFFER,s.COLOR_ATTACHMENT0,s.TEXTURE_2D,this.base.glTexture,0),s.framebufferRenderbuffer(s.FRAMEBUFFER,s.STENCIL_ATTACHMENT,s.RENDERBUFFER,this.renderbuffer),s.bindFramebuffer(s.FRAMEBUFFER,null),s.bindRenderbuffer(s.RENDERBUFFER,null),s.bindTexture(s.TEXTURE_2D,null)),this.rawWidth=t,this.rawHeight=e,this.uvX=0,this.uvW=t/this._allocW,this.uvY=0,this.uvH=e/this._allocH}activate(t=!1){if(!this.framebuffer)return;const e=this.gl;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer),e.viewport(0,0,this.rawWidth,this.rawHeight),t&&this.clear()}clear(t){if(!this.framebuffer)return;const e=this.gl,r=t??this.clearColor;r&&(r.setClearColor(e,this.premultipliedAlpha),e.clear(e.COLOR_BUFFER_BIT|e.STENCIL_BUFFER_BIT))}deactivate(){const t=this.gl;t.bindFramebuffer(t.FRAMEBUFFER,null)}GetPixels(t=0,e=0,r=this.rawWidth,i=this.rawHeight){if(!this.framebuffer)return new Uint8Array(0);const s=Math.floor(t),a=Math.floor(e),o=Math.floor(r),h=Math.floor(i);if(o<=0||h<=0)return new Uint8Array(0);if(s<0||a<0||s>=this.rawWidth||a>=this.rawHeight)return new Uint8Array(0);const c=Math.min(o,this.rawWidth-s),u=Math.min(h,this.rawHeight-a),l=this.gl,d=l.getParameter(l.FRAMEBUFFER_BINDING);l.bindFramebuffer(l.FRAMEBUFFER,this.framebuffer);const f=new Uint8Array(c*u*4);return l.readPixels(s,a,c,u,l.RGBA,l.UNSIGNED_BYTE,f),l.bindFramebuffer(l.FRAMEBUFFER,d),f}GetColorAt(t,e){const r=this.GetPixels(t,e,1,1);return r.length<4?new p(0,0,0,0):new p(r[0],r[1],r[2],r[3])}destroy(){super.destroy(),this.framebuffer&&this.gl.deleteFramebuffer(this.framebuffer),this.renderbuffer&&this.gl.deleteRenderbuffer(this.renderbuffer),this.base?.destroy(this.gl)}}const jt={fontFamily:"Arial",fontSize:24,fontWeight:"normal",fill:"#000000",strokeThickness:0,align:"left",lineHeight:1};class Tt extends W{canvas;ctx;render;_text;_style;options;resolution=1;constructor(t,e){super(),this.render=t,this._style={...jt,...e},this._text=e?.text??"",this.options={premultipliedAlpha:t.premultipliedAlpha,...e,textureFilter:1},this.canvas=document.createElement("canvas");const r=this.canvas.getContext("2d",{willReadFrequently:!0});if(!r)throw new Error("Failed to get 2d context for TextTexture");this.ctx=r,this.canvas.width=1,this.canvas.height=1;const i=st(t,this.canvas,this.options);this.setBase(new X(i,1,1)),this.updateResolution(),this.update()}get text(){return this._text}set text(t){this._text!==t&&(this._text=t,this.update())}get style(){return this._style}set style(t){this._style={...this._style,...t},this.update()}updateOffset(t,e){switch(this._style.align){case"center":return t/2;case"right":return t-e;default:return e}}updateResolution(){let t=1;t*=this.render.viewport.resolution,t!=this.resolution&&(this.resolution=t,this.update())}update(){const t=this.ctx,e=this.style,r=e.fontSize,i=e.fontWeight,s=e.fontFamily,a=e.lineHeight,h=Math.max(r,32),c=r/h,u=`${i} ${r}px ${s}`,l=`${i} ${h}px ${s}`,d=this.resolution,f=e.baseline??"top",m=e.align??"left",x=e.strokeThickness??0,T=x>0,y=this._text.split(`
1
+ (function(v,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(v=typeof globalThis<"u"?globalThis:v||self,p(v.RapidRender={}))})(this,(function(v){"use strict";class p{_r;_g;_b;_a;uint32;premultipliedUint32;static clampByte(t){return t<=0?0:t>=255?255:Math.round(t)}constructor(t,e,r,i=255){this._r=t,this._g=e,this._b=r,this._a=i,this.updateUint()}setClearColor(t,e=!0){const r=e?this.premultipliedUint32:this.uint32;t.clearColor((r&255)/255,(r>>>8&255)/255,(r>>>16&255)/255,(r>>>24)/255)}get r(){return this._r}set r(t){this._r=t,this.updateUint()}get g(){return this._g}set g(t){this._g=t,this.updateUint()}get b(){return this._b}set b(t){this._b=t,this.updateUint()}get a(){return this._a}set a(t){this._a=t,this.updateUint()}updateUint(){this.uint32=(this._a<<24|this._b<<16|this._g<<8|this._r)>>>0;const t=p.clampByte(this._a),e=p.clampByte(this._r*t/255),r=p.clampByte(this._g*t/255),i=p.clampByte(this._b*t/255);this.premultipliedUint32=(t<<24|i<<16|r<<8|e)>>>0}reset(){this._r=0,this._g=0,this._b=0,this._a=255,this.updateUint()}setRGBA(t,e,r,i){this._r=t,this._g=e,this._b=r,this._a=i,this.updateUint()}setHSL(t,e,r){t=(t%360+360)%360,e=Math.max(0,Math.min(100,e))/100,r=Math.max(0,Math.min(100,r))/100;const i=(1-Math.abs(2*r-1))*e,s=i*(1-Math.abs(t/60%2-1)),a=r-i/2;let o=0,h=0,c=0;return t<60?[o,h,c]=[i,s,0]:t<120?[o,h,c]=[s,i,0]:t<180?[o,h,c]=[0,i,s]:t<240?[o,h,c]=[0,s,i]:t<300?[o,h,c]=[s,0,i]:[o,h,c]=[i,0,s],this.setRGBA((o+a)*255,(h+a)*255,(c+a)*255,255),this}copy(t){this.setRGBA(t.r,t.g,t.b,t.a)}clone(){return new p(this._r,this._g,this._b,this._a)}toHexString(t=!0){const e=this.r.toString(16).padStart(2,"0"),r=this.g.toString(16).padStart(2,"0"),i=this.b.toString(16).padStart(2,"0"),s=this.a.toString(16).padStart(2,"0");return`#${e}${r}${i}${t?s:""}`}equals(t){return t.r===this.r&&t.g===this.g&&t.b===this.b&&t.a===this.a}static FromHSL(t,e,r){return new p(0,0,0).setHSL(t,e,r)}static FromRGB(t,e,r){return new p(t,e,r)}static fromNorm(t,e,r,i=1){return new p(Math.round(t*255),Math.round(e*255),Math.round(r*255),Math.round(i*255))}static packColor(t,e,r,i,s){const a=p.clampByte(i),o=s?a/255:1,h=p.clampByte(t*o),c=p.clampByte(e*o),u=p.clampByte(r*o);return(a<<24|u<<16|c<<8|h)>>>0}static fromHex(t){t.startsWith("#")&&(t=t.slice(1));const e=parseInt(t.slice(0,2),16),r=parseInt(t.slice(2,4),16),i=parseInt(t.slice(4,6),16);let s=255;return t.length>=8&&(s=parseInt(t.slice(6,8),16)),new p(e,r,i,s)}add(t){return new p(Math.min(this.r+t.r,255),Math.min(this.g+t.g,255),Math.min(this.b+t.b,255),Math.min(this.a+t.a,255))}subtract(t){return new p(this.r-t.r,this.g-t.g,this.b-t.b,this.a-t.a)}divide(t){return t instanceof p?new p(this.r/t.r,this.g/t.g,this.b/t.b,this.a/t.a):new p(this.r/t,this.g/t,this.b/t,this.a/t)}multiply(t){return t instanceof p?new p(this.r*t.r,this.g*t.g,this.b*t.b,this.a*t.a):new p(this.r*t,this.g*t,this.b*t,this.a*t)}clamp(){this._r=Math.max(0,Math.min(255,this._r)),this._g=Math.max(0,Math.min(255,this._g)),this._b=Math.max(0,Math.min(255,this._b)),this._a=Math.max(0,Math.min(255,this._a)),this.updateUint()}static Red=new p(255,0,0,255);static Green=new p(0,255,0,255);static Blue=new p(0,0,255,255);static Yellow=new p(255,255,0,255);static Purple=new p(128,0,128,255);static Orange=new p(255,165,0,255);static Pink=new p(255,192,203,255);static Gray=new p(128,128,128,255);static Brown=new p(139,69,19,255);static Cyan=new p(0,255,255,255);static Magenta=new p(255,0,255,255);static Lime=new p(192,255,0,255);static White=new p(255,255,255,255);static Black=new p(0,0,0,255);static Transparent=new p(0,0,0,0)}var q=(n=>(n[n.LINEAR=0]="LINEAR",n[n.NEAREST=1]="NEAREST",n))(q||{}),j=(n=>(n[n.REPEAT=0]="REPEAT",n[n.CLAMP=1]="CLAMP",n[n.MIRRORED_REPEAT=2]="MIRRORED_REPEAT",n))(j||{});class vt{render;cache=new Map;texture=new Set;constructor(t){this.render=t}addTexture(t){return this.texture.add(t),t}removeTexture(t){return this.texture.delete(t),t}async load(t,e){let r=this.cache.get(t);if(r)return this.addTexture(new k(r));try{const i=await this._fetchImage(t);return r=X.fromSource(this.render,i,e),r.uid=t,this.cache.set(t,r),this.addTexture(new k(r))}catch(i){throw console.error(`[TextureManager] Failed to load: ${t}`,i),i}}create(t,e){if(e?.key&&this.cache.has(e.key))return this.addTexture(new k(this.cache.get(e.key)));const r=X.fromSource(this.render,t,e);return e?.key&&(r.uid=e.key,this.cache.set(e.key,r)),this.addTexture(new k(r))}createRenderTexture(t){return this.addTexture(new yt(this.render,t))}createTextTexture(t){return this.addTexture(new Tt(this.render,t))}destroy(t,e=!1){let r,i;typeof t=="string"?(i=t,r=this.cache.get(i)):t instanceof k?(r=t.base,i=r?.uid,this.removeTexture(t),t.destroy()):(r=t,i=r.uid),r&&(r.refCount<=0||e)&&(r.destroy(this.render.gl),i&&this.cache.delete(i))}destroyAll(){for(const t of this.cache.values())t.destroy(this.render.gl);this.cache.clear()}_fetchImage(t){return new Promise((e,r)=>{const i=new Image;i.crossOrigin="anonymous",i.onload=()=>e(i),i.onerror=()=>r(new Error(`Failed to load image resource: ${t}`)),i.src=t})}}class X{glTexture=null;width;height;uid;refCount=0;constructor(t,e,r){this.glTexture=t,this.width=e,this.height=r}static fromSource(t,e,r={}){const i=st(t,e,r);return new X(i,e.width,e.height)}updateSource(t,e,r={}){this.glTexture&&(t.bindTexture(t.TEXTURE_2D,this.glTexture),r.textureFilter!==void 0&&ct(t,r.textureFilter),r.wrap!==void 0&&ht(t,r.wrap),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,1),t.pixelStorei(t.UNPACK_ALIGNMENT,1),r.premultipliedAlpha!==void 0&&t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,r.premultipliedAlpha),this.width===e.width&&this.height===e.height?t.texSubImage2D(t.TEXTURE_2D,0,0,0,t.RGBA,t.UNSIGNED_BYTE,e):(t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),this.width=e.width,this.height=e.height),r.premultipliedAlpha!==void 0&&t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1))}setFilterMode(t,e){this.glTexture&&(t.bindTexture(t.TEXTURE_2D,this.glTexture),ct(t,e),t.bindTexture(t.TEXTURE_2D,null))}setWrapMode(t,e){this.glTexture&&(t.bindTexture(t.TEXTURE_2D,this.glTexture),ht(t,e),t.bindTexture(t.TEXTURE_2D,null))}destroy(t){this.glTexture&&(t.deleteTexture(this.glTexture),this.glTexture=null)}}class k{base;uvX=0;uvY=0;uvW=1;uvH=1;rawWidth=0;rawHeight=0;offsetX=0;offsetY=0;scale=1;isAtlas=!1;flipY=!1;isRotated=!1;glTexture=null;get width(){return this.isRotated?this.rawHeight:this.rawWidth}get height(){return this.isRotated?this.rawWidth:this.rawHeight}_px=0;_py=0;constructor(t){t&&this.setBase(t)}updateResolution(){}setBase(t){return this.base===t?this:(this.base&&this.base.refCount--,this.base=t,this.base.refCount++,this.setRegion(0,0,t.width,t.height),this.glTexture=t.glTexture,this)}setRegion(t,e,r,i){return this.base?(this._px=t,this._py=e,this.isAtlas=t!==0||e!==0||r!==this.base.width||i!==this.base.height,this.uvX=t/this.base.width,this.uvY=e/this.base.height,this.uvW=this.uvX+r/this.base.width,this.uvH=this.uvY+i/this.base.height,this.rawWidth=r*this.scale,this.rawHeight=i*this.scale,this):this}getSubTexture(t,e,r,i){if(!this.base)return new k;const s=this.clone(),a=this._px,o=this._py;return s.setRegion(a+t,o+e,r,i),s}clone(t){const e=t??new k(this.base);return t&&this.base&&t.setBase(this.base),e.scale=this.scale,e.uvX=this.uvX,e.uvY=this.uvY,e.uvW=this.uvW,e.uvH=this.uvH,e.rawWidth=this.rawWidth,e.rawHeight=this.rawHeight,e.offsetX=this.offsetX,e.offsetY=this.offsetY,e.flipY=this.flipY,e.isRotated=this.isRotated,e.isAtlas=this.isAtlas,e._px=this._px,e._py=this._py,e}splitGrid(t,e,r,i,s=0){if(!this.base)return[];const a=[],o=this.rawWidth,h=this.rawHeight,c=Math.max(0,s),u=t+c,l=e+c,d=r??Math.floor((o+c)/u),f=i??Math.floor((h+c)/l);for(let m=0;m<f;m++)for(let x=0;x<d;x++)a.push(this.getSubTexture(x*u,m*l,t,e));return a}static fromImageSource(t,e,r={}){const i=st(t,e,r);return new k(new X(i,e.width,e.height))}destroy(){this.base&&(this.base.refCount--,this.base=void 0),this.glTexture=null}}class yt extends k{framebuffer;renderbuffer;gl;premultipliedAlpha;clearColor;_allocW=0;_allocH=0;constructor(t,e){super(),this.gl=t.gl,this.premultipliedAlpha=t.premultipliedAlpha,this.clearColor=e.clearColor??p.Black;const r=Math.max(Math.round(e.width),1),i=Math.max(Math.round(e.height),1),a=st(t,{width:r,height:i},{...e,onlySize:!0});if(this.setBase(new X(a,r,i)),this.framebuffer=this.gl.createFramebuffer(),this.renderbuffer=this.gl.createRenderbuffer(),!this.framebuffer||!this.renderbuffer)throw new Error("Failed to create Framebuffer or Renderbuffer");this.resize(r,i,!0)}resize(t,e,r=!1){t=Math.max(Math.round(t),1),e=Math.max(Math.round(e),1);const i=this.rawWidth===t&&this.rawHeight===e;if(!r&&i)return;const s=this.gl;(r||t>this._allocW||e>this._allocH)&&this.base&&(this._allocW=Math.max(this._allocW,t),this._allocH=Math.max(this._allocH,e),this.base.width=this._allocW,this.base.height=this._allocH,s.bindTexture(s.TEXTURE_2D,this.base.glTexture),s.texImage2D(s.TEXTURE_2D,0,s.RGBA,this._allocW,this._allocH,0,s.RGBA,s.UNSIGNED_BYTE,null),s.bindRenderbuffer(s.RENDERBUFFER,this.renderbuffer),s.renderbufferStorage(s.RENDERBUFFER,s.STENCIL_INDEX8,this._allocW,this._allocH),s.bindFramebuffer(s.FRAMEBUFFER,this.framebuffer),s.framebufferTexture2D(s.FRAMEBUFFER,s.COLOR_ATTACHMENT0,s.TEXTURE_2D,this.base.glTexture,0),s.framebufferRenderbuffer(s.FRAMEBUFFER,s.STENCIL_ATTACHMENT,s.RENDERBUFFER,this.renderbuffer),s.bindFramebuffer(s.FRAMEBUFFER,null),s.bindRenderbuffer(s.RENDERBUFFER,null),s.bindTexture(s.TEXTURE_2D,null)),this.rawWidth=t,this.rawHeight=e,this.uvX=0,this.uvW=t/this._allocW,this.uvY=0,this.uvH=e/this._allocH}activate(t=!1){if(!this.framebuffer)return;const e=this.gl;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer),e.viewport(0,0,this.rawWidth,this.rawHeight),t&&this.clear()}clear(t){if(!this.framebuffer)return;const e=this.gl,r=t??this.clearColor;r&&(r.setClearColor(e,this.premultipliedAlpha),e.clear(e.COLOR_BUFFER_BIT|e.STENCIL_BUFFER_BIT))}deactivate(){const t=this.gl;t.bindFramebuffer(t.FRAMEBUFFER,null)}GetPixels(t=0,e=0,r=this.rawWidth,i=this.rawHeight){if(!this.framebuffer)return new Uint8Array(0);const s=Math.floor(t),a=Math.floor(e),o=Math.floor(r),h=Math.floor(i);if(o<=0||h<=0)return new Uint8Array(0);if(s<0||a<0||s>=this.rawWidth||a>=this.rawHeight)return new Uint8Array(0);const c=Math.min(o,this.rawWidth-s),u=Math.min(h,this.rawHeight-a),l=this.gl,d=l.getParameter(l.FRAMEBUFFER_BINDING);l.bindFramebuffer(l.FRAMEBUFFER,this.framebuffer);const f=new Uint8Array(c*u*4);return l.readPixels(s,a,c,u,l.RGBA,l.UNSIGNED_BYTE,f),l.bindFramebuffer(l.FRAMEBUFFER,d),f}GetColorAt(t,e){const r=this.GetPixels(t,e,1,1);return r.length<4?new p(0,0,0,0):new p(r[0],r[1],r[2],r[3])}destroy(){super.destroy(),this.framebuffer&&this.gl.deleteFramebuffer(this.framebuffer),this.renderbuffer&&this.gl.deleteRenderbuffer(this.renderbuffer),this.base?.destroy(this.gl)}}const jt={fontFamily:"Arial",fontSize:24,fontWeight:"normal",fill:"#000000",strokeThickness:0,align:"left",lineHeight:1};class Tt extends k{canvas;ctx;render;_text;_style;options;resolution=1;constructor(t,e){super(),this.render=t,this._style={...jt,...e},this._text=e?.text??"",this.options={premultipliedAlpha:t.premultipliedAlpha,...e,textureFilter:1},this.canvas=document.createElement("canvas");const r=this.canvas.getContext("2d",{willReadFrequently:!0});if(!r)throw new Error("Failed to get 2d context for TextTexture");this.ctx=r,this.canvas.width=1,this.canvas.height=1;const i=st(t,this.canvas,this.options);this.setBase(new X(i,1,1)),this.updateResolution(),this.update()}get text(){return this._text}set text(t){this._text!==t&&(this._text=t,this.update())}get style(){return this._style}set style(t){this._style={...this._style,...t},this.update()}updateOffset(t,e){switch(this._style.align){case"center":return t/2;case"right":return t-e;default:return e}}updateResolution(){let t=1;t*=this.render.viewport.resolution,t!=this.resolution&&(this.resolution=t,this.update())}update(){const t=this.ctx,e=this.style,r=e.fontSize,i=e.fontWeight,s=e.fontFamily,a=e.lineHeight,h=Math.max(r,32),c=r/h,u=`${i} ${r}px ${s}`,l=`${i} ${h}px ${s}`,d=this.resolution,f=e.baseline??"top",m=e.align??"left",x=e.strokeThickness??0,T=x>0,y=this._text.split(`
2
2
  `),w="国g",R=y[0]||w;t.font=l,t.textBaseline="alphabetic",t.textAlign="left";let C=0,L=0,B=0;for(const D of y){const $=t.measureText(D||w);C=Math.max(C,D?$.width*c:0),D==y.at(0)&&(L=$.actualBoundingBoxAscent*c),D==y.at(-1)&&(B=$.actualBoundingBoxDescent*c)}t.textBaseline="alphabetic";const N=t.measureText(R).fontBoundingBoxDescent*c;t.textBaseline=f;const A=t.measureText(R).fontBoundingBoxDescent*c,M=r*a,U=L+B+(y.length-1)*M,F=x/2+2/d,G=C+F*2,H=U+F*2,I=Math.max(1,Math.ceil(G*d)),O=Math.max(1,Math.ceil(H*d)),Y=I/d;(this.canvas.width!==I||this.canvas.height!==O)&&(this.canvas.width=I,this.canvas.height=O),t.setTransform(d,0,0,-d,0,O),t.clearRect(0,0,I/d,O/d),t.font=u,t.textBaseline="alphabetic",t.textAlign=m;const V=this.updateOffset(Y,F);T&&(t.lineWidth=x,t.strokeStyle=e.stroke??"#000000",t.lineJoin="round"),e.fill&&(t.fillStyle=e.fill);let b=F+L;for(const D of y)T&&t.strokeText(D,V,b),e.fill&&t.fillText(D,V,b),b+=M;const it=A-N;this.scale=1/this.resolution,this.offsetX=-V,this.offsetY=-F-L+it,this.base?.updateSource(this.render.gl,this.canvas,this.options),this.setRegion(0,0,I,O)}}const Kt=(n,t=!1,e=!0)=>{const r=n.getContext("webgl2",{stencil:!0,antialias:t,premultipliedAlpha:e});if(!r)throw new Error("WebGL2 is not supported in this browser.");return r},wt=(n,t,e)=>{const r=n.createShader(e);if(!r)throw new Error("Unable to create webgl shader");if(n.shaderSource(r,t),n.compileShader(r),!n.getShaderParameter(r,n.COMPILE_STATUS)){const s=n.getShaderInfoLog(r);throw console.error("Shader compilation failed:",s),new Error("Unable to compile shader: "+s+t)}return r},qt=(n,t,e)=>{var r=n.createProgram(),i=wt(n,t,35633),s=wt(n,e,35632);if(!r)throw new Error("Unable to create program shader");if(n.attachShader(r,i),n.attachShader(r,s),n.linkProgram(r),!n.getProgramParameter(r,n.LINK_STATUS)){const o=n.getProgramInfoLog(r);throw new Error("Unable to link shader program: "+o)}return r};function ht(n,t){const e={[j.CLAMP]:n.CLAMP_TO_EDGE,[j.REPEAT]:n.REPEAT,[j.MIRRORED_REPEAT]:n.MIRRORED_REPEAT}[t]||n.CLAMP_TO_EDGE;n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,e),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,e)}function ct(n,t){const e={[q.LINEAR]:n.LINEAR,[q.NEAREST]:n.NEAREST}[t]??n.NEAREST;n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,e),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,e)}function st(n,t,e){const r=n.gl,i=r.createTexture();if(!i)throw new Error("Unable to create WebGL texture");if(r.bindTexture(r.TEXTURE_2D,i),r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,0),r.pixelStorei(r.UNPACK_ALIGNMENT,1),ht(r,e.wrap??j.CLAMP),ct(r,e.textureFilter??n.textureFilter),e.onlySize){const s=t;r.texImage2D(r.TEXTURE_2D,0,r.RGBA,s.width,s.height,0,r.RGBA,r.UNSIGNED_BYTE,null)}else{const s=e.premultipliedAlpha??n.premultipliedAlpha;s&&r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),r.texImage2D(r.TEXTURE_2D,0,r.RGBA,r.RGBA,r.UNSIGNED_BYTE,t),s&&r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1)}return r.bindTexture(r.TEXTURE_2D,null),i}function Z(n,t,e="vTextureId",r="uv",i="return"){if(n.includes("%TEXTURE_NUM%")&&(n=n.replaceAll("%TEXTURE_NUM%",t.toString())),n.includes("%GET_COLOR%")){let s="";for(let a=0;a<t;a++)a==0?s+=`if(${e} == ${a})`:a==t-1?s+="else":s+=`else if(${e} == ${a})`,s+=`{${i} texture(uTextures[${a}], ${r});}`;n=n.replaceAll("%GET_COLOR%",s)}return n}const Zt=5126,ut=5121;function Qt(n,t,e){n.vertexAttribDivisor(t,e)}function Et(n,t,e,r,i){n.drawArraysInstanced(t,e,r,i)}let Jt=0;class lt{program;attributeLoc={};uniformLoc={};isCustom=!1;padding=0;uniformType={};uniformIsArray={};gl;shaderId=Jt++;vao;constructor(t,e,r,i){this.gl=t,this.program=qt(t,e,r),this.parseShader(e),this.parseShader(r),this.vao=t.createVertexArray(),i&&this.setAttributes(i)}use(){this.gl.useProgram(this.program)}bindVAO(){this.gl.bindVertexArray(this.vao)}unbindVAO(){this.gl.bindVertexArray(null)}setUniform(t,e){const r=this.uniformLoc[t];if(r===void 0)return;const i=this.uniformType[t],s=this.uniformIsArray[t];te(this.gl,r,i,e,s)}setUniforms(t){for(const e in t)this.setUniform(e,t[e])}setAttribute(t){const e=this.attributeLoc[t.name];if(e===void 0)return;const r=this.gl;r.vertexAttribPointer(e,t.size,t.type??Zt,t.normalized??!1,t.stride,t.offset??0),r.enableVertexAttribArray(e),Qt(r,e,t.divisor??0)}setAttributes(t){for(const e of t)this.setAttribute(e)}destroy(){this.gl.deleteProgram(this.program)}parseShader(t){const e=this.gl,r=t.match(/(?:in|attribute)\s+\w+\s+\w+/g);if(r)for(const s of r){const o=s.split(/\s+/)[2],h=e.getAttribLocation(this.program,o);h!==-1&&(this.attributeLoc[o]=h)}const i=t.matchAll(/uniform\s+(?:(?:lowp|mediump|highp)\s+)?(\w+)\s+(\w+)(\s*\[\s*\d+\s*\])?/g);for(const s of i){const a=s[1],o=s[2],h=e.getUniformLocation(this.program,o);h!==null&&(this.uniformLoc[o]=h,this.uniformType[o]=a,this.uniformIsArray[o]=s[3]!==void 0)}}}function te(n,t,e,r,i=!1){switch(e){case"float":return i?n.uniform1fv(t,r):n.uniform1f(t,r);case"int":case"bool":case"sampler2D":case"samplerCube":return i?n.uniform1iv(t,r):n.uniform1i(t,r);case"vec2":return n.uniform2fv(t,r);case"vec3":return n.uniform3fv(t,r);case"vec4":return n.uniform4fv(t,r);case"ivec2":case"bvec2":return n.uniform2iv(t,r);case"ivec3":case"bvec3":return n.uniform3iv(t,r);case"ivec4":case"bvec4":return n.uniform4iv(t,r);case"mat2":return n.uniformMatrix2fv(t,!1,r);case"mat3":return n.uniformMatrix3fv(t,!1,r);case"mat4":return n.uniformMatrix4fv(t,!1,r);case"mat3x2":return n.uniformMatrix3x2fv(t,!1,r);default:return ee(n,t,r)}}function ee(n,t,e){if(typeof e=="number")return n.uniform1f(t,e);const r=e;switch(r.length){case 2:return n.uniform2fv(t,r);case 3:return n.uniform3fv(t,r);case 4:return n.uniform4fv(t,r);case 9:return n.uniformMatrix3fv(t,!1,r);case 16:return n.uniformMatrix4fv(t,!1,r);default:return n.uniform1fv(t,r)}}class nt{vs;fs;glshader=new Map;uniforms={};uniformDirty=new Set;uniformTextures={};uniformArrayTexture={};usedTextureUnitNum=0;padding=0;rapid;prefix=[];constructor(t,e="",r="",i=0,s){this.vs=e,this.fs=r,this.rapid=t,this.uniforms=s??{},this.usedTextureUnitNum=i,this.beforePreCompile(),this.preCompile()}beforePreCompile(){}preCompile(){}setUniforms(t){this.rapid.flush();const e={},r={},i={};for(const[s,a]of Object.entries(t))a instanceof WebGLTexture?r[s]=a:Array.isArray(a)&&a[0]instanceof WebGLTexture?i[s]=a:e[s]=a;Object.assign(this.uniforms,e),Object.assign(this.uniformTextures,r),Object.assign(this.uniformArrayTexture,i);for(const s of this.glshader.keys())this.uniformDirty.add(s)}setPadding(t){this.padding=t;for(const e of this.glshader.values())e.padding=t;return this}applyUniform(t,e){const r=this.glshader.get(t);r&&(Object.keys(e).length>0&&r.setUniforms(e),this.uniformDirty.has(t)&&(r.setUniforms(this.uniforms),this.uniformDirty.delete(t)))}replaceCustomCode(t,e){return t=t.replace("// CUSTOM_CODE",e+"// CUSTOM_CODE"),t}getGLShader(t,e,r,i){if(this.glshader.has(e))return this.glshader.get(e);if(i==null||r==null)return console.warn("CustomGlShader: missing base shader for "+e),null;const s=this.prefix.length==0?[""]:this.prefix;r=r.replace("// CUSTOM_CODE_CALL",s.map(o=>o+"vertex(position, vRegion);").join("")),r=this.replaceCustomCode(r,this.vs),i=i.replace("// CUSTOM_CODE_CALL",s.map(o=>o+"fragment(fragColor, vRegion);").join("")),i=this.replaceCustomCode(i,this.fs);const a=t.createShader(r,i);return a.isCustom=!0,a.padding=this.padding,this.glshader.set(e,a),this.uniformDirty.add(e),a}destroy(){this.glshader.forEach(t=>t.destroy())}}class Rt{constructor(t){this.rapid=t,this.gl=t.gl,this.maxTextureUnits=t.maxTextureUnits,this.matrixStore=t.matrix}defaultShader;currentShader;customShader=null;customShaderUsedTextureNum=0;gl;maxTextureUnits;matrixStore;isDefaultShader=!0;KEY="default";vs="";fs="";usedTextures=[];usedTexturePadding=[];extraTextureUnit=0;createBuffer(){}createDefaultShader(){}get freeTextureUnitNum(){return this.maxTextureUnits-this.usedTextures.length-this.customShaderUsedTextureNum}getTextureUnitList(){return Array.from({length:this.maxTextureUnits},(t,e)=>e)}findTextureUnit(t,e=0,r=0){for(let i=0;i<this.usedTextures.length;i++){const s=i*2;if(this.usedTextures[i]===t&&this.usedTexturePadding[s]===e&&this.usedTexturePadding[s+1]===r)return i}return-1}useTexture(t,e=0,r=0){const i=this.findTextureUnit(t,e,r);return i==-1?(this.freeTextureUnitNum===0&&this.flush(),this.usedTextures.push(t),this.usedTexturePadding.push(e),this.usedTexturePadding.push(r),this.usedTextures.length-1):i}getMaxTexutreUnit(t){return this.rapid.maxTextureUnits-this.extraTextureUnit-(t?.usedTextureUnitNum??0)}createShader(t,e){const r=this.getMaxTexutreUnit();return e=Z(e,r),t=Z(t,r),new lt(this.gl,t,e)}createCustomShader(t){const e=this.getMaxTexutreUnit(t),r=Z(this.fs,e),i=Z(this.vs,e);return t.getGLShader(this,this.KEY,i,r)}getCustomShader(t){if(!t)return this.defaultShader;if(t instanceof nt){const e=this.createCustomShader(t);return e??this.defaultShader}return t}isSameShader(t){return this.isDefaultShader&&!t?!0:this.getCustomShader(t)==this.currentShader}enter(t){this.resetRender(),this.currentShader=this.getCustomShader(t),t instanceof nt?(this.customShader=t,this.customShaderUsedTextureNum=t.usedTextureUnitNum):(this.customShader=null,this.customShaderUsedTextureNum=0),this.isDefaultShader=this.currentShader==this.defaultShader,this.currentShader.use(),this.currentShader.setUniform("u_projection",this.rapid.projection)}exit(){this.hasPendingContent()&&this.flush(),this.gl.bindVertexArray(null)}flush(){this.render(),this.resetRender()}render(){this.prepareRender()}prepareRender(){const t=this.currentShader;if(t.use(),this.customShader){const r=this.customShader,i={};for(const[s,a]of Object.entries(r.uniformTextures))i[s]=this.useTexture(a);for(const[s,a]of Object.entries(r.uniformArrayTexture))i[s]=a.map(o=>this.useTexture(o));this.customShader.applyUniform(this.KEY,i)}const e=this.gl;for(let r=0;r<this.usedTextures.length;r++)e.activeTexture(e.TEXTURE0+r),e.bindTexture(e.TEXTURE_2D,this.usedTextures[r]);t.setUniform("uTextures",Int32Array.from({length:this.usedTextures.length},(r,i)=>i)),t.setUniform("uPadding",Float32Array.from({length:this.usedTexturePadding.length},(r,i)=>this.usedTexturePadding[i]))}resetRender(){const t=this.gl;for(let e=0;e<this.usedTextures.length;e++)t.activeTexture(t.TEXTURE0+e),t.bindTexture(t.TEXTURE_2D,null);this.usedTextures.length=0,this.usedTexturePadding.length=0}hasPendingContent(){return!1}}var _=(n=>(n[n.Float32=0]="Float32",n[n.Uint32=1]="Uint32",n[n.Uint16=2]="Uint16",n))(_||{});class P{usedElemNum;typedArray;arrayType;maxElemNum;bytePerElem;arraybuffer;uint32;float32;uint16;constructor(t){this.usedElemNum=0,this.maxElemNum=512,this.bytePerElem=this.getArrayType(t).BYTES_PER_ELEMENT,this.arrayType=t,this.arraybuffer=new ArrayBuffer(this.maxElemNum*this.bytePerElem),this.updateTypedArray()}getArrayType(t){switch(t){case 0:return Float32Array;case 1:return Uint32Array;case 2:return Uint16Array;default:throw new Error("Unsupported ArrayType")}}updateTypedArray(){switch(this.uint32=new Uint32Array(this.arraybuffer),this.float32=new Float32Array(this.arraybuffer),this.uint16=new Uint16Array(this.arraybuffer),this.arrayType){case 0:this.typedArray=this.float32;break;case 1:this.typedArray=this.uint32;break;case 2:this.typedArray=this.uint16;break}}clear(){this.usedElemNum=0}static removeAtIndices(t,e){const r=Math.max(...e.map(o=>o.usedElemNum)),i=[...new Set(t)].filter(o=>o>=0&&o<r).sort((o,h)=>o-h);if(i.length===0)return 0;let s=0,a=0;for(let o=0;o<r;o++){if(a<i.length&&o===i[a]){a++;continue}if(s!==o)for(const h of e)h.typedArray[s]=h.typedArray[o];s++}for(const o of e)o.usedElemNum=s;return r-s}resize(t=0){if(t+=this.usedElemNum,t>this.maxElemNum){for(;t>this.maxElemNum;)this.maxElemNum*=2;return this.setMaxSize(this.maxElemNum),!0}return!1}setMaxSize(t=this.maxElemNum){const e=this.typedArray;this.maxElemNum=t,this.arraybuffer=new ArrayBuffer(t*this.bytePerElem),this.updateTypedArray(),this.typedArray.set(e)}pushUint32(t){this.resize(1),this.uint32[this.usedElemNum++]=t}pushFloat32(t){this.resize(1),this.float32[this.usedElemNum++]=t}push(t){this.resize(1),this.typedArray[this.usedElemNum++]=t}pop(){return this.typedArray[--this.usedElemNum]}top(){return this.typedArray[this.usedElemNum-1]}get(t){return this.typedArray[t]}getArray(t=0,e){return e===void 0?this.typedArray:this.typedArray.subarray(t,e)}get length(){return this.usedElemNum}}class dt extends P{buffer;gl;dirty=!0;type;webglBufferSize=0;usage;constructor(t,e,r=t.ARRAY_BUFFER,i=t.DYNAMIC_DRAW){super(e),this.gl=t,this.buffer=t.createBuffer(),this.type=r,this.usage=i}makeDirty(){this.dirty=!0}clear(){super.clear(),this.dirty=!1}bindBuffer(){this.gl.bindBuffer(this.type,this.buffer)}bufferData(){if(this.dirty){const t=this.gl;this.maxElemNum>this.webglBufferSize&&(t.bufferData(this.type,this.maxElemNum*this.bytePerElem,this.usage),this.webglBufferSize=this.maxElemNum),t.bufferSubData(this.type,0,this.getArray(0,this.usedElemNum)),this.dirty=!1}}}const at=`#version 300 es\r
3
3
  precision highp float;\r
4
4
  \r
@@ -84,7 +84,7 @@ void main(void) {\r
84
84
  \r
85
85
  // CUSTOM_CODE_CALL\r
86
86
  }\r
87
- `,Q=48,re=new Float32Array([0,0,1,0,0,1,1,1]);class ft extends Rt{instanceBuffer;quadBuffer;instanceCount=0;localSpriteMatrix=new Float32Array(6);worldSpriteMatrix=new Float32Array(6);KEY="Sprite";constructor(t){super(t),this.createBuffer(),this.createDefaultShader()}createBuffer(){const t=this.gl;this.quadBuffer=new dt(t,_.Float32,t.ARRAY_BUFFER,t.STATIC_DRAW),this.quadBuffer.bindBuffer();for(const e of re)this.quadBuffer.pushFloat32(e);this.quadBuffer.makeDirty(),this.quadBuffer.bufferData(),this.instanceBuffer=new dt(t,_.Uint32,t.ARRAY_BUFFER,t.DYNAMIC_DRAW)}createDefaultShader(){return this.vs=at,this.fs=Mt,this.defaultShader=this.createShader(at,Mt),this.defaultShader}createShader(t,e){const r=super.createShader(t,e);return r.use(),r.bindVAO(),this.instanceBuffer.bindBuffer(),r.setAttributes([{name:"aMatrixRow0",size:3,stride:Q,offset:0,divisor:1},{name:"aMatrixRow1",size:3,stride:Q,offset:12,divisor:1},{name:"aUVRect",size:4,stride:Q,offset:24,divisor:1},{name:"aColor",size:4,type:ut,normalized:!0,stride:Q,offset:40,divisor:1},{name:"aTextureId",size:1,type:ut,stride:Q,offset:44,divisor:1}]),this.quadBuffer.bindBuffer(),r.setAttributes([{name:"aVertex",size:2,stride:8,offset:0,divisor:0}]),r.unbindVAO(),this.currentShader&&this.currentShader.use(),r}drawSprite(t,e,r=0,i=0,s=1,a=1,o=4294967295,h=0,c=0,u=!1,l=!1,d=!1){const f=e*6,m=this.matrixStore.data;this.drawSpriteAffine(t,m[f],m[f+1],m[f+2],m[f+3],m[f+4],m[f+5],r,i,s,a,o,h,c,u,l,d)}drawSpriteAffine(t,e,r,i,s,a,o,h=0,c=0,u=1,l=1,d=4294967295,f=0,m=0,x=!1,T=!1,y=!1){const w=t.base,R=t.rawWidth,C=t.rawHeight,L=t.offsetX,B=t.offsetY,N=this.useTexture(t.glTexture,f/w.width,m/w.height),A=this.instanceBuffer,M=A.usedElemNum;A.resize(12);const U=A.float32,F=A.uint32,G=y?C:R,H=y?R:C,I=G+2*f,O=H+2*m,Y=L-f,V=B-m,S=this.localSpriteMatrix;y?(S[0]=0,S[1]=T?O:-O,S[2]=x?-I:I,S[3]=0,S[4]=Y+(x?I:0),S[5]=V+(T?0:O)):(S[0]=x?-I:I,S[1]=0,S[2]=0,S[3]=T?-O:O,S[4]=Y+(x?I:0),S[5]=V+(T?O:0));const b=this.worldSpriteMatrix;b[0]=e*S[0]+i*S[1],b[1]=r*S[0]+s*S[1],b[2]=e*S[2]+i*S[3],b[3]=r*S[2]+s*S[3],b[4]=a+e*S[4]+i*S[5],b[5]=o+r*S[4]+s*S[5],U[M+6]=h,U[M+7]=c,U[M+8]=u,U[M+9]=l,F[M+10]=d,F[M+11]=N,this.rapid.roundPixels&&(b[4]=Math.round(b[4]),b[5]=Math.round(b[5])),U[M]=b[0],U[M+1]=b[2],U[M+2]=b[4],U[M+3]=b[1],U[M+4]=b[3],U[M+5]=b[5],A.usedElemNum+=12,A.makeDirty(),this.instanceCount++}render(){if(this.instanceCount===0)return;this.prepareRender();const t=this.gl,e=this.currentShader;this.instanceBuffer.bindBuffer(),this.instanceBuffer.bufferData(),e.bindVAO(),Et(t,t.TRIANGLE_STRIP,0,4,this.instanceCount),this.rapid.drawcallCount++}resetRender(){super.resetRender(),this.instanceBuffer.clear(),this.instanceCount=0}hasPendingContent(){return this.instanceCount>0}}const E=6;class ie{matrixCount=0;buffer;data;freeFlag;freeMatrixStack;temporary=-1;identityMatrix=-1;constructor(t=10){this.buffer=new P(_.Float32),this.buffer.resize(t*E),this.data=this.buffer.getArray(),this.freeFlag=new P(_.Uint32),this.freeMatrixStack=new P(_.Uint32),this.reset()}alloc(){const t=this.allocDirty();return this.identity(t),t}allocDirty(){if(this.freeMatrixStack.length>0){const e=this.freeMatrixStack.pop();return this.freeFlag.typedArray[e]=1,e}this.buffer.resize(E)&&(this.data=this.buffer.getArray()),this.buffer.usedElemNum+=E,this.freeFlag.resize(1);const t=this.matrixCount++;return this.freeFlag.typedArray[this.freeFlag.usedElemNum++]=1,t}free(t){!Number.isInteger(t)||t<0||t>=this.matrixCount||this.freeFlag.typedArray[t]!==0&&(this.freeFlag.typedArray[t]=0,this.freeMatrixStack.push(t))}reset(){this.matrixCount=0,this.buffer.usedElemNum=0,this.freeFlag.clear(),this.freeMatrixStack.clear(),this.temporary=this.alloc(),this.identityMatrix=this.alloc()}identity(t){const e=t*E,r=this.data;r[e]=1,r[e+1]=0,r[e+2]=0,r[e+3]=1,r[e+4]=0,r[e+5]=0}translate(t,e,r){const i=t*E,s=this.data;s[i+4]=s[i]*e+s[i+2]*r+s[i+4],s[i+5]=s[i+1]*e+s[i+3]*r+s[i+5]}scale(t,e,r){const i=t*E,s=this.data;s[i]*=e,s[i+1]*=e,s[i+2]*=r,s[i+3]*=r}rotate(t,e){const r=t*E,i=this.data,s=Math.cos(e),a=Math.sin(e),o=i[r],h=i[r+1],c=i[r+2],u=i[r+3];i[r]=o*s+c*a,i[r+1]=h*s+u*a,i[r+2]=o*-a+c*s,i[r+3]=h*-a+u*s}rotateWithOffset(t,e,r,i){this.translate(t,r,i),this.rotate(t,e),this.translate(t,-r,-i)}copy(t,e){const r=t*E,i=e*E,s=this.data;s[r]=s[i],s[r+1]=s[i+1],s[r+2]=s[i+2],s[r+3]=s[i+3],s[r+4]=s[i+4],s[r+5]=s[i+5]}multiply(t,e){this.multiplyOut(t,t,e)}multiplyOut(t,e,r){const i=t*E,s=e*E,a=r*E,o=this.data,h=o[s],c=o[s+1],u=o[s+2],l=o[s+3],d=o[s+4],f=o[s+5],m=o[a],x=o[a+1],T=o[a+2],y=o[a+3],w=o[a+4],R=o[a+5];o[i]=h*m+u*x,o[i+1]=c*m+l*x,o[i+2]=h*T+u*y,o[i+3]=c*T+l*y,o[i+4]=h*w+u*R+d,o[i+5]=c*w+l*R+f}invert(t){const e=t*E,r=this.data,i=r[e],s=r[e+1],a=r[e+2],o=r[e+3],h=r[e+4],c=r[e+5];let u=i*o-s*a;if(!u){this.identity(t);return}u=1/u,r[e]=o*u,r[e+1]=-s*u,r[e+2]=-a*u,r[e+3]=i*u,r[e+4]=(a*c-o*h)*u,r[e+5]=(s*h-i*c)*u}transformPoint(t,e,r){const i=t*E,s=this.data;return{x:e*s[i]+r*s[i+2]+s[i+4],y:e*s[i+1]+r*s[i+3]+s[i+5]}}worldToLocal(t,e,r){const i=this.allocDirty();this.copy(i,t),this.invert(i);const s=this.transformPoint(i,e,r);return this.free(i),s}localToWorld(t,e,r){return this.transformPoint(t,e,r)}getPosition(t){const e=t*E,r=this.data;return{x:r[e+4],y:r[e+5]}}getScale(t){const e=t*E,r=this.data,i=Math.sqrt(r[e]*r[e]+r[e+1]*r[e+1]),s=Math.sqrt(r[e+2]*r[e+2]+r[e+3]*r[e+3]);return{x:i,y:s}}getRotation(t){const e=t*E,r=this.data;return Math.atan2(r[e+1],r[e])}toCSSMatrix(t,e=1,r=1){const i=t*E,s=this.data;return`matrix(${s[i]*e}, ${s[i+1]*r}, ${s[i+2]*e}, ${s[i+3]*r}, ${s[i+4]*e}, ${s[i+5]*r})`}getMatrix(t){const e=t*E;return this.data.slice(e,e+E)}getMatrixRef(t){const e=t*E;return this.data.subarray(e,e+E)}setMatrix(t,e){const r=t*E,i=this.data;i[r]=e[0],i[r+1]=e[1],i[r+2]=e[2],i[r+3]=e[3],i[r+4]=e[4],i[r+5]=e[5]}multiplyAffineInPlace(t,e,r,i,s,a,o){const h=t*6,c=this.data,u=c[h],l=c[h+1],d=c[h+2],f=c[h+3],m=c[h+4],x=c[h+5];c[h]=u*e+d*r,c[h+1]=l*e+f*r,c[h+2]=u*i+d*s,c[h+3]=l*i+f*s,c[h+4]=u*a+d*o+m,c[h+5]=l*a+f*o+x}multiplyAffine(t,e,r,i,s,a,o,h){const c=t*6,u=e*6,l=this.data,d=l[c],f=l[c+1],m=l[c+2],x=l[c+3],T=l[c+4],y=l[c+5];l[u]=d*r+m*i,l[u+1]=f*r+x*i,l[u+2]=d*s+m*a,l[u+3]=f*s+x*a,l[u+4]=d*o+m*h+T,l[u+5]=f*o+x*h+y}clampBounds(t,e,r,i,s,a,o){if(i===void 0&&s===void 0&&a===void 0&&o===void 0)return;const h=t*E,c=this.data,u=Math.sqrt(c[h]*c[h]+c[h+1]*c[h+1])||1,l=Math.sqrt(c[h+2]*c[h+2]+c[h+3]*c[h+3])||1,d=e*.5*u,f=r*.5*l;let m=c[h+4],x=c[h+5];i!==void 0&&s!==void 0?m=s-i<d*2?(i+s)*.5:Math.max(i+d,Math.min(m,s-d)):i!==void 0?m=Math.max(m,i+d):s!==void 0&&(m=Math.min(m,s-d)),a!==void 0&&o!==void 0?x=o-a<f*2?(a+o)*.5:Math.max(a+f,Math.min(x,o-f)):a!==void 0?x=Math.max(x,a+f):o!==void 0&&(x=Math.min(x,o-f)),c[h+4]=m,c[h+5]=x}applyTransform(t,e=0,r=0){let i=t.x??0,s=t.y??0;t.position&&(i+=t.position.x,s+=t.position.y);let a=1,o=1;const h=t.scale;h!==void 0&&(typeof h=="number"?(a=h,o=h):(a=h.x,o=h.y));const c=t.rotation??0;let u=t.offsetX??0,l=t.offsetY??0;t.offset&&(u+=t.offset.x,l+=t.offset.y);const d=t.origin;d!==void 0&&(typeof d=="number"?(u-=d*e,l-=d*r):(u-=d.x*e,l-=d.y*r));const f=c?Math.cos(c):1,m=c?Math.sin(c):0,x=f*a,T=m*a,y=-m*o,w=f*o,R=i+x*u+y*l,C=s+T*u+w*l;return[x,T,y,w,R,C]}}class se{matrix=new ie;stack=new P(_.Uint32);currStack=new P(_.Uint32);curLocalM=-1;curWorldM=-1;rapid;constructor(t){this.reset(),this.rapid=t}save(t,e){this.stack.push(this.curLocalM),this.stack.push(this.curWorldM);const r=this.curWorldM;return this.curLocalM=e??this.matrix.alloc(),this.curWorldM=t??this.matrix.allocDirty(),t===void 0&&(e===void 0?this.matrix.copy(this.curWorldM,r):this.matrix.multiplyOut(this.curWorldM,r,this.curLocalM)),this.currStack.push(this.curLocalM),this.currStack.push(this.curWorldM),{parent:r,world:this.curWorldM,local:this.curLocalM}}restore(){this.stack.length!=0&&(this.curWorldM=this.stack.pop(),this.curLocalM=this.stack.pop())}restoreAll(){for(;this.stack.length>0;)this.restore()}retainMatrix(t){const e=new Set(typeof t=="number"?[t]:[t.local,t.world]),r=[];for(let i=0;i<this.currStack.length;i++)e.has(this.currStack.get(i))&&r.push(i);P.removeAtIndices(r,[this.currStack])}translate(t,e){this.matrix.translate(this.curLocalM,t,e),this.matrix.translate(this.curWorldM,t,e)}scale(t,e=t){this.matrix.scale(this.curLocalM,t,e),this.matrix.scale(this.curWorldM,t,e)}rotate(t){this.matrix.rotate(this.curLocalM,t),this.matrix.rotate(this.curWorldM,t)}rotateWithOffset(t,e,r){this.matrix.rotateWithOffset(this.curLocalM,t,e,r),this.matrix.rotateWithOffset(this.curWorldM,t,e,r)}identity(){this.matrix.identity(this.curLocalM),this.matrix.identity(this.curWorldM)}reset(){for(let t=0;t<this.currStack.length;t++)this.matrix.free(this.currStack.typedArray[t]);this.currStack.clear(),this.stack.clear(),this.curLocalM=this.matrix.alloc(),this.curWorldM=this.matrix.alloc(),this.currStack.push(this.curLocalM),this.currStack.push(this.curWorldM)}localToWorld(t,e){return this.matrix.localToWorld(this.curWorldM,t,e)}worldToLocal(t,e){return this.matrix.worldToLocal(this.curWorldM,t,e)}getGlobalPosition(){return this.matrix.getPosition(this.curWorldM)}getGlobalScale(){return this.matrix.getScale(this.curWorldM)}getGlobalRotation(){return this.matrix.getRotation(this.curWorldM)}toCSSMatrix(){return this.matrix.toCSSMatrix(this.curWorldM)}getTransform(){const t=this.curWorldM*E;return this.matrix.data.slice(t,t+E)}setTransform(t){const e=this.curWorldM*E,r=this.matrix.data;r[e]=t[0],r[e+1]=t[1],r[e+2]=t[2],r[e+3]=t[3],r[e+4]=t[4],r[e+5]=t[5]}transformPoint(t,e){return this.matrix.transformPoint(this.curLocalM,t,e)}applyTransform(t,e=0,r=0,i,s=this.curWorldM,a=this.curLocalM){const[o,h,c,u,l,d]=this.matrix.applyTransform(t,e,r);i!=null?this.matrix.multiplyAffine(s,i,o,h,c,u,l,d):(this.matrix.multiplyAffineInPlace(a,o,h,c,u,l,d),this.matrix.multiplyAffineInPlace(s,o,h,c,u,l,d))}}const ne=`#version 300 es\r
87
+ `,Q=48,re=new Float32Array([0,0,1,0,0,1,1,1]);class ft extends Rt{instanceBuffer;quadBuffer;instanceCount=0;localSpriteMatrix=new Float32Array(6);worldSpriteMatrix=new Float32Array(6);KEY="Sprite";constructor(t){super(t),this.createBuffer(),this.createDefaultShader()}createBuffer(){const t=this.gl;this.quadBuffer=new dt(t,_.Float32,t.ARRAY_BUFFER,t.STATIC_DRAW),this.quadBuffer.bindBuffer();for(const e of re)this.quadBuffer.pushFloat32(e);this.quadBuffer.makeDirty(),this.quadBuffer.bufferData(),this.instanceBuffer=new dt(t,_.Uint32,t.ARRAY_BUFFER,t.DYNAMIC_DRAW)}createDefaultShader(){return this.vs=at,this.fs=Mt,this.defaultShader=this.createShader(at,Mt),this.defaultShader}createShader(t,e){const r=super.createShader(t,e);return r.use(),r.bindVAO(),this.instanceBuffer.bindBuffer(),r.setAttributes([{name:"aMatrixRow0",size:3,stride:Q,offset:0,divisor:1},{name:"aMatrixRow1",size:3,stride:Q,offset:12,divisor:1},{name:"aUVRect",size:4,stride:Q,offset:24,divisor:1},{name:"aColor",size:4,type:ut,normalized:!0,stride:Q,offset:40,divisor:1},{name:"aTextureId",size:1,type:ut,stride:Q,offset:44,divisor:1}]),this.quadBuffer.bindBuffer(),r.setAttributes([{name:"aVertex",size:2,stride:8,offset:0,divisor:0}]),r.unbindVAO(),this.currentShader&&this.currentShader.use(),r}drawSprite(t,e,r=0,i=0,s=1,a=1,o=4294967295,h=0,c=0,u=!1,l=!1,d=!1){const f=e*6,m=this.matrixStore.data;this.drawSpriteAffine(t,m[f],m[f+1],m[f+2],m[f+3],m[f+4],m[f+5],r,i,s,a,o,h,c,u,l,d)}drawSpriteAffine(t,e,r,i,s,a,o,h=0,c=0,u=1,l=1,d=4294967295,f=0,m=0,x=!1,T=!1,y=!1){const w=t.base,R=t.rawWidth,C=t.rawHeight,L=t.offsetX,B=t.offsetY,N=this.useTexture(t.glTexture,f/w.width,m/w.height),A=this.instanceBuffer,M=A.usedElemNum;A.resize(12);const U=A.float32,F=A.uint32,G=y?C:R,H=y?R:C,I=G+2*f,O=H+2*m,Y=L-f,V=B-m,S=this.localSpriteMatrix;y?(S[0]=0,S[1]=T?O:-O,S[2]=x?-I:I,S[3]=0,S[4]=Y+(x?I:0),S[5]=V+(T?0:O)):(S[0]=x?-I:I,S[1]=0,S[2]=0,S[3]=T?-O:O,S[4]=Y+(x?I:0),S[5]=V+(T?O:0));const b=this.worldSpriteMatrix;b[0]=e*S[0]+i*S[1],b[1]=r*S[0]+s*S[1],b[2]=e*S[2]+i*S[3],b[3]=r*S[2]+s*S[3],b[4]=a+e*S[4]+i*S[5],b[5]=o+r*S[4]+s*S[5],U[M+6]=h,U[M+7]=c,U[M+8]=u,U[M+9]=l,F[M+10]=d,F[M+11]=N,this.rapid.roundPixels&&(b[4]=Math.round(b[4]),b[5]=Math.round(b[5])),U[M]=b[0],U[M+1]=b[2],U[M+2]=b[4],U[M+3]=b[1],U[M+4]=b[3],U[M+5]=b[5],A.usedElemNum+=12,A.makeDirty(),this.instanceCount++}render(){if(this.instanceCount===0)return;this.prepareRender();const t=this.gl,e=this.currentShader;this.instanceBuffer.bindBuffer(),this.instanceBuffer.bufferData(),e.bindVAO(),Et(t,t.TRIANGLE_STRIP,0,4,this.instanceCount),this.rapid.drawcallCount++}resetRender(){super.resetRender(),this.instanceBuffer.clear(),this.instanceCount=0}hasPendingContent(){return this.instanceCount>0}}const E=6;class ie{matrixCount=0;buffer;data;freeFlag;freeMatrixStack;temporary=-1;identityMatrix=-1;constructor(t=10){this.buffer=new P(_.Float32),this.buffer.resize(t*E),this.data=this.buffer.getArray(),this.freeFlag=new P(_.Uint32),this.freeMatrixStack=new P(_.Uint32),this.reset()}alloc(){const t=this.allocDirty();return this.identity(t),t}allocDirty(){if(this.freeMatrixStack.length>0){const e=this.freeMatrixStack.pop();return this.freeFlag.typedArray[e]=1,e}this.buffer.resize(E)&&(this.data=this.buffer.getArray()),this.buffer.usedElemNum+=E,this.freeFlag.resize(1);const t=this.matrixCount++;return this.freeFlag.typedArray[this.freeFlag.usedElemNum++]=1,t}free(t){if(typeof t!="number"){this.free(t.local),this.free(t.world);return}!Number.isInteger(t)||t<0||t>=this.matrixCount||this.freeFlag.typedArray[t]!==0&&(this.freeFlag.typedArray[t]=0,this.freeMatrixStack.push(t))}reset(){this.matrixCount=0,this.buffer.usedElemNum=0,this.freeFlag.clear(),this.freeMatrixStack.clear(),this.temporary=this.alloc(),this.identityMatrix=this.alloc()}identity(t){const e=t*E,r=this.data;r[e]=1,r[e+1]=0,r[e+2]=0,r[e+3]=1,r[e+4]=0,r[e+5]=0}translate(t,e,r){const i=t*E,s=this.data;s[i+4]=s[i]*e+s[i+2]*r+s[i+4],s[i+5]=s[i+1]*e+s[i+3]*r+s[i+5]}scale(t,e,r){const i=t*E,s=this.data;s[i]*=e,s[i+1]*=e,s[i+2]*=r,s[i+3]*=r}rotate(t,e){const r=t*E,i=this.data,s=Math.cos(e),a=Math.sin(e),o=i[r],h=i[r+1],c=i[r+2],u=i[r+3];i[r]=o*s+c*a,i[r+1]=h*s+u*a,i[r+2]=o*-a+c*s,i[r+3]=h*-a+u*s}rotateWithOffset(t,e,r,i){this.translate(t,r,i),this.rotate(t,e),this.translate(t,-r,-i)}copy(t,e){const r=t*E,i=e*E,s=this.data;s[r]=s[i],s[r+1]=s[i+1],s[r+2]=s[i+2],s[r+3]=s[i+3],s[r+4]=s[i+4],s[r+5]=s[i+5]}multiply(t,e){this.multiplyOut(t,t,e)}multiplyOut(t,e,r){const i=t*E,s=e*E,a=r*E,o=this.data,h=o[s],c=o[s+1],u=o[s+2],l=o[s+3],d=o[s+4],f=o[s+5],m=o[a],x=o[a+1],T=o[a+2],y=o[a+3],w=o[a+4],R=o[a+5];o[i]=h*m+u*x,o[i+1]=c*m+l*x,o[i+2]=h*T+u*y,o[i+3]=c*T+l*y,o[i+4]=h*w+u*R+d,o[i+5]=c*w+l*R+f}invert(t){const e=t*E,r=this.data,i=r[e],s=r[e+1],a=r[e+2],o=r[e+3],h=r[e+4],c=r[e+5];let u=i*o-s*a;if(!u){this.identity(t);return}u=1/u,r[e]=o*u,r[e+1]=-s*u,r[e+2]=-a*u,r[e+3]=i*u,r[e+4]=(a*c-o*h)*u,r[e+5]=(s*h-i*c)*u}transformPoint(t,e,r){const i=t*E,s=this.data;return{x:e*s[i]+r*s[i+2]+s[i+4],y:e*s[i+1]+r*s[i+3]+s[i+5]}}worldToLocal(t,e,r){const i=this.allocDirty();this.copy(i,t),this.invert(i);const s=this.transformPoint(i,e,r);return this.free(i),s}localToWorld(t,e,r){return this.transformPoint(t,e,r)}getPosition(t){const e=t*E,r=this.data;return{x:r[e+4],y:r[e+5]}}getScale(t){const e=t*E,r=this.data,i=Math.sqrt(r[e]*r[e]+r[e+1]*r[e+1]),s=Math.sqrt(r[e+2]*r[e+2]+r[e+3]*r[e+3]);return{x:i,y:s}}getRotation(t){const e=t*E,r=this.data;return Math.atan2(r[e+1],r[e])}toCSSMatrix(t,e=1,r=1){const i=t*E,s=this.data;return`matrix(${s[i]*e}, ${s[i+1]*r}, ${s[i+2]*e}, ${s[i+3]*r}, ${s[i+4]*e}, ${s[i+5]*r})`}getMatrix(t){const e=t*E;return this.data.slice(e,e+E)}getMatrixRef(t){const e=t*E;return this.data.subarray(e,e+E)}setMatrix(t,e){const r=t*E,i=this.data;i[r]=e[0],i[r+1]=e[1],i[r+2]=e[2],i[r+3]=e[3],i[r+4]=e[4],i[r+5]=e[5]}multiplyAffineInPlace(t,e,r,i,s,a,o){const h=t*6,c=this.data,u=c[h],l=c[h+1],d=c[h+2],f=c[h+3],m=c[h+4],x=c[h+5];c[h]=u*e+d*r,c[h+1]=l*e+f*r,c[h+2]=u*i+d*s,c[h+3]=l*i+f*s,c[h+4]=u*a+d*o+m,c[h+5]=l*a+f*o+x}multiplyAffine(t,e,r,i,s,a,o,h){const c=t*6,u=e*6,l=this.data,d=l[c],f=l[c+1],m=l[c+2],x=l[c+3],T=l[c+4],y=l[c+5];l[u]=d*r+m*i,l[u+1]=f*r+x*i,l[u+2]=d*s+m*a,l[u+3]=f*s+x*a,l[u+4]=d*o+m*h+T,l[u+5]=f*o+x*h+y}clampBounds(t,e,r,i,s,a,o){if(i===void 0&&s===void 0&&a===void 0&&o===void 0)return;const h=t*E,c=this.data,u=Math.sqrt(c[h]*c[h]+c[h+1]*c[h+1])||1,l=Math.sqrt(c[h+2]*c[h+2]+c[h+3]*c[h+3])||1,d=e*.5*u,f=r*.5*l;let m=c[h+4],x=c[h+5];i!==void 0&&s!==void 0?m=s-i<d*2?(i+s)*.5:Math.max(i+d,Math.min(m,s-d)):i!==void 0?m=Math.max(m,i+d):s!==void 0&&(m=Math.min(m,s-d)),a!==void 0&&o!==void 0?x=o-a<f*2?(a+o)*.5:Math.max(a+f,Math.min(x,o-f)):a!==void 0?x=Math.max(x,a+f):o!==void 0&&(x=Math.min(x,o-f)),c[h+4]=m,c[h+5]=x}applyTransform(t,e=0,r=0){let i=t.x??0,s=t.y??0;t.position&&(i+=t.position.x,s+=t.position.y);let a=1,o=1;const h=t.scale;h!==void 0&&(typeof h=="number"?(a=h,o=h):(a=h.x,o=h.y));const c=t.rotation??0;let u=t.offsetX??0,l=t.offsetY??0;t.offset&&(u+=t.offset.x,l+=t.offset.y);const d=t.origin;d!==void 0&&(typeof d=="number"?(u-=d*e,l-=d*r):(u-=d.x*e,l-=d.y*r));const f=c?Math.cos(c):1,m=c?Math.sin(c):0,x=f*a,T=m*a,y=-m*o,w=f*o,R=i+x*u+y*l,C=s+T*u+w*l;return[x,T,y,w,R,C]}}class se{matrix=new ie;stack=new P(_.Uint32);currStack=new P(_.Uint32);curLocalM=-1;curWorldM=-1;rapid;constructor(t){this.reset(),this.rapid=t}save(t,e){this.stack.push(this.curLocalM),this.stack.push(this.curWorldM);const r=this.curWorldM;return t!==void 0&&typeof t!="number"&&([t,e]=[t?.world,t?.local]),this.curLocalM=e??this.matrix.alloc(),this.curWorldM=t??this.matrix.allocDirty(),t===void 0&&(e===void 0?this.matrix.copy(this.curWorldM,r):this.matrix.multiplyOut(this.curWorldM,r,this.curLocalM)),e===void 0&&this.currStack.push(this.curLocalM),t===void 0&&this.currStack.push(this.curWorldM),{parent:r,world:this.curWorldM,local:this.curLocalM}}restore(){this.stack.length!=0&&(this.curWorldM=this.stack.pop(),this.curLocalM=this.stack.pop())}restoreAll(){for(;this.stack.length>0;)this.restore()}retainMatrix(t){const e=new Set(typeof t=="number"?[t]:[t.local,t.world]),r=[];for(let i=0;i<this.currStack.length;i++)e.has(this.currStack.get(i))&&r.push(i);return P.removeAtIndices(r,[this.currStack]),t}translate(t,e){this.matrix.translate(this.curLocalM,t,e),this.matrix.translate(this.curWorldM,t,e)}scale(t,e=t){this.matrix.scale(this.curLocalM,t,e),this.matrix.scale(this.curWorldM,t,e)}rotate(t){this.matrix.rotate(this.curLocalM,t),this.matrix.rotate(this.curWorldM,t)}rotateWithOffset(t,e,r){this.matrix.rotateWithOffset(this.curLocalM,t,e,r),this.matrix.rotateWithOffset(this.curWorldM,t,e,r)}identity(){this.matrix.identity(this.curLocalM),this.matrix.identity(this.curWorldM)}reset(){for(let t=0;t<this.currStack.length;t++)this.matrix.free(this.currStack.typedArray[t]);this.currStack.clear(),this.stack.clear(),this.curLocalM=this.matrix.alloc(),this.curWorldM=this.matrix.alloc(),this.currStack.push(this.curLocalM),this.currStack.push(this.curWorldM)}localToWorld(t,e){return this.matrix.localToWorld(this.curWorldM,t,e)}worldToLocal(t,e){return this.matrix.worldToLocal(this.curWorldM,t,e)}getGlobalPosition(){return this.matrix.getPosition(this.curWorldM)}getGlobalScale(){return this.matrix.getScale(this.curWorldM)}getGlobalRotation(){return this.matrix.getRotation(this.curWorldM)}toCSSMatrix(){return this.matrix.toCSSMatrix(this.curWorldM)}getTransform(){const t=this.curWorldM*E;return this.matrix.data.slice(t,t+E)}setTransform(t){const e=this.curWorldM*E,r=this.matrix.data;r[e]=t[0],r[e+1]=t[1],r[e+2]=t[2],r[e+3]=t[3],r[e+4]=t[4],r[e+5]=t[5]}transformPoint(t,e){return this.matrix.transformPoint(this.curLocalM,t,e)}applyTransform(t,e=0,r=0,i,s=this.curWorldM,a=this.curLocalM){const[o,h,c,u,l,d]=this.matrix.applyTransform(t,e,r);i!=null?this.matrix.multiplyAffine(s,i,o,h,c,u,l,d):(this.matrix.multiplyAffineInPlace(a,o,h,c,u,l,d),this.matrix.multiplyAffineInPlace(s,o,h,c,u,l,d))}}const ne=`#version 300 es\r
88
88
  precision highp float;\r
89
89
  \r
90
90
  in vec2 aPosition;\r
@@ -342,7 +342,7 @@ f32[idx + 11] = originY;
342
342
  }
343
343
  return idx;
344
344
  }
345
- `;const l=new Function(u)();return this.particleLoopCache.set(c,l),l}render(){if(this.instanceCount===0)return;this.prepareRender();const t=this.gl;this.texture&&(t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.texture.glTexture));const e=this.currentShader;this.instanceBuffer.bindBuffer(),this.instanceBuffer.bufferData(),e.bindVAO();const r=this.rapid.matrixStack,s=this.rapid.matrix.getMatrix(this.customMatrix??r.curWorldM),a=St(this.rapid.projection,s);this.currentShader.setUniform("u_matrix",a),Et(t,t.TRIANGLE_STRIP,0,4,this.instanceCount),this.rapid.drawcallCount++,this.texture=void 0,this.customMatrix=void 0}}var Wt=(n=>(n[n.KEEP_W=0]="KEEP_W",n[n.KEEP_H=1]="KEEP_H",n[n.KEEP=2]="KEEP",n[n.IGNORE=3]="IGNORE",n[n.EXPAND=4]="EXPAND",n[n.NONE=5]="NONE",n))(Wt||{});const pe={4:new g(1,1),0:new g(0,1),1:new g(1,0),2:new g(0,0)},kt={4:new g(.5,.5),0:new g(.5,0),1:new g(0,.5),2:new g(.5,.5)};class Gt{constructor(t,e){this.rapid=t,this.updateWindowOption(e)}viewLeft=0;viewRight=0;viewTop=0;viewBottom=0;window={};scissorViewport=null;resolution=0;updateWindowOption(t){Object.assign(this.window,t)}resize(t,e,r,i){const s=this.rapid,a=this.window,o=a.scale??1;t/=o,e/=o,s.flush();const h=r??s.canvas.clientWidth??s.canvas.width,c=i??s.canvas.clientHeight??s.canvas.height;r!==void 0&&(s.canvas.style.width=h+"px"),i!==void 0&&(s.canvas.style.height=c+"px"),s.physicsWidth=h*s.dpr,s.physicsHeight=c*s.dpr,s.logicWidth=t,s.logicHeight=e;let u=0,l=t,d=e,f=0;const m=a.scaleMode??K.CanvasItem,x=a.expand??2;let T=g.ZERO,y=g.ZERO;switch(x in kt&&(T=a.expandPosition??kt[x],y=pe[x]),this.scissorViewport=null,x){case 3:{u=0,l=t,d=e,f=0;break}case 5:{u=0,l=s.physicsWidth,d=s.physicsHeight,f=0;break}default:case 4:case 0:case 1:case 2:{const w=T,R=y,C=Math.min(s.physicsWidth/t,s.physicsHeight/e),L=s.physicsWidth/C,B=s.physicsHeight/C,N=L-t,A=B-e;if(u=-N*w.x,l=t+N*(1-w.x),f=-A*w.y,d=e+A*(1-w.y),!R.x&&N>0||!R.y&&A>0){const M=R.x&&N>0?u:0,U=R.x&&N>0?l:t,F=R.y&&A>0?f:0,G=R.y&&A>0?d:e;this.scissorViewport={x:M,y:F,width:U-M,height:G-F}}break}}switch(m){case K.Viewport:s.canvas.width=t,s.canvas.height=e,s.canvas.style.imageRendering="pixelated",s.gl.viewport(0,0,t,e);break;default:case K.CanvasItem:s.canvas.width=s.physicsWidth,s.canvas.height=s.physicsHeight,s.canvas.style.imageRendering="auto",s.gl.viewport(0,0,s.physicsWidth,s.physicsHeight);break}this.viewLeft=u,this.viewRight=l,this.viewTop=f,this.viewBottom=d,this.updateProjection(),this.restoreViewportScissor(),this.updateResolution(m)}updateResolution(t){let e=1;const r=this.rapid.texture;if(t!==K.Viewport){const i=this.viewRight-this.viewLeft,s=this.viewBottom-this.viewTop;e=Math.max(this.rapid.physicsWidth/i,this.rapid.physicsHeight/s)}e!=this.resolution&&(this.resolution=e,r.texture.forEach(i=>i.updateResolution()))}updateProjection(){this.rapid.updateProjection(this.viewLeft,this.viewRight,this.viewBottom,this.viewTop)}updateOrthMatrix(t,e,r,i,s){t[0]=2/(r-e),t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2/(s-i),t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=-1,t[11]=0,t[12]=-(r+e)/(r-e),t[13]=-(s+i)/(s-i),t[14]=0,t[15]=1}applyCamera(t){const e=this.rapid,r=e.matrix,i=e.matrixStack,s=this.scissorViewport&&e.gl.getParameter(e.gl.FRAMEBUFFER_BINDING)===null?this.scissorViewport:null,a=s?.width??this.viewRight-this.viewLeft,o=s?.height??this.viewBottom-this.viewTop,h=s?s.x+a/2:(this.viewLeft+this.viewRight)/2,c=s?s.y+o/2:(this.viewTop+this.viewBottom)/2,u=i.curWorldM,l=r.temporary,d=r.applyTransform(t,0,0);r.setMatrix(l,d),r.clampBounds(l,a,o,t.limitLeft,t.limitRight,t.limitTop,t.limitBottom),i.translate(h,c),r.invert(l),r.multiplyOut(u,u,l)}startScissor(t,e,r,i){const s=this.rapid;s.flush();const a=s.gl,o=this.scissorViewport;if(o&&a.getParameter(a.FRAMEBUFFER_BINDING)===null){const L=Math.max(Math.min(t,t+r),o.x),B=Math.min(Math.max(t,t+r),o.x+o.width),N=Math.max(Math.min(e,e+i),o.y),A=Math.min(Math.max(e,e+i),o.y+o.height);t=L,e=N,r=Math.max(0,B-L),i=Math.max(0,A-N)}const[h,c,u,l]=a.getParameter(a.VIEWPORT),d=s.projection,f=h+(d[0]*t+d[12]+1)*u/2,m=h+(d[0]*(t+r)+d[12]+1)*u/2,x=c+(d[5]*e+d[13]+1)*l/2,T=c+(d[5]*(e+i)+d[13]+1)*l/2,y=Math.round(Math.min(f,m)),w=Math.round(Math.max(f,m)),R=Math.round(Math.min(x,T)),C=Math.round(Math.max(x,T));a.enable(a.SCISSOR_TEST),a.scissor(y,R,w-y,C-R)}restoreViewportScissor(){this.rapid.flush();const t=this.rapid.gl,e=this.scissorViewport;e&&t.getParameter(t.FRAMEBUFFER_BINDING)===null?this.startScissor(e.x,e.y,e.width,e.height):t.disable(t.SCISSOR_TEST)}endScissor(){this.restoreViewportScissor()}}var pt=(n=>(n[n.EQUAL=0]="EQUAL",n[n.NOT_EQUAL=1]="NOT_EQUAL",n))(pt||{}),Ht=(n=>(n[n.NORMAL=0]="NORMAL",n[n.ADD=1]="ADD",n[n.MULTIPLY=2]="MULTIPLY",n[n.SCREEN=3]="SCREEN",n[n.ERASE=4]="ERASE",n))(Ht||{}),K=(n=>(n[n.CanvasItem=0]="CanvasItem",n[n.Viewport=1]="Viewport",n))(K||{});class ge{gl;canvas;projection=new Float32Array(16);projectionDirty=!0;dpr;backgroundColor=p.Black;logicWidth=0;logicHeight=0;physicsWidth=0;physicsHeight=0;currentRegion=null;maxTextureUnits=0;matrixStack=new se(this);matrix;spriteRegion;graphicRegion;atlasSpriteRegion;particleRegion;regions;drawcallCount=0;inCreateMask=!1;texture;premultipliedAlpha;antialias;roundPixels;textureFilter;viewport;_filterRT=[null,null];_filterInput=new W;get height(){return this.logicHeight}get width(){return this.logicWidth}constructor(t){this.canvas=t.canvas,this.dpr=window.devicePixelRatio||1,this.antialias=t.antialias??!1,this.textureFilter=t.textureFilter??q.NEAREST,this.premultipliedAlpha=t.premultipliedAlpha??!0,this.roundPixels=t.roundPixels??!1;const e=Kt(this.canvas,this.antialias,this.premultipliedAlpha);this.gl=e,this.maxTextureUnits=e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS),this.matrix=this.matrixStack.matrix,this.spriteRegion=new ft(this),this.graphicRegion=new ce(this),this.atlasSpriteRegion=new le(this),this.particleRegion=new xe(this),this.viewport=new Gt(this,t.window),this.texture=new vt(this),this.regions=[this.spriteRegion,this.atlasSpriteRegion];const r=this.canvas.clientWidth??this.canvas.width,i=this.canvas.clientHeight??this.canvas.height;this.physicsWidth=t.physicsWidth??Math.round(r*this.dpr),this.physicsHeight=t.physicsHeight??Math.round(i*this.dpr),this.logicWidth=t.width??this.physicsWidth/this.dpr,this.logicHeight=t.height??this.physicsHeight/this.dpr,this.resize(this.logicWidth,this.logicHeight,this.physicsWidth,this.physicsHeight),t.backgroundColor&&(this.backgroundColor=t.backgroundColor),e.enable(e.BLEND),this.premultipliedAlpha?e.blendFunc(e.ONE,e.ONE_MINUS_SRC_ALPHA):e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA),e.enable(e.STENCIL_TEST),e.stencilFunc(e.ALWAYS,1,255),e.stencilOp(e.KEEP,e.KEEP,e.KEEP)}setTextureFilter(t){this.textureFilter=t}getColorUint32(t){return Pt(this.premultipliedAlpha,t)}enterRegion(t,e){this.currentRegion===t&&this.currentRegion.isSameShader(e)||(this.flush(),this.currentRegion=t,t.enter(e))}drawParticles(t){Nt(this,t)}drawSprite(t){Lt(this,t)}drawLine(t){It(this,t)}drawGraphic(t){xt(this,t)}drawRect(t){Ot(this,t)}drawCircle(t){Bt(this,t)}startGraphic(t=this.gl.TRIANGLES,e,r,i){this.enterRegion(this.graphicRegion,r),this.graphicRegion.startGraphic(i??this.matrixStack.curWorldM,t,e)}startMaskGraphic(t=this.gl.TRIANGLES,e,r){this.startGraphic(t,e,this.graphicRegion.maskShader,r)}drawMaskImage(t){Ft(this,t)}addRectVertex(t,e,r){const i=this.getColorUint32(r);this.addGraphicVertex(0,0,0,0,i),this.addGraphicVertex(t,0,1,0,i),this.addGraphicVertex(t,e,1,1,i),this.addGraphicVertex(0,e,0,1,i)}addCircleVertex(t,e,r=32){const i=Math.PI*2/r,s=this.getColorUint32(e);for(let a=0;a<r;a++){const o=i*a,h=Math.cos(o)*t,c=Math.sin(o)*t,u=.5+Math.cos(o)*.5,l=.5+Math.sin(o)*.5;this.addGraphicVertex(h,c,u,l,s)}}addGraphicVertex(t,e,r=0,i=0,s=4294967295){this.graphicRegion.addVertex(t,e,r,i,typeof s=="number"?s:this.getColorUint32(s))}endGraphic(){this.graphicRegion.endGraphic()}resize(t,e,r,i){this.viewport.resize(t,e,r,i)}updateProjection(t,e,r,i){this.viewport.updateOrthMatrix(this.projection,t,e,r,i),this.projectionDirty=!0}clear(){const t=this.gl;this.flush(),t.disable(t.SCISSOR_TEST),this.viewport.scissorViewport&&t.getParameter(t.FRAMEBUFFER_BINDING)===null?(t.clearColor(0,0,0,1),t.clear(t.COLOR_BUFFER_BIT|t.STENCIL_BUFFER_BIT),this.backgroundColor.setClearColor(t,this.premultipliedAlpha),this.viewport.restoreViewportScissor(),t.clear(t.COLOR_BUFFER_BIT)):(this.backgroundColor.setClearColor(t,this.premultipliedAlpha),t.clear(t.COLOR_BUFFER_BIT|t.STENCIL_BUFFER_BIT)),this.drawcallCount=0,this.matrixStack.reset()}flush(){this.currentRegion&&(this.currentRegion.exit(),this.currentRegion=null)}applyFilters(t,e){if(e.length===0)throw new Error("applyFilters: shaders array must not be empty.");const r=Math.max(...e.map(c=>c.padding)),i=r,s=t.rawWidth+r*2,a=t.rawHeight+r*2;for(let c=0;c<2;c++)this._filterRT[c]?this._filterRT[c].resize(s,a):this._filterRT[c]=this.texture.createRenderTexture({width:s,height:a});let o=t.clone(this._filterInput),h=0;this.matrixStack.save(),this.matrixStack.identity();for(let c=0;c<e.length;c++){const u=this._filterRT[h%2];u.offsetX=0,u.offsetY=0,this.enterRenderTexture(u),this.clearRenderTexture(),this.drawSprite({texture:o,shader:e[c],offsetX:c==0?i:0,offsetY:c==0?i:0,padding:r}),this.leaveRenderTexture(),o=u,h++}return this.matrixStack.restore(),o.offsetX=-i,o.offsetY=-i,o}enterRenderTexture(t){this.flush(),t.activate(),this.viewport.restoreViewportScissor(),this.gl.viewport(0,0,t.rawWidth,t.rawHeight),this.updateProjection(0,t.rawWidth,0,t.rawHeight)}clearRenderTexture(t=new p(0,0,0,0)){this.flush();const e=this.gl;t.setClearColor(e,this.premultipliedAlpha),e.clear(e.COLOR_BUFFER_BIT)}leaveRenderTexture(){this.flush(),this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.viewport.updateProjection(),this.viewport.restoreViewportScissor()}drawToRenderTexture(t,e,r=new p(0,0,0,0)){this.enterRenderTexture(t);try{r!==null&&this.clearRenderTexture(r),e()}finally{this.leaveRenderTexture()}}withMask(t,e,r=0,i=1){this.clearMask(),this.startDrawMask(i);try{t()}finally{this.endDrawMask()}this.enterMask(r,i);try{e()}finally{this.exitMask()}}withTransform(t,e,r=0,i=0){this.matrixStack.save();try{e&&this.matrixStack.applyTransform(e,r,i),t()}finally{this.matrixStack.restore()}}withScissor(t,e,r,i,s){this.startScissor(t,e,r,i);try{s()}finally{this.endScissor()}}withBlendMode(t,e){this.setBlendMode(t);try{e()}finally{this.setBlendMode(0)}}startDrawMask(t=1,e=255){this.flush();const r=this.gl;r.stencilMask(e),r.colorMask(!1,!1,!1,!1),r.stencilFunc(r.ALWAYS,t,e),r.stencilOp(r.KEEP,r.KEEP,r.REPLACE),this.enterRegion(this.graphicRegion,this.graphicRegion.maskShader),this.inCreateMask=!0}endDrawMask(){this.flush();const t=this.gl;t.colorMask(!0,!0,!0,!0),t.stencilMask(0),this.inCreateMask=!1}clearMask(t=255){this.flush();const e=this.gl;e.stencilMask(t),e.clear(e.STENCIL_BUFFER_BIT),this.inCreateMask=!1}enterMask(t,e=1,r=255){this.flush();const i=this.gl;i.colorMask(!0,!0,!0,!0),i.stencilMask(0),i.stencilFunc(t===0?i.EQUAL:i.NOTEQUAL,e,r),i.stencilOp(i.KEEP,i.KEEP,i.KEEP),this.inCreateMask=!1}exitMask(){this.flush();const t=this.gl;t.colorMask(!0,!0,!0,!0),t.stencilMask(255),t.stencilFunc(t.ALWAYS,1,255),t.stencilOp(t.KEEP,t.KEEP,t.KEEP),this.inCreateMask=!1}setBlendMode(t){this.flush();const e=this.gl;switch(t){case 0:this.premultipliedAlpha?e.blendFuncSeparate(e.ONE,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA):e.blendFuncSeparate(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 1:e.blendFuncSeparate(e.ONE,e.ONE,e.ONE,e.ONE);break;case 2:e.blendFuncSeparate(e.DST_COLOR,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 3:e.blendFuncSeparate(e.ONE,e.ONE_MINUS_SRC_COLOR,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 4:e.blendFuncSeparate(e.ZERO,e.ONE_MINUS_SRC_ALPHA,e.ZERO,e.ONE_MINUS_SRC_ALPHA);break}}startScissor(t,e,r,i){this.viewport.startScissor(t,e,r,i)}endScissor(){this.viewport.endScissor()}applyCamera(t){this.viewport.applyCamera(t)}logicToPhysics(t){return t.multiply(new g(this.physicsWidth/this.logicWidth,this.physicsHeight/this.logicHeight))}physicsToLogic(t){return t.multiply(new g(this.logicWidth/this.physicsWidth,this.logicHeight/this.physicsHeight))}cssToDevicePixel(t){return t.multiply(this.dpr)}cssToLogic(t){const e=this.cssToDevicePixel(t);return this.physicsToLogic(e)}devicePixelToCss(t){return t.divide(this.dpr)}toCSSMatrix(t){const e=this.physicsWidth/this.dpr/this.logicWidth,r=this.physicsHeight/this.dpr/this.logicHeight;return this.matrix.toCSSMatrix(t??this.matrixStack.curWorldM,e,r)}}function ve(n){return!(n===null||typeof n!="object"||Array.isArray(n)||n instanceof g||n instanceof p)}class k{static float(t,e){return Math.random()*(e-t)+t}static int(t,e){return Math.floor(Math.random()*(e-t+1))+t}static angle(){return Math.random()*Math.PI*2}static vector(t,e,r,i){return new g(k.float(t,e),k.float(r,i))}static randomColor(t,e){return new p(k.float(t.r,e.r),k.float(t.g,e.g),k.float(t.b,e.b),k.float(t.a,e.a))}static pick(t){return t[k.int(0,t.length-1)]}static pickWeight(t){if(!t||t.length===0)return null;let e=0;for(const[,i]of t)e+=i;let r=Math.random()*e;for(const[i,s]of t)if(r-=s,r<=0)return i;return t[t.length-1][0]}static scalarOrRange(t,e){if(t==null)return e;if(Array.isArray(t)){const[r,i]=t;if(typeof r=="number")return k.float(r,i);if(r instanceof g)return k.vector(r.x,i.x,r.y,i.y);if(r instanceof p)return k.randomColor(r,i)}return typeof t=="number"?t:t.clone()}}const ot=(n,t)=>(Array.isArray(n)?n:[n]).slice(0,t);var Vt=(n=>(n.POINT="point",n.CIRCLE="circle",n.RECT="rect",n))(Vt||{});const Xt=10,Yt=0,zt=!0;class et{components;constructor(t=1){if(!Number.isInteger(t)||t<=0)throw new RangeError("ParticleAttributeStore size must be a positive integer");this.components=Array.from({length:t},()=>({value:new P(_.Float32),delta:new P(_.Float32),damping:new P(_.Float32)}))}getArrayBuffer(){return this.components.flatMap(({value:t,delta:e,damping:r})=>[t,e,r])}update(t){for(const{value:e,delta:r,damping:i}of this.components)for(let s=0;s<e.usedElemNum;s++)e.typedArray[s]*=Math.pow(i.get(s),t),e.typedArray[s]+=r.get(s)*t}get(t,e=0){return this.components[e].value.get(t)}getComponent(t,e){if(typeof t=="number")return t;if(t instanceof g)return e===0?t.x:t.y;switch(e){case 0:return t.r;case 1:return t.g;case 2:return t.b;case 3:return t.a;default:return 0}}resolveComponent(t,e,r){return t===void 0?r:Array.isArray(t)?k.float(this.getComponent(t[0],e),this.getComponent(t[1],e)):this.getComponent(t,e)}create(t,e,r=1){const i=ve(t)?t:void 0,s=i===void 0?t:void 0,a=r>0?r:1;let o=0;for(let h=0;h<this.components.length;h++){const{value:c,delta:u,damping:l}=this.components[h],d=this.getComponent(e,h),f=s===void 0?this.resolveComponent(i?.start,h,d):this.getComponent(s,h),m=i?.end===void 0?f:this.resolveComponent(i.end,h,d);c.push(f),u.push(i?.delta===void 0?(m-f)/a:this.getComponent(i.delta,h)),l.push(i?.damping??1),h===0&&(o=f)}return o}}class gt{options;emitting=!1;emitTimer=0;emitRate=Xt;emitTime=Yt;emitTimeCounter=0;localSpace=zt;rapid;x=new P(_.Float32);y=new P(_.Float32);scaleX=new P(_.Float32);scaleY=new P(_.Float32);rotation=new P(_.Float32);color=new P(_.Uint32);remainingLife=new P(_.Float32);animations={speed:new et,rotation:new et,scale:new et,color:new et(4),velocity:new et(2)};count=0;constructor(t,e){this.rapid=t,this.options=e,this.emitRate=e.emitRate??Xt,this.emitTime=e.emitTime??Yt,this.localSpace=e.localSpace??zt}getAllArrayBuffer(){return[this.x,this.y,this.scaleX,this.scaleY,this.rotation,this.color,this.remainingLife,...Object.values(this.animations).flatMap(t=>t.getArrayBuffer())]}setTexture(t){this.options.texture=t}clone(){return new gt(this.rapid,{...this.options})}setEmitRate(t){this.emitRate=t}setEmitTime(t){this.emitTime=t}start(){this.emitting=!0,this.emitTimeCounter=0}stop(){this.emitting=!1}clear(){for(const t of this.getAllArrayBuffer())t.clear();this.count=0,this.emitTimeCounter=0}emit(t){const e=this.options.maxParticles??1/0,r=Math.min(t,e-this.count);for(let i=0;i<r;i++)this.createParticle()}createParticle(){const t=k.scalarOrRange(this.options.life,1);this.remainingLife.push(t);let e=0,r=0;switch(this.options.emitShape){case"circle":{const c=Math.random()*Math.PI*2,u=(this.options.emitRadius??0)*Math.sqrt(Math.random());e=Math.cos(c)*u,r=Math.sin(c)*u;break}case"rect":{e=(Math.random()-.5)*(this.options.emitRect?.width??0),r=(Math.random()-.5)*(this.options.emitRect?.height??0);break}}const i=this.rapid.matrixStack;if(this.localSpace)this.x.push(e),this.y.push(r);else{const{x:c,y:u}=i.localToWorld(e,r);this.x.push(c),this.y.push(u)}const s=this.options.animation,a=this.animations,o=a.scale.create(s.scale,1,t),h=a.rotation.create(s.rotation,0,t);a.speed.create(s.speed,0,t),a.velocity.create(s.velocity,g.ZERO,t),a.color.create(s.color,p.White,t),this.rotation.push(h),this.scaleX.push(o),this.scaleY.push(o),this.color.pushUint32(p.packColor(a.color.get(this.count,0),a.color.get(this.count,1),a.color.get(this.count,2),a.color.get(this.count,3),this.rapid.premultipliedAlpha)),this.count+=1}update(t){if(this.emitting&&this.emitRate>0)if(this.emitTime>0){if(this.emitTimeCounter+=t,this.emitTimeCounter>=this.emitTime){const r=Math.floor(this.emitTimeCounter/this.emitTime);this.emit(this.emitRate*r),this.emitTimeCounter-=r*this.emitTime}}else{this.emitTimer+=t;const r=Math.floor(this.emitTimer*this.emitRate);r>0&&(this.emit(r),this.emitTimer-=r/this.emitRate)}const e=this.updateParticle(t);this.count-=e.length,P.removeAtIndices(e,this.getAllArrayBuffer())}updateParticle(t){const e=[],r=this.animations;Object.values(r).forEach(i=>i.update(t));for(let i=0;i<this.count;i++){if(this.remainingLife.typedArray[i]-=t,this.remainingLife.typedArray[i]<=0){e.push(i);continue}const s=r.rotation.get(i),a=r.scale.get(i),o=r.speed.get(i);this.rotation.typedArray[i]=s,this.scaleX.typedArray[i]=a,this.scaleY.typedArray[i]=a,this.color.uint32[i]=p.packColor(r.color.get(i,0),r.color.get(i,1),r.color.get(i,2),r.color.get(i,3),this.rapid.premultipliedAlpha),this.x.typedArray[i]+=(o*Math.cos(s)+r.velocity.get(i,0))*t,this.y.typedArray[i]+=(o*Math.sin(s)+r.velocity.get(i,1))*t}return e}render(t){const e=this.options,r=t??(this.localSpace?void 0:this.rapid.matrix.alloc());try{this.rapid.drawParticles({texture:e.texture,shader:e.shader,x:this.x.typedArray,y:this.y.typedArray,scaleX:this.scaleX.typedArray,scaleY:this.scaleY.typedArray,rotation:this.rotation.typedArray,color:this.color.typedArray,count:this.count,reverseOrder:!0,originX:e.origin?.x??.5,originY:e.origin?.y??.5,customMatrix:r})}finally{t===void 0&&r!==void 0&&!this.localSpace&&this.rapid.matrix.free(r)}}isActive(){return this.emitting||this.count>0}oneShot(){this.emit(this.emitRate)}}const ye=`
345
+ `;const l=new Function(u)();return this.particleLoopCache.set(c,l),l}render(){if(this.instanceCount===0)return;this.prepareRender();const t=this.gl;this.texture&&(t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.texture.glTexture));const e=this.currentShader;this.instanceBuffer.bindBuffer(),this.instanceBuffer.bufferData(),e.bindVAO();const r=this.rapid.matrixStack,s=this.rapid.matrix.getMatrix(this.customMatrix??r.curWorldM),a=St(this.rapid.projection,s);this.currentShader.setUniform("u_matrix",a),Et(t,t.TRIANGLE_STRIP,0,4,this.instanceCount),this.rapid.drawcallCount++,this.texture=void 0,this.customMatrix=void 0}}var kt=(n=>(n[n.KEEP_W=0]="KEEP_W",n[n.KEEP_H=1]="KEEP_H",n[n.KEEP=2]="KEEP",n[n.IGNORE=3]="IGNORE",n[n.EXPAND=4]="EXPAND",n[n.NONE=5]="NONE",n))(kt||{});const pe={4:new g(1,1),0:new g(0,1),1:new g(1,0),2:new g(0,0)},Wt={4:new g(.5,.5),0:new g(.5,0),1:new g(0,.5),2:new g(.5,.5)};class Gt{constructor(t,e={}){this.rapid=t,this.updateWindowOption(e)}viewLeft=0;viewRight=0;viewTop=0;viewBottom=0;window={};scissorViewport=null;resolution=0;updateWindowOption(t){Object.assign(this.window,t)}resize(t,e,r,i){const s=this.rapid,a=this.window,o=a.scale??1;t/=o,e/=o,s.flush();const h=r??s.canvas.clientWidth??s.canvas.width,c=i??s.canvas.clientHeight??s.canvas.height;r!==void 0&&(s.canvas.style.width=h+"px"),i!==void 0&&(s.canvas.style.height=c+"px"),s.physicsWidth=h*s.dpr,s.physicsHeight=c*s.dpr,s.logicWidth=t,s.logicHeight=e;let u=0,l=t,d=e,f=0;const m=a.scaleMode??K.CanvasItem,x=a.expand??2;let T=g.ZERO,y=g.ZERO;switch(x in Wt&&(T=a.expandPosition??Wt[x],y=pe[x]),this.scissorViewport=null,x){case 3:{u=0,l=t,d=e,f=0;break}case 5:{u=0,l=s.physicsWidth,d=s.physicsHeight,f=0;break}default:case 4:case 0:case 1:case 2:{const w=T,R=y,C=Math.min(s.physicsWidth/t,s.physicsHeight/e),L=s.physicsWidth/C,B=s.physicsHeight/C,N=L-t,A=B-e;if(u=-N*w.x,l=t+N*(1-w.x),f=-A*w.y,d=e+A*(1-w.y),!R.x&&N>0||!R.y&&A>0){const M=R.x&&N>0?u:0,U=R.x&&N>0?l:t,F=R.y&&A>0?f:0,G=R.y&&A>0?d:e;this.scissorViewport={x:M,y:F,width:U-M,height:G-F}}break}}switch(m){case K.Viewport:s.canvas.width=t,s.canvas.height=e,s.canvas.style.imageRendering="pixelated",s.gl.viewport(0,0,t,e);break;default:case K.CanvasItem:s.canvas.width=s.physicsWidth,s.canvas.height=s.physicsHeight,s.canvas.style.imageRendering="auto",s.gl.viewport(0,0,s.physicsWidth,s.physicsHeight);break}this.viewLeft=u,this.viewRight=l,this.viewTop=f,this.viewBottom=d,this.updateProjection(),this.restoreViewportScissor(),this.updateResolution(m)}updateResolution(t){let e=1;const r=this.rapid.texture;if(t!==K.Viewport){const i=this.viewRight-this.viewLeft,s=this.viewBottom-this.viewTop;e=Math.max(this.rapid.physicsWidth/i,this.rapid.physicsHeight/s)}e!=this.resolution&&(this.resolution=e,r.texture.forEach(i=>i.updateResolution()))}updateProjection(){this.rapid.updateProjection(this.viewLeft,this.viewRight,this.viewBottom,this.viewTop)}updateOrthMatrix(t,e,r,i,s){t[0]=2/(r-e),t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2/(s-i),t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=-1,t[11]=0,t[12]=-(r+e)/(r-e),t[13]=-(s+i)/(s-i),t[14]=0,t[15]=1}applyCamera(t){const e=this.rapid,r=e.matrix,i=e.matrixStack,s=this.scissorViewport&&e.gl.getParameter(e.gl.FRAMEBUFFER_BINDING)===null?this.scissorViewport:null,a=s?.width??this.viewRight-this.viewLeft,o=s?.height??this.viewBottom-this.viewTop,h=s?s.x+a/2:(this.viewLeft+this.viewRight)/2,c=s?s.y+o/2:(this.viewTop+this.viewBottom)/2,u=i.curWorldM,l=r.temporary,d=r.applyTransform(t,0,0);r.setMatrix(l,d),r.clampBounds(l,a,o,t.limitLeft,t.limitRight,t.limitTop,t.limitBottom),i.translate(h,c),r.invert(l),r.multiplyOut(u,u,l)}startScissor(t,e,r,i){const s=this.rapid;s.flush();const a=s.gl,o=this.scissorViewport;if(o&&a.getParameter(a.FRAMEBUFFER_BINDING)===null){const L=Math.max(Math.min(t,t+r),o.x),B=Math.min(Math.max(t,t+r),o.x+o.width),N=Math.max(Math.min(e,e+i),o.y),A=Math.min(Math.max(e,e+i),o.y+o.height);t=L,e=N,r=Math.max(0,B-L),i=Math.max(0,A-N)}const[h,c,u,l]=a.getParameter(a.VIEWPORT),d=s.projection,f=h+(d[0]*t+d[12]+1)*u/2,m=h+(d[0]*(t+r)+d[12]+1)*u/2,x=c+(d[5]*e+d[13]+1)*l/2,T=c+(d[5]*(e+i)+d[13]+1)*l/2,y=Math.round(Math.min(f,m)),w=Math.round(Math.max(f,m)),R=Math.round(Math.min(x,T)),C=Math.round(Math.max(x,T));a.enable(a.SCISSOR_TEST),a.scissor(y,R,w-y,C-R)}restoreViewportScissor(){this.rapid.flush();const t=this.rapid.gl,e=this.scissorViewport;e&&t.getParameter(t.FRAMEBUFFER_BINDING)===null?this.startScissor(e.x,e.y,e.width,e.height):t.disable(t.SCISSOR_TEST)}endScissor(){this.restoreViewportScissor()}}var pt=(n=>(n[n.EQUAL=0]="EQUAL",n[n.NOT_EQUAL=1]="NOT_EQUAL",n))(pt||{}),Ht=(n=>(n[n.NORMAL=0]="NORMAL",n[n.ADD=1]="ADD",n[n.MULTIPLY=2]="MULTIPLY",n[n.SCREEN=3]="SCREEN",n[n.ERASE=4]="ERASE",n))(Ht||{}),K=(n=>(n[n.CanvasItem=0]="CanvasItem",n[n.Viewport=1]="Viewport",n))(K||{});class ge{gl;canvas;projection=new Float32Array(16);projectionDirty=!0;dpr;backgroundColor=p.Black;logicWidth=0;logicHeight=0;physicsWidth=0;physicsHeight=0;currentRegion=null;maxTextureUnits=0;matrixStack=new se(this);matrix;spriteRegion;graphicRegion;atlasSpriteRegion;particleRegion;regions;drawcallCount=0;inCreateMask=!1;texture;premultipliedAlpha;antialias;roundPixels;textureFilter;viewport;_filterRT=[null,null];_filterInput=new k;get height(){return this.logicHeight}get width(){return this.logicWidth}constructor(t){this.canvas=t.canvas,this.dpr=window.devicePixelRatio||1,this.antialias=t.antialias??!1,this.textureFilter=t.textureFilter??q.NEAREST,this.premultipliedAlpha=t.premultipliedAlpha??!0,this.roundPixels=t.roundPixels??!1;const e=Kt(this.canvas,this.antialias,this.premultipliedAlpha);this.gl=e,this.maxTextureUnits=e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS),this.matrix=this.matrixStack.matrix,this.spriteRegion=new ft(this),this.graphicRegion=new ce(this),this.atlasSpriteRegion=new le(this),this.particleRegion=new xe(this),this.viewport=new Gt(this,t.window),this.texture=new vt(this),this.regions=[this.spriteRegion,this.atlasSpriteRegion];const r=this.canvas.clientWidth??this.canvas.width,i=this.canvas.clientHeight??this.canvas.height;this.physicsWidth=t.physicsWidth??Math.round(r*this.dpr),this.physicsHeight=t.physicsHeight??Math.round(i*this.dpr),this.logicWidth=t.width??this.physicsWidth/this.dpr,this.logicHeight=t.height??this.physicsHeight/this.dpr,this.resize(this.logicWidth,this.logicHeight,this.physicsWidth,this.physicsHeight),t.backgroundColor&&(this.backgroundColor=t.backgroundColor),e.enable(e.BLEND),this.premultipliedAlpha?e.blendFunc(e.ONE,e.ONE_MINUS_SRC_ALPHA):e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA),e.enable(e.STENCIL_TEST),e.stencilFunc(e.ALWAYS,1,255),e.stencilOp(e.KEEP,e.KEEP,e.KEEP)}setTextureFilter(t){this.textureFilter=t}getColorUint32(t){return Pt(this.premultipliedAlpha,t)}enterRegion(t,e){this.currentRegion===t&&this.currentRegion.isSameShader(e)||(this.flush(),this.currentRegion=t,t.enter(e))}drawParticles(t){Nt(this,t)}drawSprite(t){Lt(this,t)}drawLine(t){It(this,t)}drawGraphic(t){xt(this,t)}drawRect(t){Ot(this,t)}drawCircle(t){Bt(this,t)}startGraphic(t=this.gl.TRIANGLES,e,r,i){this.enterRegion(this.graphicRegion,r),this.graphicRegion.startGraphic(i??this.matrixStack.curWorldM,t,e)}startMaskGraphic(t=this.gl.TRIANGLES,e,r){this.startGraphic(t,e,this.graphicRegion.maskShader,r)}drawMaskImage(t){Ft(this,t)}addRectVertex(t,e,r){const i=this.getColorUint32(r);this.addGraphicVertex(0,0,0,0,i),this.addGraphicVertex(t,0,1,0,i),this.addGraphicVertex(t,e,1,1,i),this.addGraphicVertex(0,e,0,1,i)}addCircleVertex(t,e,r=32){const i=Math.PI*2/r,s=this.getColorUint32(e);for(let a=0;a<r;a++){const o=i*a,h=Math.cos(o)*t,c=Math.sin(o)*t,u=.5+Math.cos(o)*.5,l=.5+Math.sin(o)*.5;this.addGraphicVertex(h,c,u,l,s)}}addGraphicVertex(t,e,r=0,i=0,s=4294967295){this.graphicRegion.addVertex(t,e,r,i,typeof s=="number"?s:this.getColorUint32(s))}endGraphic(){this.graphicRegion.endGraphic()}resize(t,e,r,i){this.viewport.resize(t,e,r,i)}updateProjection(t,e,r,i){this.viewport.updateOrthMatrix(this.projection,t,e,r,i),this.projectionDirty=!0}clear(){const t=this.gl;this.flush(),t.disable(t.SCISSOR_TEST),this.viewport.scissorViewport&&t.getParameter(t.FRAMEBUFFER_BINDING)===null?(t.clearColor(0,0,0,1),t.clear(t.COLOR_BUFFER_BIT|t.STENCIL_BUFFER_BIT),this.backgroundColor.setClearColor(t,this.premultipliedAlpha),this.viewport.restoreViewportScissor(),t.clear(t.COLOR_BUFFER_BIT)):(this.backgroundColor.setClearColor(t,this.premultipliedAlpha),t.clear(t.COLOR_BUFFER_BIT|t.STENCIL_BUFFER_BIT)),this.drawcallCount=0,this.matrixStack.reset()}flush(){this.currentRegion&&(this.currentRegion.exit(),this.currentRegion=null)}applyFilters(t,e){if(e.length===0)throw new Error("applyFilters: shaders array must not be empty.");const r=Math.max(...e.map(c=>c.padding)),i=r,s=t.rawWidth+r*2,a=t.rawHeight+r*2;for(let c=0;c<2;c++)this._filterRT[c]?this._filterRT[c].resize(s,a):this._filterRT[c]=this.texture.createRenderTexture({width:s,height:a});let o=t.clone(this._filterInput),h=0;this.matrixStack.save(),this.matrixStack.identity();for(let c=0;c<e.length;c++){const u=this._filterRT[h%2];u.offsetX=0,u.offsetY=0,this.enterRenderTexture(u),this.clearRenderTexture(),this.drawSprite({texture:o,shader:e[c],offsetX:c==0?i:0,offsetY:c==0?i:0,padding:r}),this.leaveRenderTexture(),o=u,h++}return this.matrixStack.restore(),o.offsetX=-i,o.offsetY=-i,o}enterRenderTexture(t){this.flush(),t.activate(),this.viewport.restoreViewportScissor(),this.gl.viewport(0,0,t.rawWidth,t.rawHeight),this.updateProjection(0,t.rawWidth,0,t.rawHeight)}clearRenderTexture(t=new p(0,0,0,0)){this.flush();const e=this.gl;t.setClearColor(e,this.premultipliedAlpha),e.clear(e.COLOR_BUFFER_BIT)}leaveRenderTexture(){this.flush(),this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.viewport.updateProjection(),this.viewport.restoreViewportScissor()}drawToRenderTexture(t,e,r=new p(0,0,0,0)){this.enterRenderTexture(t);try{r!==null&&this.clearRenderTexture(r),e()}finally{this.leaveRenderTexture()}}withMask(t,e,r=0,i=1){this.clearMask(),this.startDrawMask(i);try{t()}finally{this.endDrawMask()}this.enterMask(r,i);try{e()}finally{this.exitMask()}}withTransform(t,e,r=0,i=0){this.matrixStack.save();try{e&&this.matrixStack.applyTransform(e,r,i),t()}finally{this.matrixStack.restore()}}withScissor(t,e,r,i,s){this.startScissor(t,e,r,i);try{s()}finally{this.endScissor()}}withBlendMode(t,e){this.setBlendMode(t);try{e()}finally{this.setBlendMode(0)}}startDrawMask(t=1,e=255){this.flush();const r=this.gl;r.stencilMask(e),r.colorMask(!1,!1,!1,!1),r.stencilFunc(r.ALWAYS,t,e),r.stencilOp(r.KEEP,r.KEEP,r.REPLACE),this.enterRegion(this.graphicRegion,this.graphicRegion.maskShader),this.inCreateMask=!0}endDrawMask(){this.flush();const t=this.gl;t.colorMask(!0,!0,!0,!0),t.stencilMask(0),this.inCreateMask=!1}clearMask(t=255){this.flush();const e=this.gl;e.stencilMask(t),e.clear(e.STENCIL_BUFFER_BIT),this.inCreateMask=!1}enterMask(t,e=1,r=255){this.flush();const i=this.gl;i.colorMask(!0,!0,!0,!0),i.stencilMask(0),i.stencilFunc(t===0?i.EQUAL:i.NOTEQUAL,e,r),i.stencilOp(i.KEEP,i.KEEP,i.KEEP),this.inCreateMask=!1}exitMask(){this.flush();const t=this.gl;t.colorMask(!0,!0,!0,!0),t.stencilMask(255),t.stencilFunc(t.ALWAYS,1,255),t.stencilOp(t.KEEP,t.KEEP,t.KEEP),this.inCreateMask=!1}setBlendMode(t){this.flush();const e=this.gl;switch(t){case 0:this.premultipliedAlpha?e.blendFuncSeparate(e.ONE,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA):e.blendFuncSeparate(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 1:e.blendFuncSeparate(e.ONE,e.ONE,e.ONE,e.ONE);break;case 2:e.blendFuncSeparate(e.DST_COLOR,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 3:e.blendFuncSeparate(e.ONE,e.ONE_MINUS_SRC_COLOR,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 4:e.blendFuncSeparate(e.ZERO,e.ONE_MINUS_SRC_ALPHA,e.ZERO,e.ONE_MINUS_SRC_ALPHA);break}}startScissor(t,e,r,i){this.viewport.startScissor(t,e,r,i)}endScissor(){this.viewport.endScissor()}applyCamera(t){this.viewport.applyCamera(t)}logicToPhysics(t){return t.multiply(new g(this.physicsWidth/this.logicWidth,this.physicsHeight/this.logicHeight))}physicsToLogic(t){return t.multiply(new g(this.logicWidth/this.physicsWidth,this.logicHeight/this.physicsHeight))}cssToDevicePixel(t){return t.multiply(this.dpr)}cssToLogic(t){const e=this.cssToDevicePixel(t);return this.physicsToLogic(e)}devicePixelToCss(t){return t.divide(this.dpr)}toCSSMatrix(t){const e=this.physicsWidth/this.dpr/this.logicWidth,r=this.physicsHeight/this.dpr/this.logicHeight;return this.matrix.toCSSMatrix(t??this.matrixStack.curWorldM,e,r)}}function ve(n){return!(n===null||typeof n!="object"||Array.isArray(n)||n instanceof g||n instanceof p)}class W{static float(t,e){return Math.random()*(e-t)+t}static int(t,e){return Math.floor(Math.random()*(e-t+1))+t}static angle(){return Math.random()*Math.PI*2}static vector(t,e,r,i){return new g(W.float(t,e),W.float(r,i))}static randomColor(t,e){return new p(W.float(t.r,e.r),W.float(t.g,e.g),W.float(t.b,e.b),W.float(t.a,e.a))}static pick(t){return t[W.int(0,t.length-1)]}static pickWeight(t){if(!t||t.length===0)return null;let e=0;for(const[,i]of t)e+=i;let r=Math.random()*e;for(const[i,s]of t)if(r-=s,r<=0)return i;return t[t.length-1][0]}static scalarOrRange(t,e){if(t==null)return e;if(Array.isArray(t)){const[r,i]=t;if(typeof r=="number")return W.float(r,i);if(r instanceof g)return W.vector(r.x,i.x,r.y,i.y);if(r instanceof p)return W.randomColor(r,i)}return typeof t=="number"?t:t.clone()}}const ot=(n,t)=>(Array.isArray(n)?n:[n]).slice(0,t);var Vt=(n=>(n.POINT="point",n.CIRCLE="circle",n.RECT="rect",n))(Vt||{});const Xt=10,Yt=0,zt=!0;class et{components;constructor(t=1){if(!Number.isInteger(t)||t<=0)throw new RangeError("ParticleAttributeStore size must be a positive integer");this.components=Array.from({length:t},()=>({value:new P(_.Float32),delta:new P(_.Float32),damping:new P(_.Float32)}))}getArrayBuffer(){return this.components.flatMap(({value:t,delta:e,damping:r})=>[t,e,r])}update(t){for(const{value:e,delta:r,damping:i}of this.components)for(let s=0;s<e.usedElemNum;s++)e.typedArray[s]*=Math.pow(i.get(s),t),e.typedArray[s]+=r.get(s)*t}get(t,e=0){return this.components[e].value.get(t)}getComponent(t,e){if(typeof t=="number")return t;if(t instanceof g)return e===0?t.x:t.y;switch(e){case 0:return t.r;case 1:return t.g;case 2:return t.b;case 3:return t.a;default:return 0}}resolveComponent(t,e,r){return t===void 0?r:Array.isArray(t)?W.float(this.getComponent(t[0],e),this.getComponent(t[1],e)):this.getComponent(t,e)}create(t,e,r=1){const i=ve(t)?t:void 0,s=i===void 0?t:void 0,a=r>0?r:1;let o=0;for(let h=0;h<this.components.length;h++){const{value:c,delta:u,damping:l}=this.components[h],d=this.getComponent(e,h),f=s===void 0?this.resolveComponent(i?.start,h,d):this.getComponent(s,h),m=i?.end===void 0?f:this.resolveComponent(i.end,h,d);c.push(f),u.push(i?.delta===void 0?(m-f)/a:this.getComponent(i.delta,h)),l.push(i?.damping??1),h===0&&(o=f)}return o}}class gt{options;emitting=!1;emitTimer=0;emitRate=Xt;emitTime=Yt;emitTimeCounter=0;localSpace=zt;rapid;x=new P(_.Float32);y=new P(_.Float32);scaleX=new P(_.Float32);scaleY=new P(_.Float32);rotation=new P(_.Float32);color=new P(_.Uint32);remainingLife=new P(_.Float32);animations={speed:new et,rotation:new et,scale:new et,color:new et(4),velocity:new et(2)};count=0;constructor(t,e){this.rapid=t,this.options=e,this.emitRate=e.emitRate??Xt,this.emitTime=e.emitTime??Yt,this.localSpace=e.localSpace??zt}getAllArrayBuffer(){return[this.x,this.y,this.scaleX,this.scaleY,this.rotation,this.color,this.remainingLife,...Object.values(this.animations).flatMap(t=>t.getArrayBuffer())]}setTexture(t){this.options.texture=t}clone(){return new gt(this.rapid,{...this.options})}setEmitRate(t){this.emitRate=t}setEmitTime(t){this.emitTime=t}start(){this.emitting=!0,this.emitTimeCounter=0}stop(){this.emitting=!1}clear(){for(const t of this.getAllArrayBuffer())t.clear();this.count=0,this.emitTimeCounter=0}emit(t){const e=this.options.maxParticles??1/0,r=Math.min(t,e-this.count);for(let i=0;i<r;i++)this.createParticle()}createParticle(){const t=W.scalarOrRange(this.options.life,1);this.remainingLife.push(t);let e=0,r=0;switch(this.options.emitShape){case"circle":{const c=Math.random()*Math.PI*2,u=(this.options.emitRadius??0)*Math.sqrt(Math.random());e=Math.cos(c)*u,r=Math.sin(c)*u;break}case"rect":{e=(Math.random()-.5)*(this.options.emitRect?.width??0),r=(Math.random()-.5)*(this.options.emitRect?.height??0);break}}const i=this.rapid.matrixStack;if(this.localSpace)this.x.push(e),this.y.push(r);else{const{x:c,y:u}=i.localToWorld(e,r);this.x.push(c),this.y.push(u)}const s=this.options.animation,a=this.animations,o=a.scale.create(s.scale,1,t),h=a.rotation.create(s.rotation,0,t);a.speed.create(s.speed,0,t),a.velocity.create(s.velocity,g.ZERO,t),a.color.create(s.color,p.White,t),this.rotation.push(h),this.scaleX.push(o),this.scaleY.push(o),this.color.pushUint32(p.packColor(a.color.get(this.count,0),a.color.get(this.count,1),a.color.get(this.count,2),a.color.get(this.count,3),this.rapid.premultipliedAlpha)),this.count+=1}update(t){if(this.emitting&&this.emitRate>0)if(this.emitTime>0){if(this.emitTimeCounter+=t,this.emitTimeCounter>=this.emitTime){const r=Math.floor(this.emitTimeCounter/this.emitTime);this.emit(this.emitRate*r),this.emitTimeCounter-=r*this.emitTime}}else{this.emitTimer+=t;const r=Math.floor(this.emitTimer*this.emitRate);r>0&&(this.emit(r),this.emitTimer-=r/this.emitRate)}const e=this.updateParticle(t);this.count-=e.length,P.removeAtIndices(e,this.getAllArrayBuffer())}updateParticle(t){const e=[],r=this.animations;Object.values(r).forEach(i=>i.update(t));for(let i=0;i<this.count;i++){if(this.remainingLife.typedArray[i]-=t,this.remainingLife.typedArray[i]<=0){e.push(i);continue}const s=r.rotation.get(i),a=r.scale.get(i),o=r.speed.get(i);this.rotation.typedArray[i]=s,this.scaleX.typedArray[i]=a,this.scaleY.typedArray[i]=a,this.color.uint32[i]=p.packColor(r.color.get(i,0),r.color.get(i,1),r.color.get(i,2),r.color.get(i,3),this.rapid.premultipliedAlpha),this.x.typedArray[i]+=(o*Math.cos(s)+r.velocity.get(i,0))*t,this.y.typedArray[i]+=(o*Math.sin(s)+r.velocity.get(i,1))*t}return e}render(t){const e=this.options,r=t??(this.localSpace?void 0:this.rapid.matrix.alloc());try{this.rapid.drawParticles({texture:e.texture,shader:e.shader,x:this.x.typedArray,y:this.y.typedArray,scaleX:this.scaleX.typedArray,scaleY:this.scaleY.typedArray,rotation:this.rotation.typedArray,color:this.color.typedArray,count:this.count,reverseOrder:!0,originX:e.origin?.x??.5,originY:e.origin?.y??.5,customMatrix:r})}finally{t===void 0&&r!==void 0&&!this.localSpace&&this.rapid.matrix.free(r)}}isActive(){return this.emitting||this.count>0}oneShot(){this.emit(this.emitRate)}}const ye=`
346
346
  uniform mediump int uLightTextureId[%TEXTURE_NUM%];
347
347
 
348
348
  uniform sampler2D uNormalMap;
@@ -400,4 +400,4 @@ void light_fragment(inout vec4 color, in vec2 vRegion) {
400
400
  void light_vertex(inout vec4 p, vec2 u) {
401
401
  light_worldPos = p.xy;
402
402
  }
403
- `,rt=8;class $t extends nt{constructor(t,e="",r="",i=0,s){super(t,e,r,i+2,s)}beforePreCompile(){this.prefix.push("light_")}getGLShader(t,e,r,i){const s=Z(ye,t.getMaxTexutreUnit(this),"layer","lightUV","lightTex = ");return i=this.replaceCustomCode(i,s),r=this.replaceCustomCode(r,Te),super.getGLShader(t,e,r,i)}}class we{shader;rapid;rt;constructor(t){this.rapid=t,this.shader=new $t(t),this.rt=t.texture.createRenderTexture({width:0,height:0})}lightShadow(t,e,r){if(r.length===0)return;const i=this.rapid,s=typeof e=="number"?e:e.world,a=new g(t.rawWidth*.5,t.rawHeight*.5),o=r.map(c=>{const u=i.matrixStack.localToWorld(c.x,c.y),l=i.matrix.worldToLocal(s,u.x,u.y);return new g((l.x+.5)*t.rawWidth,(l.y+.5)*t.rawHeight)});this.rt.resize(t.rawWidth,t.rawHeight);const h=Math.hypot(t.rawWidth,t.rawHeight)*.5*1.05;return i.drawToRenderTexture(this.rt,()=>{i.matrixStack.save(),i.matrixStack.identity();try{i.withMask(()=>{i.startMaskGraphic(i.gl.TRIANGLES);for(let c=0;c<o.length;c++){const u=o[c],l=o[(c+1)%o.length],d=u.subtract(a).normalized(),f=l.subtract(a).normalized(),m=Math.max(-.999,Math.min(1,d.dot(f))),x=Math.sqrt((1+m)*.5),T=h/x,y=a.add(d.multiply(T)),w=a.add(f.multiply(T));i.addGraphicVertex(u.x,u.y),i.addGraphicVertex(l.x,l.y),i.addGraphicVertex(w.x,w.y),i.addGraphicVertex(u.x,u.y),i.addGraphicVertex(w.x,w.y),i.addGraphicVertex(y.x,y.y)}i.endGraphic()},()=>{i.drawSprite({texture:t})},pt.NOT_EQUAL)}finally{i.matrixStack.restore()}}),this.rt}setupLight(t){const e=t.customShader??this.shader,r=ot(t.lightMatrix,rt),i=ot(t.color,rt),s=ot(t.lightHeight,rt),a=ot(t.lightTexture,rt);return e.setUniforms({uNormalMap:t.normalMap.glTexture,uLightTextureId:a.map(o=>o.glTexture),uLightCount:r.length,uLightMatrix:Float32Array.from(r.flatMap(o=>Array.from(this.rapid.matrix.getMatrix(typeof o=="number"?o:o.world)))),uLightColor:Float32Array.from(r.flatMap((o,h)=>{const c=i[h]??i[0];return c?[c.r/255,c.g/255,c.b/255,c.a/255]:[1,1,1,1]})),uLightHeight:Float32Array.from(r.map((o,h)=>s[h]??s[0]??80)),uMetallic:t.metallic??.8,uRoughness:t.roughness??.15,uAmbientColor:t.ambientColor?[t.ambientColor.r/255,t.ambientColor.g/255,t.ambientColor.b/255]:[.1,.1,.15],uNormalScale:[t.normalScaleX??1,t.normalScaleY??1]}),e}}v.BaseTexture=X,v.BlendMode=Ht,v.CanvasScaleMode=K,v.Color=p,v.CustomGlShader=nt,v.ExpandMode=Wt,v.GLShader=lt,v.Light=we,v.LightShader=$t,v.LineTextureMode=bt,v.MAX_LIGHTS=rt,v.MaskType=pt,v.ParticleEmitter=gt,v.ParticleShape=Vt,v.Rapid=ge,v.RenderTexture=yt,v.TextTexture=Tt,v.Texture=W,v.TextureFilterMode=q,v.TextureManager=vt,v.TextureWrapMode=j,v.Vec2=g,v.ViewPort=Gt,v.composeProjectionWithAffine=St,v.drawCircle=Bt,v.drawGraphic=xt,v.drawLine=It,v.drawMaskImage=Ft,v.drawParticles=Nt,v.drawRect=Ot,v.drawSprite=Lt,v.getColorUint32=Pt,v.getLineGeometry=_t,v.getLineNormal=Ct,v.multiplyMat4=At,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"})}));
403
+ `,rt=8;class $t extends nt{constructor(t,e="",r="",i=0,s){super(t,e,r,i+2,s)}beforePreCompile(){this.prefix.push("light_")}getGLShader(t,e,r,i){const s=Z(ye,t.getMaxTexutreUnit(this),"layer","lightUV","lightTex = ");return i=this.replaceCustomCode(i,s),r=this.replaceCustomCode(r,Te),super.getGLShader(t,e,r,i)}}class we{shader;rapid;rt;constructor(t){this.rapid=t,this.shader=new $t(t),this.rt=t.texture.createRenderTexture({width:0,height:0})}lightShadow(t,e,r){if(r.length===0)return;const i=this.rapid,s=typeof e=="number"?e:e.world,a=new g(t.rawWidth*.5,t.rawHeight*.5),o=r.map(c=>{const u=i.matrixStack.localToWorld(c.x,c.y),l=i.matrix.worldToLocal(s,u.x,u.y);return new g((l.x+.5)*t.rawWidth,(l.y+.5)*t.rawHeight)});this.rt.resize(t.rawWidth,t.rawHeight);const h=Math.hypot(t.rawWidth,t.rawHeight)*.5*1.05;return i.drawToRenderTexture(this.rt,()=>{i.matrixStack.save(),i.matrixStack.identity();try{i.withMask(()=>{i.startMaskGraphic(i.gl.TRIANGLES);for(let c=0;c<o.length;c++){const u=o[c],l=o[(c+1)%o.length],d=u.subtract(a).normalized(),f=l.subtract(a).normalized(),m=Math.max(-.999,Math.min(1,d.dot(f))),x=Math.sqrt((1+m)*.5),T=h/x,y=a.add(d.multiply(T)),w=a.add(f.multiply(T));i.addGraphicVertex(u.x,u.y),i.addGraphicVertex(l.x,l.y),i.addGraphicVertex(w.x,w.y),i.addGraphicVertex(u.x,u.y),i.addGraphicVertex(w.x,w.y),i.addGraphicVertex(y.x,y.y)}i.endGraphic()},()=>{i.drawSprite({texture:t})},pt.NOT_EQUAL)}finally{i.matrixStack.restore()}}),this.rt}setupLight(t){const e=t.customShader??this.shader,r=ot(t.lightMatrix,rt),i=ot(t.color,rt),s=ot(t.lightHeight,rt),a=ot(t.lightTexture,rt);return e.setUniforms({uNormalMap:t.normalMap.glTexture,uLightTextureId:a.map(o=>o.glTexture),uLightCount:r.length,uLightMatrix:Float32Array.from(r.flatMap(o=>Array.from(this.rapid.matrix.getMatrix(typeof o=="number"?o:o.world)))),uLightColor:Float32Array.from(r.flatMap((o,h)=>{const c=i[h]??i[0];return c?[c.r/255,c.g/255,c.b/255,c.a/255]:[1,1,1,1]})),uLightHeight:Float32Array.from(r.map((o,h)=>s[h]??s[0]??80)),uMetallic:t.metallic??.8,uRoughness:t.roughness??.15,uAmbientColor:t.ambientColor?[t.ambientColor.r/255,t.ambientColor.g/255,t.ambientColor.b/255]:[.1,.1,.15],uNormalScale:[t.normalScaleX??1,t.normalScaleY??1]}),e}}v.BaseTexture=X,v.BlendMode=Ht,v.CanvasScaleMode=K,v.Color=p,v.CustomGlShader=nt,v.ExpandMode=kt,v.GLShader=lt,v.Light=we,v.LightShader=$t,v.LineTextureMode=bt,v.MAX_LIGHTS=rt,v.MaskType=pt,v.ParticleEmitter=gt,v.ParticleShape=Vt,v.Rapid=ge,v.RenderTexture=yt,v.TextTexture=Tt,v.Texture=k,v.TextureFilterMode=q,v.TextureManager=vt,v.TextureWrapMode=j,v.Vec2=g,v.ViewPort=Gt,v.composeProjectionWithAffine=St,v.drawCircle=Bt,v.drawGraphic=xt,v.drawLine=It,v.drawMaskImage=Ft,v.drawParticles=Nt,v.drawRect=Ot,v.drawSprite=Lt,v.getColorUint32=Pt,v.getLineGeometry=_t,v.getLineNormal=Ct,v.multiplyMat4=At,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"})}));
package/dist/render.d.ts CHANGED
@@ -33,7 +33,7 @@ export interface IAppOptions {
33
33
  /** Whether textures are uploaded with premultiplied alpha. Default: true. */
34
34
  premultipliedAlpha?: boolean;
35
35
  roundPixels?: boolean;
36
- window: IWindowsOptions;
36
+ window?: IWindowsOptions;
37
37
  }
38
38
  export interface IWindowsOptions {
39
39
  scaleMode?: CanvasScaleMode;
@@ -29,7 +29,7 @@ export declare class ViewPort {
29
29
  private window;
30
30
  scissorViewport: ScissorViewport | null;
31
31
  resolution: number;
32
- constructor(rapid: Rapid, options: IWindowsOptions);
32
+ constructor(rapid: Rapid, options?: IWindowsOptions);
33
33
  updateWindowOption(window: IWindowsOptions): void;
34
34
  /**
35
35
  * Resizes the canvas, updates internal viewport values, and recreates projection boundaries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rapid-render",
3
3
  "private": false,
4
- "version": "1.0.24",
4
+ "version": "1.0.27",
5
5
  "type": "module",
6
6
  "description": "A high-performance lightweight WebGL 2D renderer for browser games.",
7
7
  "repository": "https://github.com/Nightre/Rapid.js",