rapid-render 1.0.15 → 1.0.17

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.
@@ -1,229 +1,4 @@
1
- var A = /* @__PURE__ */ ((n) => (n[n.Float32 = 0] = "Float32", n[n.Uint32 = 1] = "Uint32", n[n.Uint16 = 2] = "Uint16", n))(A || {});
2
- class b {
3
- /** The number of elements currently used in the buffer. */
4
- usedElemNum;
5
- /** The main typed array view corresponding to the specified ArrayType. */
6
- typedArray;
7
- arrayType;
8
- /** The maximum number of elements the buffer can currently hold without resizing. */
9
- maxElemNum;
10
- /** The number of bytes per element based on the `ArrayType`. */
11
- bytePerElem;
12
- arraybuffer;
13
- /** `Uint32Array` view of the underlying memory buffer. */
14
- uint32;
15
- /** `Float32Array` view of the underlying memory buffer. */
16
- float32;
17
- /** `Uint16Array` view of the underlying memory buffer. */
18
- uint16;
19
- /**
20
- * Initializes a new dynamic array buffer.
21
- * @param arrayType - The type of elements this buffer will store primarily.
22
- */
23
- constructor(t) {
24
- 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();
25
- }
26
- /**
27
- * Returns the typed array constructor for the corresponding `ArrayType`.
28
- * @param arrayType - The type of the array.
29
- * @returns The typed array constructor.
30
- * @throws Dispatches an error if the specified type is unsupported.
31
- */
32
- getArrayType(t) {
33
- switch (t) {
34
- case 0:
35
- return Float32Array;
36
- case 1:
37
- return Uint32Array;
38
- case 2:
39
- return Uint16Array;
40
- default:
41
- throw new Error("Unsupported ArrayType");
42
- }
43
- }
44
- /**
45
- * Updates the typed array views when the internal array buffer gets reallocated.
46
- */
47
- updateTypedArray() {
48
- switch (this.uint32 = new Uint32Array(this.arraybuffer), this.float32 = new Float32Array(this.arraybuffer), this.uint16 = new Uint16Array(this.arraybuffer), this.arrayType) {
49
- case 0:
50
- this.typedArray = this.float32;
51
- break;
52
- case 1:
53
- this.typedArray = this.uint32;
54
- break;
55
- case 2:
56
- this.typedArray = this.uint16;
57
- break;
58
- }
59
- }
60
- /**
61
- * Resets the element usage count to zero. The underlying memory capacity is preserved.
62
- */
63
- clear() {
64
- this.usedElemNum = 0;
65
- }
66
- static removeAtIndices(t, e) {
67
- const r = Math.max(...e.map((o) => o.usedElemNum)), i = [...new Set(t)].filter(
68
- (o) => o >= 0 && o < r
69
- ).sort((o, h) => o - h);
70
- if (i.length === 0)
71
- return 0;
72
- let s = 0, a = 0;
73
- for (let o = 0; o < r; o++) {
74
- if (a < i.length && o === i[a]) {
75
- a++;
76
- continue;
77
- }
78
- if (s !== o)
79
- for (const h of e)
80
- h.typedArray[s] = h.typedArray[o];
81
- s++;
82
- }
83
- for (const o of e)
84
- o.usedElemNum = s;
85
- return r - s;
86
- }
87
- /**
88
- * Checks if the buffer has enough space for additional elements and resizes the buffer if necessary.
89
- * @param size - The number of new elements that need to be accommodated.
90
- * @returns `true` if the buffer was resized, `false` otherwise.
91
- */
92
- resize(t = 0) {
93
- if (t += this.usedElemNum, t > this.maxElemNum) {
94
- for (; t > this.maxElemNum; )
95
- this.maxElemNum *= 2;
96
- return this.setMaxSize(this.maxElemNum), !0;
97
- }
98
- return !1;
99
- }
100
- /**
101
- * Reallocates the underlying array buffer to a new size and copies existing data.
102
- * @param size - The new maximum number of elements.
103
- */
104
- setMaxSize(t = this.maxElemNum) {
105
- const e = this.typedArray;
106
- this.maxElemNum = t, this.arraybuffer = new ArrayBuffer(t * this.bytePerElem), this.updateTypedArray(), this.typedArray.set(e);
107
- }
108
- /**
109
- * Appends a new 32-bit unsigned integer element to the buffer.
110
- * @param value - The item to add.
111
- */
112
- pushUint32(t) {
113
- this.resize(1), this.uint32[this.usedElemNum++] = t;
114
- }
115
- /**
116
- * Appends a new 32-bit floating point element to the buffer.
117
- * @param value - The item to add.
118
- */
119
- pushFloat32(t) {
120
- this.resize(1), this.float32[this.usedElemNum++] = t;
121
- }
122
- /**
123
- * Appends an element to the buffer, using the primary typed array view.
124
- * @param value - The item to add.
125
- */
126
- push(t) {
127
- this.resize(1), this.typedArray[this.usedElemNum++] = t;
128
- }
129
- /**
130
- * Removes and returns the last element in the buffer.
131
- * @returns The removed element or undefined if the buffer is empty.
132
- */
133
- pop() {
134
- return this.typedArray[--this.usedElemNum];
135
- }
136
- /**
137
- * Returns the last element pushed to the buffer without removing it.
138
- * @returns The last element.
139
- */
140
- top() {
141
- return this.typedArray[this.usedElemNum - 1];
142
- }
143
- /**
144
- * Gets the value of the element at the specified index.
145
- * @param index - The index of the element to retrieve.
146
- * @returns The requested element.
147
- */
148
- get(t) {
149
- return this.typedArray[t];
150
- }
151
- /**
152
- * Returns a constrained view of the primary typed array up to the specified range.
153
- * If `end` is omitted, returns the whole reallocated buffer slice.
154
- * @param begin - The starting index (inclusive). Defaults to 0.
155
- * @param end - The ending index (exclusive). Optional.
156
- * @returns A subarray corresponding to the specified range.
157
- */
158
- getArray(t = 0, e) {
159
- return e === void 0 ? this.typedArray : this.typedArray.subarray(t, e);
160
- }
161
- /**
162
- * The number of elements currently stored in the buffer.
163
- */
164
- get length() {
165
- return this.usedElemNum;
166
- }
167
- /**
168
- * Resets the buffer's used element count, effectively emptying it.
169
- * Same behavior as `clear`.
170
- */
171
- reset() {
172
- this.usedElemNum = 0;
173
- }
174
- }
175
- class tt extends b {
176
- /** The actual WebGLBuffer object maintained by this instance. */
177
- buffer;
178
- /** The related WebGL rendering context. */
179
- gl;
180
- /** Signifies whether the buffer has been updated and requires resyncing to the GPU. */
181
- dirty = !0;
182
- /** The WebGL buffer type, e.g., gl.ARRAY_BUFFER. */
183
- type;
184
- /** Size of the allocated buffer block on the GPU side, bounded in elements count. */
185
- webglBufferSize = 0;
186
- /** Usage hint for WebGL, e.g., gl.DYNAMIC_DRAW. */
187
- usage;
188
- /**
189
- * Initializes a new WebGL dynamic buffer.
190
- * @param gl - The active WebGL rendering context state.
191
- * @param arrayType - Type of the underlying data elements to bind.
192
- * @param type - Determines the type of WebGLBuffer (defaults to gl.ARRAY_BUFFER).
193
- * @param usage - Determines the data usage pattern (defaults to gl.DYNAMIC_DRAW).
194
- */
195
- constructor(t, e, r = t.ARRAY_BUFFER, i = t.DYNAMIC_DRAW) {
196
- super(e), this.gl = t, this.buffer = t.createBuffer(), this.type = r, this.usage = i;
197
- }
198
- /**
199
- * Flags the buffer as dirty, marking it for future data synchronization.
200
- */
201
- makeDirty() {
202
- this.dirty = !0;
203
- }
204
- /**
205
- * Clears CPU side data usage and marks buffer as synced to stop needless updates.
206
- */
207
- clear() {
208
- super.clear(), this.dirty = !1;
209
- }
210
- /**
211
- * Binds this buffer object tracking it as the current bound buffer to the GPU.
212
- */
213
- bindBuffer() {
214
- this.gl.bindBuffer(this.type, this.buffer);
215
- }
216
- /**
217
- * Uploads the local buffer data to the GPU memory synchronously.
218
- */
219
- bufferData() {
220
- if (this.dirty) {
221
- const t = this.gl;
222
- 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;
223
- }
224
- }
225
- }
226
- class x {
1
+ class m {
227
2
  _r;
228
3
  _g;
229
4
  _b;
@@ -233,200 +8,100 @@ class x {
233
8
  static clampByte(t) {
234
9
  return t <= 0 ? 0 : t >= 255 ? 255 : Math.round(t);
235
10
  }
236
- /**
237
- * Creates an instance of Color.
238
- * @param r - The red component (0-255).
239
- * @param g - The green component (0-255).
240
- * @param b - The blue component (0-255).
241
- * @param a - The alpha component (0-255).
242
- */
243
11
  constructor(t, e, r, i = 255) {
244
12
  this._r = t, this._g = e, this._b = r, this._a = i, this.updateUint();
245
13
  }
246
14
  setClearColor(t) {
247
15
  t.clearColor(this.r / 255, this.g / 255, this.b / 255, this.a / 255);
248
16
  }
249
- /**
250
- * Gets the red component.
251
- */
252
17
  get r() {
253
18
  return this._r;
254
19
  }
255
- /**
256
- * Sets the red component and updates the uint32 representation.
257
- * @param value - The new red component (0-255).
258
- */
259
20
  set r(t) {
260
21
  this._r = t, this.updateUint();
261
22
  }
262
- /**
263
- * Gets the green component.
264
- */
265
23
  get g() {
266
24
  return this._g;
267
25
  }
268
- /**
269
- * Sets the green component and updates the uint32 representation.
270
- * @param value - The new green component (0-255).
271
- */
272
26
  set g(t) {
273
27
  this._g = t, this.updateUint();
274
28
  }
275
- /**
276
- * Gets the blue component.
277
- */
278
29
  get b() {
279
30
  return this._b;
280
31
  }
281
- /**
282
- * Sets the blue component and updates the uint32 representation.
283
- * @param value - The new blue component (0-255).
284
- */
285
32
  set b(t) {
286
33
  this._b = t, this.updateUint();
287
34
  }
288
- /**
289
- * Gets the alpha component.
290
- */
291
35
  get a() {
292
36
  return this._a;
293
37
  }
294
- /**
295
- * Sets the alpha component and updates the uint32 representation.
296
- * @param value - The new alpha component (0-255).
297
- */
298
38
  set a(t) {
299
39
  this._a = t, this.updateUint();
300
40
  }
301
- /**
302
- * Updates the uint32 representation of the color.
303
- * @private
304
- */
305
41
  updateUint() {
306
42
  this.uint32 = (this._a << 24 | this._b << 16 | this._g << 8 | this._r) >>> 0;
307
- const t = x.clampByte(this._a), e = x.clampByte(this._r * t / 255), r = x.clampByte(this._g * t / 255), i = x.clampByte(this._b * t / 255);
43
+ const t = m.clampByte(this._a), e = m.clampByte(this._r * t / 255), r = m.clampByte(this._g * t / 255), i = m.clampByte(this._b * t / 255);
308
44
  this.premultipliedUint32 = (t << 24 | i << 16 | r << 8 | e) >>> 0;
309
45
  }
310
46
  reset() {
311
47
  this._r = 0, this._g = 0, this._b = 0, this._a = 255, this.updateUint();
312
48
  }
313
- /**
314
- * Sets the RGBA values of the color and updates the uint32 representation.
315
- * @param r - The red component (0-255).
316
- * @param g - The green component (0-255).
317
- * @param b - The blue component (0-255).
318
- * @param a - The alpha component (0-255).
319
- */
320
49
  setRGBA(t, e, r, i) {
321
- this.r = t, this.g = e, this.b = r, this.a = i, this.updateUint();
50
+ this._r = t, this._g = e, this._b = r, this._a = i, this.updateUint();
322
51
  }
323
52
  setHSL(t, e, r) {
324
53
  t = (t % 360 + 360) % 360, e = Math.max(0, Math.min(100, e)) / 100, r = Math.max(0, Math.min(100, r)) / 100;
325
54
  const i = (1 - Math.abs(2 * r - 1)) * e, s = i * (1 - Math.abs(t / 60 % 2 - 1)), a = r - i / 2;
326
- let o = 0, h = 0, c = 0;
327
- 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;
328
- }
329
- toHex() {
330
- const t = (e) => Math.max(0, Math.min(255, Math.round(e))).toString(16).padStart(2, "0");
331
- return `#${t(this._r)}${t(this._g)}${t(this._b)}${t(this._a)}`;
55
+ let h = 0, o = 0, c = 0;
56
+ return t < 60 ? [h, o, c] = [i, s, 0] : t < 120 ? [h, o, c] = [s, i, 0] : t < 180 ? [h, o, c] = [0, i, s] : t < 240 ? [h, o, c] = [0, s, i] : t < 300 ? [h, o, c] = [s, 0, i] : [h, o, c] = [i, 0, s], this.setRGBA((h + a) * 255, (o + a) * 255, (c + a) * 255, 255), this;
332
57
  }
333
- /**
334
- * Copies the RGBA values from another color.
335
- * @param color - The color to copy from.
336
- */
337
58
  copy(t) {
338
59
  this.setRGBA(t.r, t.g, t.b, t.a);
339
60
  }
340
- /**
341
- * Clone the current color
342
- * @returns A new `Color` instance with the same RGBA values.
343
- */
344
61
  clone() {
345
- return new x(this._r, this._g, this._b, this._a);
62
+ return new m(this._r, this._g, this._b, this._a);
346
63
  }
347
- /**
348
- * Converts the color to a hexadecimal string representation (e.g., '#RRGGBBAA').
349
- * @param includeAlpha - Whether to include the alpha channel in the hex string.
350
- * @returns The hexadecimal string representation of the color.
351
- */
352
64
  toHexString(t = !0) {
353
65
  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");
354
66
  return `#${e}${r}${i}${t ? s : ""}`;
355
67
  }
356
- /**
357
- * Checks if the current color is equal to another color.
358
- * @param color - The color to compare with.
359
- * @returns True if the colors are equal, otherwise false.
360
- */
361
- equal(t) {
68
+ equals(t) {
362
69
  return t.r === this.r && t.g === this.g && t.b === this.b && t.a === this.a;
363
70
  }
364
- equals(t) {
365
- return this.equal(t);
366
- }
367
- /**
368
- * Creates a Color instance from normalized float components (0–1 range).
369
- * Use this instead of `new Color()` when working with shader-style 0.0–1.0 values.
370
- * @param r - Red channel (0.0–1.0)
371
- * @param g - Green channel (0.0–1.0)
372
- * @param b - Blue channel (0.0–1.0)
373
- * @param a - Alpha channel (0.0–1.0), defaults to 1.0
374
- * @returns A new Color instance with components scaled to 0–255.
375
- * @example
376
- * Color.fromNorm(0.9, 0.87, 0.55, 0.1) // moon glow
377
- */
378
71
  static FromHSL(t, e, r) {
379
- return new x(0, 0, 0).setHSL(t, e, r);
72
+ return new m(0, 0, 0).setHSL(t, e, r);
380
73
  }
381
74
  static FromRGB(t, e, r) {
382
- return new x(t, e, r);
75
+ return new m(t, e, r);
383
76
  }
384
77
  static fromNorm(t, e, r, i = 1) {
385
- return new x(
78
+ return new m(
386
79
  Math.round(t * 255),
387
80
  Math.round(e * 255),
388
81
  Math.round(r * 255),
389
82
  Math.round(i * 255)
390
83
  );
391
84
  }
392
- static clampColorByte(t) {
393
- return t <= 0 ? 0 : t >= 255 ? 255 : Math.round(t);
394
- }
395
85
  static packColor(t, e, r, i, s) {
396
- const a = x.clampColorByte(i), o = s ? a / 255 : 1, h = x.clampColorByte(t * o), c = x.clampColorByte(e * o), u = x.clampColorByte(r * o);
397
- return (a << 24 | u << 16 | c << 8 | h) >>> 0;
398
- }
399
- /**
400
- * Creates a Color instance from a hexadecimal color string.
401
- * @param hexString - The hexadecimal color string, e.g., '#RRGGBB' or '#RRGGBBAA'.
402
- * @returns A new Color instance.
403
- */
86
+ const a = m.clampByte(i), h = s ? a / 255 : 1, o = m.clampByte(t * h), c = m.clampByte(e * h), u = m.clampByte(r * h);
87
+ return (a << 24 | u << 16 | c << 8 | o) >>> 0;
88
+ }
404
89
  static fromHex(t) {
405
90
  t.startsWith("#") && (t = t.slice(1));
406
91
  const e = parseInt(t.slice(0, 2), 16), r = parseInt(t.slice(2, 4), 16), i = parseInt(t.slice(4, 6), 16);
407
92
  let s = 255;
408
- return t.length >= 8 && (s = parseInt(t.slice(6, 8), 16)), new x(e, r, i, s);
93
+ return t.length >= 8 && (s = parseInt(t.slice(6, 8), 16)), new m(e, r, i, s);
409
94
  }
410
- /**
411
- * Adds the components of another color to this color, clamping the result to 255.
412
- * @param color - The color to add.
413
- * @returns A new Color instance with the result of the addition.
414
- */
415
95
  add(t) {
416
- return new x(
96
+ return new m(
417
97
  Math.min(this.r + t.r, 255),
418
98
  Math.min(this.g + t.g, 255),
419
99
  Math.min(this.b + t.b, 255),
420
100
  Math.min(this.a + t.a, 255)
421
101
  );
422
102
  }
423
- /**
424
- * Subtracts the components of another color from this color, clamping the result to 0.
425
- * @param color - The color to subtract.
426
- * @returns A new Color instance with the result of the subtraction.
427
- */
428
103
  subtract(t) {
429
- return new x(
104
+ return new m(
430
105
  this.r - t.r,
431
106
  this.g - t.g,
432
107
  this.b - t.b,
@@ -434,12 +109,12 @@ class x {
434
109
  );
435
110
  }
436
111
  divide(t) {
437
- return t instanceof x ? new x(
112
+ return t instanceof m ? new m(
438
113
  this.r / t.r,
439
114
  this.g / t.g,
440
115
  this.b / t.b,
441
116
  this.a / t.a
442
- ) : new x(
117
+ ) : new m(
443
118
  this.r / t,
444
119
  this.g / t,
445
120
  this.b / t,
@@ -447,12 +122,12 @@ class x {
447
122
  );
448
123
  }
449
124
  multiply(t) {
450
- return t instanceof x ? new x(
125
+ return t instanceof m ? new m(
451
126
  this.r * t.r,
452
127
  this.g * t.g,
453
128
  this.b * t.b,
454
129
  this.a * t.a
455
- ) : new x(
130
+ ) : new m(
456
131
  this.r * t,
457
132
  this.g * t,
458
133
  this.b * t,
@@ -460,566 +135,58 @@ class x {
460
135
  );
461
136
  }
462
137
  clamp() {
463
- 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));
464
- }
465
- static Red = new x(255, 0, 0, 255);
466
- static Green = new x(0, 255, 0, 255);
467
- static Blue = new x(0, 0, 255, 255);
468
- static Yellow = new x(255, 255, 0, 255);
469
- static Purple = new x(128, 0, 128, 255);
470
- static Orange = new x(255, 165, 0, 255);
471
- static Pink = new x(255, 192, 203, 255);
472
- static Gray = new x(128, 128, 128, 255);
473
- static Brown = new x(139, 69, 19, 255);
474
- static Cyan = new x(0, 255, 255, 255);
475
- static Magenta = new x(255, 0, 255, 255);
476
- static Lime = new x(192, 255, 0, 255);
477
- static White = new x(255, 255, 255, 255);
478
- static Black = new x(0, 0, 0, 255);
479
- static Transparent = new x(0, 0, 0, 0);
480
- static TRANSPARENT = new x(0, 0, 0, 0);
138
+ 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();
139
+ }
140
+ static Red = new m(255, 0, 0, 255);
141
+ static Green = new m(0, 255, 0, 255);
142
+ static Blue = new m(0, 0, 255, 255);
143
+ static Yellow = new m(255, 255, 0, 255);
144
+ static Purple = new m(128, 0, 128, 255);
145
+ static Orange = new m(255, 165, 0, 255);
146
+ static Pink = new m(255, 192, 203, 255);
147
+ static Gray = new m(128, 128, 128, 255);
148
+ static Brown = new m(139, 69, 19, 255);
149
+ static Cyan = new m(0, 255, 255, 255);
150
+ static Magenta = new m(255, 0, 255, 255);
151
+ static Lime = new m(192, 255, 0, 255);
152
+ static White = new m(255, 255, 255, 255);
153
+ static Black = new m(0, 0, 0, 255);
154
+ static Transparent = new m(0, 0, 0, 0);
481
155
  }
482
- const E = 6;
483
- class Rt {
484
- /** Total number of matrices currently allocated in the store. */
485
- matrixCount = 0;
486
- /** The dynamic buffer used to hold matrix data. */
487
- buffer;
488
- /** The raw floating-point data of all matrices. */
489
- data;
490
- temporary = -1;
491
- /**
492
- * Creates a new MatrixStore.
493
- * @param capacity - The initial capacity of the matrix store (default is 10).
494
- */
495
- constructor(t = 10) {
496
- this.buffer = new b(A.Float32), this.buffer.resize(t * E), this.data = this.buffer.getArray(), this.reset();
497
- }
498
- /**
499
- * Allocates a new matrix and initializes it to the identity matrix.
500
- * @returns The index of the newly allocated matrix.
501
- */
502
- alloc() {
503
- const t = this.allocDirty();
504
- return this.identity(t), t;
505
- }
506
- /**
507
- * Allocates a new matrix without initializing its elements.
508
- * @returns The index of the newly allocated matrix.
509
- */
510
- allocDirty() {
511
- return this.buffer.resize(E) && (this.data = this.buffer.getArray()), this.buffer.usedElemNum += E, this.matrixCount++;
512
- }
513
- /**
514
- * Resets the store, clearing all allocated matrices.
515
- */
516
- reset() {
517
- this.matrixCount = 0, this.buffer.usedElemNum = 0, this.temporary = this.alloc();
518
- }
519
- /**
520
- * Sets the matrix at the given index to the identity matrix.
521
- * @param index - The index of the matrix to modify.
522
- */
523
- identity(t) {
524
- const e = t * E, r = this.data;
525
- r[e] = 1, r[e + 1] = 0, r[e + 2] = 0, r[e + 3] = 1, r[e + 4] = 0, r[e + 5] = 0;
526
- }
527
- /**
528
- * Translates the matrix at the given index by x and y.
529
- * @param index - The index of the matrix to modify.
530
- * @param x - The x translation.
531
- * @param y - The y translation.
532
- */
533
- translate(t, e, r) {
534
- const i = t * E, s = this.data;
535
- 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];
536
- }
537
- /**
538
- * Scales the matrix at the given index by scaleX and scaleY.
539
- * @param index - The index of the matrix to modify.
540
- * @param scaleX - The scale factor along the x-axis.
541
- * @param scaleY - The scale factor along the y-axis.
542
- */
543
- scale(t, e, r) {
544
- const i = t * E, s = this.data;
545
- s[i] *= e, s[i + 1] *= e, s[i + 2] *= r, s[i + 3] *= r;
546
- }
547
- /**
548
- * Rotates the matrix at the given index by the specified radians.
549
- * @param index - The index of the matrix to modify.
550
- * @param radians - The rotation angle in radians.
551
- */
552
- rotate(t, e) {
553
- 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];
554
- 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;
555
- }
556
- /**
557
- * Rotates the matrix at the given index around a local offset point (pivot).
558
- *
559
- * This is equivalent to:
560
- * 1. Translating by `(offsetX, offsetY)` to move the pivot to the origin.
561
- * 2. Rotating by `radians`.
562
- * 3. Translating back by `(-offsetX, -offsetY)`.
563
- *
564
- * Useful for rotating a sprite around a point other than its own origin,
565
- * e.g. a character's limb rotating around its joint.
566
- *
567
- * @param index - The index of the matrix to modify.
568
- * @param radians - The rotation angle in radians.
569
- * @param offsetX - The x component of the pivot point in local space.
570
- * @param offsetY - The y component of the pivot point in local space.
571
- */
572
- rotateWithOffset(t, e, r, i) {
573
- this.translate(t, r, i), this.rotate(t, e), this.translate(t, -r, -i);
574
- }
575
- /**
576
- * Copies the elements from the source matrix to the destination matrix.
577
- * @param dst - The index of the destination matrix.
578
- * @param src - The index of the source matrix.
579
- */
580
- copy(t, e) {
581
- const r = t * E, i = e * E, s = this.data;
582
- 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];
583
- }
584
- /**
585
- * Multiplies the destination matrix by the source matrix and stores the result in the destination.
586
- * @param dst - The index of the destination matrix.
587
- * @param src - The index of the source matrix.
588
- */
589
- multiply(t, e) {
590
- this.multiplyOut(t, t, e);
591
- }
592
- /**
593
- * Multiplies matrix A by matrix B and stores the result in the output matrix.
594
- * @param out - The index of the output matrix.
595
- * @param aIdx - The index of matrix A.
596
- * @param bIdx - The index of matrix B.
597
- */
598
- multiplyOut(t, e, r) {
599
- 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], g = o[a + 1], v = o[a + 2], y = o[a + 3], R = o[a + 4], M = o[a + 5];
600
- o[i] = h * m + u * g, o[i + 1] = c * m + l * g, o[i + 2] = h * v + u * y, o[i + 3] = c * v + l * y, o[i + 4] = h * R + u * M + d, o[i + 5] = c * R + l * M + f;
601
- }
602
- /**
603
- * Inverts the matrix at the given index. If the matrix is not invertible, it defaults to the identity matrix.
604
- * @param index - The index of the matrix to invert.
605
- */
606
- invert(t) {
607
- 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];
608
- let u = i * o - s * a;
609
- if (!u) {
610
- this.identity(t);
611
- return;
612
- }
613
- 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;
614
- }
615
- /**
616
- * Transforms a point by the matrix at the given index.
617
- * @param index - The index of the transformation matrix.
618
- * @param x - The x coordinate of the point.
619
- * @param y - The y coordinate of the point.
620
- * @returns The transformed point {x, y}.
621
- */
622
- transformPoint(t, e, r) {
623
- const i = t * E, s = this.data;
624
- return {
625
- x: e * s[i] + r * s[i + 2] + s[i + 4],
626
- y: e * s[i + 1] + r * s[i + 3] + s[i + 5]
627
- };
628
- }
629
- /**
630
- * Transforms a point from world coordinates to local coordinates using the matrix at the specified index.
631
- * Useful for hit testing against objects placed in world space.
632
- * @param index - The index of the world transformation matrix.
633
- * @param x - World x coordinate.
634
- * @param y - World y coordinate.
635
- * @returns The transformed point in local coordinates.
636
- */
637
- worldToLocal(t, e, r) {
638
- const i = this.allocDirty();
639
- this.copy(i, t), this.invert(i);
640
- const s = this.transformPoint(i, e, r);
641
- return this.matrixCount--, this.buffer.usedElemNum -= E, s;
642
- }
643
- /**
644
- * Transforms a point from local coordinates to world coordinates.
645
- * @param index - The index of the local transformation matrix.
646
- * @param x - Local x coordinate.
647
- * @param y - Local y coordinate.
648
- * @returns The transformed point in world coordinates.
649
- */
650
- localToWorld(t, e, r) {
651
- return this.transformPoint(t, e, r);
652
- }
653
- /**
654
- * Extracts the global position (translation) from the matrix at the given index.
655
- * @param index - The index of the matrix.
656
- * @returns An object containing `x` and `y` global coordinates.
657
- */
658
- getPosition(t) {
659
- const e = t * E, r = this.data;
660
- return { x: r[e + 4], y: r[e + 5] };
661
- }
662
- /**
663
- * Extracts the global scale from the matrix at the given index.
664
- * @param index - The index of the matrix.
665
- * @returns An object containing `x` and `y` global scale factors.
666
- */
667
- getScale(t) {
668
- 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]);
669
- return { x: i, y: s };
670
- }
671
- /**
672
- * Extracts the global rotation (in radians) from the matrix at the given index.
673
- * @param index - The index of the matrix.
674
- * @returns The global rotation in radians.
675
- */
676
- getRotation(t) {
677
- const e = t * E, r = this.data;
678
- return Math.atan2(r[e + 1], r[e]);
679
- }
680
- /**
681
- * Converts the matrix at the given index to a CSS matrix string.
682
- * @param index - The index of the matrix.
683
- * @param scaleX - Extra scale applied to the a/c/tx components (e.g. to convert logic pixels to CSS pixels).
684
- * @param scaleY - Extra scale applied to the b/d/ty components.
685
- * @returns A CSS matrix string.
686
- */
687
- toCSSMatrix(t, e = 1, r = 1) {
688
- const i = t * E, s = this.data;
689
- 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})`;
690
- }
691
- /**
692
- * Retrieves a copy of the 6 elements [a, b, c, d, tx, ty] for the matrix at the specified index.
693
- * Note: This uses `slice` to return a new Float32Array instance, ensuring the original data remains safely isolated.
694
- *
695
- * @param index - The index of the matrix.
696
- * @returns A new Float32Array containing the 6 elements of the matrix.
697
- */
698
- getMatrix(t) {
699
- const e = t * E;
700
- return this.data.slice(e, e + E);
701
- }
702
- /**
703
- * Retrieves a direct reference (view) to the 6 elements [a, b, c, d, tx, ty] for the matrix at the specified index.
704
- * Note: This uses `subarray`. Any modifications made to the returned array will directly affect the underlying MatrixStore data.
705
- *
706
- * @param index - The index of the matrix.
707
- * @returns A Float32Array view pointing directly to the matrix's data in memory.
708
- */
709
- getMatrixRef(t) {
710
- const e = t * E;
711
- return this.data.subarray(e, e + E);
712
- }
713
- /**
714
- * Overwrites the matrix at the specified index with the provided 6 elements [a, b, c, d, tx, ty].
715
- *
716
- * @param index - The index of the matrix to modify.
717
- * @param f - An array (Float32Array or standard number array) containing the 6 new elements.
718
- */
719
- setMatrix(t, e) {
720
- const r = t * E, i = this.data;
721
- 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];
722
- }
723
- multiplyAffineInPlace(t, e, r, i, s, a, o) {
724
- 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], g = c[h + 5];
725
- 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 + g;
726
- }
727
- multiplyAffine(t, e, r, i, s, a, o, h) {
728
- const c = t * 6, u = e * 6, l = this.data, d = l[c], f = l[c + 1], m = l[c + 2], g = l[c + 3], v = l[c + 4], y = l[c + 5];
729
- l[u] = d * r + m * i, l[u + 1] = f * r + g * i, l[u + 2] = d * s + m * a, l[u + 3] = f * s + g * a, l[u + 4] = d * o + m * h + v, l[u + 5] = f * o + g * h + y;
730
- }
731
- }
732
- class wt {
733
- /** The underlying store for matrices. */
734
- matrix = new Rt();
735
- /** The current step or depth in the transformation hierarchy. */
736
- step = 0;
737
- /** Internal stack maintaining structural information. */
738
- stack = new b(A.Uint32);
739
- /** Records the world matrices generated at each step. */
740
- stepWorldM = new b(A.Uint32);
741
- /** Records actions (push/pop) taken during the traversal. */
742
- stepAction = new b(A.Uint32);
743
- /** Records the parent world matrix for each step (used by updateMatrixSubtree). */
744
- stepParentM = new b(A.Uint32);
745
- /** Buffer used during hierarchy traversal updates. */
746
- parentStack = new b(A.Uint32);
747
- /** The index of the current local matrix in the matrix store. */
748
- curLocalM = -1;
749
- /** The index of the current world matrix in the matrix store. */
750
- curWorldM = -1;
751
- rapid;
752
- /**
753
- * Creates a new MatrixStack and initializes its state.
754
- */
755
- constructor(t) {
756
- this.reset(), this.rapid = t;
757
- }
758
- /**
759
- * Saves the current matrix state and pushes it onto the stack.
760
- * Equivalent to context.save().
761
- * @returns The current step counter before saving.
762
- */
763
- save() {
764
- this.stack.push(this.curWorldM);
765
- const t = this.curWorldM;
766
- return this.curLocalM = this.matrix.alloc(), this.curWorldM = this.matrix.allocDirty(), this.stepWorldM.push(this.curWorldM), this.stepParentM.push(t), this.stepAction.push(1), this.matrix.copy(this.curWorldM, t), { world: this.curWorldM, local: this.curLocalM, step: this.step++ };
767
- }
768
- /**
769
- * Restores the matrix state from the top of the stack.
770
- * Equivalent to context.restore().
771
- */
772
- restore() {
773
- this.stack.length != 0 && (this.curWorldM = this.stack.pop(), this.curLocalM = this.curWorldM - 1, this.stepParentM.push(this.stack.get(this.stack.length - 1)), this.stepWorldM.push(this.curWorldM), this.stepAction.push(0), this.step++);
774
- }
775
- /**
776
- * Evaluates and updates matrices from the given step. Used primarily for deferred transformation.
777
- * @param step - The initial step to update matrices from.
778
- */
779
- updateMatrixSubtree(t) {
780
- const e = typeof t == "number" ? t : t.step;
781
- let r = 0, i = e;
782
- for (; i < this.step; ) {
783
- if (this.stepAction.get(i) === 1) {
784
- const a = this.stepWorldM.get(i), o = a - 1, h = this.stepParentM.get(i);
785
- this.matrix.multiplyOut(a, h, o), r++;
786
- } else if (r--, r === 0)
787
- break;
788
- i++;
789
- }
790
- }
791
- /**
792
- * Translates the current local and world matrices by x and y.
793
- * @param x - Translation along the x-axis.
794
- * @param y - Translation along the y-axis.
795
- */
796
- translate(t, e) {
797
- this.matrix.translate(this.curLocalM, t, e), this.matrix.translate(this.curWorldM, t, e);
798
- }
799
- /**
800
- * Scales the current local and world matrices by scaleX and scaleY.
801
- * @param scaleX - Scaling factor along the x-axis.
802
- * @param scaleY - Scaling factor along the y-axis.
803
- */
804
- scale(t, e = t) {
805
- this.matrix.scale(this.curLocalM, t, e), this.matrix.scale(this.curWorldM, t, e);
806
- }
807
- /**
808
- * Rotates the current local and world matrices by the given radians.
809
- * @param radians - The rotation angle in radians.
810
- */
811
- rotate(t) {
812
- this.matrix.rotate(this.curLocalM, t), this.matrix.rotate(this.curWorldM, t);
813
- }
814
- /**
815
- * Rotates the current local and world matrices around a pivot point
816
- * that is offset from the matrix origin by `(offsetX, offsetY)`.
817
- *
818
- * This is a convenience wrapper around the common translate → rotate → translate-back
819
- * pattern, avoiding manual coordinate juggling at the call site.
820
- *
821
- * @example
822
- * ```ts
823
- * // Rotate a 64×64 sprite around its centre
824
- * stack.rotateWithOffset(angle, 32, 32);
825
- * ```
826
- *
827
- * @param radians - The rotation angle in radians.
828
- * @param offsetX - The x component of the pivot point in local space.
829
- * @param offsetY - The y component of the pivot point in local space.
830
- */
831
- rotateWithOffset(t, e, r) {
832
- this.matrix.rotateWithOffset(this.curLocalM, t, e, r), this.matrix.rotateWithOffset(this.curWorldM, t, e, r);
833
- }
834
- /**
835
- * Sets the current local and world matrices to the identity matrix.
836
- */
837
- identity() {
838
- this.matrix.identity(this.curLocalM), this.matrix.identity(this.curWorldM);
839
- }
840
- /**
841
- * Resets the entire stack state context, clearing matrices and step actions.
842
- */
843
- reset() {
844
- this.matrix.reset(), this.stack.reset(), this.stepAction.reset(), this.stepWorldM.reset(), this.stepParentM.reset(), this.step = 0, this.curLocalM = this.matrix.alloc(), this.curWorldM = this.matrix.alloc();
845
- }
846
- /**
847
- * Transforms a point from local coordinates to world coordinates.
848
- * Uses the current world matrix to apply the transformation.
849
- * @param x - Local x coordinate.
850
- * @param y - Local y coordinate.
851
- * @returns The transformed point in world coordinates.
852
- */
853
- localToWorld(t, e) {
854
- return this.matrix.localToWorld(this.curWorldM, t, e);
855
- }
856
- /**
857
- * Transforms a point from world coordinates to local coordinates.
858
- * Useful for hit testing against objects placed in world space.
859
- * @param x - World x coordinate.
860
- * @param y - World y coordinate.
861
- * @returns The transformed point in local coordinates.
862
- */
863
- worldToLocal(t, e) {
864
- return this.matrix.worldToLocal(this.curWorldM, t, e);
865
- }
866
- /**
867
- * Extracts the global position (translation) from the current world matrix.
868
- * @returns An object containing `x` and `y` global coordinates.
869
- */
870
- getGlobalPosition() {
871
- return this.matrix.getPosition(this.curWorldM);
872
- }
873
- /**
874
- * Extracts the global scale from the current world matrix.
875
- * @returns An object containing `x` and `y` global scale factors.
876
- */
877
- getGlobalScale() {
878
- return this.matrix.getScale(this.curWorldM);
879
- }
880
- /**
881
- * Extracts the global rotation (in radians) from the current world matrix.
882
- * @returns The global rotation in radians.
883
- */
884
- getGlobalRotation() {
885
- return this.matrix.getRotation(this.curWorldM);
886
- }
887
- toCSSMatrix() {
888
- return this.matrix.toCSSMatrix(this.curWorldM);
889
- }
890
- /**
891
- * Returns the current world matrix as Float32Array [a, b, c, d, tx, ty].
892
- */
893
- getTransform() {
894
- const t = this.curWorldM * E;
895
- return this.matrix.data.slice(t, t + E);
896
- }
897
- /**
898
- * Directly overwrites the current world matrix with the given 6-element 2D transform.
899
- */
900
- setTransform(t) {
901
- const e = this.curWorldM * E, r = this.matrix.data;
902
- 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];
903
- }
904
- transformPoint(t, e) {
905
- return this.matrix.transformPoint(this.curLocalM, t, e);
906
- }
907
- /**
908
- * Applies a transform options object to the current matrix state.
909
- * Optionally saves the matrix first
910
- */
911
- applyTransform(t, e = 0, r = 0, i = -1) {
912
- let s = t.x ?? 0, a = t.y ?? 0;
913
- t.position && (s += t.position.x, a += t.position.y);
914
- let o = 1, h = 1;
915
- const c = t.scale;
916
- c && (typeof c == "number" ? (o = c, h = c) : (o = c.x, h = c.y));
917
- const u = t.rotation ?? 0;
918
- let l = t.offsetX ?? 0, d = t.offsetY ?? 0;
919
- t.offset && (l += t.offset.x, d += t.offset.y);
920
- const f = t.origin;
921
- f !== void 0 && (typeof f == "number" ? (l -= f * e, d -= f * r) : (l -= f.x * e, d -= f.y * r));
922
- const m = u ? Math.cos(u) : 1, g = u ? Math.sin(u) : 0, v = m * o, y = g * o, R = -g * h, M = m * h, C = s + v * l + R * d, P = a + y * l + M * d;
923
- if (i !== -1) {
924
- this.matrix.multiplyAffine(
925
- this.curWorldM,
926
- i,
927
- v,
928
- y,
929
- R,
930
- M,
931
- C,
932
- P
933
- );
934
- return;
935
- }
936
- this.matrix.multiplyAffineInPlace(
937
- this.curLocalM,
938
- v,
939
- y,
940
- R,
941
- M,
942
- C,
943
- P
944
- ), this.matrix.multiplyAffineInPlace(
945
- this.curWorldM,
946
- v,
947
- y,
948
- R,
949
- M,
950
- C,
951
- P
952
- );
953
- }
954
- }
955
- var K = /* @__PURE__ */ ((n) => (n[n.REPEAT = 0] = "REPEAT", n[n.CLAMP = 1] = "CLAMP", n[n.MIRRORED_REPEAT = 2] = "MIRRORED_REPEAT", n))(K || {});
956
- class Mt {
156
+ var tt = /* @__PURE__ */ ((n) => (n[n.LINEAR = 0] = "LINEAR", n[n.NEAREST = 1] = "NEAREST", n))(tt || {}), q = /* @__PURE__ */ ((n) => (n[n.REPEAT = 0] = "REPEAT", n[n.CLAMP = 1] = "CLAMP", n[n.MIRRORED_REPEAT = 2] = "MIRRORED_REPEAT", n))(q || {});
157
+ class Ct {
957
158
  render;
958
159
  cache = /* @__PURE__ */ new Map();
959
160
  constructor(t) {
960
161
  this.render = t;
961
162
  }
962
- /**
963
- * Asynchronously loads a texture from a URL.
964
- * @param url - The image URL to load.
965
- * @param options - Optional configuration for the texture.
966
- * @returns A promise that resolves to the loaded Texture.
967
- */
968
163
  async load(t, e) {
969
164
  let r = this.cache.get(t);
970
165
  if (r)
971
166
  return new N(r);
972
167
  try {
973
168
  const i = await this._fetchImage(t);
974
- return r = Y.fromSource(this.render, i, e), r.uid = t, this.cache.set(t, r), new N(r);
169
+ return r = V.fromSource(this.render, i, e), r.uid = t, this.cache.set(t, r), new N(r);
975
170
  } catch (i) {
976
171
  throw console.error(`[TextureManager] Failed to load: ${t}`, i), i;
977
172
  }
978
173
  }
979
- /**
980
- * Creates a texture synchronously from an existing HTML element (Image, Canvas, Video).
981
- * @param source - The source image element.
982
- * @param options - Optional configuration for the texture.
983
- * @returns The newly created Texture.
984
- */
985
174
  create(t, e) {
986
175
  if (e?.key && this.cache.has(e.key))
987
176
  return new N(this.cache.get(e.key));
988
- const r = Y.fromSource(this.render, t, e);
177
+ const r = V.fromSource(this.render, t, e);
989
178
  return e?.key && (r.uid = e.key, this.cache.set(e.key, r)), new N(r);
990
179
  }
991
- /**
992
- * Creates a generic Render Texture (FrameBuffer).
993
- * @param width - The width of the render texture.
994
- * @param height - The height of the render texture.
995
- * @param options - Optional configuration for the texture.
996
- * @returns The newly created RenderTexture.
997
- */
998
180
  createRenderTexture(t) {
999
- return new At(this.render, t);
181
+ return new _t(this.render, t);
1000
182
  }
1001
- /**
1002
- * Creates a TextTexture for rendering text.
1003
- * @param options - Optional configuration for the texture.
1004
- * @returns The newly created TextTexture.
1005
- */
1006
183
  createTextTexture(t) {
1007
- return new bt(this.render, t);
1008
- }
1009
- /**
1010
- * Destroys a texture and potentially removes its BaseTexture from the cache.
1011
- * If a Texture instance is provided, it decrements the reference count of the BaseTexture.
1012
- * The BaseTexture will only be destroyed if its reference count drops to 0, or if `force` is true.
1013
- * @param textureOrUrl - The texture instance, base texture, or cache key (URL) to destroy.
1014
- * @param force - If true, destroys the underlying BaseTexture immediately regardless of reference count.
1015
- */
184
+ return new Pt(this.render, t);
185
+ }
1016
186
  destroy(t, e = !1) {
1017
187
  let r, i;
1018
188
  typeof t == "string" ? (i = t, r = this.cache.get(i)) : t instanceof N ? (r = t.base, i = r?.uid, t.destroy()) : (r = t, i = r.uid), r && (r.refCount <= 0 || e) && (r.destroy(this.render.gl), i && this.cache.delete(i));
1019
189
  }
1020
- /**
1021
- * Destroys all cached textures and clears the cache, ignoring reference counts.
1022
- */
1023
190
  destroyAll() {
1024
191
  for (const t of this.cache.values())
1025
192
  t.destroy(this.render.gl);
@@ -1032,7 +199,7 @@ class Mt {
1032
199
  });
1033
200
  }
1034
201
  }
1035
- class Y {
202
+ class V {
1036
203
  glTexture = null;
1037
204
  width;
1038
205
  height;
@@ -1041,42 +208,19 @@ class Y {
1041
208
  constructor(t, e, r) {
1042
209
  this.glTexture = t, this.width = e, this.height = r;
1043
210
  }
1044
- /**
1045
- * Creates a BaseTexture from an image source.
1046
- * @param render - The Rapid renderer instance.
1047
- * @param source - The image source.
1048
- * @param options - Optional configuration.
1049
- * @returns The created BaseTexture.
1050
- */
1051
211
  static fromSource(t, e, r = {}) {
1052
- const i = Z(t, e, r);
1053
- return new Y(i, e.width, e.height);
1054
- }
1055
- /**
1056
- * Updates the content of the existing texture (e.g. for Video or dynamic Canvas).
1057
- * Uses texSubImage2D if dimensions haven't changed for better performance.
1058
- * @param gl - The WebGL rendering context.
1059
- * @param source - The new image source.
1060
- */
212
+ const i = rt(t, e, r);
213
+ return new V(i, e.width, e.height);
214
+ }
1061
215
  updateSource(t, e, r = {}) {
1062
- this.glTexture && (t.bindTexture(t.TEXTURE_2D, this.glTexture), r.textureFilter !== void 0 && rt(t, r.textureFilter), r.wrap !== void 0 && et(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));
216
+ this.glTexture && (t.bindTexture(t.TEXTURE_2D, this.glTexture), r.textureFilter !== void 0 && ht(t, r.textureFilter), r.wrap !== void 0 && at(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));
1063
217
  }
1064
- /**
1065
- * Dynamically updates the texture filtering mode.
1066
- */
1067
218
  setFilterMode(t, e) {
1068
- this.glTexture && (t.bindTexture(t.TEXTURE_2D, this.glTexture), rt(t, e), t.bindTexture(t.TEXTURE_2D, null));
219
+ this.glTexture && (t.bindTexture(t.TEXTURE_2D, this.glTexture), ht(t, e), t.bindTexture(t.TEXTURE_2D, null));
1069
220
  }
1070
- /**
1071
- * Dynamically updates the texture wrap mode.
1072
- */
1073
221
  setWrapMode(t, e) {
1074
- this.glTexture && (t.bindTexture(t.TEXTURE_2D, this.glTexture), et(t, e), t.bindTexture(t.TEXTURE_2D, null));
222
+ this.glTexture && (t.bindTexture(t.TEXTURE_2D, this.glTexture), at(t, e), t.bindTexture(t.TEXTURE_2D, null));
1075
223
  }
1076
- /**
1077
- * Destroys the WebGL texture resource.
1078
- * @param gl - The WebGL rendering context.
1079
- */
1080
224
  destroy(t) {
1081
225
  this.glTexture && (t.deleteTexture(this.glTexture), this.glTexture = null);
1082
226
  }
@@ -1105,113 +249,54 @@ class N {
1105
249
  // Stored pixel-space region (before UV conversion), used by getSubTexture()
1106
250
  _px = 0;
1107
251
  _py = 0;
1108
- _pw = 0;
1109
- _ph = 0;
1110
252
  constructor(t) {
1111
253
  t && this.setBase(t);
1112
254
  }
1113
- /**
1114
- * Sets the base texture and increments its reference count.
1115
- * @param base - The BaseTexture instance.
1116
- * @returns The current Texture instance.
1117
- */
1118
255
  setBase(t) {
1119
256
  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);
1120
257
  }
1121
- /**
1122
- * Sets the visible region (clipping) in pixels relative to the BaseTexture.
1123
- * @param x - The x coordinate in pixels.
1124
- * @param y - The y coordinate in pixels.
1125
- * @param w - The width in pixels.
1126
- * @param h - The height in pixels.
1127
- * @returns The current Texture instance.
1128
- */
1129
258
  setRegion(t, e, r, i) {
1130
- return this.base ? (this._px = t, this._py = e, this._pw = r, this._ph = i, 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;
1131
- }
1132
- /**
1133
- * Creates a new Texture representing a sub-region of this Texture.
1134
- * @param x - The x coordinate in pixels, relative to this texture's logical start.
1135
- * @param y - The y coordinate in pixels, relative to this texture's logical start.
1136
- * @param width - The width of the sub-texture in pixels.
1137
- * @param height - The height of the sub-texture in pixels.
1138
- * @returns A new Texture pointing to the sub-region.
1139
- */
259
+ 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;
260
+ }
1140
261
  getSubTexture(t, e, r, i) {
1141
262
  if (!this.base) return new N();
1142
- const s = this.clone(), a = this._px, o = this._py;
1143
- return s.setRegion(a + t, o + e, r, i), s;
263
+ const s = this.clone(), a = this._px, h = this._py;
264
+ return s.setRegion(a + t, h + e, r, i), s;
1144
265
  }
1145
- /**
1146
- * Creates a shallow copy of this Texture, sharing the same BaseTexture.
1147
- * @returns A new Texture instance.
1148
- */
1149
266
  clone(t) {
1150
267
  const e = t ?? new N(this.base);
1151
- 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._pw = this._pw, e._ph = this._ph, e;
1152
- }
1153
- /**
1154
- * Utility to split this texture into a grid of sprite textures.
1155
- * Sub-textures will respect the current UV offsets.
1156
- * @param cellWidth - The width of each cell in pixels.
1157
- * @param cellHeight - The height of each cell in pixels.
1158
- * @param cols - Optional number of columns. Truncates based on texture width if omitted.
1159
- * @param rows - Optional number of rows. Truncates based on texture height if omitted.
1160
- * @param gap - Optional pixel gap between cells.
1161
- * @returns An array of split Textures.
1162
- */
268
+ 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;
269
+ }
1163
270
  splitGrid(t, e, r, i, s = 0) {
1164
271
  if (!this.base) return [];
1165
- 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);
1166
- for (let m = 0; m < f; m++)
1167
- for (let g = 0; g < d; g++)
1168
- a.push(this.getSubTexture(g * u, m * l, t, e));
272
+ const a = [], h = this.rawWidth, o = this.rawHeight, c = Math.max(0, s), u = t + c, l = e + c, f = r ?? Math.floor((h + c) / u), d = i ?? Math.floor((o + c) / l);
273
+ for (let x = 0; x < d; x++)
274
+ for (let p = 0; p < f; p++)
275
+ a.push(this.getSubTexture(p * u, x * l, t, e));
1169
276
  return a;
1170
277
  }
1171
- /**
1172
- * Creates a Texture directly from an image source, bypassing the TextureManager.
1173
- * @param source - The image element, canvas, video, or bitmap.
1174
- * @param options - Optional antialias and wrap mode settings.
1175
- */
1176
278
  static fromImageSource(t, e, r = {}) {
1177
- const i = Z(t, e, r);
1178
- return new N(new Y(i, e.width, e.height));
279
+ const i = rt(t, e, r);
280
+ return new N(new V(i, e.width, e.height));
1179
281
  }
1180
- /**
1181
- * Marks this Texture as destroyed, decrementing the BaseTexture reference count.
1182
- */
1183
282
  destroy() {
1184
283
  this.base && (this.base.refCount--, this.base = void 0), this.glTexture = null;
1185
284
  }
1186
285
  }
1187
- class At extends N {
286
+ class _t extends N {
1188
287
  framebuffer;
1189
288
  renderbuffer;
1190
289
  gl;
1191
- flipY = !0;
1192
290
  clearColor;
1193
- /** Actual GPU-allocated dimensions — grow-only, never shrink */
1194
291
  _allocW = 0;
1195
292
  _allocH = 0;
1196
293
  constructor(t, e) {
1197
- super(), this.gl = t.gl, this.clearColor = e.clearColor ?? x.Black;
1198
- const r = Math.max(Math.round(e.width), 1), i = Math.max(Math.round(e.height), 1), a = Z(t, { width: r, height: i }, { ...e, onlySize: !0 });
1199
- if (this.setBase(new Y(a, r, i)), this.framebuffer = this.gl.createFramebuffer(), this.renderbuffer = this.gl.createRenderbuffer(), !this.framebuffer || !this.renderbuffer)
294
+ super(), this.gl = t.gl, this.clearColor = e.clearColor ?? m.Black;
295
+ const r = Math.max(Math.round(e.width), 1), i = Math.max(Math.round(e.height), 1), a = rt(t, { width: r, height: i }, { ...e, onlySize: !0 });
296
+ if (this.setBase(new V(a, r, i)), this.framebuffer = this.gl.createFramebuffer(), this.renderbuffer = this.gl.createRenderbuffer(), !this.framebuffer || !this.renderbuffer)
1200
297
  throw new Error("Failed to create Framebuffer or Renderbuffer");
1201
298
  this.resize(r, i, !0);
1202
299
  }
1203
- /**
1204
- * Resizes the render texture using a grow-only GPU allocation strategy.
1205
- *
1206
- * - GPU memory is only reallocated when the new size **exceeds** the current allocation.
1207
- * - Shrinking only updates the logical dimensions and UV sub-region — no GPU work.
1208
- *
1209
- * This makes it safe to call every frame with varying sizes (e.g. inside applyFilters).
1210
- *
1211
- * @param width - New logical width.
1212
- * @param height - New logical height.
1213
- * @param force - Force full GPU reallocation regardless of current allocation size.
1214
- */
1215
300
  resize(t, e, r = !1) {
1216
301
  t = Math.max(Math.round(t), 1), e = Math.max(Math.round(e), 1);
1217
302
  const i = this.rawWidth === t && this.rawHeight === e;
@@ -1219,10 +304,6 @@ class At extends N {
1219
304
  const s = this.gl;
1220
305
  (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;
1221
306
  }
1222
- /**
1223
- * Activates this texture as the current render target.
1224
- * @param clear - Whether to clear the render target after activation.
1225
- */
1226
307
  activate(t = !1) {
1227
308
  if (!this.framebuffer) return;
1228
309
  const e = this.gl;
@@ -1233,48 +314,30 @@ class At extends N {
1233
314
  const e = this.gl, r = t ?? this.clearColor;
1234
315
  r && (r.setClearColor(e), e.clear(e.COLOR_BUFFER_BIT | e.STENCIL_BUFFER_BIT));
1235
316
  }
1236
- /**
1237
- * Deactivates this texture, returning rendering to the default frame buffer.
1238
- */
1239
317
  deactivate() {
1240
318
  const t = this.gl;
1241
319
  t.bindFramebuffer(t.FRAMEBUFFER, null);
1242
320
  }
1243
- /**
1244
- * Get raw pixels from the render texture.
1245
- * @param x - X coordinate in logical pixel space (top-left origin).
1246
- * @param y - Y coordinate in logical pixel space (top-left origin).
1247
- * @param width - Width of the region to read.
1248
- * @param height - Height of the region to read.
1249
- */
1250
321
  GetPixels(t = 0, e = 0, r = this.rawWidth, i = this.rawHeight) {
1251
322
  if (!this.framebuffer) return new Uint8Array(0);
1252
- const s = Math.floor(t), a = Math.floor(e), o = Math.floor(r), h = Math.floor(i);
1253
- if (o <= 0 || h <= 0) return new Uint8Array(0);
323
+ const s = Math.floor(t), a = Math.floor(e), h = Math.floor(r), o = Math.floor(i);
324
+ if (h <= 0 || o <= 0) return new Uint8Array(0);
1254
325
  if (s < 0 || a < 0 || s >= this.rawWidth || a >= this.rawHeight)
1255
326
  return new Uint8Array(0);
1256
- const c = Math.min(o, this.rawWidth - s), u = Math.min(h, this.rawHeight - a), l = this.rawHeight - a - u, d = this.gl, f = d.getParameter(d.FRAMEBUFFER_BINDING);
1257
- d.bindFramebuffer(d.FRAMEBUFFER, this.framebuffer);
1258
- const m = new Uint8Array(c * u * 4);
1259
- return d.readPixels(s, l, c, u, d.RGBA, d.UNSIGNED_BYTE, m), d.bindFramebuffer(d.FRAMEBUFFER, f), m;
1260
- }
1261
- /**
1262
- * Get the color at a pixel in the render texture.
1263
- * @param x - X coordinate in logical pixel space (top-left origin).
1264
- * @param y - Y coordinate in logical pixel space (top-left origin).
1265
- */
327
+ const c = Math.min(h, this.rawWidth - s), u = Math.min(o, this.rawHeight - a), l = this.gl, f = l.getParameter(l.FRAMEBUFFER_BINDING);
328
+ l.bindFramebuffer(l.FRAMEBUFFER, this.framebuffer);
329
+ const d = new Uint8Array(c * u * 4);
330
+ return l.readPixels(s, a, c, u, l.RGBA, l.UNSIGNED_BYTE, d), l.bindFramebuffer(l.FRAMEBUFFER, f), d;
331
+ }
1266
332
  GetColorAt(t, e) {
1267
333
  const r = this.GetPixels(t, e, 1, 1);
1268
- return r.length < 4 ? new x(0, 0, 0, 0) : new x(r[0], r[1], r[2], r[3]);
334
+ return r.length < 4 ? new m(0, 0, 0, 0) : new m(r[0], r[1], r[2], r[3]);
1269
335
  }
1270
- /**
1271
- * Destroys the framebuffer, renderbuffer, and base texture.
1272
- */
1273
336
  destroy() {
1274
337
  super.destroy(), this.framebuffer && this.gl.deleteFramebuffer(this.framebuffer), this.renderbuffer && this.gl.deleteRenderbuffer(this.renderbuffer), this.base?.destroy(this.gl);
1275
338
  }
1276
339
  }
1277
- const St = {
340
+ const Lt = {
1278
341
  fontFamily: "Arial",
1279
342
  fontSize: 24,
1280
343
  fontWeight: "normal",
@@ -1283,7 +346,7 @@ const St = {
1283
346
  align: "left",
1284
347
  lineHeight: 1
1285
348
  };
1286
- class bt extends N {
349
+ class Pt extends N {
1287
350
  canvas;
1288
351
  ctx;
1289
352
  render;
@@ -1292,28 +355,22 @@ class bt extends N {
1292
355
  options;
1293
356
  flipY = !0;
1294
357
  constructor(t, e) {
1295
- super(), this.render = t, this._style = { ...St, ...e }, this._text = e?.text ?? "", this.options = { premultipliedAlpha: t.premultipliedAlpha, ...e }, this.scale = 1 / t.dpr, this.canvas = document.createElement("canvas");
358
+ super(), this.render = t, this._style = { ...Lt, ...e }, this._text = e?.text ?? "", this.options = { premultipliedAlpha: t.premultipliedAlpha, ...e }, this.scale = 1 / t.dpr, this.canvas = document.createElement("canvas");
1296
359
  const r = this.canvas.getContext("2d", { willReadFrequently: !0 });
1297
360
  if (!r) throw new Error("Failed to get 2d context for TextTexture");
1298
361
  this.ctx = r, this.canvas.width = 1, this.canvas.height = 1;
1299
- const i = Z(t, this.canvas, this.options);
1300
- this.setBase(new Y(i, 1, 1)), this.update();
362
+ const i = rt(t, this.canvas, this.options);
363
+ this.setBase(new V(i, 1, 1)), this.update();
1301
364
  }
1302
365
  get text() {
1303
366
  return this._text;
1304
367
  }
1305
- /**
1306
- * Set new text and update the texture
1307
- */
1308
368
  set text(t) {
1309
369
  this._text !== t && (this._text = t, this.update());
1310
370
  }
1311
371
  get style() {
1312
372
  return this._style;
1313
373
  }
1314
- /**
1315
- * Set new style partially and update the texture
1316
- */
1317
374
  set style(t) {
1318
375
  this._style = { ...this._style, ...t }, this.update();
1319
376
  }
@@ -1327,37 +384,34 @@ class bt extends N {
1327
384
  return e;
1328
385
  }
1329
386
  }
1330
- /**
1331
- * Updates the internal canvas and uploads it to WebGL
1332
- */
1333
387
  update() {
1334
- const t = this.ctx, e = this.style, r = e.fontSize, i = e.fontWeight, s = e.fontFamily, a = e.lineHeight, o = `${i} ${r}px ${s}`, h = this.render.dpr;
1335
- t.font = o, t.textBaseline = "top";
388
+ const t = this.ctx, e = this.style, r = e.fontSize, i = e.fontWeight, s = e.fontFamily, a = e.lineHeight, h = `${i} ${r}px ${s}`, o = this.render.dpr;
389
+ t.font = h, t.textBaseline = "top";
1336
390
  const c = this._text.split(`
