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.
- package/README.md +37 -18
- package/dist/buffer.d.ts +0 -5
- package/dist/color.d.ts +0 -4
- package/dist/extensions/light.d.ts +29 -0
- package/dist/{particle.d.ts → extensions/particle.d.ts} +6 -6
- package/dist/index.d.ts +3 -8
- package/dist/math.d.ts +0 -3
- package/dist/matrix-engine.d.ts +19 -11
- package/dist/rapid-render.js +1004 -1833
- package/dist/rapid-render.umd.cjs +86 -50
- package/dist/render.d.ts +3 -6
- package/dist/texture-filter-mode.d.ts +5 -0
- package/dist/texture.d.ts +2 -4
- package/dist/utils.d.ts +1 -0
- package/dist/webgl/glshader.d.ts +5 -3
- package/dist/webgl/utils.d.ts +4 -3
- package/package.json +7 -5
- package/dist/vite.svg +0 -1
package/dist/rapid-render.js
CHANGED
|
@@ -1,229 +1,4 @@
|
|
|
1
|
-
|
|
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 =
|
|
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.
|
|
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
|
|
327
|
-
return t < 60 ? [
|
|
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
|
|
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
|
|
72
|
+
return new m(0, 0, 0).setHSL(t, e, r);
|
|
380
73
|
}
|
|
381
74
|
static FromRGB(t, e, r) {
|
|
382
|
-
return new
|
|
75
|
+
return new m(t, e, r);
|
|
383
76
|
}
|
|
384
77
|
static fromNorm(t, e, r, i = 1) {
|
|
385
|
-
return new
|
|
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 =
|
|
397
|
-
return (a << 24 | u << 16 | c << 8 |
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
464
|
-
}
|
|
465
|
-
static Red = new
|
|
466
|
-
static Green = new
|
|
467
|
-
static Blue = new
|
|
468
|
-
static Yellow = new
|
|
469
|
-
static Purple = new
|
|
470
|
-
static Orange = new
|
|
471
|
-
static Pink = new
|
|
472
|
-
static Gray = new
|
|
473
|
-
static Brown = new
|
|
474
|
-
static Cyan = new
|
|
475
|
-
static Magenta = new
|
|
476
|
-
static Lime = new
|
|
477
|
-
static White = new
|
|
478
|
-
static Black = new
|
|
479
|
-
static Transparent = new
|
|
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
|
-
|
|
483
|
-
class
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
1053
|
-
return new
|
|
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 &&
|
|
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),
|
|
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),
|
|
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.
|
|
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,
|
|
1143
|
-
return s.setRegion(a + t,
|
|
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
|
|
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 = [],
|
|
1166
|
-
for (let
|
|
1167
|
-
for (let
|
|
1168
|
-
a.push(this.getSubTexture(
|
|
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 =
|
|
1178
|
-
return new N(new
|
|
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
|
|
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 ??
|
|
1198
|
-
const r = Math.max(Math.round(e.width), 1), i = Math.max(Math.round(e.height), 1), a =
|
|
1199
|
-
if (this.setBase(new
|
|
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),
|
|
1253
|
-
if (
|
|
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(
|
|
1257
|
-
|
|
1258
|
-
const
|
|
1259
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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 = { ...
|
|
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 =
|
|
1300
|
-
this.setBase(new
|
|
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,
|
|
1335
|
-
t.font =
|
|
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
|
|
1340
|
-
for (const
|
|
1341
|
-
const
|
|
1342
|
-
|
|
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 -=
|
|
1345
|
-
const
|
|
1346
|
-
(this.canvas.width !==
|
|
1347
|
-
const
|
|
1348
|
-
|
|
1349
|
-
let
|
|
1350
|
-
for (const
|
|
1351
|
-
|
|
1352
|
-
this.base?.updateSource(this.render.gl, this.canvas, this.options), this.setRegion(0, 0,
|
|
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
|
|
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
|
-
},
|
|
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
|
-
},
|
|
1370
|
-
var r = n.createProgram(), i =
|
|
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
|
|
1375
|
-
throw new Error("Unable to link shader program: " +
|
|
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
|
|
433
|
+
function at(n, t) {
|
|
1380
434
|
const e = {
|
|
1381
|
-
[
|
|
1382
|
-
[
|
|
1383
|
-
[
|
|
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
|
|
441
|
+
function ht(n, t) {
|
|
1388
442
|
const e = {
|
|
1389
|
-
[
|
|
1390
|
-
[
|
|
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
|
|
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),
|
|
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
|
|
1408
|
-
if (n.includes("%TEXTURE_NUM%") && (n = n.
|
|
1409
|
-
let
|
|
1410
|
-
for (let
|
|
1411
|
-
|
|
1412
|
-
n = n.
|
|
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
|
|
1417
|
-
function
|
|
470
|
+
const Wt = 5126, ot = 5121;
|
|
471
|
+
function Ot(n, t, e) {
|
|
1418
472
|
n.vertexAttribDivisor(t, e);
|
|
1419
473
|
}
|
|
1420
|
-
function
|
|
474
|
+
function Et(n, t, e, r, i) {
|
|
1421
475
|
n.drawArraysInstanced(t, e, r, i);
|
|
1422
476
|
}
|
|
1423
|
-
let
|
|
1424
|
-
class
|
|
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 =
|
|
487
|
+
shaderId = Ft++;
|
|
1437
488
|
// for debug
|
|
1438
489
|
vao;
|
|
1439
490
|
constructor(t, e, r, i) {
|
|
1440
|
-
this.gl = t, this.program =
|
|
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
|
-
|
|
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 ??
|
|
521
|
+
t.type ?? Wt,
|
|
1494
522
|
t.normalized ?? !1,
|
|
1495
523
|
t.stride,
|
|
1496
524
|
t.offset ?? 0
|
|
1497
|
-
), r.enableVertexAttribArray(e),
|
|
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
|
|
1515
|
-
|
|
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],
|
|
1522
|
-
|
|
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
|
|
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
|
|
589
|
+
return Bt(n, t, r);
|
|
1563
590
|
}
|
|
1564
591
|
}
|
|
1565
|
-
function
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 [
|
|
1613
|
-
|
|
1614
|
-
Object.assign(this.uniforms, e), Object.assign(this.uniformTextures, r);
|
|
1615
|
-
for (const
|
|
1616
|
-
this.uniformDirty.add(
|
|
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
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1741
|
-
i[s] = this.useTexture(
|
|
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
|
-
|
|
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
|
-
`,
|
|
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
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
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
|
-
|
|
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
|
-
`,
|
|
1860
|
-
class
|
|
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
|
|
1873
|
-
for (const e of
|
|
1874
|
-
this.quadBuffer.makeDirty(), this.quadBuffer.bufferData(), this.instanceBuffer = new
|
|
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 =
|
|
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:
|
|
1884
|
-
{ name: "aMatrixRow1", size: 3, stride:
|
|
1885
|
-
{ name: "aUVRect", size: 4, stride:
|
|
1886
|
-
{ name: "aColor", size: 4, type:
|
|
1887
|
-
{ name: "aTextureId", size: 1, type:
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
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
|
-
|
|
1029
|
+
f
|
|
1928
1030
|
);
|
|
1929
1031
|
}
|
|
1930
|
-
drawSpriteAffine(t, e, r, i, s, a,
|
|
1931
|
-
const
|
|
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
|
-
|
|
1934
|
-
|
|
1935
|
-
),
|
|
1936
|
-
|
|
1937
|
-
const
|
|
1938
|
-
y ? (
|
|
1939
|
-
const
|
|
1940
|
-
|
|
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(),
|
|
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
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
2076
|
-
class
|
|
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
|
|
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 =
|
|
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
|
|
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:
|
|
2098
|
-
{ name: "aUV", size: 2, type: r.FLOAT, stride:
|
|
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:
|
|
2105
|
-
{ name: "aColor", size: 4, type: r.UNSIGNED_BYTE, normalized: !0, stride:
|
|
2106
|
-
{ name: "aUV", size: 2, type: r.FLOAT, stride:
|
|
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
|
|
1505
|
+
class g {
|
|
2151
1506
|
x;
|
|
2152
1507
|
y;
|
|
2153
|
-
static ZERO = new
|
|
2154
|
-
static ONE = new
|
|
2155
|
-
static UP = new
|
|
2156
|
-
static DOWN = new
|
|
2157
|
-
static LEFT = new
|
|
2158
|
-
static RIGHT = new
|
|
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
|
|
1521
|
+
return new g(this.x + t.x, this.y + t.y);
|
|
2167
1522
|
}
|
|
2168
1523
|
subtract(t) {
|
|
2169
|
-
return new
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1588
|
+
return new g(Math.abs(this.x), Math.abs(this.y));
|
|
2243
1589
|
}
|
|
2244
1590
|
floor() {
|
|
2245
|
-
return new
|
|
1591
|
+
return new g(Math.floor(this.x), Math.floor(this.y));
|
|
2246
1592
|
}
|
|
2247
1593
|
ceil() {
|
|
2248
|
-
return new
|
|
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
|
|
1615
|
+
return t.map((e) => new g(e[0], e[1]));
|
|
2270
1616
|
}
|
|
2271
1617
|
static fromAngle(t) {
|
|
2272
|
-
return new
|
|
1618
|
+
return new g(Math.cos(t), Math.sin(t));
|
|
2273
1619
|
}
|
|
2274
1620
|
}
|
|
2275
|
-
const
|
|
2276
|
-
const [e, r, i, s, a,
|
|
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
|
-
|
|
1636
|
+
h,
|
|
2291
1637
|
0,
|
|
2292
1638
|
1
|
|
2293
1639
|
]);
|
|
2294
|
-
return
|
|
2295
|
-
},
|
|
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
|
|
2307
|
-
const
|
|
2308
|
-
const a = [],
|
|
2309
|
-
for (let l = 0; l <
|
|
2310
|
-
const
|
|
2311
|
-
a.push(n),
|
|
2312
|
-
}
|
|
2313
|
-
return { vertices: a, uv:
|
|
2314
|
-
},
|
|
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
|
|
2321
|
-
const c = n[
|
|
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
|
|
2326
|
-
a += n[
|
|
2327
|
-
const
|
|
2328
|
-
const l = c.subtract(
|
|
2329
|
-
if (
|
|
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
|
|
2333
|
-
l.cross(
|
|
2334
|
-
let
|
|
2335
|
-
return { normal:
|
|
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
|
|
2340
|
-
const c =
|
|
2341
|
-
e.push(
|
|
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
|
|
2345
|
-
if (
|
|
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 (
|
|
2349
|
-
const c = n[
|
|
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(
|
|
1698
|
+
e.push(h(n[o - 1], n[o], n[o + 1]));
|
|
2353
1699
|
return { normals: e, length: a };
|
|
2354
|
-
},
|
|
1700
|
+
}, Zt = (n) => {
|
|
2355
1701
|
const t = n.points;
|
|
2356
1702
|
if (t.length < 2) return { vertices: [], uv: [] };
|
|
2357
|
-
const { normals: e, length: r } =
|
|
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
|
|
2361
|
-
const
|
|
2362
|
-
let
|
|
2363
|
-
|
|
2364
|
-
const B = new
|
|
2365
|
-
s.push(
|
|
2366
|
-
}
|
|
2367
|
-
if (
|
|
2368
|
-
const
|
|
2369
|
-
s.push(...
|
|
2370
|
-
const v = t[t.length - 1], y = e[t.length - 1].normal,
|
|
2371
|
-
s.push(...
|
|
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
|
-
},
|
|
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
|
-
},
|
|
2394
|
-
const e =
|
|
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,
|
|
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 +=
|
|
2403
|
-
const
|
|
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
|
-
},
|
|
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
|
-
},
|
|
1790
|
+
}, wt = (n, t) => {
|
|
2445
1791
|
if (t.points.length === 0) return;
|
|
2446
|
-
const e =
|
|
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
|
-
},
|
|
1810
|
+
}, ie = (n, t) => {
|
|
2465
1811
|
if (n.inCreateMask)
|
|
2466
1812
|
return;
|
|
2467
|
-
const { vertices: e, uv: r } =
|
|
2468
|
-
|
|
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
|
-
},
|
|
2475
|
-
const e =
|
|
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
|
-
},
|
|
2487
|
-
const e =
|
|
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
|
-
},
|
|
2495
|
-
const e = t.segments ?? 32, r =
|
|
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
|
-
},
|
|
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
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
1946
|
+
gl_Position = u_projection * vec4(position, 0.0, 1.0);\r
|
|
2608
1947
|
}\r
|
|
2609
|
-
`,
|
|
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
|
-
`,
|
|
2626
|
-
class
|
|
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,
|
|
1974
|
+
return t.getGLShader(this, this.KEY, gt, pt);
|
|
2636
1975
|
}
|
|
2637
1976
|
createDefaultShader() {
|
|
2638
|
-
const t =
|
|
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:
|
|
2648
|
-
{ name: "aScale", size: 2, stride:
|
|
2649
|
-
{ name: "aRotation", size: 1, stride:
|
|
2650
|
-
{ name: "aUVRect", size: 4, stride:
|
|
2651
|
-
{ name: "aColor", size: 4, type:
|
|
2652
|
-
{ name: "aOrigin", size: 2, stride:
|
|
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,
|
|
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
|
|
2661
|
-
let
|
|
2662
|
-
|
|
2663
|
-
let
|
|
2664
|
-
|
|
2665
|
-
let
|
|
2666
|
-
O && (
|
|
2667
|
-
const
|
|
2668
|
-
|
|
2669
|
-
|
|
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
|
-
|
|
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
|
|
2679
|
-
let
|
|
2680
|
-
|
|
2681
|
-
const
|
|
2682
|
-
|
|
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
|
-
|
|
2030
|
+
f,
|
|
2692
2031
|
s,
|
|
2693
|
-
|
|
2694
|
-
|
|
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
|
-
|
|
2703
|
-
|
|
2704
|
-
),
|
|
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,
|
|
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
|
-
${
|
|
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].${
|
|
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 =
|
|
2761
|
-
this.currentShader.setUniform("u_projection", a),
|
|
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
|
|
2765
|
-
class
|
|
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
|
-
|
|
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
|
-
|
|
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 ??
|
|
2829
|
-
const e =
|
|
2830
|
-
this.gl = e, this.maxTextureUnits = e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS), this.matrix = this.matrixStack.matrix, this.spriteRegion = new
|
|
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
|
|
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
|
|
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
|
-
|
|
2158
|
+
re(this, t);
|
|
2853
2159
|
}
|
|
2854
2160
|
drawSprite(t) {
|
|
2855
|
-
|
|
2161
|
+
ee(this, t);
|
|
2856
2162
|
}
|
|
2857
2163
|
drawLine(t) {
|
|
2858
|
-
|
|
2164
|
+
ie(this, t);
|
|
2859
2165
|
}
|
|
2860
2166
|
drawGraphic(t) {
|
|
2861
|
-
|
|
2167
|
+
wt(this, t);
|
|
2862
2168
|
}
|
|
2863
2169
|
drawRect(t) {
|
|
2864
|
-
|
|
2170
|
+
ne(this, t);
|
|
2865
2171
|
}
|
|
2866
2172
|
drawCircle(t) {
|
|
2867
|
-
|
|
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
|
-
|
|
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
|
|
2913
|
-
this.addGraphicVertex(
|
|
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
|
|
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[
|
|
2238
|
+
const u = this._filterRT[o % 2];
|
|
3006
2239
|
u.offsetX = 0, u.offsetY = 0, this.enterRenderTexture(u), this.clearRenderTexture(), this.drawSprite({
|
|
3007
|
-
texture:
|
|
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(),
|
|
2246
|
+
}), this.leaveRenderTexture(), h = u, o++;
|
|
3014
2247
|
}
|
|
3015
|
-
return this.matrixStack.restore(),
|
|
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
|
|
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,
|
|
3239
|
-
s.enable(s.SCISSOR_TEST), s.scissor(
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
3288
|
-
return !(n === null || typeof n != "object" || Array.isArray(n) || n instanceof
|
|
2396
|
+
function de(n) {
|
|
2397
|
+
return !(n === null || typeof n != "object" || Array.isArray(n) || n instanceof g || n instanceof m);
|
|
3289
2398
|
}
|
|
3290
|
-
class
|
|
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
|
|
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
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
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[
|
|
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
|
|
3345
|
-
if (r instanceof
|
|
3346
|
-
return
|
|
3347
|
-
if (r instanceof
|
|
3348
|
-
return
|
|
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
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
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
|
|
3362
|
-
delta: new
|
|
3363
|
-
damping: new
|
|
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
|
|
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) ?
|
|
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 =
|
|
3403
|
-
let
|
|
3404
|
-
for (let
|
|
3405
|
-
const { value: c, delta: u, damping: l } = this.components[
|
|
3406
|
-
c.push(
|
|
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
|
|
2502
|
+
return h;
|
|
3409
2503
|
}
|
|
3410
2504
|
}
|
|
3411
|
-
class
|
|
2505
|
+
class At {
|
|
3412
2506
|
options;
|
|
3413
2507
|
emitting = !1;
|
|
3414
2508
|
emitTimer = 0;
|
|
3415
|
-
emitRate =
|
|
3416
|
-
emitTime =
|
|
2509
|
+
emitRate = vt;
|
|
2510
|
+
emitTime = yt;
|
|
3417
2511
|
emitTimeCounter = 0;
|
|
3418
|
-
|
|
3419
|
-
localSpace = xt;
|
|
2512
|
+
localSpace = Tt;
|
|
3420
2513
|
rapid;
|
|
3421
|
-
x = new
|
|
3422
|
-
y = new
|
|
3423
|
-
scaleX = new
|
|
3424
|
-
scaleY = new
|
|
3425
|
-
rotation = new
|
|
3426
|
-
color = new
|
|
3427
|
-
remainingLife = new
|
|
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
|
|
3430
|
-
rotation: new
|
|
3431
|
-
scale: new
|
|
3432
|
-
color: new
|
|
3433
|
-
velocity: new
|
|
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 ??
|
|
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
|
|
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 =
|
|
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,
|
|
3521
|
-
a.speed.create(s.speed, 0, t), a.velocity.create(s.velocity,
|
|
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,
|
|
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),
|
|
3557
|
-
this.rotation.typedArray[i] = s, this.scaleX.typedArray[i] = a, this.scaleY.typedArray[i] = a, this.color.uint32[i] =
|
|
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] += (
|
|
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
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
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
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
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
|
};
|