1337
391
  `);
1338
392
  let u = 0, l = 0;
1339
- const d = t.measureText(c[0] || "M"), f = (d.fontBoundingBoxAscent || r) + (d.fontBoundingBoxDescent || r * 0.2);
1340
- for (const O of c) {
1341
- const _ = t.measureText(O);
1342
- _.width > u && (u = _.width), l += f * a;
393
+ const x = t.measureText(c[0] || "M").fontBoundingBoxDescent;
394
+ for (const b of c) {
395
+ const M = t.measureText(b);
396
+ M.width > u && (u = M.width), l += x * a;
1343
397
  }
1344
- l -= f * (a - 1);
1345
- const m = this._style.strokeThickness || 0, g = Math.ceil(u + m * 2) || 1, v = Math.ceil(l + m * 2) || 1, y = Math.ceil(g * h), R = Math.ceil(v * h);
1346
- (this.canvas.width !== y || this.canvas.height !== R) && (this.canvas.width = y, this.canvas.height = R), t.setTransform(h, 0, 0, h, 0, 0), t.clearRect(0, 0, g, v), t.font = o, t.textBaseline = "top", t.textAlign = this._style.align;
1347
- const M = this.updateOffset(g, m), C = e.strokeThickness, P = C > 0;
1348
- P && (t.lineWidth = C, t.strokeStyle = e.stroke, t.lineJoin = "round"), e.fill && (t.fillStyle = e.fill);
1349
- let I = m;
1350
- for (const O of c)
1351
- P && t.strokeText(O, M, I), e.fill && t.fillText(O, M, I), I += f * a;
1352
- this.base?.updateSource(this.render.gl, this.canvas, this.options), this.setRegion(0, 0, y, R);
398
+ l -= x * (a - 1);
399
+ const p = this._style.strokeThickness || 0, v = Math.ceil(u + p * 2) || 1, y = Math.ceil(l + p * 2) || 1, E = Math.ceil(v * o), w = Math.ceil(y * o);
400
+ (this.canvas.width !== E || this.canvas.height !== w) && (this.canvas.width = E, this.canvas.height = w), t.setTransform(o, 0, 0, o, 0, 0), t.clearRect(0, 0, v, y), t.font = h, t.textBaseline = "top", t.textAlign = this._style.align;
401
+ const _ = this.updateOffset(v, p), L = e.strokeThickness, W = L > 0;
402
+ W && (t.lineWidth = L, t.strokeStyle = e.stroke, t.lineJoin = "round"), e.fill && (t.fillStyle = e.fill);
403
+ let O = p;
404
+ for (const b of c)
405
+ W && t.strokeText(b, _, O), e.fill && t.fillText(b, _, O), O += x * a;
406
+ this.base?.updateSource(this.render.gl, this.canvas, this.options), this.setRegion(0, 0, E, w);
1353
407
  }
1354
408
  }
1355
- const Ut = (n, t = !1, e = !0) => {
409
+ const Nt = (n, t = !1, e = !0) => {
1356
410
  const r = n.getContext("webgl2", { stencil: !0, antialias: t, premultipliedAlpha: e });
1357
411
  if (!r)
1358
412
  throw new Error("WebGL2 is not supported in this browser.");
1359
413
  return r;
1360
- }, at = (n, t, e) => {
414
+ }, dt = (n, t, e) => {
1361
415
  const r = n.createShader(e);
1362
416
  if (!r)
1363
417
  throw new Error("Unable to create webgl shader");
@@ -1366,36 +420,36 @@ const Ut = (n, t = !1, e = !0) => {
1366
420
  throw console.error("Shader compilation failed:", s), new Error("Unable to compile shader: " + s + t);
1367
421
  }
1368
422
  return r;
1369
- }, Ct = (n, t, e) => {
1370
- var r = n.createProgram(), i = at(n, t, 35633), s = at(n, e, 35632);
423
+ }, It = (n, t, e) => {
424
+ var r = n.createProgram(), i = dt(n, t, 35633), s = dt(n, e, 35632);
1371
425
  if (!r)
1372
426
  throw new Error("Unable to create program shader");
1373
427
  if (n.attachShader(r, i), n.attachShader(r, s), n.linkProgram(r), !n.getProgramParameter(r, n.LINK_STATUS)) {
1374
- const o = n.getProgramInfoLog(r);
1375
- throw new Error("Unable to link shader program: " + o);
428
+ const h = n.getProgramInfoLog(r);
429
+ throw new Error("Unable to link shader program: " + h);
1376
430
  }
1377
431
  return r;
1378
432
  };
1379
- function et(n, t) {
433
+ function at(n, t) {
1380
434
  const e = {
1381
- [K.CLAMP]: n.CLAMP_TO_EDGE,
1382
- [K.REPEAT]: n.REPEAT,
1383
- [K.MIRRORED_REPEAT]: n.MIRRORED_REPEAT
435
+ [q.CLAMP]: n.CLAMP_TO_EDGE,
436
+ [q.REPEAT]: n.REPEAT,
437
+ [q.MIRRORED_REPEAT]: n.MIRRORED_REPEAT
1384
438
  }[t] || n.CLAMP_TO_EDGE;
1385
439
  n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_S, e), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_T, e);
1386
440
  }
1387
- function rt(n, t) {
441
+ function ht(n, t) {
1388
442
  const e = {
1389
- [st.LINEAR]: n.LINEAR,
1390
- [st.NEAREST]: n.NEAREST
443
+ [tt.LINEAR]: n.LINEAR,
444
+ [tt.NEAREST]: n.NEAREST
1391
445
  }[t] ?? n.NEAREST;
1392
446
  n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MIN_FILTER, e), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MAG_FILTER, e);
1393
447
  }
1394
- function Z(n, t, e) {
448
+ function rt(n, t, e) {
1395
449
  const r = n.gl, i = r.createTexture();
1396
450
  if (!i)
1397
451
  throw new Error("Unable to create WebGL texture");
1398
- if (r.bindTexture(r.TEXTURE_2D, i), r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL, 0), r.pixelStorei(r.UNPACK_ALIGNMENT, 1), et(r, e.wrap ?? K.CLAMP), rt(r, e.textureFilter ?? n.textureFilter), e.onlySize) {
452
+ if (r.bindTexture(r.TEXTURE_2D, i), r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL, 0), r.pixelStorei(r.UNPACK_ALIGNMENT, 1), at(r, e.wrap ?? q.CLAMP), ht(r, e.textureFilter ?? n.textureFilter), e.onlySize) {
1399
453
  const s = t;
1400
454
  r.texImage2D(r.TEXTURE_2D, 0, r.RGBA, s.width, s.height, 0, r.RGBA, r.UNSIGNED_BYTE, null);
1401
455
  } else {
@@ -1404,85 +458,59 @@ function Z(n, t, e) {
1404
458
  }
1405
459
  return r.bindTexture(r.TEXTURE_2D, null), i;
1406
460
  }
1407
- function H(n, t) {
1408
- if (n.includes("%TEXTURE_NUM%") && (n = n.replace("%TEXTURE_NUM%", t.toString())), n.includes("%GET_COLOR%")) {
1409
- let e = "";
1410
- for (let r = 0; r < t; r++)
1411
- r == 0 ? e += `if(vTextureId == ${r})` : r == t - 1 ? e += "else" : e += `else if(vTextureId == ${r})`, e += `{return texture(uTextures[${r}], uv);}`;
1412
- n = n.replace("%GET_COLOR%", e);
461
+ function D(n, t, e = "vTextureId", r = "uv", i = "return") {
462
+ if (n.includes("%TEXTURE_NUM%") && (n = n.replaceAll("%TEXTURE_NUM%", t.toString())), n.includes("%GET_COLOR%")) {
463
+ let s = "";
464
+ for (let a = 0; a < t; a++)
465
+ a == 0 ? s += `if(${e} == ${a})` : a == t - 1 ? s += "else" : s += `else if(${e} == ${a})`, s += `{${i} texture(uTextures[${a}], ${r});}`;
466
+ n = n.replaceAll("%GET_COLOR%", s);
1413
467
  }
1414
468
  return n;
1415
469
  }
1416
- const _t = 5126, it = 5121;
1417
- function Pt(n, t, e) {
470
+ const Wt = 5126, ot = 5121;
471
+ function Ot(n, t, e) {
1418
472
  n.vertexAttribDivisor(t, e);
1419
473
  }
1420
- function pt(n, t, e, r, i) {
474
+ function Et(n, t, e, r, i) {
1421
475
  n.drawArraysInstanced(t, e, r, i);
1422
476
  }
1423
- let Lt = 0;
1424
- class gt {
477
+ let Ft = 0;
478
+ class Rt {
1425
479
  program;
1426
480
  attributeLoc = {};
1427
481
  uniformLoc = {};
1428
482
  isCustom = !1;
1429
- /** Padding in pixels this shader needs beyond the sprite bounds (for outline/glow effects) */
1430
483
  padding = 0;
1431
- /** GLSL type for each uniform, parsed from source */
1432
484
  uniformType = {};
1433
- /** Whether the uniform is an array (e.g. sampler2D uTextures[8]) */
1434
485
  uniformIsArray = {};
1435
486
  gl;
1436
- shaderId = Lt++;
487
+ shaderId = Ft++;
1437
488
  // for debug
1438
489
  vao;
1439
490
  constructor(t, e, r, i) {
1440
- this.gl = t, this.program = Ct(t, e, r), this.parseShader(e), this.parseShader(r), this.vao = t.createVertexArray(), i && this.setAttributes(i);
491
+ this.gl = t, this.program = It(t, e, r), this.parseShader(e), this.parseShader(r), this.vao = t.createVertexArray(), i && this.setAttributes(i);
1441
492
  }
1442
- /** Switch GPU to use this shader program */
1443
493
  use() {
1444
494
  this.gl.useProgram(this.program);
1445
495
  }
1446
- /** Bind this shader's VAO (start recording or replaying attribute state) */
1447
496
  bindVAO() {
1448
497
  this.gl.bindVertexArray(this.vao);
1449
498
  }
1450
- /** Unbind VAO (finish recording) */
1451
499
  unbindVAO() {
1452
500
  this.gl.bindVertexArray(null);
1453
501
  }
1454
502
  // ── Uniforms ─────────────────────────────────────────────────────────────
1455
- /**
1456
- * Set a single uniform by name. Type is inferred from the parsed GLSL source.
1457
- * @example
1458
- * shader.setUniform("uTime", 1.5);
1459
- * shader.setUniform("uColor", [1, 0, 0, 1]);
1460
- * shader.setUniform("uMVP", mat4array);
1461
- */
1462
503
  setUniform(t, e) {
1463
504
  const r = this.uniformLoc[t];
1464
505
  if (r === void 0) return;
1465
506
  const i = this.uniformType[t], s = this.uniformIsArray[t];
1466
- Nt(this.gl, r, i, e, s);
1467
- }
1468
- /**
1469
- * Batch-set uniforms via a plain value map.
1470
- * @example
1471
- * shader.setUniforms({
1472
- * uTime: 1.5,
1473
- * uResolution: [800, 600],
1474
- * uMVP: mat4,
1475
- * });
1476
- */
507
+ Dt(this.gl, r, i, e, s);
508
+ }
1477
509
  setUniforms(t) {
1478
510
  for (const e in t)
1479
511
  this.setUniform(e, t[e]);
1480
512
  }
1481
513
  // ── Attributes ────────────────────────────────────────────────────────────
1482
- /**
1483
- * Bind a single vertex attribute pointer.
1484
- * The VBO must already be bound before calling this.
1485
- */
1486
514
  setAttribute(t) {
1487
515
  const e = this.attributeLoc[t.name];
1488
516
  if (e === void 0) return;
@@ -1490,44 +518,41 @@ class gt {
1490
518
  r.vertexAttribPointer(
1491
519
  e,
1492
520
  t.size,
1493
- t.type ?? _t,
521
+ t.type ?? Wt,
1494
522
  t.normalized ?? !1,
1495
523
  t.stride,
1496
524
  t.offset ?? 0
1497
- ), r.enableVertexAttribArray(e), Pt(r, e, t.divisor ?? 0);
525
+ ), r.enableVertexAttribArray(e), Ot(r, e, t.divisor ?? 0);
1498
526
  }
1499
- /** Bind all vertex attribute pointers at once */
1500
527
  setAttributes(t) {
1501
528
  for (const e of t)
1502
529
  this.setAttribute(e);
1503
530
  }
1504
531
  // ── Lifecycle ─────────────────────────────────────────────────────────────
1505
- /** Free GPU resources */
1506
532
  destroy() {
1507
533
  this.gl.deleteProgram(this.program);
1508
534
  }
1509
- /** Parse attribute/uniform names and GLSL types from raw shader source */
1510
535
  parseShader(t) {
1511
536
  const e = this.gl, r = t.match(/(?:in|attribute)\s+\w+\s+\w+/g);
1512
537
  if (r)
1513
538
  for (const s of r) {
1514
- const o = s.split(/\s+/)[2], h = e.getAttribLocation(this.program, o);
1515
- h !== -1 && (this.attributeLoc[o] = h);
539
+ const h = s.split(/\s+/)[2], o = e.getAttribLocation(this.program, h);
540
+ o !== -1 && (this.attributeLoc[h] = o);
1516
541
  }
1517
542
  const i = t.matchAll(
1518
543
  /uniform\s+(?:(?:lowp|mediump|highp)\s+)?(\w+)\s+(\w+)(\s*\[\s*\d+\s*\])?/g
1519
544
  );
1520
545
  for (const s of i) {
1521
- const a = s[1], o = s[2], h = e.getUniformLocation(this.program, o);
1522
- h !== null && (this.uniformLoc[o] = h, this.uniformType[o] = a, this.uniformIsArray[o] = s[3] !== void 0);
546
+ const a = s[1], h = s[2], o = e.getUniformLocation(this.program, h);
547
+ o !== null && (this.uniformLoc[h] = o, this.uniformType[h] = a, this.uniformIsArray[h] = s[3] !== void 0);
1523
548
  }
1524
549
  }
1525
550
  }
1526
- function Nt(n, t, e, r, i = !1) {
551
+ function Dt(n, t, e, r, i = !1) {
1527
552
  switch (e) {
1528
553
  // scalars
1529
554
  case "float":
1530
- return n.uniform1f(t, r);
555
+ return i ? n.uniform1fv(t, r) : n.uniform1f(t, r);
1531
556
  case "int":
1532
557
  case "bool":
1533
558
  case "sampler2D":
@@ -1557,12 +582,14 @@ function Nt(n, t, e, r, i = !1) {
1557
582
  return n.uniformMatrix3fv(t, !1, r);
1558
583
  case "mat4":
1559
584
  return n.uniformMatrix4fv(t, !1, r);
585
+ case "mat3x2":
586
+ return n.uniformMatrix3x2fv(t, !1, r);
1560
587
  // fallback: guess by value shape
1561
588
  default:
1562
- return It(n, t, r);
589
+ return Bt(n, t, r);
1563
590
  }
1564
591
  }
1565
- function It(n, t, e) {
592
+ function Bt(n, t, e) {
1566
593
  if (typeof e == "number")
1567
594
  return n.uniform1f(t, e);
1568
595
  const r = e;
@@ -1581,82 +608,55 @@ function It(n, t, e) {
1581
608
  return n.uniform1fv(t, r);
1582
609
  }
1583
610
  }
1584
- class ht {
1585
- /** Custom vertex shader code */
611
+ class ct {
1586
612
  vs;
1587
- /** Custom fragment shader code */
1588
613
  fs;
1589
- /** Map of compiled GLShader instances per region key */
1590
614
  glshader = /* @__PURE__ */ new Map();
1591
- /** Currently stored uniform values */
1592
615
  uniforms = {};
1593
- /** Set of region keys that need uniform updates */
1594
616
  uniformDirty = /* @__PURE__ */ new Set();
1595
- /** Map of textures to be bound to this shader */
1596
617
  uniformTextures = {};
1597
- /** Number of texture units reserved by this custom shader */
618
+ uniformArrayTexture = {};
1598
619
  usedTextureUnitNum = 0;
1599
- /** Padding in pixels this shader needs beyond the sprite bounds (for outline/glow effects) */
1600
620
  padding = 0;
1601
621
  rapid;
1602
- constructor(t, e, r, i = 0, s) {
622
+ prefix = [];
623
+ constructor(t, e = "", r = "", i = 0, s) {
1603
624
  this.vs = e, this.fs = r, this.rapid = t, this.uniforms = s ?? {}, this.usedTextureUnitNum = i;
1604
625
  }
1605
- /**
1606
- * Updates uniform values or textures for the custom shader.
1607
- * @param uniforms Map of uniform values or WebGL textures to apply.
1608
- */
1609
626
  setUniforms(t) {
1610
627
  this.rapid.flush();
1611
- const e = {}, r = {};
1612
- for (const [i, s] of Object.entries(t))
1613
- s instanceof WebGLTexture ? r[i] = s : e[i] = s;
1614
- Object.assign(this.uniforms, e), Object.assign(this.uniformTextures, r);
1615
- for (const i of this.glshader.keys())
1616
- this.uniformDirty.add(i);
1617
- }
1618
- /**
1619
- * Sets the padding (in pixels) for this shader and propagates to all compiled GLShaders.
1620
- * Must be called before the first draw call if set after construction.
1621
- * @param pixels - Number of pixels to expand the quad on each side.
1622
- */
628
+ const e = {}, r = {}, i = {};
629
+ for (const [s, a] of Object.entries(t))
630
+ a instanceof WebGLTexture ? r[s] = a : Array.isArray(a) && a[0] instanceof WebGLTexture ? i[s] = a : e[s] = a;
631
+ Object.assign(this.uniforms, e), Object.assign(this.uniformTextures, r), Object.assign(this.uniformArrayTexture, i);
632
+ for (const s of this.glshader.keys())
633
+ this.uniformDirty.add(s);
634
+ }
1623
635
  setPadding(t) {
1624
636
  this.padding = t;
1625
637
  for (const e of this.glshader.values())
1626
638
  e.padding = t;
1627
639
  return this;
1628
640
  }
1629
- /**
1630
- * Applies current uniforms and texture unit mappings to the region-specific shader.
1631
- * @param key The region key.
1632
- * @param textureUniforms Map of texture uniform names to assigned texture unit indices.
1633
- */
1634
641
  applyUniform(t, e) {
1635
642
  const r = this.glshader.get(t);
1636
643
  r && (Object.keys(e).length > 0 && r.setUniforms(e), this.uniformDirty.has(t) && (r.setUniforms(this.uniforms), this.uniformDirty.delete(t)));
1637
644
  }
1638
- /**
1639
- * Retrieves or compiles a customized GLShader for a specific region.
1640
- * @param region The Region requesting the shader.
1641
- * @param key The region key.
1642
- * @param baseVS The base vertex shader template.
1643
- * @param baseFS The base fragment shader template.
1644
- * @returns The combined and compiled GLShader.
1645
- */
1646
645
  getGLShader(t, e, r, i) {
1647
646
  if (this.glshader.has(e))
1648
647
  return this.glshader.get(e);
1649
648
  if (i == null || r == null)
1650
649
  return console.warn("CustomGlShader: missing base shader for " + e), null;
1651
- r = r.replace("// CUSTOM_CODE_CALL", "vertex(position, vRegion);"), i = i.replace("// CUSTOM_CODE_CALL", "fragment(fragColor);"), r = r.replace("// CUSTOM_CODE", this.vs), i = i.replace("// CUSTOM_CODE", this.fs);
1652
- const s = t.createShader(r, i);
1653
- return s.isCustom = !0, s.padding = this.padding, this.glshader.set(e, s), this.uniformDirty.add(e), s;
650
+ const s = this.prefix.length == 0 ? [""] : this.prefix;
651
+ r = r.replace("// CUSTOM_CODE_CALL", s.map((h) => h + "vertex(position, vRegion);").join("")), r = r.replace("// CUSTOM_CODE", this.vs), i = i.replace("// CUSTOM_CODE_CALL", s.map((h) => h + "fragment(fragColor, vRegion);").join("")), i = i.replace("// CUSTOM_CODE", this.fs);
652
+ const a = t.createShader(r, i);
653
+ return a.isCustom = !0, a.padding = this.padding, this.glshader.set(e, a), this.uniformDirty.add(e), a;
1654
654
  }
1655
655
  destroy() {
1656
656
  this.glshader.forEach((t) => t.destroy());
1657
657
  }
1658
658
  }
1659
- class vt {
659
+ class Mt {
1660
660
  constructor(t) {
1661
661
  this.rapid = t, this.gl = t.gl, this.maxTextureUnits = t.maxTextureUnits, this.matrixStore = t.matrix;
1662
662
  }
@@ -1699,7 +699,7 @@ class vt {
1699
699
  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;
1700
700
  }
1701
701
  createShader(t, e) {
1702
- return new gt(this.gl, t, e);
702
+ return new Rt(this.gl, t, e);
1703
703
  }
1704
704
  createCustomShader(t) {
1705
705
  return t.getGLShader(this, this.KEY, this.vs, this.fs);
@@ -1707,22 +707,17 @@ class vt {
1707
707
  getCustomShader(t) {
1708
708
  if (!t)
1709
709
  return this.defaultShader;
1710
- if (t instanceof ht) {
710
+ if (t instanceof ct) {
1711
711
  const e = this.createCustomShader(t);
1712
712
  return e ?? this.defaultShader;
1713
713
  }
1714
714
  return t;
1715
715
  }
1716
- /**
1717
- * Checks if the given shader is the same as the currently bound shader.
1718
- * @param customShader Optional custom shader.
1719
- * @returns True if already bound, otherwise false.
1720
- */
1721
716
  isSameShader(t) {
1722
717
  return this.isDefaultShader && !t ? !0 : this.getCustomShader(t) == this.currentShader;
1723
718
  }
1724
719
  enter(t) {
1725
- this.resetRender(), this.currentShader = this.getCustomShader(t), t instanceof ht ? (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);
720
+ this.resetRender(), this.currentShader = this.getCustomShader(t), t instanceof ct ? (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);
1726
721
  }
1727
722
  exit() {
1728
723
  this.hasPendingContent() && this.flush(), this.gl.bindVertexArray(null);
@@ -1737,8 +732,10 @@ class vt {
1737
732
  const t = this.currentShader;
1738
733
  if (t.use(), this.customShader) {
1739
734
  const r = this.customShader, i = {};
1740
- for (const s in r.uniformTextures)
1741
- i[s] = this.useTexture(r.uniformTextures[s]);
735
+ for (const [s, a] of Object.entries(r.uniformTextures))
736
+ i[s] = this.useTexture(a);
737
+ for (const [s, a] of Object.entries(r.uniformArrayTexture))
738
+ i[s] = a.map((h) => this.useTexture(h));
1742
739
  this.customShader.applyUniform(this.KEY, i);
1743
740
  }
1744
741
  const e = this.gl;
@@ -1753,13 +750,142 @@ class vt {
1753
750
  ));
1754
751
  }
1755
752
  resetRender() {
753
+ const t = this.gl;
754
+ for (let e = 0; e < this.usedTextures.length; e++)
755
+ t.activeTexture(t.TEXTURE0 + e), t.bindTexture(t.TEXTURE_2D, null);
1756
756
  this.usedTextures.length = 0, this.usedTexturePadding.length = 0;
1757
757
  }
1758
758
  hasPendingContent() {
1759
759
  return !1;
1760
760
  }
1761
761
  }
1762
- const Q = `#version 300 es\r
762
+ var S = /* @__PURE__ */ ((n) => (n[n.Float32 = 0] = "Float32", n[n.Uint32 = 1] = "Uint32", n[n.Uint16 = 2] = "Uint16", n))(S || {});
763
+ class A {
764
+ usedElemNum;
765
+ typedArray;
766
+ arrayType;
767
+ maxElemNum;
768
+ bytePerElem;
769
+ arraybuffer;
770
+ uint32;
771
+ float32;
772
+ uint16;
773
+ constructor(t) {
774
+ 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();
775
+ }
776
+ getArrayType(t) {
777
+ switch (t) {
778
+ case 0:
779
+ return Float32Array;
780
+ case 1:
781
+ return Uint32Array;
782
+ case 2:
783
+ return Uint16Array;
784
+ default:
785
+ throw new Error("Unsupported ArrayType");
786
+ }
787
+ }
788
+ updateTypedArray() {
789
+ switch (this.uint32 = new Uint32Array(this.arraybuffer), this.float32 = new Float32Array(this.arraybuffer), this.uint16 = new Uint16Array(this.arraybuffer), this.arrayType) {
790
+ case 0:
791
+ this.typedArray = this.float32;
792
+ break;
793
+ case 1:
794
+ this.typedArray = this.uint32;
795
+ break;
796
+ case 2:
797
+ this.typedArray = this.uint16;
798
+ break;
799
+ }
800
+ }
801
+ clear() {
802
+ this.usedElemNum = 0;
803
+ }
804
+ static removeAtIndices(t, e) {
805
+ const r = Math.max(...e.map((h) => h.usedElemNum)), i = [...new Set(t)].filter(
806
+ (h) => h >= 0 && h < r
807
+ ).sort((h, o) => h - o);
808
+ if (i.length === 0)
809
+ return 0;
810
+ let s = 0, a = 0;
811
+ for (let h = 0; h < r; h++) {
812
+ if (a < i.length && h === i[a]) {
813
+ a++;
814
+ continue;
815
+ }
816
+ if (s !== h)
817
+ for (const o of e)
818
+ o.typedArray[s] = o.typedArray[h];
819
+ s++;
820
+ }
821
+ for (const h of e)
822
+ h.usedElemNum = s;
823
+ return r - s;
824
+ }
825
+ resize(t = 0) {
826
+ if (t += this.usedElemNum, t > this.maxElemNum) {
827
+ for (; t > this.maxElemNum; )
828
+ this.maxElemNum *= 2;
829
+ return this.setMaxSize(this.maxElemNum), !0;
830
+ }
831
+ return !1;
832
+ }
833
+ setMaxSize(t = this.maxElemNum) {
834
+ const e = this.typedArray;
835
+ this.maxElemNum = t, this.arraybuffer = new ArrayBuffer(t * this.bytePerElem), this.updateTypedArray(), this.typedArray.set(e);
836
+ }
837
+ pushUint32(t) {
838
+ this.resize(1), this.uint32[this.usedElemNum++] = t;
839
+ }
840
+ pushFloat32(t) {
841
+ this.resize(1), this.float32[this.usedElemNum++] = t;
842
+ }
843
+ push(t) {
844
+ this.resize(1), this.typedArray[this.usedElemNum++] = t;
845
+ }
846
+ pop() {
847
+ return this.typedArray[--this.usedElemNum];
848
+ }
849
+ top() {
850
+ return this.typedArray[this.usedElemNum - 1];
851
+ }
852
+ get(t) {
853
+ return this.typedArray[t];
854
+ }
855
+ getArray(t = 0, e) {
856
+ return e === void 0 ? this.typedArray : this.typedArray.subarray(t, e);
857
+ }
858
+ get length() {
859
+ return this.usedElemNum;
860
+ }
861
+ }
862
+ class ut extends A {
863
+ buffer;
864
+ gl;
865
+ dirty = !0;
866
+ type;
867
+ webglBufferSize = 0;
868
+ usage;
869
+ constructor(t, e, r = t.ARRAY_BUFFER, i = t.DYNAMIC_DRAW) {
870
+ super(e), this.gl = t, this.buffer = t.createBuffer(), this.type = r, this.usage = i;
871
+ }
872
+ makeDirty() {
873
+ this.dirty = !0;
874
+ }
875
+ clear() {
876
+ super.clear(), this.dirty = !1;
877
+ }
878
+ bindBuffer() {
879
+ this.gl.bindBuffer(this.type, this.buffer);
880
+ }
881
+ bufferData() {
882
+ if (this.dirty) {
883
+ const t = this.gl;
884
+ 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;
885
+ }
886
+ }
887
+ }
888
+ const et = `#version 300 es\r
1763
889
  precision highp float;\r
1764
890
  \r
1765
891
  // per-vertex\r
@@ -1807,7 +933,7 @@ void main(void) {\r
1807
933
  \r
1808
934
  gl_Position = u_projection * position;\r
1809
935
  }\r
1810
- `, ot = `#version 300 es\r
936
+ `, ft = `#version 300 es\r
1811
937
  precision mediump float;\r
1812
938
  \r
1813
939
  uniform sampler2D uTextures[%TEXTURE_NUM%];\r
@@ -1821,43 +947,31 @@ in vec4 vUVRect;\r
1821
947
  out vec4 fragColor;\r
1822
948
  in vec2 vPadding;\r
1823
949
  \r
1824
- bool clampUV(vec2 uv) {\r
1825
- return uv.x < vUVRect.x || uv.x > vUVRect.z || uv.y < vUVRect.y || uv.y > vUVRect.w;\r
1826
- }\r
1827
- \r
1828
950
  vec4 sampleTexture(vec2 uv) {\r
1829
951
  %GET_COLOR%\r
1830
952
  }\r
1831
953
  \r
1832
- vec4 sampleClampTexture(vec2 uv) {\r
1833
- if (clampUV(uv)) {\r
1834
- return vec4(0.0, 0.0, 0.0, 0.0);\r
1835
- }\r
1836
- return sampleTexture(uv);\r
954
+ vec4 sampleClampTexture(vec2 uv) {\r
955
+ vec2 inMin = step(vUVRect.xy, uv);\r
956
+ vec2 inMax = step(uv, vUVRect.zw);\r
957
+ \r
958
+ float mask = inMin.x * inMin.y * inMax.x * inMax.y;\r
959
+ \r
960
+ return sampleTexture(uv) * mask;\r
1837
961
  }\r
1838
962
  \r
1839
963
  vec4 sampleTextureLocal(vec2 uv){\r
1840
- vec2 gUV = mix(vUVRect.xy, vUVRect.zw, uv);\r
1841
- if (clampUV(gUV)) {\r
1842
- return vec4(0.0, 0.0, 0.0, 0.0);\r
1843
- }\r
1844
- return sampleTexture(gUV);\r
964
+ return sampleClampTexture(mix(vUVRect.xy, vUVRect.zw, uv));\r
1845
965
  }\r
1846
- \r
1847
966
  // CUSTOM_CODE\r
1848
967
  \r
1849
968
  void main(void) {\r
1850
969
  fragColor = sampleTexture(vRegion) * vColor;\r
1851
- // if (vPadding.x != 0.0) {\r
1852
- // if (clampUV(vRegion)) {\r
1853
- // fragColor = vec4(0.0, 0.0, 0.0, 0.0);\r
1854
- // }\r
1855
- // }\r
1856
970
  \r
1857
971
  // CUSTOM_CODE_CALL\r
1858
972
  }\r
1859
- `, z = 48, Ot = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
1860
- class nt extends vt {
973
+ `, $ = 48, kt = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
974
+ class lt extends Mt {
1861
975
  instanceBuffer;
1862
976
  quadBuffer;
1863
977
  instanceCount = 0;
@@ -1869,81 +983,69 @@ class nt extends vt {
1869
983
  }
1870
984
  createBuffer() {
1871
985
  const t = this.gl;
1872
- this.quadBuffer = new tt(t, A.Float32, t.ARRAY_BUFFER, t.STATIC_DRAW), this.quadBuffer.bindBuffer();
1873
- for (const e of Ot) this.quadBuffer.pushFloat32(e);
1874
- this.quadBuffer.makeDirty(), this.quadBuffer.bufferData(), this.instanceBuffer = new tt(t, A.Uint32, t.ARRAY_BUFFER, t.DYNAMIC_DRAW);
986
+ this.quadBuffer = new ut(t, S.Float32, t.ARRAY_BUFFER, t.STATIC_DRAW), this.quadBuffer.bindBuffer();
987
+ for (const e of kt) this.quadBuffer.pushFloat32(e);
988
+ this.quadBuffer.makeDirty(), this.quadBuffer.bufferData(), this.instanceBuffer = new ut(t, S.Uint32, t.ARRAY_BUFFER, t.DYNAMIC_DRAW);
1875
989
  }
1876
990
  createDefaultShader() {
1877
- const t = this.rapid, e = H(ot, t.maxTextureUnits), r = H(Q, t.maxTextureUnits);
991
+ const t = this.rapid, e = D(ft, t.maxTextureUnits), r = D(et, t.maxTextureUnits);
1878
992
  return this.vs = r, this.fs = e, this.defaultShader = this.createShader(r, e), this.defaultShader;
1879
993
  }
1880
994
  createShader(t, e) {
1881
995
  const r = super.createShader(t, e);
1882
996
  return r.use(), r.bindVAO(), this.instanceBuffer.bindBuffer(), r.setAttributes([
1883
- { name: "aMatrixRow0", size: 3, stride: z, offset: 0, divisor: 1 },
1884
- { name: "aMatrixRow1", size: 3, stride: z, offset: 12, divisor: 1 },
1885
- { name: "aUVRect", size: 4, stride: z, offset: 24, divisor: 1 },
1886
- { name: "aColor", size: 4, type: it, normalized: !0, stride: z, offset: 40, divisor: 1 },
1887
- { name: "aTextureId", size: 1, type: it, stride: z, offset: 44, divisor: 1 }
997
+ { name: "aMatrixRow0", size: 3, stride: $, offset: 0, divisor: 1 },
998
+ { name: "aMatrixRow1", size: 3, stride: $, offset: 12, divisor: 1 },
999
+ { name: "aUVRect", size: 4, stride: $, offset: 24, divisor: 1 },
1000
+ { name: "aColor", size: 4, type: ot, normalized: !0, stride: $, offset: 40, divisor: 1 },
1001
+ { name: "aTextureId", size: 1, type: ot, stride: $, offset: 44, divisor: 1 }
1888
1002
  ]), this.quadBuffer.bindBuffer(), r.setAttributes([
1889
1003
  { name: "aVertex", size: 2, stride: 8, offset: 0, divisor: 0 }
1890
1004
  ]), r.unbindVAO(), this.currentShader && this.currentShader.use(), r;
1891
1005
  }
1892
1006
  createCustomShader(t) {
1893
- const e = H(ot, this.rapid.maxTextureUnits - t.usedTextureUnitNum), r = H(Q, this.rapid.maxTextureUnits - t.usedTextureUnitNum);
1007
+ const e = D(ft, this.rapid.maxTextureUnits - t.usedTextureUnitNum), r = D(et, this.rapid.maxTextureUnits - t.usedTextureUnitNum);
1894
1008
  return t.getGLShader(this, this.KEY, r, e);
1895
1009
  }
1896
- /**
1897
- * Draws a textured sprite via instanced rendering to significantly improve performance.
1898
- * @param texture The WebGLTexture to map.
1899
- * @param matrixIndex The index for the transform matrix in MatrixStore.
1900
- * @param width Render width.
1901
- * @param height Render height.
1902
- * @param u0 Left UV mapped coordinate (default 0).
1903
- * @param v0 Top UV mapped coordinate (default 0).
1904
- * @param u1 Right UV mapped coordinate (default 1).
1905
- * @param v1 Bottom UV mapped coordinate (default 1).
1906
- * @param color The tint color as packed ABGR uniform uint32 (default 0xFFFFFFFF).
1907
- */
1908
- drawSprite(t, e, r = 0, i = 0, s = 1, a = 1, o = 4294967295, h = 0, c = 0, u = !1, l = !1, d = !1) {
1909
- const f = e * 6, m = this.matrixStore.data;
1010
+ drawSprite(t, e, r = 0, i = 0, s = 1, a = 1, h = 4294967295, o = 0, c = 0, u = !1, l = !1, f = !1) {
1011
+ const d = e * 6, x = this.matrixStore.data;
1910
1012
  this.drawSpriteAffine(
1911
1013
  t,
1912
- m[f],
1913
- m[f + 1],
1914
- m[f + 2],
1915
- m[f + 3],
1916
- m[f + 4],
1917
- m[f + 5],
1014
+ x[d],
1015
+ x[d + 1],
1016
+ x[d + 2],
1017
+ x[d + 3],
1018
+ x[d + 4],
1019
+ x[d + 5],
1918
1020
  r,
1919
1021
  i,
1920
1022
  s,
1921
1023
  a,
1922
- o,
1923
1024
  h,
1025
+ o,
1924
1026
  c,
1925
1027
  u,
1926
1028
  l,
1927
- d
1029
+ f
1928
1030
  );
1929
1031
  }
1930
- drawSpriteAffine(t, e, r, i, s, a, o, h = 0, c = 0, u = 1, l = 1, d = 4294967295, f = 0, m = 0, g = !1, v = !1, y = !1) {
1931
- const R = t.base, M = t.rawWidth, C = t.rawHeight, P = t.offsetX, I = t.offsetY, O = this.useTexture(
1032
+ drawSpriteAffine(t, e, r, i, s, a, h, o = 0, c = 0, u = 1, l = 1, f = 4294967295, d = 0, x = 0, p = !1, v = !1, y = !1) {
1033
+ const E = t.base, w = t.rawWidth, _ = t.rawHeight, L = t.offsetX, W = t.offsetY, O = this.useTexture(
1932
1034
  t.glTexture,
1933
- f / R.width,
1934
- m / R.height
1935
- ), _ = this.instanceBuffer, w = _.usedElemNum;
1936
- _.resize(12);
1937
- const U = _.float32, B = _.uint32, D = y ? C : M, G = y ? M : C, F = D + 2 * f, k = G + 2 * m, X = P - f, W = I - m, T = this.localSpriteMatrix;
1938
- y ? (T[0] = 0, T[1] = v ? k : -k, T[2] = g ? -F : F, T[3] = 0, T[4] = X + (g ? F : 0), T[5] = W + (v ? 0 : k)) : (T[0] = g ? -F : F, T[1] = 0, T[2] = 0, T[3] = v ? -k : k, T[4] = X + (g ? F : 0), T[5] = W + (v ? k : 0));
1939
- const S = this.worldSpriteMatrix;
1940
- S[0] = e * T[0] + i * T[1], S[1] = r * T[0] + s * T[1], S[2] = e * T[2] + i * T[3], S[3] = r * T[2] + s * T[3], S[4] = a + e * T[4] + i * T[5], S[5] = o + r * T[4] + s * T[5], U[w + 6] = h, U[w + 7] = c, U[w + 8] = u, U[w + 9] = l, B[w + 10] = d, B[w + 11] = O, this.rapid.roundPixels && (S[4] = Math.round(S[4]), S[5] = Math.round(S[5])), U[w] = S[0], U[w + 1] = S[2], U[w + 2] = S[4], U[w + 3] = S[1], U[w + 4] = S[3], U[w + 5] = S[5], _.usedElemNum += 12, _.makeDirty(), this.instanceCount++;
1035
+ d / E.width,
1036
+ x / E.height
1037
+ ), b = this.instanceBuffer, M = b.usedElemNum;
1038
+ b.resize(12);
1039
+ const C = b.float32, B = b.uint32, k = y ? _ : w, H = y ? w : _, I = k + 2 * d, F = H + 2 * x, X = L - d, z = W - x, R = this.localSpriteMatrix;
1040
+ y ? (R[0] = 0, R[1] = v ? F : -F, R[2] = p ? -I : I, R[3] = 0, R[4] = X + (p ? I : 0), R[5] = z + (v ? 0 : F)) : (R[0] = p ? -I : I, R[1] = 0, R[2] = 0, R[3] = v ? -F : F, R[4] = X + (p ? I : 0), R[5] = z + (v ? F : 0));
1041
+ const U = this.worldSpriteMatrix;
1042
+ U[0] = e * R[0] + i * R[1], U[1] = r * R[0] + s * R[1], U[2] = e * R[2] + i * R[3], U[3] = r * R[2] + s * R[3], U[4] = a + e * R[4] + i * R[5], U[5] = h + r * R[4] + s * R[5], C[M + 6] = o, C[M + 7] = c, C[M + 8] = u, C[M + 9] = l, B[M + 10] = f, B[M + 11] = O, this.rapid.roundPixels && (U[4] = Math.round(U[4]), U[5] = Math.round(U[5])), C[M] = U[0], C[M + 1] = U[2], C[M + 2] = U[4], C[M + 3] = U[1], C[M + 4] = U[3], C[M + 5] = U[5], b.usedElemNum += 12, b.makeDirty(), this.instanceCount++;
1941
1043
  }
1942
1044
  render() {
1943
1045
  if (this.instanceCount === 0) return;
1944
1046
  this.prepareRender();
1945
1047
  const t = this.gl, e = this.currentShader;
1946
- this.instanceBuffer.bindBuffer(), this.instanceBuffer.bufferData(), e.bindVAO(), pt(t, t.TRIANGLE_STRIP, 0, 4, this.instanceCount), this.rapid.drawcallCount++;
1048
+ this.instanceBuffer.bindBuffer(), this.instanceBuffer.bufferData(), e.bindVAO(), Et(t, t.TRIANGLE_STRIP, 0, 4, this.instanceCount), this.rapid.drawcallCount++;
1947
1049
  }
1948
1050
  resetRender() {
1949
1051
  super.resetRender(), this.instanceBuffer.clear(), this.instanceCount = 0;
@@ -1952,7 +1054,277 @@ class nt extends vt {
1952
1054
  return this.instanceCount > 0;
1953
1055
  }
1954
1056
  }
1955
- const Ft = `#version 300 es\r
1057
+ const T = 6;
1058
+ class Ht {
1059
+ matrixCount = 0;
1060
+ buffer;
1061
+ data;
1062
+ temporary = -1;
1063
+ constructor(t = 10) {
1064
+ this.buffer = new A(S.Float32), this.buffer.resize(t * T), this.data = this.buffer.getArray(), this.reset();
1065
+ }
1066
+ alloc() {
1067
+ const t = this.allocDirty();
1068
+ return this.identity(t), t;
1069
+ }
1070
+ allocDirty() {
1071
+ return this.buffer.resize(T) && (this.data = this.buffer.getArray()), this.buffer.usedElemNum += T, this.matrixCount++;
1072
+ }
1073
+ reset() {
1074
+ this.matrixCount = 0, this.buffer.usedElemNum = 0, this.temporary = this.alloc();
1075
+ }
1076
+ identity(t) {
1077
+ const e = t * T, r = this.data;
1078
+ r[e] = 1, r[e + 1] = 0, r[e + 2] = 0, r[e + 3] = 1, r[e + 4] = 0, r[e + 5] = 0;
1079
+ }
1080
+ translate(t, e, r) {
1081
+ const i = t * T, s = this.data;
1082
+ 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];
1083
+ }
1084
+ scale(t, e, r) {
1085
+ const i = t * T, s = this.data;
1086
+ s[i] *= e, s[i + 1] *= e, s[i + 2] *= r, s[i + 3] *= r;
1087
+ }
1088
+ rotate(t, e) {
1089
+ const r = t * T, i = this.data, s = Math.cos(e), a = Math.sin(e), h = i[r], o = i[r + 1], c = i[r + 2], u = i[r + 3];
1090
+ i[r] = h * s + c * a, i[r + 1] = o * s + u * a, i[r + 2] = h * -a + c * s, i[r + 3] = o * -a + u * s;
1091
+ }
1092
+ rotateWithOffset(t, e, r, i) {
1093
+ this.translate(t, r, i), this.rotate(t, e), this.translate(t, -r, -i);
1094
+ }
1095
+ copy(t, e) {
1096
+ const r = t * T, i = e * T, s = this.data;
1097
+ 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];
1098
+ }
1099
+ multiply(t, e) {
1100
+ this.multiplyOut(t, t, e);
1101
+ }
1102
+ multiplyOut(t, e, r) {
1103
+ const i = t * T, s = e * T, a = r * T, h = this.data, o = h[s], c = h[s + 1], u = h[s + 2], l = h[s + 3], f = h[s + 4], d = h[s + 5], x = h[a], p = h[a + 1], v = h[a + 2], y = h[a + 3], E = h[a + 4], w = h[a + 5];
1104
+ h[i] = o * x + u * p, h[i + 1] = c * x + l * p, h[i + 2] = o * v + u * y, h[i + 3] = c * v + l * y, h[i + 4] = o * E + u * w + f, h[i + 5] = c * E + l * w + d;
1105
+ }
1106
+ invert(t) {
1107
+ const e = t * T, r = this.data, i = r[e], s = r[e + 1], a = r[e + 2], h = r[e + 3], o = r[e + 4], c = r[e + 5];
1108
+ let u = i * h - s * a;
1109
+ if (!u) {
1110
+ this.identity(t);
1111
+ return;
1112
+ }
1113
+ u = 1 / u, r[e] = h * u, r[e + 1] = -s * u, r[e + 2] = -a * u, r[e + 3] = i * u, r[e + 4] = (a * c - h * o) * u, r[e + 5] = (s * o - i * c) * u;
1114
+ }
1115
+ transformPoint(t, e, r) {
1116
+ const i = t * T, s = this.data;
1117
+ return {
1118
+ x: e * s[i] + r * s[i + 2] + s[i + 4],
1119
+ y: e * s[i + 1] + r * s[i + 3] + s[i + 5]
1120
+ };
1121
+ }
1122
+ worldToLocal(t, e, r) {
1123
+ const i = this.allocDirty();
1124
+ this.copy(i, t), this.invert(i);
1125
+ const s = this.transformPoint(i, e, r);
1126
+ return this.matrixCount--, this.buffer.usedElemNum -= T, s;
1127
+ }
1128
+ localToWorld(t, e, r) {
1129
+ return this.transformPoint(t, e, r);
1130
+ }
1131
+ getPosition(t) {
1132
+ const e = t * T, r = this.data;
1133
+ return { x: r[e + 4], y: r[e + 5] };
1134
+ }
1135
+ getScale(t) {
1136
+ const e = t * T, 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]);
1137
+ return { x: i, y: s };
1138
+ }
1139
+ getRotation(t) {
1140
+ const e = t * T, r = this.data;
1141
+ return Math.atan2(r[e + 1], r[e]);
1142
+ }
1143
+ toCSSMatrix(t, e = 1, r = 1) {
1144
+ const i = t * T, s = this.data;
1145
+ 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})`;
1146
+ }
1147
+ getMatrix(t) {
1148
+ const e = t * T;
1149
+ return this.data.slice(e, e + T);
1150
+ }
1151
+ getMatrixRef(t) {
1152
+ const e = t * T;
1153
+ return this.data.subarray(e, e + T);
1154
+ }
1155
+ setMatrix(t, e) {
1156
+ const r = t * T, i = this.data;
1157
+ 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];
1158
+ }
1159
+ multiplyAffineInPlace(t, e, r, i, s, a, h) {
1160
+ const o = t * 6, c = this.data, u = c[o], l = c[o + 1], f = c[o + 2], d = c[o + 3], x = c[o + 4], p = c[o + 5];
1161
+ c[o] = u * e + f * r, c[o + 1] = l * e + d * r, c[o + 2] = u * i + f * s, c[o + 3] = l * i + d * s, c[o + 4] = u * a + f * h + x, c[o + 5] = l * a + d * h + p;
1162
+ }
1163
+ multiplyAffine(t, e, r, i, s, a, h, o) {
1164
+ const c = t * 6, u = e * 6, l = this.data, f = l[c], d = l[c + 1], x = l[c + 2], p = l[c + 3], v = l[c + 4], y = l[c + 5];
1165
+ l[u] = f * r + x * i, l[u + 1] = d * r + p * i, l[u + 2] = f * s + x * a, l[u + 3] = d * s + p * a, l[u + 4] = f * h + x * o + v, l[u + 5] = d * h + p * o + y;
1166
+ }
1167
+ }
1168
+ class Gt {
1169
+ matrix = new Ht();
1170
+ step = 0;
1171
+ stack = new A(S.Uint32);
1172
+ stepWorldM = new A(S.Uint32);
1173
+ stepAction = new A(S.Uint32);
1174
+ stepParentM = new A(S.Uint32);
1175
+ stepClose = new A(S.Uint32);
1176
+ stepStack = new A(S.Uint32);
1177
+ curLocalM = -1;
1178
+ curWorldM = -1;
1179
+ rapid;
1180
+ constructor(t) {
1181
+ this.reset(), this.rapid = t;
1182
+ }
1183
+ save() {
1184
+ this.stack.push(this.curWorldM);
1185
+ const t = this.curWorldM;
1186
+ return this.curLocalM = this.matrix.alloc(), this.curWorldM = this.matrix.allocDirty(), this.stepWorldM.push(this.curWorldM), this.stepParentM.push(t), this.stepAction.push(1), this.stepClose.push(0), this.stepStack.push(this.step), this.matrix.copy(this.curWorldM, t), { world: this.curWorldM, local: this.curLocalM, step: this.step++ };
1187
+ }
1188
+ restore() {
1189
+ this.stack.length == 0 || this.stepStack.length == 0 || (this.curWorldM = this.stack.pop(), this.curLocalM = this.curWorldM - 1, this.stepParentM.push(this.stack.get(this.stack.length - 1)), this.stepWorldM.push(this.curWorldM), this.stepAction.push(0), this.stepClose.push(0), this.stepClose.typedArray[this.stepStack.pop()] = this.step, this.step++);
1190
+ }
1191
+ restoreAll() {
1192
+ for (; this.stack.length > 0 && this.stepStack.length > 0; )
1193
+ this.restore();
1194
+ }
1195
+ getStep(t) {
1196
+ return typeof t == "number" ? t : t.step;
1197
+ }
1198
+ walkSubtree(t, e, r = 1 / 0) {
1199
+ let i = 0, s = t;
1200
+ for (; s < this.step; ) {
1201
+ const a = this.stepAction.get(s);
1202
+ if (a === 1) {
1203
+ if (i++, i > r) {
1204
+ const h = this.stepClose.get(s);
1205
+ if (h > s) {
1206
+ s = h + 1, i--;
1207
+ continue;
1208
+ }
1209
+ }
1210
+ } else
1211
+ i--;
1212
+ if (e(s, a, i) === !1 || a === 0 && i === 0) return;
1213
+ s++;
1214
+ }
1215
+ }
1216
+ getParent(t) {
1217
+ const e = this.getStep(t);
1218
+ return this.stepParentM.get(e);
1219
+ }
1220
+ getChildren(t) {
1221
+ const e = this.getStep(t), r = this.stepClose.get(e), i = [];
1222
+ let s = e + 1;
1223
+ for (; s < r; )
1224
+ this.stepAction.get(s) === 1 ? (i.push(s), s = this.stepClose.get(s) + 1) : s++;
1225
+ return i;
1226
+ }
1227
+ updateMatrixSubtree(t) {
1228
+ const e = this.getStep(t);
1229
+ this.walkSubtree(e, (r, i) => {
1230
+ if (i === 1) {
1231
+ const s = this.stepWorldM.get(r), a = s - 1, h = this.stepParentM.get(r);
1232
+ this.matrix.multiplyOut(s, h, a);
1233
+ }
1234
+ });
1235
+ }
1236
+ translate(t, e) {
1237
+ this.matrix.translate(this.curLocalM, t, e), this.matrix.translate(this.curWorldM, t, e);
1238
+ }
1239
+ scale(t, e = t) {
1240
+ this.matrix.scale(this.curLocalM, t, e), this.matrix.scale(this.curWorldM, t, e);
1241
+ }
1242
+ rotate(t) {
1243
+ this.matrix.rotate(this.curLocalM, t), this.matrix.rotate(this.curWorldM, t);
1244
+ }
1245
+ rotateWithOffset(t, e, r) {
1246
+ this.matrix.rotateWithOffset(this.curLocalM, t, e, r), this.matrix.rotateWithOffset(this.curWorldM, t, e, r);
1247
+ }
1248
+ identity() {
1249
+ this.matrix.identity(this.curLocalM), this.matrix.identity(this.curWorldM);
1250
+ }
1251
+ reset() {
1252
+ this.matrix.reset(), this.stack.clear(), this.stepAction.clear(), this.stepWorldM.clear(), this.stepParentM.clear(), this.stepClose.clear(), this.stepStack.clear(), this.step = 0, this.curLocalM = this.matrix.alloc(), this.curWorldM = this.matrix.alloc();
1253
+ }
1254
+ localToWorld(t, e) {
1255
+ return this.matrix.localToWorld(this.curWorldM, t, e);
1256
+ }
1257
+ worldToLocal(t, e) {
1258
+ return this.matrix.worldToLocal(this.curWorldM, t, e);
1259
+ }
1260
+ getGlobalPosition() {
1261
+ return this.matrix.getPosition(this.curWorldM);
1262
+ }
1263
+ getGlobalScale() {
1264
+ return this.matrix.getScale(this.curWorldM);
1265
+ }
1266
+ getGlobalRotation() {
1267
+ return this.matrix.getRotation(this.curWorldM);
1268
+ }
1269
+ toCSSMatrix() {
1270
+ return this.matrix.toCSSMatrix(this.curWorldM);
1271
+ }
1272
+ getTransform() {
1273
+ const t = this.curWorldM * T;
1274
+ return this.matrix.data.slice(t, t + T);
1275
+ }
1276
+ setTransform(t) {
1277
+ const e = this.curWorldM * T, r = this.matrix.data;
1278
+ 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];
1279
+ }
1280
+ transformPoint(t, e) {
1281
+ return this.matrix.transformPoint(this.curLocalM, t, e);
1282
+ }
1283
+ applyTransform(t, e = 0, r = 0, i = -1) {
1284
+ let s = t.x ?? 0, a = t.y ?? 0;
1285
+ t.position && (s += t.position.x, a += t.position.y);
1286
+ let h = 1, o = 1;
1287
+ const c = t.scale;
1288
+ c && (typeof c == "number" ? (h = c, o = c) : (h = c.x, o = c.y));
1289
+ const u = t.rotation ?? 0;
1290
+ let l = t.offsetX ?? 0, f = t.offsetY ?? 0;
1291
+ t.offset && (l += t.offset.x, f += t.offset.y);
1292
+ const d = t.origin;
1293
+ d !== void 0 && (typeof d == "number" ? (l -= d * e, f -= d * r) : (l -= d.x * e, f -= d.y * r));
1294
+ const x = u ? Math.cos(u) : 1, p = u ? Math.sin(u) : 0, v = x * h, y = p * h, E = -p * o, w = x * o, _ = s + v * l + E * f, L = a + y * l + w * f;
1295
+ if (i !== -1) {
1296
+ this.matrix.multiplyAffine(
1297
+ this.curWorldM,
1298
+ i,
1299
+ v,
1300
+ y,
1301
+ E,
1302
+ w,
1303
+ _,
1304
+ L
1305
+ );
1306
+ return;
1307
+ }
1308
+ this.matrix.multiplyAffineInPlace(
1309
+ this.curLocalM,
1310
+ v,
1311
+ y,
1312
+ E,
1313
+ w,
1314
+ _,
1315
+ L
1316
+ ), this.matrix.multiplyAffineInPlace(
1317
+ this.curWorldM,
1318
+ v,
1319
+ y,
1320
+ E,
1321
+ w,
1322
+ _,
1323
+ L
1324
+ );
1325
+ }
1326
+ }
1327
+ const Vt = `#version 300 es\r
1956
1328
  precision highp float;\r
1957
1329
  \r
1958
1330
  in vec2 aPosition;\r
@@ -1983,7 +1355,7 @@ void main(void) {\r
1983
1355
  // CUSTOM_CODE_CALL\r
1984
1356
  gl_Position = u_projection * position;\r
1985
1357
  }\r
1986
- `, Wt = `#version 300 es\r
1358
+ `, Xt = `#version 300 es\r
1987
1359
  precision mediump float;\r
1988
1360
  \r
1989
1361
  in vec4 vColor;\r
@@ -2029,7 +1401,7 @@ void main(void) {\r
2029
1401
  fragColor = sampleTexture(vRegion) * vColor;\r
2030
1402
  // CUSTOM_CODE_CALL\r
2031
1403
  }\r
2032
- `, Bt = `#version 300 es\r
1404
+ `, Yt = `#version 300 es\r
2033
1405
  precision highp float;\r
2034
1406
  \r
2035
1407
  in vec2 aPosition;\r
@@ -2052,7 +1424,7 @@ void main(void) {\r
2052
1424
  );\r
2053
1425
  gl_Position = u_projection * position;\r
2054
1426
  }\r
2055
- `, Dt = `#version 300 es\r
1427
+ `, zt = `#version 300 es\r
2056
1428
  precision mediump float;\r
2057
1429
  \r
2058
1430
  in vec2 vRegion;\r
@@ -2072,8 +1444,8 @@ void main(void) {\r
2072
1444
  discard;\r
2073
1445
  }\r
2074
1446
  }\r
2075
- `, $ = 20;
2076
- class kt extends vt {
1447
+ `, j = 20;
1448
+ class $t extends Mt {
2077
1449
  vertexBuffer;
2078
1450
  vertexCount = 0;
2079
1451
  matrixIndex = -1;
@@ -2086,50 +1458,33 @@ class kt extends vt {
2086
1458
  }
2087
1459
  createBuffer() {
2088
1460
  const t = this.gl;
2089
- this.vertexBuffer = new tt(t, A.Float32, t.ARRAY_BUFFER, t.DYNAMIC_DRAW), this.maskShader = this.createMaskShader(Bt, Dt);
1461
+ this.vertexBuffer = new ut(t, S.Float32, t.ARRAY_BUFFER, t.DYNAMIC_DRAW), this.maskShader = this.createMaskShader(Yt, zt);
2090
1462
  }
2091
1463
  createDefaultShader() {
2092
- return this.vs = Ft, this.fs = Wt, this.defaultShader = this.createShader(this.vs, this.fs), this.defaultShader;
1464
+ return this.vs = Vt, this.fs = Xt, this.defaultShader = this.createShader(this.vs, this.fs), this.defaultShader;
2093
1465
  }
2094
1466
  createMaskShader(t, e) {
2095
- const r = this.gl, i = new gt(r, t, e);
1467
+ const r = this.gl, i = new Rt(r, t, e);
2096
1468
  return i.use(), i.bindVAO(), this.vertexBuffer.bindBuffer(), i.setAttributes([
2097
- { name: "aPosition", size: 2, type: r.FLOAT, stride: $ - 4, offset: 0, divisor: 0 },
2098
- { name: "aUV", size: 2, type: r.FLOAT, stride: $ - 4, offset: 8, divisor: 0 }
1469
+ { name: "aPosition", size: 2, type: r.FLOAT, stride: j - 4, offset: 0, divisor: 0 },
1470
+ { name: "aUV", size: 2, type: r.FLOAT, stride: j - 4, offset: 8, divisor: 0 }
2099
1471
  ]), i.unbindVAO(), this.currentShader && this.currentShader.use(), i;
2100
1472
  }
2101
1473
  createShader(t, e) {
2102
1474
  const r = this.gl, i = super.createShader(t, e);
2103
1475
  return i.use(), i.bindVAO(), this.vertexBuffer.bindBuffer(), i.setAttributes([
2104
- { name: "aPosition", size: 2, type: r.FLOAT, stride: $, offset: 0, divisor: 0 },
2105
- { name: "aColor", size: 4, type: r.UNSIGNED_BYTE, normalized: !0, stride: $, offset: 8, divisor: 0 },
2106
- { name: "aUV", size: 2, type: r.FLOAT, stride: $, offset: 12, divisor: 0 }
1476
+ { name: "aPosition", size: 2, type: r.FLOAT, stride: j, offset: 0, divisor: 0 },
1477
+ { name: "aColor", size: 4, type: r.UNSIGNED_BYTE, normalized: !0, stride: j, offset: 8, divisor: 0 },
1478
+ { name: "aUV", size: 2, type: r.FLOAT, stride: j, offset: 12, divisor: 0 }
2107
1479
  ]), i.unbindVAO(), this.currentShader && this.currentShader.use(), i;
2108
1480
  }
2109
- /**
2110
- * Begins a new polygon drawing sequence. Must be followed by addVertex() calls and endGraphic().
2111
- * @param matrixIndex The index targeting a specific transform matrix in the MatrixStore.
2112
- * @param drawMode The WebGL drawing primitive mode (e.g., gl.TRIANGLES).
2113
- * @param texture Optional texture to apply over the polygon.
2114
- */
2115
1481
  startGraphic(t, e = this.gl.TRIANGLES, r) {
2116
1482
  this.vertexBuffer.clear(), this.vertexCount = 0, this.matrixIndex = t, this.drawMode = e, this.texture = r, this.texture?.glTexture && this.useTexture(this.texture.glTexture, 0, 0);
2117
1483
  }
2118
- /**
2119
- * Adds a vertex to the current polygon. Local coordinates and color settings.
2120
- * @param x Local X coordinate.
2121
- * @param y Local Y coordinate.
2122
- * @param u UV mapped X value (0-1, default 0).
2123
- * @param v UV mapped Y value (0-1, default 0).
2124
- * @param color Pre-multiplied hex color combined using ABGR byte order (default 0xFFFFFFFF).
2125
- */
2126
1484
  addVertex(t, e, r = 0, i = 0, s = 4294967295) {
2127
1485
  const a = this.vertexBuffer;
2128
1486
  a.pushFloat32(t), a.pushFloat32(e), this.currentShader != this.maskShader && a.pushUint32(s), a.pushFloat32(r), a.pushFloat32(i), this.vertexCount++, this.vertexBuffer.makeDirty();
2129
1487
  }
2130
- /**
2131
- * Finishes the graphic construction and dispatches the rendering call immediately.
2132
- */
2133
1488
  endGraphic() {
2134
1489
  this.flush();
2135
1490
  }
@@ -2147,15 +1502,15 @@ class kt extends vt {
2147
1502
  return !1;
2148
1503
  }
2149
1504
  }
2150
- class p {
1505
+ class g {
2151
1506
  x;
2152
1507
  y;
2153
- static ZERO = new p(0, 0);
2154
- static ONE = new p(1, 1);
2155
- static UP = new p(0, 1);
2156
- static DOWN = new p(0, -1);
2157
- static LEFT = new p(-1, 0);
2158
- static RIGHT = new p(1, 0);
1508
+ static ZERO = new g(0, 0);
1509
+ static ONE = new g(1, 1);
1510
+ static UP = new g(0, 1);
1511
+ static DOWN = new g(0, -1);
1512
+ static LEFT = new g(-1, 0);
1513
+ static RIGHT = new g(1, 0);
2159
1514
  constructor(t, e) {
2160
1515
  this.x = t !== void 0 ? t : 0, this.y = e !== void 0 ? e : 0;
2161
1516
  }
@@ -2163,22 +1518,16 @@ class p {
2163
1518
  return e === void 0 ? (this.x = t, this.y = t) : (this.x = t, this.y = e), this;
2164
1519
  }
2165
1520
  add(t) {
2166
- return new p(this.x + t.x, this.y + t.y);
1521
+ return new g(this.x + t.x, this.y + t.y);
2167
1522
  }
2168
1523
  subtract(t) {
2169
- return new p(this.x - t.x, this.y - t.y);
2170
- }
2171
- sub(t) {
2172
- return new p(this.x - t.x, this.y - t.y);
1524
+ return new g(this.x - t.x, this.y - t.y);
2173
1525
  }
2174
1526
  multiply(t) {
2175
- return t instanceof p ? new p(this.x * t.x, this.y * t.y) : new p(this.x * t, this.y * t);
2176
- }
2177
- mul(t) {
2178
- return this.multiply(t);
1527
+ return t instanceof g ? new g(this.x * t.x, this.y * t.y) : new g(this.x * t, this.y * t);
2179
1528
  }
2180
1529
  divide(t) {
2181
- return t instanceof p ? new p(this.x / t.x, this.y / t.y) : new p(this.x / t, this.y / t);
1530
+ return t instanceof g ? new g(this.x / t.x, this.y / t.y) : new g(this.x / t, this.y / t);
2182
1531
  }
2183
1532
  dot(t) {
2184
1533
  return this.x * t.x + this.y * t.y;
@@ -2191,14 +1540,11 @@ class p {
2191
1540
  return Math.sqrt(e * e + r * r);
2192
1541
  }
2193
1542
  clone() {
2194
- return new p(this.x, this.y);
1543
+ return new g(this.x, this.y);
2195
1544
  }
2196
1545
  to(t) {
2197
1546
  this.x = t.x, this.y = t.y;
2198
1547
  }
2199
- copy() {
2200
- return new p(this.x, this.y);
2201
- }
2202
1548
  equals(t) {
2203
1549
  return t.x == this.x && t.y == this.y;
2204
1550
  }
@@ -2210,7 +1556,7 @@ class p {
2210
1556
  return this.x = -this.x, this.y = -this.y, this;
2211
1557
  }
2212
1558
  inverted() {
2213
- return new p(this.x * -1, this.y * -1);
1559
+ return new g(this.x * -1, this.y * -1);
2214
1560
  }
2215
1561
  length() {
2216
1562
  return Math.sqrt(this.x * this.x + this.y * this.y);
@@ -2224,13 +1570,13 @@ class p {
2224
1570
  }
2225
1571
  normalized() {
2226
1572
  const t = this.length();
2227
- return new p(this.x / t || 0, this.y / t || 0);
1573
+ return new g(this.x / t || 0, this.y / t || 0);
2228
1574
  }
2229
1575
  fix(t = 1e-13) {
2230
1576
  this.x = Math.abs(this.x) < t ? 0 : this.x, this.y = Math.abs(this.y) < t ? 0 : this.y;
2231
1577
  }
2232
1578
  fixed(t = 1e-13) {
2233
- return new p(
1579
+ return new g(
2234
1580
  Math.abs(this.x) < t ? 0 : this.x,
2235
1581
  Math.abs(this.y) < t ? 0 : this.y
2236
1582
  );
@@ -2239,13 +1585,13 @@ class p {
2239
1585
  return Math.atan2(this.y, this.x);
2240
1586
  }
2241
1587
  abs() {
2242
- return new p(Math.abs(this.x), Math.abs(this.y));
1588
+ return new g(Math.abs(this.x), Math.abs(this.y));
2243
1589
  }
2244
1590
  floor() {
2245
- return new p(Math.floor(this.x), Math.floor(this.y));
1591
+ return new g(Math.floor(this.x), Math.floor(this.y));
2246
1592
  }
2247
1593
  ceil() {
2248
- return new p(Math.ceil(this.x), Math.ceil(this.y));
1594
+ return new g(Math.ceil(this.x), Math.ceil(this.y));
2249
1595
  }
2250
1596
  stringify() {
2251
1597
  return `Vec2(${this.x}, ${this.y})`;
@@ -2266,14 +1612,14 @@ class p {
2266
1612
  return this.x = Math.cos(t) * e, this.y = Math.sin(t) * e, this;
2267
1613
  }
2268
1614
  static FromArray(t) {
2269
- return t.map((e) => new p(e[0], e[1]));
1615
+ return t.map((e) => new g(e[0], e[1]));
2270
1616
  }
2271
1617
  static fromAngle(t) {
2272
- return new p(Math.cos(t), Math.sin(t));
1618
+ return new g(Math.cos(t), Math.sin(t));
2273
1619
  }
2274
1620
  }
2275
- const Ht = (n, t) => {
2276
- const [e, r, i, s, a, o] = t, h = new Float32Array([
1621
+ const jt = (n, t) => {
1622
+ const [e, r, i, s, a, h] = t, o = new Float32Array([
2277
1623
  e,
2278
1624
  i,
2279
1625
  0,
@@ -2287,12 +1633,12 @@ const Ht = (n, t) => {
2287
1633
  1,
2288
1634
  0,
2289
1635
  a,
2290
- o,
1636
+ h,
2291
1637
  0,
2292
1638
  1
2293
1639
  ]);
2294
- return Gt(h, n);
2295
- }, Gt = (n, t) => {
1640
+ return Kt(o, n);
1641
+ }, Kt = (n, t) => {
2296
1642
  const e = new Float32Array(16);
2297
1643
  for (let r = 0; r < 4; r++)
2298
1644
  for (let i = 0; i < 4; i++) {
@@ -2303,75 +1649,75 @@ const Ht = (n, t) => {
2303
1649
  }
2304
1650
  return e;
2305
1651
  };
2306
- var Vt = /* @__PURE__ */ ((n) => (n[n.STRETCH = 0] = "STRETCH", n[n.REPEAT = 1] = "REPEAT", n))(Vt || {});
2307
- const J = 10, ct = (n, t, e, r, i, s) => {
2308
- const a = [], o = [], h = r ? Math.atan2(t.y, t.x) : Math.atan2(-t.y, -t.x), c = Math.PI, u = new p(t.y, -t.x);
2309
- for (let l = 0; l < J; l++) {
2310
- const d = l / J, f = (l + 1) / J, m = h + d * c, g = h + f * c, v = new p(Math.cos(m) * e, Math.sin(m) * e), y = new p(Math.cos(g) * e, Math.sin(g) * e);
2311
- a.push(n), o.push(new p(i, 0.5)), a.push(n.add(v)), o.push(new p(i + v.dot(u) * s, 0.5 - 0.5 * v.dot(t) / e)), a.push(n.add(y)), o.push(new p(i + y.dot(u) * s, 0.5 - 0.5 * y.dot(t) / e));
2312
- }
2313
- return { vertices: a, uv: o };
2314
- }, Yt = (n, t = !1) => {
1652
+ var qt = /* @__PURE__ */ ((n) => (n[n.STRETCH = 0] = "STRETCH", n[n.REPEAT = 1] = "REPEAT", n))(qt || {});
1653
+ const nt = 10, mt = (n, t, e, r, i, s) => {
1654
+ const a = [], h = [], o = r ? Math.atan2(t.y, t.x) : Math.atan2(-t.y, -t.x), c = Math.PI, u = new g(t.y, -t.x);
1655
+ for (let l = 0; l < nt; l++) {
1656
+ const f = l / nt, d = (l + 1) / nt, x = o + f * c, p = o + d * c, v = new g(Math.cos(x) * e, Math.sin(x) * e), y = new g(Math.cos(p) * e, Math.sin(p) * e);
1657
+ a.push(n), h.push(new g(i, 0.5)), a.push(n.add(v)), h.push(new g(i + v.dot(u) * s, 0.5 - 0.5 * v.dot(t) / e)), a.push(n.add(y)), h.push(new g(i + y.dot(u) * s, 0.5 - 0.5 * y.dot(t) / e));
1658
+ }
1659
+ return { vertices: a, uv: h };
1660
+ }, Qt = (n, t = !1) => {
2315
1661
  const e = [];
2316
1662
  if (n.length < 2 || t && n.length < 3) return { normals: e, length: 0 };
2317
1663
  const r = 4, i = 1e-3, s = n.length;
2318
1664
  let a = 0;
2319
1665
  if (t)
2320
- for (let h = 0; h < s; h++) {
2321
- const c = n[h], u = n[(h + 1) % s];
1666
+ for (let o = 0; o < s; o++) {
1667
+ const c = n[o], u = n[(o + 1) % s];
2322
1668
  a += c.distanceTo(u);
2323
1669
  }
2324
1670
  else
2325
- for (let h = 0; h < s - 1; h++)
2326
- a += n[h].distanceTo(n[h + 1]);
2327
- const o = (h, c, u) => {
2328
- const l = c.subtract(h).normalize(), d = c.subtract(u).normalize(), f = d.dot(l);
2329
- if (f < -1 + i)
1671
+ for (let o = 0; o < s - 1; o++)
1672
+ a += n[o].distanceTo(n[o + 1]);
1673
+ const h = (o, c, u) => {
1674
+ const l = c.subtract(o).normalize(), f = c.subtract(u).normalize(), d = f.dot(l);
1675
+ if (d < -1 + i)
2330
1676
  return { normal: l.perpendicular(), miters: 1 };
2331
1677
  {
2332
- let m = d.add(l).normalize();
2333
- l.cross(d) < 0 && (m = m.multiply(-1));
2334
- let g = 1 / Math.sqrt((1 - f) / 2);
2335
- return { normal: m, miters: Math.min(g, r) };
1678
+ let x = f.add(l).normalize();
1679
+ l.cross(f) < 0 && (x = x.multiply(-1));
1680
+ let p = 1 / Math.sqrt((1 - d) / 2);
1681
+ return { normal: x, miters: Math.min(p, r) };
2336
1682
  }
2337
1683
  };
2338
1684
  if (t)
2339
- for (let h = 0; h < s; h++) {
2340
- const c = h === 0 ? n[s - 1] : n[h - 1], u = n[h], l = h === s - 1 ? n[0] : n[h + 1];
2341
- e.push(o(c, u, l));
1685
+ for (let o = 0; o < s; o++) {
1686
+ const c = o === 0 ? n[s - 1] : n[o - 1], u = n[o], l = o === s - 1 ? n[0] : n[o + 1];
1687
+ e.push(h(c, u, l));
2342
1688
  }
2343
1689
  else
2344
- for (let h = 0; h < s; h++)
2345
- if (h === 0) {
1690
+ for (let o = 0; o < s; o++)
1691
+ if (o === 0) {
2346
1692
  const c = n[1].subtract(n[0]).normalize();
2347
1693
  e.push({ normal: c.perpendicular(), miters: 1 });
2348
- } else if (h === s - 1) {
2349
- const c = n[h].subtract(n[h - 1]).normalize();
1694
+ } else if (o === s - 1) {
1695
+ const c = n[o].subtract(n[o - 1]).normalize();
2350
1696
  e.push({ normal: c.perpendicular(), miters: 1 });
2351
1697
  } else
2352
- e.push(o(n[h - 1], n[h], n[h + 1]));
1698
+ e.push(h(n[o - 1], n[o], n[o + 1]));
2353
1699
  return { normals: e, length: a };
2354
- }, Xt = (n) => {
1700
+ }, Zt = (n) => {
2355
1701
  const t = n.points;
2356
1702
  if (t.length < 2) return { vertices: [], uv: [] };
2357
- const { normals: e, length: r } = Yt(t, n.closed), i = (n.width || 1) / 2, s = [], a = [], o = n.roundCap || !1, h = n.textureMode || 0;
1703
+ const { normals: e, length: r } = Qt(t, n.closed), i = (n.width || 1) / 2, s = [], a = [], h = n.roundCap || !1, o = n.textureMode || 0;
2358
1704
  let c = 0;
2359
1705
  const u = n.texture?.rawWidth || 1, l = n.closed ? t.length : t.length - 1;
2360
- for (let d = 0; d < l; d++) {
2361
- const f = t[d], m = e[d].normal, g = e[d].miters, v = (d + 1) % t.length, y = t[v], R = e[v].normal, M = e[v].miters, C = f.add(m.multiply(g * i)), P = f.subtract(m.multiply(g * i)), I = y.add(R.multiply(M * i)), O = y.subtract(R.multiply(M * i)), _ = f.distanceTo(y);
2362
- let w = 0, U = 0;
2363
- h === 0 ? (w = c / r, U = (c + _) / r) : (w = c / u, U = w + _ / u);
2364
- const B = new p(w, 0), D = new p(w, 1), G = new p(U, 0), F = new p(U, 1);
2365
- s.push(C), a.push(B), s.push(P), a.push(D), s.push(I), a.push(G), s.push(I), a.push(G), s.push(O), a.push(F), s.push(P), a.push(D), c += _;
2366
- }
2367
- if (o && !n.closed) {
2368
- const d = t[0], f = e[0].normal, m = h === 0 ? r > 0 ? 1 / r : 0 : 1 / u, g = ct(d, f, i, !0, 0, m);
2369
- s.push(...g.vertices), a.push(...g.uv);
2370
- const v = t[t.length - 1], y = e[t.length - 1].normal, R = h === 0 ? 1 : c / u, M = h === 0 ? r > 0 ? 1 / r : 0 : 1 / u, C = ct(v, y, i, !1, R, M);
2371
- s.push(...C.vertices), a.push(...C.uv);
1706
+ for (let f = 0; f < l; f++) {
1707
+ const d = t[f], x = e[f].normal, p = e[f].miters, v = (f + 1) % t.length, y = t[v], E = e[v].normal, w = e[v].miters, _ = d.add(x.multiply(p * i)), L = d.subtract(x.multiply(p * i)), W = y.add(E.multiply(w * i)), O = y.subtract(E.multiply(w * i)), b = d.distanceTo(y);
1708
+ let M = 0, C = 0;
1709
+ o === 0 ? (M = c / r, C = (c + b) / r) : (M = c / u, C = M + b / u);
1710
+ const B = new g(M, 0), k = new g(M, 1), H = new g(C, 0), I = new g(C, 1);
1711
+ s.push(_), a.push(B), s.push(L), a.push(k), s.push(W), a.push(H), s.push(W), a.push(H), s.push(O), a.push(I), s.push(L), a.push(k), c += b;
1712
+ }
1713
+ if (h && !n.closed) {
1714
+ const f = t[0], d = e[0].normal, x = o === 0 ? r > 0 ? 1 / r : 0 : 1 / u, p = mt(f, d, i, !0, 0, x);
1715
+ s.push(...p.vertices), a.push(...p.uv);
1716
+ const v = t[t.length - 1], y = e[t.length - 1].normal, E = o === 0 ? 1 : c / u, w = o === 0 ? r > 0 ? 1 / r : 0 : 1 / u, _ = mt(v, y, i, !1, E, w);
1717
+ s.push(..._.vertices), a.push(..._.uv);
2372
1718
  }
2373
1719
  return { vertices: s, uv: a };
2374
- }, q = (n, t, e, r) => {
1720
+ }, Q = (n, t, e, r) => {
2375
1721
  if (t.customMatrix !== void 0)
2376
1722
  return t.customMatrix;
2377
1723
  if (t.modifyStack) {
@@ -2390,32 +1736,32 @@ const J = 10, ct = (n, t, e, r, i, s) => {
2390
1736
  i
2391
1737
  ), i;
2392
1738
  }
2393
- }, zt = (n, t) => t ? n ? t.premultipliedUint32 : t.uint32 : 4294967295, $t = 2, jt = (n, t) => {
2394
- const e = q(n, t, t.texture.rawWidth, t.texture.rawHeight), r = t.texture;
1739
+ }, Jt = (n, t) => t ? n ? t.premultipliedUint32 : t.uint32 : 4294967295, te = 2, ee = (n, t) => {
1740
+ const e = Q(n, t, t.texture.rawWidth, t.texture.rawHeight), r = t.texture;
2395
1741
  if (!r?.base || n.inCreateMask)
2396
1742
  return;
2397
1743
  const i = r.isAtlas ? n.atlasSpriteRegion : n.spriteRegion;
2398
1744
  n.enterRegion(i, t.shader);
2399
- let s = r.uvX, a = r.uvY, o = r.uvW, h = r.uvH;
1745
+ let s = r.uvX, a = r.uvY, h = r.uvW, o = r.uvH;
2400
1746
  const c = !!t.flipX, u = !!t.flipY != !!r.flipY;
2401
1747
  let l = t.padding ?? i.currentShader.padding;
2402
- r.isAtlas && (l += $t);
2403
- const d = s <= o ? l : -l, f = a <= h ? l : -l;
1748
+ r.isAtlas && (l += te);
1749
+ const f = s <= h ? l : -l, d = a <= o ? l : -l;
2404
1750
  i.drawSprite(
2405
1751
  r,
2406
1752
  e ?? t.customMatrix ?? n.matrixStack.curWorldM,
2407
1753
  s,
2408
1754
  a,
2409
- o,
2410
1755
  h,
1756
+ o,
2411
1757
  n.getColorUint32(t.color),
2412
- d,
2413
1758
  f,
1759
+ d,
2414
1760
  c,
2415
1761
  u,
2416
1762
  r.isRotated
2417
1763
  );
2418
- }, Kt = (n, t) => {
1764
+ }, re = (n, t) => {
2419
1765
  const e = n.particleRegion;
2420
1766
  n.enterRegion(e, t.shader);
2421
1767
  const r = t.texture, i = t.count ?? t.x.length, s = t.color;
@@ -2441,9 +1787,9 @@ const J = 10, ct = (n, t, e, r, i, s) => {
2441
1787
  t.reverseOrder,
2442
1788
  t.customMatrix
2443
1789
  );
2444
- }, yt = (n, t) => {
1790
+ }, wt = (n, t) => {
2445
1791
  if (t.points.length === 0) return;
2446
- const e = q(n, t, 0, 0);
1792
+ const e = Q(n, t, 0, 0);
2447
1793
  n.startGraphic(
2448
1794
  t.drawMode ?? n.gl.TRIANGLES,
2449
1795
  t.texture,
@@ -2461,18 +1807,18 @@ const J = 10, ct = (n, t, e, r, i, s) => {
2461
1807
  );
2462
1808
  }
2463
1809
  n.endGraphic();
2464
- }, qt = (n, t) => {
1810
+ }, ie = (n, t) => {
2465
1811
  if (n.inCreateMask)
2466
1812
  return;
2467
- const { vertices: e, uv: r } = Xt(t);
2468
- yt(n, {
1813
+ const { vertices: e, uv: r } = Zt(t);
1814
+ wt(n, {
2469
1815
  ...t,
2470
1816
  points: e,
2471
1817
  uv: r,
2472
1818
  drawMode: n.gl.TRIANGLES
2473
1819
  });
2474
- }, Qt = (n, t) => {
2475
- const e = q(
1820
+ }, se = (n, t) => {
1821
+ const e = Q(
2476
1822
  n,
2477
1823
  t,
2478
1824
  t.texture.rawWidth,
@@ -2483,16 +1829,16 @@ const J = 10, ct = (n, t, e, r, i, s) => {
2483
1829
  t.texture,
2484
1830
  e ?? t.customMatrix
2485
1831
  ), n.addRectVertex(t.texture.rawWidth, t.texture.rawHeight), n.endGraphic();
2486
- }, Zt = (n, t) => {
2487
- const e = q(n, t, t.width, t.height);
1832
+ }, ne = (n, t) => {
1833
+ const e = Q(n, t, t.width, t.height);
2488
1834
  n.startGraphic(
2489
1835
  n.gl.TRIANGLE_FAN,
2490
1836
  t.texture,
2491
1837
  t.shader,
2492
1838
  e ?? t.customMatrix
2493
1839
  ), n.addRectVertex(t.width, t.height, t.color), n.endGraphic();
2494
- }, Jt = (n, t) => {
2495
- const e = t.segments ?? 32, r = q(n, t, 0, 0);
1840
+ }, ae = (n, t) => {
1841
+ const e = t.segments ?? 32, r = Q(n, t, 0, 0);
2496
1842
  n.startGraphic(
2497
1843
  n.gl.TRIANGLE_FAN,
2498
1844
  void 0,
@@ -2501,7 +1847,7 @@ const J = 10, ct = (n, t, e, r, i, s) => {
2501
1847
  );
2502
1848
  const i = n.getColorUint32(t.color);
2503
1849
  n.addGraphicVertex(0, 0, 0.5, 0.5, i), n.addCircleVertex(t.radius, t.color, e), n.addGraphicVertex(t.radius, 0, 1, 0.5, i), n.endGraphic();
2504
- }, ut = `#version 300 es\r
1850
+ }, xt = `#version 300 es\r
2505
1851
  precision mediump float;\r
2506
1852
  \r
2507
1853
  uniform sampler2D uTextures[%TEXTURE_NUM%];\r
@@ -2515,27 +1861,21 @@ in vec4 vUVRect;\r
2515
1861
  out vec4 fragColor;\r
2516
1862
  in vec2 vPadding;\r
2517
1863
  \r
2518
- bool clampUV(vec2 uv) {\r
2519
- return uv.x < vUVRect.x || uv.x > vUVRect.z || uv.y < vUVRect.y || uv.y > vUVRect.w;\r
2520
- }\r
2521
- \r
2522
1864
  vec4 sampleTexture(vec2 uv) {\r
2523
1865
  %GET_COLOR%\r
2524
1866
  }\r
2525
1867
  \r
2526
1868
  vec4 sampleClampTexture(vec2 uv) {\r
2527
- if (clampUV(uv)) {\r
2528
- return vec4(0.0, 0.0, 0.0, 0.0);\r
2529
- }\r
2530
- return sampleTexture(uv);\r
1869
+ vec2 inMin = step(vUVRect.xy, uv);\r
1870
+ vec2 inMax = step(uv, vUVRect.zw);\r
1871
+ \r
1872
+ float mask = inMin.x * inMin.y * inMax.x * inMax.y;\r
1873
+ \r
1874
+ return sampleTexture(uv) * mask;\r
2531
1875
  }\r
2532
1876
  \r
2533
1877
  vec4 sampleTextureLocal(vec2 uv){\r
2534
- vec2 gUV = mix(vUVRect.xy, vUVRect.zw, uv);\r
2535
- if (clampUV(gUV)) {\r
2536
- return vec4(0.0, 0.0, 0.0, 0.0);\r
2537
- }\r
2538
- return sampleTexture(gUV);\r
1878
+ return sampleClampTexture(mix(vUVRect.xy, vUVRect.zw, uv));\r
2539
1879
  }\r
2540
1880
  \r
2541
1881
  // CUSTOM_CODE\r
@@ -2551,21 +1891,21 @@ void main(void) {\r
2551
1891
  // CUSTOM_CODE_CALL\r
2552
1892
  }\r
2553
1893
  `;
2554
- class te extends nt {
1894
+ class he extends lt {
2555
1895
  KEY = "AtlasSprite";
2556
1896
  constructor(t) {
2557
1897
  super(t);
2558
1898
  }
2559
1899
  createCustomShader(t) {
2560
- const e = H(ut, this.rapid.maxTextureUnits - t.usedTextureUnitNum), r = H(Q, this.rapid.maxTextureUnits - t.usedTextureUnitNum);
1900
+ const e = D(xt, this.rapid.maxTextureUnits - t.usedTextureUnitNum), r = D(et, this.rapid.maxTextureUnits - t.usedTextureUnitNum);
2561
1901
  return t.getGLShader(this, this.KEY, r, e);
2562
1902
  }
2563
1903
  createDefaultShader() {
2564
- const t = this.rapid, e = H(ut, t.maxTextureUnits), r = H(Q, t.maxTextureUnits);
1904
+ const t = this.rapid, e = D(xt, t.maxTextureUnits), r = D(et, t.maxTextureUnits);
2565
1905
  return this.vs = r, this.fs = e, this.defaultShader = this.createShader(r, e), this.defaultShader;
2566
1906
  }
2567
1907
  }
2568
- const lt = `#version 300 es\r
1908
+ const gt = `#version 300 es\r
2569
1909
  precision highp float;\r
2570
1910
  \r
2571
1911
  // per-vertex\r
@@ -2577,7 +1917,7 @@ in vec2 aScale;\r
2577
1917
  in float aRotation;\r
2578
1918
  in vec2 aOrigin;\r
2579
1919
  \r
2580
- // per-instance:UV 区域 (u0, v0, u1, v1)\r
1920
+ // per-instance:UV\r
2581
1921
  in vec4 aUVRect;\r
2582
1922
  \r
2583
1923
  // per-instance:tint color\r
@@ -2591,7 +1931,6 @@ out vec4 vColor;\r
2591
1931
  void main(void) {\r
2592
1932
  vColor = aColor;\r
2593
1933
  \r
2594
- //vRegion = mix(aUVRect.xy, aUVRect.zw, vertex.xy);\r
2595
1934
  vRegion = aUVRect.xy + aVertex * (aUVRect.zw - aUVRect.xy);\r
2596
1935
  // CUSTOM_CODE_CALL\r
2597
1936
  \r
@@ -2599,14 +1938,14 @@ void main(void) {\r
2599
1938
  float c = cos(aRotation);\r
2600
1939
  float s = sin(aRotation);\r
2601
1940
  \r
2602
- vec2 v = vec2(\r
1941
+ vec2 position = vec2(\r
2603
1942
  scaled.x * c - scaled.y * s,\r
2604
1943
  scaled.x * s + scaled.y * c\r
2605
1944
  ) + aPosition;\r
2606
1945
  \r
2607
- gl_Position = u_projection * vec4(v, 0.0, 1.0);\r
1946
+ gl_Position = u_projection * vec4(position, 0.0, 1.0);\r
2608
1947
  }\r
2609
- `, dt = `#version 300 es\r
1948
+ `, pt = `#version 300 es\r
2610
1949
  precision mediump float;\r
2611
1950
  \r
2612
1951
  uniform sampler2D uTexture;\r
@@ -2622,8 +1961,8 @@ void main(void) {\r
2622
1961
  \r
2623
1962
  // CUSTOM_CODE_CALL\r
2624
1963
  }\r
2625
- `, V = 48, ee = V / 4;
2626
- class re extends nt {
1964
+ `, G = 48, oe = G / 4;
1965
+ class ce extends lt {
2627
1966
  KEY = "ParticleSprite";
2628
1967
  texture;
2629
1968
  customMatrix;
@@ -2632,10 +1971,10 @@ class re extends nt {
2632
1971
  super(t);
2633
1972
  }
2634
1973
  createCustomShader(t) {
2635
- return t.getGLShader(this, this.KEY, lt, dt);
1974
+ return t.getGLShader(this, this.KEY, gt, pt);
2636
1975
  }
2637
1976
  createDefaultShader() {
2638
- const t = dt, e = lt;
1977
+ const t = pt, e = gt;
2639
1978
  return this.vs = e, this.fs = t, this.defaultShader = this.createShader(e, t), this.defaultShader;
2640
1979
  }
2641
1980
  enter(t) {
@@ -2644,71 +1983,73 @@ class re extends nt {
2644
1983
  createShader(t, e) {
2645
1984
  const r = super.createShader(t, e);
2646
1985
  return r.use(), r.bindVAO(), this.instanceBuffer.bindBuffer(), r.setAttributes([
2647
- { name: "aPosition", size: 2, stride: V, offset: 0, divisor: 1 },
2648
- { name: "aScale", size: 2, stride: V, offset: 8, divisor: 1 },
2649
- { name: "aRotation", size: 1, stride: V, offset: 16, divisor: 1 },
2650
- { name: "aUVRect", size: 4, stride: V, offset: 20, divisor: 1 },
2651
- { name: "aColor", size: 4, type: it, normalized: !0, stride: V, offset: 36, divisor: 1 },
2652
- { name: "aOrigin", size: 2, stride: V, offset: 40, divisor: 1 }
1986
+ { name: "aPosition", size: 2, stride: G, offset: 0, divisor: 1 },
1987
+ { name: "aScale", size: 2, stride: G, offset: 8, divisor: 1 },
1988
+ { name: "aRotation", size: 1, stride: G, offset: 16, divisor: 1 },
1989
+ { name: "aUVRect", size: 4, stride: G, offset: 20, divisor: 1 },
1990
+ { name: "aColor", size: 4, type: ot, normalized: !0, stride: G, offset: 36, divisor: 1 },
1991
+ { name: "aOrigin", size: 2, stride: G, offset: 40, divisor: 1 }
2653
1992
  ]), this.quadBuffer.bindBuffer(), r.setAttributes([
2654
1993
  { name: "aVertex", size: 2, stride: 8, offset: 0, divisor: 0 }
2655
1994
  ]), r.unbindVAO(), this.currentShader && this.currentShader.use(), r;
2656
1995
  }
2657
- 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, g = !1, v = 0.5, y = 0.5, R, M = !1, C) {
1996
+ drawParticles(t, e, r, i = 0, s = 4294967295, a, h = 1, o = 1, c = 0, u = 0, l = 1, f = 1, d = !1, x = !1, p = !1, v = 0.5, y = 0.5, E, w = !1, _) {
2658
1997
  if (!t.glTexture || a <= 0) return;
2659
1998
  this.texture && t !== this.texture && this.flush();
2660
- const P = typeof o == "number", I = typeof h == "number", O = typeof i == "number", _ = typeof s == "number", w = typeof c == "number", U = !_ && typeof s[0] == "number";
2661
- let B = t.rawWidth * (f ? -1 : 1);
2662
- P && (B *= o);
2663
- let D = t.rawHeight * (m ? -1 : 1);
2664
- I && (D *= h), w && (B *= l - c, D *= d - u);
2665
- let G = g ? Math.PI / 2 : 0;
2666
- O && (G += i);
2667
- const F = s ?? 4294967295, k = this.getParticleLoop(
2668
- P,
2669
- I,
1999
+ const L = typeof h == "number", W = typeof o == "number", O = typeof i == "number", b = typeof s == "number", M = typeof c == "number", C = !b && typeof s[0] == "number", B = t.uvW - t.uvX, k = t.uvH - t.uvY, H = B === 0 ? 0 : 1 / B, I = k === 0 ? 0 : 1 / k;
2000
+ let F = t.rawWidth * (d ? -1 : 1);
2001
+ L && (F *= h);
2002
+ let X = t.rawHeight * (x ? -1 : 1);
2003
+ W && (X *= o), M && (F *= (l - c) * H, X *= (f - u) * I);
2004
+ let z = p ? Math.PI / 2 : 0;
2005
+ O && (z += i);
2006
+ const R = s ?? 4294967295, U = this.getParticleLoop(
2007
+ L,
2008
+ W,
2670
2009
  O,
2671
- w,
2672
- _,
2673
- U,
2674
2010
  M,
2675
- R
2011
+ b,
2012
+ C,
2013
+ w,
2014
+ E
2676
2015
  );
2677
2016
  this.texture || (this.texture = t, this.useTexture(t.glTexture, 0, 0));
2678
- const X = a, W = this.instanceBuffer;
2679
- let T = W.usedElemNum;
2680
- W.resize(X * ee);
2681
- const S = W.float32, Et = W.uint32;
2682
- T = k(
2017
+ const it = a, Y = this.instanceBuffer;
2018
+ let st = Y.usedElemNum;
2019
+ Y.resize(it * oe);
2020
+ const bt = Y.float32, Ut = Y.uint32;
2021
+ st = U(
2683
2022
  e,
2684
2023
  r,
2685
- o,
2686
2024
  h,
2025
+ o,
2687
2026
  i,
2688
2027
  c,
2689
2028
  u,
2690
2029
  l,
2691
- d,
2030
+ f,
2692
2031
  s,
2693
- S,
2694
- Et,
2695
- B,
2696
- D,
2697
- G,
2032
+ bt,
2033
+ Ut,
2698
2034
  F,
2035
+ X,
2036
+ H,
2037
+ I,
2038
+ z,
2039
+ R,
2699
2040
  v,
2700
2041
  y,
2701
2042
  a,
2702
- X,
2703
- T
2704
- ), W.usedElemNum = T, W.makeDirty(), this.instanceCount += X, this.customMatrix = C, this.flush();
2043
+ it,
2044
+ st
2045
+ ), Y.usedElemNum = st, Y.makeDirty(), this.instanceCount += it, this.customMatrix = _, this.flush();
2705
2046
  }
2706
- getParticleLoop(t, e, r, i, s, a, o, h) {
2047
+ getParticleLoop(t, e, r, i, s, a, h, o) {
2707
2048
  const c = [...arguments].join("_");
2708
2049
  if (this.particleLoopCache.has(c))
2709
2050
  return this.particleLoopCache.get(c);
2710
2051
  let u = `
2711
- return function( x, y, scaleX, scaleY, rotation, u0, v0, u1, v1, color, f32, u32, rawWidth, rawHeight, rotationOffset, staticColor, originX, originY, count, batchCount, index ) {
2052
+ return function( x, y, scaleX, scaleY, rotation, u0, v0, u1, v1, color, f32, u32, rawWidth, rawHeight, uv2texW, uv2texH, rotationOffset, staticColor, originX, originY, count, batchCount, index ) {
2712
2053
  ${t && i ? "const baseSx = rawWidth;" : ""}
2713
2054
  ${e && i ? "const baseSy = rawHeight;" : ""}
2714
2055
 
@@ -2716,7 +2057,7 @@ const endIdx = index + batchCount * 12;
2716
2057
  let idx = index;
2717
2058
  if (endIdx > f32.length) return index;
2718
2059
 
2719
- ${o ? "for (let src = count - 1; idx < endIdx; src--, idx += 12) {" : "for (let src = 0; idx < endIdx; src++, idx += 12) {"}
2060
+ ${h ? "for (let src = count - 1; idx < endIdx; src--, idx += 12) {" : "for (let src = 0; idx < endIdx; src++, idx += 12) {"}
2720
2061
  f32[idx] = x[src];
2721
2062
  f32[idx + 1] = y[src];
2722
2063
 
@@ -2730,8 +2071,8 @@ f32[idx + 7] = u1;
2730
2071
  f32[idx + 8] = v1;
2731
2072
  ` : `
2732
2073
  const cu0 = u0[src], cv0 = v0[src], cu1 = u1[src], cv1 = v1[src];
2733
- f32[idx + 2] = (rawWidth * (cu1 - cu0)) ${t ? "" : "* scaleX[src]"};
2734
- f32[idx + 3] = (rawHeight * (cv1 - cv0)) ${e ? "" : "* scaleY[src]"};
2074
+ f32[idx + 2] = (rawWidth * (cu1 - cu0) * uv2texW) ${t ? "" : "* scaleX[src]"};
2075
+ f32[idx + 3] = (rawHeight * (cv1 - cv0) * uv2texH) ${e ? "" : "* scaleY[src]"};
2735
2076
  f32[idx + 4] = ${r ? "rotationOffset" : "rotation[src] + rotationOffset"};
2736
2077
  f32[idx + 5] = cu0;
2737
2078
  f32[idx + 6] = cv0;
@@ -2739,7 +2080,7 @@ f32[idx + 7] = cu1;
2739
2080
  f32[idx + 8] = cv1;
2740
2081
  `}
2741
2082
 
2742
- u32[idx + 9] = ${s ? "staticColor" : a ? "color[src]" : `color[src].${h ? "premultipliedUint32" : "uint32"}`};
2083
+ u32[idx + 9] = ${s ? "staticColor" : a ? "color[src]" : `color[src].${o ? "premultipliedUint32" : "uint32"}`};
2743
2084
 
2744
2085
  f32[idx + 10] = originX;
2745
2086
  f32[idx + 11] = originY;
@@ -2757,61 +2098,38 @@ return idx;
2757
2098
  this.texture && (t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, this.texture.glTexture));
2758
2099
  const e = this.currentShader;
2759
2100
  this.instanceBuffer.bindBuffer(), this.instanceBuffer.bufferData(), e.bindVAO();
2760
- const r = this.rapid.matrixStack, s = this.rapid.matrix.getMatrix(this.customMatrix ?? r.curWorldM), a = Ht(this.rapid.projection, s);
2761
- this.currentShader.setUniform("u_projection", a), pt(t, t.TRIANGLE_STRIP, 0, 4, this.instanceCount), this.rapid.drawcallCount++, this.texture = void 0, this.customMatrix = void 0;
2101
+ const r = this.rapid.matrixStack, s = this.rapid.matrix.getMatrix(this.customMatrix ?? r.curWorldM), a = jt(this.rapid.projection, s);
2102
+ this.currentShader.setUniform("u_projection", a), Et(t, t.TRIANGLE_STRIP, 0, 4, this.instanceCount), this.rapid.drawcallCount++, this.texture = void 0, this.customMatrix = void 0;
2762
2103
  }
2763
2104
  }
2764
- var ie = /* @__PURE__ */ ((n) => (n[n.EQUAL = 0] = "EQUAL", n[n.NOT_EQUAL = 1] = "NOT_EQUAL", n))(ie || {}), se = /* @__PURE__ */ ((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))(se || {}), st = /* @__PURE__ */ ((n) => (n[n.LINEAR = 0] = "LINEAR", n[n.NEAREST = 1] = "NEAREST", n))(st || {}), ne = /* @__PURE__ */ ((n) => (n[n.CanvasItem = 0] = "CanvasItem", n[n.Viewport = 1] = "Viewport", n))(ne || {});
2765
- class oe {
2766
- /** The active WebGL context. */
2105
+ var St = /* @__PURE__ */ ((n) => (n[n.EQUAL = 0] = "EQUAL", n[n.NOT_EQUAL = 1] = "NOT_EQUAL", n))(St || {}), ue = /* @__PURE__ */ ((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))(ue || {}), le = /* @__PURE__ */ ((n) => (n[n.CanvasItem = 0] = "CanvasItem", n[n.Viewport = 1] = "Viewport", n))(le || {});
2106
+ class pe {
2767
2107
  gl;
2768
- /** The target HTMLCanvasElement. */
2769
2108
  canvas;
2770
- /** The current orthographic projection matrix (16 elements). */
2771
2109
  projection = new Float32Array(16);
2772
- /** Indicates if the projection matrix has changed and needs to be uploaded to shaders. */
2773
2110
  projectionDirty = !0;
2774
- /** The current device pixel ratio. */
2775
2111
  dpr;
2776
- /** Background clear color [r, g, b, a], values range from 0 to 255. */
2777
- backgroundColor = x.Black;
2778
- /** Logical width in CSS pixels, used for coordinate system and projection matrix. */
2112
+ backgroundColor = m.Black;
2779
2113
  logicWidth = 0;
2780
- /** Logical height in CSS pixels, used for coordinate system and projection matrix. */
2781
2114
  logicHeight = 0;
2782
- /** Physical width (canvas actual pixels = logical width * dpr). */
2783
2115
  physicsWidth = 0;
2784
- /** Physical height (canvas actual pixels = logical height * dpr). */
2785
2116
  physicsHeight = 0;
2786
- /** The currently active rendering region. */
2787
2117
  currentRegion = null;
2788
- /** Maximum number of texture units supported by the device. */
2789
2118
  maxTextureUnits = 0;
2790
- /** Matrix stack for hierarchical transformations. */
2791
- matrixStack = new wt(this);
2792
- /** Direct access to the underlying matrix store. */
2119
+ matrixStack = new Gt(this);
2793
2120
  matrix;
2794
- /** Region dedicated to fast sprite rendering. */
2795
2121
  spriteRegion;
2796
- /** Region dedicated to arbitrary geometry and shapes rendering. */
2797
2122
  graphicRegion;
2798
2123
  atlasSpriteRegion;
2799
2124
  particleRegion;
2800
- /** Counts the number of WebGL draw calls made in the current frame. */
2801
2125
  drawcallCount = 0;
2802
- /** Indicates whether we are currently writing to the stencil buffer to create a mask. */
2803
2126
  inCreateMask = !1;
2804
- /** Manager for creating and organizing textures. */
2805
2127
  texture;
2806
- /** Whether textures use premultiplied alpha. Set once at construction. */
2807
2128
  premultipliedAlpha;
2808
- /** Default texture filtering preference and requested canvas MSAA setting. */
2809
2129
  antialias;
2810
2130
  roundPixels;
2811
- /** Default filtering mode used when sampling textures. */
2812
2131
  textureFilter;
2813
2132
  scaleMode;
2814
- /** Internal ping-pong RenderTextures for multi-filter chains. */
2815
2133
  _filterRT = [null, null];
2816
2134
  _filterInput = new N();
2817
2135
  get height() {
@@ -2820,123 +2138,66 @@ class oe {
2820
2138
  get width() {
2821
2139
  return this.logicWidth;
2822
2140
  }
2823
- /**
2824
- * Creates a new Rapid application instance.
2825
- * @param options Initialization options including the target canvas.
2826
- */
2827
2141
  constructor(t) {
2828
- this.canvas = t.canvas, this.dpr = window.devicePixelRatio || 1, this.antialias = t.antialias ?? !1, this.textureFilter = t.textureFilter ?? 1, this.premultipliedAlpha = t.premultipliedAlpha ?? !0, this.roundPixels = t.roundPixels ?? !1, this.scaleMode = t.scaleMode ?? 0;
2829
- const e = Ut(this.canvas, this.antialias, this.premultipliedAlpha);
2830
- this.gl = e, this.maxTextureUnits = e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS), this.matrix = this.matrixStack.matrix, this.spriteRegion = new nt(this), this.graphicRegion = new kt(this), this.atlasSpriteRegion = new te(this), this.particleRegion = new re(this);
2142
+ this.canvas = t.canvas, this.dpr = window.devicePixelRatio || 1, this.antialias = t.antialias ?? !1, this.textureFilter = t.textureFilter ?? tt.NEAREST, this.premultipliedAlpha = t.premultipliedAlpha ?? !0, this.roundPixels = t.roundPixels ?? !1, this.scaleMode = t.scaleMode ?? 0;
2143
+ const e = Nt(this.canvas, this.antialias, this.premultipliedAlpha);
2144
+ this.gl = e, this.maxTextureUnits = e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS), this.matrix = this.matrixStack.matrix, this.spriteRegion = new lt(this), this.graphicRegion = new $t(this), this.atlasSpriteRegion = new he(this), this.particleRegion = new ce(this);
2831
2145
  const r = this.canvas.clientWidth || this.canvas.width, i = this.canvas.clientHeight || this.canvas.height;
2832
- this.physicsWidth = t.physicsWidth || Math.round(r * this.dpr), this.physicsHeight = t.physicsHeight || Math.round(i * this.dpr), this.logicWidth = t.logicWidth || t.width || this.physicsWidth / this.dpr, this.logicHeight = t.logicHeight || t.height || this.physicsHeight / this.dpr, this.resize(this.logicWidth, this.logicHeight, this.physicsWidth, this.physicsHeight), this.texture = new Mt(this), 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);
2146
+ this.physicsWidth = t.physicsWidth || Math.round(r * this.dpr), this.physicsHeight = t.physicsHeight || Math.round(i * this.dpr), this.logicWidth = t.logicWidth || t.width || this.physicsWidth / this.dpr, this.logicHeight = t.logicHeight || t.height || this.physicsHeight / this.dpr, this.resize(this.logicWidth, this.logicHeight, this.physicsWidth, this.physicsHeight), this.texture = new Ct(this), 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);
2833
2147
  }
2834
2148
  setTextureFilter(t) {
2835
2149
  this.textureFilter = t;
2836
2150
  }
2837
- setAntialias(t) {
2838
- this.antialias = t;
2839
- }
2840
2151
  getColorUint32(t) {
2841
- return zt(this.premultipliedAlpha, t);
2152
+ return Jt(this.premultipliedAlpha, t);
2842
2153
  }
2843
- /**
2844
- * Enters a specific rendering region, flushing the previous one if necessary.
2845
- * @param region The rendering region to enter.
2846
- * @param customShader An optional custom shader to use for this region.
2847
- */
2848
2154
  enterRegion(t, e) {
2849
2155
  this.currentRegion === t && this.currentRegion.isSameShader(e) || (this.flush(), this.currentRegion = t, t.enter(e));
2850
2156
  }
2851
2157
  drawParticles(t) {
2852
- Kt(this, t);
2158
+ re(this, t);
2853
2159
  }
2854
2160
  drawSprite(t) {
2855
- jt(this, t);
2161
+ ee(this, t);
2856
2162
  }
2857
2163
  drawLine(t) {
2858
- qt(this, t);
2164
+ ie(this, t);
2859
2165
  }
2860
2166
  drawGraphic(t) {
2861
- yt(this, t);
2167
+ wt(this, t);
2862
2168
  }
2863
2169
  drawRect(t) {
2864
- Zt(this, t);
2170
+ ne(this, t);
2865
2171
  }
2866
2172
  drawCircle(t) {
2867
- Jt(this, t);
2868
- }
2869
- /**
2870
- * Starts rendering arbitrary graphics geometries.
2871
- * @param drawMode The WebGL drawing mode (e.g., gl.TRIANGLES, gl.TRIANGLE_FAN).
2872
- * @param texture An optional texture applied to the graphic vertices.
2873
- * @param customShader An optional custom shader overriding the region's default shader.
2874
- */
2173
+ ae(this, t);
2174
+ }
2875
2175
  startGraphic(t = this.gl.TRIANGLES, e, r, i) {
2876
2176
  this.enterRegion(this.graphicRegion, r), this.graphicRegion.startGraphic(i ?? this.matrixStack.curWorldM, t, e);
2877
2177
  }
2878
- /**
2879
- * Starts rendering graphics explicitly for use as a mask, overriding the shader.
2880
- * @param drawMode The WebGL drawing mode (e.g., gl.TRIANGLES).
2881
- * @param texture An optional texture whose alpha channel may dictate masking rules.
2882
- */
2883
2178
  startMaskGraphic(t = this.gl.TRIANGLES, e, r) {
2884
2179
  this.startGraphic(t, e, this.graphicRegion.maskShader, r);
2885
2180
  }
2886
- /**
2887
- * Utility method: Draws an image directly as a mask using a generic rectangle geometry.
2888
- * @param texture The texture to be used as a mask.
2889
- */
2890
2181
  drawMaskImage(t) {
2891
- Qt(this, t);
2892
- }
2893
- /**
2894
- * Pushes vertices for a rectangle geometry. Should be enclosed by startGraphic and endGraphic.
2895
- * @param w The width of the rectangle.
2896
- * @param h The height of the rectangle.
2897
- * @param color An optional tint color.
2898
- */
2182
+ se(this, t);
2183
+ }
2899
2184
  addRectVertex(t, e, r) {
2900
2185
  const i = this.getColorUint32(r);
2901
2186
  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);
2902
2187
  }
2903
- /**
2904
- * Pushes vertices for a circle geometry using TRIANGLES or similar primitives.
2905
- * @param r The radius of the circle.
2906
- * @param color An optional tint color.
2907
- * @param segments The number of segments (polygons) used to approximate the circle.
2908
- */
2909
2188
  addCircleVertex(t, e, r = 32) {
2910
2189
  const i = Math.PI * 2 / r, s = this.getColorUint32(e);
2911
2190
  for (let a = 0; a < r; a++) {
2912
- const o = i * a, h = Math.cos(o) * t, c = Math.sin(o) * t, u = 0.5 + Math.cos(o) * 0.5, l = 0.5 + Math.sin(o) * 0.5;
2913
- this.addGraphicVertex(h, c, u, l, s);
2191
+ const h = i * a, o = Math.cos(h) * t, c = Math.sin(h) * t, u = 0.5 + Math.cos(h) * 0.5, l = 0.5 + Math.sin(h) * 0.5;
2192
+ this.addGraphicVertex(o, c, u, l, s);
2914
2193
  }
2915
2194
  }
2916
- /**
2917
- * Adds an individual vertex to the current graphics batch.
2918
- * @param x The relative X coordinate of the vertex.
2919
- * @param y The relative Y coordinate of the vertex.
2920
- * @param u The U texture coordinate (0 to 1).
2921
- * @param v The V texture coordinate (0 to 1).
2922
- * @param color The vertex color as a 32-bit unsigned integer.
2923
- */
2924
- addGraphicVertex(t, e, r = 0, i = 0, s) {
2195
+ addGraphicVertex(t, e, r = 0, i = 0, s = 4294967295) {
2925
2196
  this.graphicRegion.addVertex(t, e, r, i, typeof s == "number" ? s : this.getColorUint32(s));
2926
2197
  }
2927
- /**
2928
- * Ends the current graphics geometry definition, readying it for rendering.
2929
- */
2930
2198
  endGraphic() {
2931
2199
  this.graphicRegion.endGraphic();
2932
2200
  }
2933
- /**
2934
- * Resizes the canvas, updates internal viewport values, and recreates projection boundaries.
2935
- * @param logicWidth The new logical display width.
2936
- * @param logicHeight The new logical display height.
2937
- * @param cssWidth Optional CSS display width.
2938
- * @param cssHeight Optional CSS display height.
2939
- */
2940
2201
  resize(t, e, r, i) {
2941
2202
  this.flush();
2942
2203
  const s = r ?? this.canvas.clientWidth ?? this.canvas.width, a = i ?? this.canvas.clientHeight ?? this.canvas.height;
@@ -2952,101 +2213,52 @@ class oe {
2952
2213
  }
2953
2214
  this.updateProjection(0, this.logicWidth, this.logicHeight, 0);
2954
2215
  }
2955
- /**
2956
- * Updates the projection matrix using an orthographic mapping.
2957
- * Automatically sets local flag projectionDirty.
2958
- */
2959
2216
  updateProjection(t, e, r, i) {
2960
2217
  this.updateOrthMatrix(this.projection, t, e, r, i), this.projectionDirty = !0;
2961
2218
  }
2962
- /**
2963
- * Clears the active framebuffer applying the default background color.
2964
- */
2965
2219
  clear() {
2966
2220
  const t = this.gl;
2967
2221
  this.backgroundColor.setClearColor(t), t.clear(t.COLOR_BUFFER_BIT | t.STENCIL_BUFFER_BIT), this.drawcallCount = 0, this.matrixStack.reset();
2968
2222
  }
2969
- /**
2970
- * Populates an orthographic projection matrix in place.
2971
- * Avoids continuous Float32Array allocations for performance reasons.
2972
- */
2973
2223
  updateOrthMatrix(t, e, r, i, s) {
2974
2224
  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;
2975
2225
  }
2976
- /**
2977
- * Flushes currently buffered rendering operations across all active regions.
2978
- */
2979
2226
  flush() {
2980
2227
  this.currentRegion && (this.currentRegion.exit(), this.currentRegion = null);
2981
2228
  }
2982
- /**
2983
- * Applies a chain of shaders to a texture sequentially using ping-pong RenderTextures.
2984
- * Each shader receives the output of the previous one as its input.
2985
- * Two internal RenderTextures are reused across calls (resized as needed).
2986
- *
2987
- * @param source The input texture to start the filter chain from.
2988
- * @param shaders An ordered array of CustomGlShader to apply in sequence.
2989
- * @returns The RenderTexture containing the final filtered result.
2990
- * Draw it with `rapid.drawSprite({ texture: result })` to display it on screen.
2991
- *
2992
- * @example
2993
- * const result = rapid.applyFilters(tex, [blurShader, outlineShader]);
2994
- * rapid.drawSprite({ texture: result });
2995
- */
2996
2229
  applyFilters(t, e) {
2997
2230
  if (e.length === 0)
2998
2231
  throw new Error("applyFilters: shaders array must not be empty.");
2999
2232
  const r = Math.max(...e.map((c) => c.padding)), i = r, s = t.rawWidth + r * 2, a = t.rawHeight + r * 2;
3000
2233
  for (let c = 0; c < 2; c++)
3001
2234
  this._filterRT[c] ? this._filterRT[c].resize(s, a) : this._filterRT[c] = this.texture.createRenderTexture({ width: s, height: a });
3002
- let o = t.clone(this._filterInput), h = 0;
2235
+ let h = t.clone(this._filterInput), o = 0;
3003
2236
  this.matrixStack.save(), this.matrixStack.identity();
3004
2237
  for (let c = 0; c < e.length; c++) {
3005
- const u = this._filterRT[h % 2];
2238
+ const u = this._filterRT[o % 2];
3006
2239
  u.offsetX = 0, u.offsetY = 0, this.enterRenderTexture(u), this.clearRenderTexture(), this.drawSprite({
3007
- texture: o,
2240
+ texture: h,
3008
2241
  shader: e[c],
3009
2242
  offsetX: c == 0 ? i : 0,
3010
2243
  // padding back
3011
2244
  offsetY: c == 0 ? i : 0,
3012
2245
  padding: r
3013
- }), this.leaveRenderTexture(), o = u, h++;
2246
+ }), this.leaveRenderTexture(), h = u, o++;
3014
2247
  }
3015
- return this.matrixStack.restore(), o.offsetX = -i, o.offsetY = -i, o;
2248
+ return this.matrixStack.restore(), h.offsetX = -i, h.offsetY = -i, h;
3016
2249
  }
3017
2250
  enterRenderTexture(t) {
3018
- this.flush(), t.activate(), this.gl.viewport(0, 0, t.rawWidth, t.rawHeight), this.updateProjection(0, t.rawWidth, t.rawHeight, 0);
3019
- }
3020
- /**
3021
- * Clears a RenderTexture to a solid color.
3022
- * Must be called while the RT is the active render target (i.e. inside enterRenderTexture/leaveRenderTexture).
3023
- * Can also be called standalone — it will bind the RT, clear it, but NOT restore the main framebuffer.
3024
- * @param rt The render texture to clear.
3025
- * @param color Clear color. Defaults to transparent black (0, 0, 0, 0).
3026
- */
3027
- clearRenderTexture(t = new x(0, 0, 0, 0)) {
2251
+ this.flush(), t.activate(), this.gl.viewport(0, 0, t.rawWidth, t.rawHeight), this.updateProjection(0, t.rawWidth, 0, t.rawHeight);
2252
+ }
2253
+ clearRenderTexture(t = new m(0, 0, 0, 0)) {
3028
2254
  this.flush();
3029
2255
  const e = this.gl;
3030
2256
  t.setClearColor(e), e.clear(e.COLOR_BUFFER_BIT);
3031
2257
  }
3032
- /**
3033
- * Completes rendering to an offscreen render texture and reverts rendering back to the main canvas.
3034
- */
3035
2258
  leaveRenderTexture() {
3036
2259
  this.flush(), this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null), this.gl.viewport(0, 0, this.physicsWidth, this.physicsHeight), this.updateProjection(0, this.logicWidth, this.logicHeight, 0);
3037
2260
  }
3038
- /**
3039
- * Convenience wrapper: enters a RenderTexture, optionally clears it, runs a callback, then leaves.
3040
- * @param rt The RenderTexture to render into.
3041
- * @param cb The callback containing draw calls to execute inside the RT.
3042
- * @param color Clear color before rendering. Pass `null` to skip clearing. Defaults to transparent black.
3043
- *
3044
- * @example
3045
- * rapid.drawToRenderTexture(myRT, () => {
3046
- * rapid.drawSprite({ texture: mySprite });
3047
- * });
3048
- */
3049
- drawToRenderTexture(t, e, r = new x(0, 0, 0, 0)) {
2261
+ drawToRenderTexture(t, e, r = new m(0, 0, 0, 0)) {
3050
2262
  this.enterRenderTexture(t);
3051
2263
  try {
3052
2264
  r !== null && this.clearRenderTexture(r), e();
@@ -3054,19 +2266,6 @@ class oe {
3054
2266
  this.leaveRenderTexture();
3055
2267
  }
3056
2268
  }
3057
- /**
3058
- * Convenience wrapper: writes a mask using the stencil buffer, then renders within it, then exits the mask.
3059
- * @param maskCb Callback that defines the mask geometry (drawn to stencil, not visible).
3060
- * @param drawCb Callback containing the actual draw calls masked by the stencil.
3061
- * @param type Mask type: EQUAL (draw inside) or NOT_EQUAL (draw outside). Defaults to EQUAL.
3062
- * @param ref Stencil reference value. Defaults to 1.
3063
- *
3064
- * @example
3065
- * rapid.withMask(
3066
- * () => rapid.drawRect({ width: 200, height: 200 }),
3067
- * () => rapid.drawSprite({ texture: myTexture }),
3068
- * );
3069
- */
3070
2269
  withMask(t, e, r = 0, i = 1) {
3071
2270
  this.clearMask(), this.startDrawMask(i);
3072
2271
  try {
@@ -3081,28 +2280,6 @@ class oe {
3081
2280
  this.exitMask();
3082
2281
  }
3083
2282
  }
3084
- /**
3085
- * Convenience wrapper: saves the matrix stack, applies an optional transform, runs a callback, then restores.
3086
- * When `transform` is provided, delegates to `matrixStack.applyTransform()` which handles
3087
- * position, rotation, scale, offset, and origin automatically.
3088
- * @param cb The callback to execute within the saved transform context.
3089
- * @param transform Optional transform options to apply before running the callback.
3090
- * @param width The logical width used to resolve `origin` anchoring. Defaults to 0.
3091
- * @param height The logical height used to resolve `origin` anchoring. Defaults to 0.
3092
- *
3093
- * @example
3094
- * // Simple save/restore
3095
- * rapid.withTransform(() => {
3096
- * rapid.matrixStack.translate(100, 100);
3097
- * rapid.drawSprite({ texture: myTexture });
3098
- * });
3099
- *
3100
- * @example
3101
- * // With a transform applied
3102
- * rapid.withTransform(() => {
3103
- * rapid.drawSprite({ texture: myTexture });
3104
- * }, { x: 100, y: 50, rotation: Math.PI / 4, origin: 0.5 }, myTexture.width, myTexture.height);
3105
- */
3106
2283
  withTransform(t, e, r = 0, i = 0) {
3107
2284
  this.matrixStack.save();
3108
2285
  try {
@@ -3111,19 +2288,6 @@ class oe {
3111
2288
  this.matrixStack.restore();
3112
2289
  }
3113
2290
  }
3114
- /**
3115
- * Convenience wrapper: enables scissor clipping for a region, runs a callback, then disables it.
3116
- * @param x Left edge in logical pixels.
3117
- * @param y Top edge in logical pixels.
3118
- * @param width Width in logical pixels.
3119
- * @param height Height in logical pixels.
3120
- * @param cb The callback to execute within the scissor region.
3121
- *
3122
- * @example
3123
- * rapid.withScissor(50, 50, 300, 200, () => {
3124
- * rapid.drawSprite({ texture: myTexture });
3125
- * });
3126
- */
3127
2291
  withScissor(t, e, r, i, s) {
3128
2292
  this.startScissor(t, e, r, i);
3129
2293
  try {
@@ -3132,16 +2296,6 @@ class oe {
3132
2296
  this.endScissor();
3133
2297
  }
3134
2298
  }
3135
- /**
3136
- * Convenience wrapper: sets a blend mode, runs a callback, then restores NORMAL blend mode.
3137
- * @param mode The BlendMode to apply for the duration of the callback.
3138
- * @param cb The callback to execute under the given blend mode.
3139
- *
3140
- * @example
3141
- * rapid.withBlendMode(BlendMode.ADD, () => {
3142
- * rapid.drawSprite({ texture: glowTexture });
3143
- * });
3144
- */
3145
2299
  withBlendMode(t, e) {
3146
2300
  this.setBlendMode(t);
3147
2301
  try {
@@ -3153,56 +2307,31 @@ class oe {
3153
2307
  );
3154
2308
  }
3155
2309
  }
3156
- /**
3157
- * Starts drawing into the stencil buffer to construct a rendering mask.
3158
- * @param ref The stencil reference value.
3159
- * @param mask The stencil bitmask.
3160
- */
3161
2310
  startDrawMask(t = 1, e = 255) {
3162
2311
  this.flush();
3163
2312
  const r = this.gl;
3164
2313
  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;
3165
2314
  }
3166
- /**
3167
- * Finishes the mask drawing phase and restores color buffer writing.
3168
- */
3169
2315
  endDrawMask() {
3170
2316
  this.flush();
3171
2317
  const t = this.gl;
3172
2318
  t.colorMask(!0, !0, !0, !0), t.stencilMask(0), this.inCreateMask = !1;
3173
2319
  }
3174
- /**
3175
- * Clears bounds created into the stencil mask.
3176
- * @param mask The bitmask specifying which stencil layer to clear.
3177
- */
3178
2320
  clearMask(t = 255) {
3179
2321
  this.flush();
3180
2322
  const e = this.gl;
3181
2323
  e.stencilMask(t), e.clear(e.STENCIL_BUFFER_BIT), this.inCreateMask = !1;
3182
2324
  }
3183
- /**
3184
- * Enters a constrained rendering phase masked by the existing stencil buffer values.
3185
- * @param type Equality check type. Use "equal" to draw inside the mask, or "notEqual" to draw outside.
3186
- * @param ref The reference value to test against.
3187
- * @param mask The bitmask specifying which stencil bits to consider.
3188
- */
3189
2325
  enterMask(t, e = 1, r = 255) {
3190
2326
  this.flush();
3191
2327
  const i = this.gl;
3192
2328
  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;
3193
2329
  }
3194
- /**
3195
- * Exits the masked rendering phase, restoring default full-screen stencil values tests.
3196
- */
3197
2330
  exitMask() {
3198
2331
  this.flush();
3199
2332
  const t = this.gl;
3200
2333
  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;
3201
2334
  }
3202
- /**
3203
- * Configures the global WebGL blending behavior.
3204
- * @param mode The targeted BlendMode to switch onto.
3205
- */
3206
2335
  setBlendMode(t) {
3207
2336
  this.flush();
3208
2337
  const e = this.gl;
@@ -3224,23 +2353,11 @@ class oe {
3224
2353
  break;
3225
2354
  }
3226
2355
  }
3227
- /**
3228
- * Enables rectangular scissor clipping. Only pixels within the specified
3229
- * rectangle (in logical coordinates) will be rendered.
3230
- * Coordinates use the same system as your drawing calls (top-left origin).
3231
- * @param x Left edge in logical pixels.
3232
- * @param y Top edge in logical pixels.
3233
- * @param width Width in logical pixels.
3234
- * @param height Height in logical pixels.
3235
- */
3236
2356
  startScissor(t, e, r, i) {
3237
2357
  this.flush();
3238
- const s = this.gl, a = this.physicsWidth / this.logicWidth, o = this.physicsHeight / this.logicHeight, h = Math.round(t * a), c = Math.round(this.physicsHeight - (e + i) * o), u = Math.round(r * a), l = Math.round(i * o);
3239
- s.enable(s.SCISSOR_TEST), s.scissor(h, c, u, l);
2358
+ const s = this.gl, a = this.physicsWidth / this.logicWidth, h = this.physicsHeight / this.logicHeight, o = Math.round(t * a), c = Math.round(this.physicsHeight - (e + i) * h), u = Math.round(r * a), l = Math.round(i * h);
2359
+ s.enable(s.SCISSOR_TEST), s.scissor(o, c, u, l);
3240
2360
  }
3241
- /**
3242
- * Disables scissor clipping, restoring full-canvas rendering.
3243
- */
3244
2361
  endScissor() {
3245
2362
  this.flush(), this.gl.disable(this.gl.SCISSOR_TEST);
3246
2363
  }
@@ -3250,19 +2367,19 @@ class oe {
3250
2367
  this.matrix.invert(e);
3251
2368
  }
3252
2369
  logicToPhysics(t) {
3253
- return t.multiply(new p(
2370
+ return t.multiply(new g(
3254
2371
  this.physicsWidth / this.logicWidth,
3255
2372
  this.physicsHeight / this.logicHeight
3256
2373
  ));
3257
2374
  }
3258
2375
  physicsToLogic(t) {
3259
- return t.multiply(new p(
2376
+ return t.multiply(new g(
3260
2377
  this.logicWidth / this.physicsWidth,
3261
2378
  this.logicHeight / this.physicsHeight
3262
2379
  ));
3263
2380
  }
3264
2381
  cssToDevicePixel(t) {
3265
- return t.mul(this.dpr);
2382
+ return t.multiply(this.dpr);
3266
2383
  }
3267
2384
  cssToLogic(t) {
3268
2385
  const e = this.cssToDevicePixel(t);
@@ -3271,56 +2388,38 @@ class oe {
3271
2388
  devicePixelToCss(t) {
3272
2389
  return t.divide(this.dpr);
3273
2390
  }
3274
- /**
3275
- * Exports a world matrix as a CSS `matrix(...)` string, ready to assign
3276
- * directly to a DOM element's `style.transform`.
3277
- * Unlike `matrixStack.toCSSMatrix()`, this bakes in the logic-pixel → CSS-pixel
3278
- * scale (accounting for dpr and a custom `logicWidth`/`logicHeight`), so the
3279
- * result lines up with the canvas without any extra `scale(...)` on your end.
3280
- * @param index - Matrix index to export. Defaults to the current world matrix.
3281
- */
3282
2391
  toCSSMatrix(t) {
3283
2392
  const e = this.physicsWidth / this.dpr / this.logicWidth, r = this.physicsHeight / this.dpr / this.logicHeight;
3284
2393
  return this.matrix.toCSSMatrix(t ?? this.matrixStack.curWorldM, e, r);
3285
2394
  }
3286
2395
  }
3287
- function ae(n) {
3288
- return !(n === null || typeof n != "object" || Array.isArray(n) || n instanceof p || n instanceof x);
2396
+ function de(n) {
2397
+ return !(n === null || typeof n != "object" || Array.isArray(n) || n instanceof g || n instanceof m);
3289
2398
  }
3290
- class L {
3291
- /** Random float in [min, max). */
2399
+ class P {
3292
2400
  static float(t, e) {
3293
2401
  return Math.random() * (e - t) + t;
3294
2402
  }
3295
- /** Random integer in [min, max] (inclusive). */
3296
2403
  static int(t, e) {
3297
2404
  return Math.floor(Math.random() * (e - t + 1)) + t;
3298
2405
  }
3299
- /** Random angle in [0, 2π). */
3300
2406
  static angle() {
3301
2407
  return Math.random() * Math.PI * 2;
3302
2408
  }
3303
- /** Random Vec2 with components in the supplied per-axis ranges. */
3304
2409
  static vector(t, e, r, i) {
3305
- return new p(L.float(t, e), L.float(r, i));
2410
+ return new g(P.float(t, e), P.float(r, i));
3306
2411
  }
3307
- /** Random Color with each component interpolated between minColor and maxColor. */
3308
2412
  static randomColor(t, e) {
3309
- return new x(
3310
- L.float(t.r, e.r),
3311
- L.float(t.g, e.g),
3312
- L.float(t.b, e.b),
3313
- L.float(t.a, e.a)
2413
+ return new m(
2414
+ P.float(t.r, e.r),
2415
+ P.float(t.g, e.g),
2416
+ P.float(t.b, e.b),
2417
+ P.float(t.a, e.a)
3314
2418
  );
3315
2419
  }
3316
- /** Pick a random element from an array with uniform probability. */
3317
2420
  static pick(t) {
3318
- return t[L.int(0, t.length - 1)];
2421
+ return t[P.int(0, t.length - 1)];
3319
2422
  }
3320
- /**
3321
- * Pick a random element using weighted probability.
3322
- * @param array - Pairs of [item, weight]. Higher weight = more likely.
3323
- */
3324
2423
  static pickWeight(t) {
3325
2424
  if (!t || t.length === 0) return null;
3326
2425
  let e = 0;
@@ -3330,37 +2429,32 @@ class L {
3330
2429
  if (r -= s, r <= 0) return i;
3331
2430
  return t[t.length - 1][0];
3332
2431
  }
3333
- /**
3334
- * Resolves a scalar-or-range value to a concrete T.
3335
- * - `undefined` → `defaultValue`
3336
- * - `T` → `T` (or a clone for objects)
3337
- * - `[T, T]` → random value between the two bounds
3338
- */
3339
2432
  static scalarOrRange(t, e) {
3340
2433
  if (t == null) return e;
3341
2434
  if (Array.isArray(t)) {
3342
2435
  const [r, i] = t;
3343
2436
  if (typeof r == "number")
3344
- return L.float(r, i);
3345
- if (r instanceof p)
3346
- return L.vector(r.x, i.x, r.y, i.y);
3347
- if (r instanceof x)
3348
- return L.randomColor(r, i);
2437
+ return P.float(r, i);
2438
+ if (r instanceof g)
2439
+ return P.vector(r.x, i.x, r.y, i.y);
2440
+ if (r instanceof m)
2441
+ return P.randomColor(r, i);
3349
2442
  }
3350
2443
  return typeof t == "number" ? t : t.clone();
3351
2444
  }
3352
2445
  }
3353
- var he = /* @__PURE__ */ ((n) => (n.POINT = "point", n.CIRCLE = "circle", n.RECT = "rect", n))(he || {});
3354
- const ft = 10, mt = 0, xt = !0;
3355
- class j {
2446
+ const Z = (n, t) => (Array.isArray(n) ? n : [n]).slice(0, t);
2447
+ var fe = /* @__PURE__ */ ((n) => (n.POINT = "point", n.CIRCLE = "circle", n.RECT = "rect", n))(fe || {});
2448
+ const vt = 10, yt = 0, Tt = !0;
2449
+ class K {
3356
2450
  components;
3357
2451
  constructor(t = 1) {
3358
2452
  if (!Number.isInteger(t) || t <= 0)
3359
2453
  throw new RangeError("ParticleAttributeStore size must be a positive integer");
3360
2454
  this.components = Array.from({ length: t }, () => ({
3361
- value: new b(A.Float32),
3362
- delta: new b(A.Float32),
3363
- damping: new b(A.Float32)
2455
+ value: new A(S.Float32),
2456
+ delta: new A(S.Float32),
2457
+ damping: new A(S.Float32)
3364
2458
  }));
3365
2459
  }
3366
2460
  getArrayBuffer() {
@@ -3377,7 +2471,7 @@ class j {
3377
2471
  getComponent(t, e) {
3378
2472
  if (typeof t == "number")
3379
2473
  return t;
3380
- if (t instanceof p)
2474
+ if (t instanceof g)
3381
2475
  return e === 0 ? t.x : t.y;
3382
2476
  switch (e) {
3383
2477
  case 0:
@@ -3393,53 +2487,47 @@ class j {
3393
2487
  }
3394
2488
  }
3395
2489
  resolveComponent(t, e, r) {
3396
- return t === void 0 ? r : Array.isArray(t) ? L.float(
2490
+ return t === void 0 ? r : Array.isArray(t) ? P.float(
3397
2491
  this.getComponent(t[0], e),
3398
2492
  this.getComponent(t[1], e)
3399
2493
  ) : this.getComponent(t, e);
3400
2494
  }
3401
2495
  create(t, e, r = 1) {
3402
- const i = ae(t) ? t : void 0, s = i === void 0 ? t : void 0, a = r > 0 ? r : 1;
3403
- let o = 0;
3404
- for (let h = 0; h < this.components.length; h++) {
3405
- 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);
3406
- 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);
2496
+ const i = de(t) ? t : void 0, s = i === void 0 ? t : void 0, a = r > 0 ? r : 1;
2497
+ let h = 0;
2498
+ for (let o = 0; o < this.components.length; o++) {
2499
+ const { value: c, delta: u, damping: l } = this.components[o], f = this.getComponent(e, o), d = s === void 0 ? this.resolveComponent(i?.start, o, f) : this.getComponent(s, o), x = i?.end === void 0 ? d : this.resolveComponent(i.end, o, f);
2500
+ c.push(d), u.push(i?.delta === void 0 ? (x - d) / a : this.getComponent(i.delta, o)), l.push(i?.damping ?? 1), o === 0 && (h = d);
3407
2501
  }
3408
- return o;
2502
+ return h;
3409
2503
  }
3410
2504
  }
3411
- class Tt {
2505
+ class At {
3412
2506
  options;
3413
2507
  emitting = !1;
3414
2508
  emitTimer = 0;
3415
- emitRate = ft;
3416
- emitTime = mt;
2509
+ emitRate = vt;
2510
+ emitTime = yt;
3417
2511
  emitTimeCounter = 0;
3418
- /** Whether spawned particles are positioned in local emitter space (default: true). */
3419
- localSpace = xt;
2512
+ localSpace = Tt;
3420
2513
  rapid;
3421
- x = new b(A.Float32);
3422
- y = new b(A.Float32);
3423
- scaleX = new b(A.Float32);
3424
- scaleY = new b(A.Float32);
3425
- rotation = new b(A.Float32);
3426
- color = new b(A.Uint32);
3427
- remainingLife = new b(A.Float32);
2514
+ x = new A(S.Float32);
2515
+ y = new A(S.Float32);
2516
+ scaleX = new A(S.Float32);
2517
+ scaleY = new A(S.Float32);
2518
+ rotation = new A(S.Float32);
2519
+ color = new A(S.Uint32);
2520
+ remainingLife = new A(S.Float32);
3428
2521
  animations = {
3429
- speed: new j(),
3430
- rotation: new j(),
3431
- scale: new j(),
3432
- color: new j(4),
3433
- velocity: new j(2)
2522
+ speed: new K(),
2523
+ rotation: new K(),
2524
+ scale: new K(),
2525
+ color: new K(4),
2526
+ velocity: new K(2)
3434
2527
  };
3435
2528
  count = 0;
3436
- /**
3437
- * Creates a new particle emitter.
3438
- * @param rapid - The Rapid renderer instance
3439
- * @param options - Emitter configuration options
3440
- */
3441
2529
  constructor(t, e) {
3442
- this.rapid = t, this.options = e, this.emitRate = e.emitRate ?? ft, this.emitTime = e.emitTime ?? mt, this.localSpace = e.localSpace ?? xt;
2530
+ this.rapid = t, this.options = e, this.emitRate = e.emitRate ?? vt, this.emitTime = e.emitTime ?? yt, this.localSpace = e.localSpace ?? Tt;
3443
2531
  }
3444
2532
  getAllArrayBuffer() {
3445
2533
  return [
@@ -3453,50 +2541,36 @@ class Tt {
3453
2541
  ...Object.values(this.animations).flatMap((t) => t.getArrayBuffer())
3454
2542
  ];
3455
2543
  }
3456
- /** Replaces the emitter's texture at runtime. */
3457
2544
  setTexture(t) {
3458
2545
  this.options.texture = t;
3459
2546
  }
3460
- /**
3461
- * Creates a new emitter sharing the same options object.
3462
- * Particle state is NOT copied.
3463
- */
3464
2547
  clone() {
3465
- return new Tt(this.rapid, { ...this.options });
2548
+ return new At(this.rapid, { ...this.options });
3466
2549
  }
3467
- /** Sets particles-per-second emission rate (continuous mode). */
3468
2550
  setEmitRate(t) {
3469
2551
  this.emitRate = t;
3470
2552
  }
3471
- /** Sets the burst interval in seconds (0 = continuous). */
3472
2553
  setEmitTime(t) {
3473
2554
  this.emitTime = t;
3474
2555
  }
3475
- /** Starts continuous particle emission. */
3476
2556
  start() {
3477
2557
  this.emitting = !0, this.emitTimeCounter = 0;
3478
2558
  }
3479
- /** Stops new particle emission; existing particles finish their lifecycle. */
3480
2559
  stop() {
3481
2560
  this.emitting = !1;
3482
2561
  }
3483
- /** Removes all particles and resets timers. */
3484
2562
  clear() {
3485
2563
  for (const t of this.getAllArrayBuffer())
3486
2564
  t.clear();
3487
2565
  this.count = 0, this.emitTimeCounter = 0;
3488
2566
  }
3489
- /**
3490
- * Spawns `count` particles immediately.
3491
- * Respects `maxParticles` if set.
3492
- */
3493
2567
  emit(t) {
3494
2568
  const e = this.options.maxParticles ?? 1 / 0, r = Math.min(t, e - this.count);
3495
2569
  for (let i = 0; i < r; i++)
3496
2570
  this.createParticle();
3497
2571
  }
3498
2572
  createParticle() {
3499
- const t = L.scalarOrRange(this.options.life, 1);
2573
+ const t = P.scalarOrRange(this.options.life, 1);
3500
2574
  this.remainingLife.push(t);
3501
2575
  let e = 0, r = 0;
3502
2576
  switch (this.options.emitShape) {
@@ -3517,8 +2591,8 @@ class Tt {
3517
2591
  const { x: c, y: u } = i.localToWorld(e, r);
3518
2592
  this.x.push(c), this.y.push(u);
3519
2593
  }
3520
- const s = this.options.animation, a = this.animations, o = a.scale.create(s.scale, 1, t), h = a.rotation.create(s.rotation, 0, t);
3521
- a.speed.create(s.speed, 0, t), a.velocity.create(s.velocity, p.ZERO, t), a.color.create(s.color, x.White, t), this.rotation.push(h), this.scaleX.push(o), this.scaleY.push(o), this.color.pushUint32(x.packColor(
2594
+ const s = this.options.animation, a = this.animations, h = a.scale.create(s.scale, 1, t), o = a.rotation.create(s.rotation, 0, t);
2595
+ a.speed.create(s.speed, 0, t), a.velocity.create(s.velocity, g.ZERO, t), a.color.create(s.color, m.White, t), this.rotation.push(o), this.scaleX.push(h), this.scaleY.push(h), this.color.pushUint32(m.packColor(
3522
2596
  a.color.get(this.count, 0),
3523
2597
  a.color.get(this.count, 1),
3524
2598
  a.color.get(this.count, 2),
@@ -3526,10 +2600,6 @@ class Tt {
3526
2600
  this.rapid.premultipliedAlpha
3527
2601
  )), this.count += 1;
3528
2602
  }
3529
- /**
3530
- * Updates the emitter and all live particles.
3531
- * @param deltaTime - Seconds elapsed since last frame
3532
- */
3533
2603
  update(t) {
3534
2604
  if (this.emitting && this.emitRate > 0)
3535
2605
  if (this.emitTime > 0) {
@@ -3543,7 +2613,7 @@ class Tt {
3543
2613
  r > 0 && (this.emit(r), this.emitTimer -= r / this.emitRate);
3544
2614
  }
3545
2615
  const e = this.updateParticle(t);
3546
- this.count -= e.length, b.removeAtIndices(e, this.getAllArrayBuffer());
2616
+ this.count -= e.length, A.removeAtIndices(e, this.getAllArrayBuffer());
3547
2617
  }
3548
2618
  updateParticle(t) {
3549
2619
  const e = [], r = this.animations;
@@ -3553,21 +2623,17 @@ class Tt {
3553
2623
  e.push(i);
3554
2624
  continue;
3555
2625
  }
3556
- const s = r.rotation.get(i), a = r.scale.get(i), o = r.speed.get(i);
3557
- this.rotation.typedArray[i] = s, this.scaleX.typedArray[i] = a, this.scaleY.typedArray[i] = a, this.color.uint32[i] = x.packColor(
2626
+ const s = r.rotation.get(i), a = r.scale.get(i), h = r.speed.get(i);
2627
+ this.rotation.typedArray[i] = s, this.scaleX.typedArray[i] = a, this.scaleY.typedArray[i] = a, this.color.uint32[i] = m.packColor(
3558
2628
  r.color.get(i, 0),
3559
2629
  r.color.get(i, 1),
3560
2630
  r.color.get(i, 2),
3561
2631
  r.color.get(i, 3),
3562
2632
  this.rapid.premultipliedAlpha
3563
- ), 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;
2633
+ ), this.x.typedArray[i] += (h * Math.cos(s) + r.velocity.get(i, 0)) * t, this.y.typedArray[i] += (h * Math.sin(s) + r.velocity.get(i, 1)) * t;
3564
2634
  }
3565
2635
  return e;
3566
2636
  }
3567
- /**
3568
- * Renders all live particles.
3569
- * In local-space mode the emitter's own transform is applied around the batch.
3570
- */
3571
2637
  render() {
3572
2638
  const t = this.options, e = this.localSpace ? void 0 : this.rapid.matrix.alloc();
3573
2639
  this.rapid.drawParticles({
@@ -3586,53 +2652,158 @@ class Tt {
3586
2652
  customMatrix: e
3587
2653
  });
3588
2654
  }
3589
- /** Returns `true` if the emitter is running or still has live particles. */
3590
2655
  isActive() {
3591
2656
  return this.emitting || this.count > 0;
3592
2657
  }
3593
- /**
3594
- * Convenience: emit `emitRate` particles in one shot (fire-and-forget burst).
3595
- */
3596
2658
  oneShot() {
3597
2659
  this.emit(this.emitRate);
3598
2660
  }
3599
2661
  }
2662
+ const me = `
2663
+ uniform mediump int uLightTextureId[%TEXTURE_NUM%];
2664
+
2665
+ uniform sampler2D uNormalMap;
2666
+ uniform vec2 uResolution;
2667
+ uniform vec2 uLogicalResolution;
2668
+ uniform mediump int uLightCount;
2669
+ uniform vec4 uLightColor[%TEXTURE_NUM%];
2670
+ uniform mat3x2 uLightMatrix[%TEXTURE_NUM%];
2671
+ uniform float uLightHeight[%TEXTURE_NUM%];
2672
+ uniform float uMetallic;
2673
+ uniform float uRoughness;
2674
+
2675
+ void light_fragment(inout vec4 color, in vec2 vRegion) {
2676
+ if (color.a < 0.005) return;
2677
+
2678
+ // 屏幕坐标映射到世界坐标
2679
+ vec2 worldPos = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) * (uLogicalResolution / uResolution);
2680
+ vec3 normal = normalize(texture(uNormalMap, vRegion).rgb * 2.0 - 1.0) * vec3(1.0, -1.0, 1.0);
2681
+
2682
+ vec3 totalDiffuse = vec3(0.0);
2683
+ vec3 totalSpecular = vec3(0.0);
2684
+ vec3 viewDir = vec3(0.0, 0.0, 1.0);
2685
+ vec3 specColor = mix(vec3(1.0), color.rgb, uMetallic);
2686
+ float shininess = exp2((1.0 - uRoughness) * 7.0 + 1.0);
2687
+
2688
+ for (int i = 0; i < %TEXTURE_NUM%; i++) {
2689
+ if (i >= uLightCount) break;
2690
+
2691
+ vec2 lightPos = uLightMatrix[i][2];
2692
+ mat2 lightBasis = mat2(uLightMatrix[i][0], uLightMatrix[i][1]);
2693
+ vec2 lightUV = inverse(lightBasis) * (worldPos - lightPos) + 0.5;
2694
+
2695
+ // 判断当前像素是否在该光源范围内
2696
+ if (lightUV.x >= 0.0 && lightUV.x <= 1.0 && lightUV.y >= 0.0 && lightUV.y <= 1.0) {
2697
+
2698
+ // ⭐️ 核心修复:sampler2DArray 采样必须传 vec3
2699
+ // 第三个分量是该光源对应的图层 ID (转为 float)
2700
+ int layer = uLightTextureId[i];
2701
+ vec4 lightTex;
2702
+ %GET_COLOR%
2703
+
2704
+ vec3 lightDir = normalize(vec3(lightPos - worldPos, uLightHeight[i]));
2705
+ float diff = max(dot(normal, lightDir), 0.0);
2706
+ float spec = pow(max(dot(normal, normalize(lightDir + viewDir)), 0.0), shininess);
2707
+ vec3 attenuation = lightTex.rgb * lightTex.a;
2708
+
2709
+ totalDiffuse += uLightColor[i].rgb * diff * attenuation * (1.0 - uMetallic);
2710
+ totalSpecular += specColor * uLightColor[i].rgb * spec * attenuation * color.a;
2711
+ }
2712
+ }
2713
+
2714
+ // 环境光 + 漫反射 + 高光
2715
+ color.rgb = color.rgb * (vec3(0.1, 0.1, 0.15) + totalDiffuse) + totalSpecular;
2716
+ }
2717
+ `, xe = "void light_vertex(inout vec4 p, vec2 u) {}", J = 8;
2718
+ class ge extends ct {
2719
+ constructor(t, e = "", r = "", i = 0, s) {
2720
+ super(
2721
+ t,
2722
+ e + xe,
2723
+ D(r + me, t.maxTextureUnits - 1, "layer", "lightUV", "lightTex = "),
2724
+ i + 1,
2725
+ s
2726
+ ), this.prefix.push("light_");
2727
+ }
2728
+ }
2729
+ class ve {
2730
+ shader;
2731
+ rapid;
2732
+ rt;
2733
+ constructor(t) {
2734
+ this.rapid = t, this.shader = new ge(t), this.rt = t.texture.createRenderTexture({ width: 0, height: 0 });
2735
+ }
2736
+ lightShadow(t, e, r) {
2737
+ if (r.length === 0) return;
2738
+ const i = this.rapid, s = typeof e == "number" ? e : e.world, a = new g(t.rawWidth * 0.5, t.rawHeight * 0.5), h = r.map((c) => {
2739
+ const u = i.matrixStack.localToWorld(c.x, c.y), l = i.matrix.worldToLocal(s, u.x, u.y);
2740
+ return new g(
2741
+ // 要把LightTexture的基向量转化为RenderTexture的坐标
2742
+ // 纹理是从左上角开始的,所以要 + 0.5
2743
+ (l.x + 0.5) * t.rawWidth,
2744
+ (l.y + 0.5) * t.rawHeight
2745
+ );
2746
+ });
2747
+ this.rt.resize(t.rawWidth, t.rawHeight);
2748
+ const o = Math.hypot(t.rawWidth, t.rawHeight) * 0.5 * 1.05;
2749
+ return i.drawToRenderTexture(this.rt, () => {
2750
+ i.withMask(() => {
2751
+ i.startMaskGraphic(i.gl.TRIANGLES);
2752
+ for (let c = 0; c < h.length; c++) {
2753
+ const u = h[c], l = h[(c + 1) % h.length], f = u.subtract(a).normalized(), d = l.subtract(a).normalized(), x = Math.max(-0.999, Math.min(1, f.dot(d))), p = Math.sqrt((1 + x) * 0.5), v = o / p, y = a.add(f.multiply(v)), E = a.add(d.multiply(v));
2754
+ i.addGraphicVertex(u.x, u.y), i.addGraphicVertex(l.x, l.y), i.addGraphicVertex(E.x, E.y), i.addGraphicVertex(u.x, u.y), i.addGraphicVertex(E.x, E.y), i.addGraphicVertex(y.x, y.y);
2755
+ }
2756
+ i.endGraphic();
2757
+ }, () => {
2758
+ i.drawSprite({ texture: t });
2759
+ }, St.NOT_EQUAL);
2760
+ }), this.rt;
2761
+ }
2762
+ setupLight(t) {
2763
+ const e = t.customShader ?? this.shader, r = Z(t.lightMatrix, J), i = Z(t.color, J), s = Z(t.lightHeight, J), a = Z(t.lightTexture, J);
2764
+ return e.setUniforms({
2765
+ uResolution: [this.rapid.physicsWidth, this.rapid.physicsHeight],
2766
+ uLogicalResolution: [this.rapid.logicWidth, this.rapid.logicHeight],
2767
+ uNormalMap: t.normalMap.glTexture,
2768
+ uLightTextureId: a.map((h) => h.glTexture),
2769
+ uLightCount: r.length,
2770
+ uLightMatrix: Float32Array.from(r.flatMap(
2771
+ (h) => Array.from(this.rapid.matrix.getMatrix(typeof h == "number" ? h : h.world))
2772
+ )),
2773
+ uLightColor: Float32Array.from(r.flatMap((h, o) => {
2774
+ const c = i[o] ?? i[0];
2775
+ return c ? [c.r / 255, c.g / 255, c.b / 255, c.a / 255] : [1, 1, 1, 1];
2776
+ })),
2777
+ uLightHeight: Float32Array.from(r.map((h, o) => s[o] ?? s[0] ?? 80)),
2778
+ uMetallic: t.metallic ?? 0.8,
2779
+ uRoughness: t.roughness ?? 0.15
2780
+ }), e;
2781
+ }
2782
+ }
3600
2783
  export {
3601
- A as ArrayType,
3602
- Y as BaseTexture,
3603
- se as BlendMode,
3604
- ne as CanvasScaleMode,
3605
- x as Color,
3606
- ht as CustomGlShader,
3607
- b as DynamicArrayBuffer,
3608
- gt as GLShader,
3609
- kt as GraphicRegion,
3610
- Vt as LineTextureMode,
3611
- ie as MaskType,
3612
- wt as MatrixStack,
3613
- Rt as MatrixStore,
3614
- Tt as ParticleEmitter,
3615
- he as ParticleShape,
3616
- Ot as QUAD_VERTICES,
3617
- oe as Rapid,
3618
- vt as Region,
3619
- At as RenderTexture,
3620
- nt as SpriteRegion,
3621
- bt as TextTexture,
2784
+ V as BaseTexture,
2785
+ ue as BlendMode,
2786
+ le as CanvasScaleMode,
2787
+ m as Color,
2788
+ ct as CustomGlShader,
2789
+ Rt as GLShader,
2790
+ ve as Light,
2791
+ ge as LightShader,
2792
+ qt as LineTextureMode,
2793
+ J as MAX_LIGHTS,
2794
+ St as MaskType,
2795
+ At as ParticleEmitter,
2796
+ fe as ParticleShape,
2797
+ pe as Rapid,
2798
+ _t as RenderTexture,
2799
+ Pt as TextTexture,
3622
2800
  N as Texture,
3623
- st as TextureFilterMode,
3624
- Mt as TextureManager,
3625
- K as TextureWrapMode,
3626
- p as Vec2,
3627
- tt as WebglBufferArray,
3628
- Ht as composeProjectionWithAffine,
3629
- Jt as drawCircle,
3630
- yt as drawGraphic,
3631
- qt as drawLine,
3632
- Qt as drawMaskImage,
3633
- Kt as drawParticles,
3634
- Zt as drawRect,
3635
- jt as drawSprite,
3636
- zt as getColorUint32,
3637
- Gt as multiplyMat4
2801
+ tt as TextureFilterMode,
2802
+ Ct as TextureManager,
2803
+ q as TextureWrapMode,
2804
+ g as Vec2,
2805
+ jt as composeProjectionWithAffine,
2806
+ Zt as getLineGeometry,
2807
+ Qt as getLineNormal,
2808
+ Kt as multiplyMat4
3638
2809
  };