rapid-render 0.1.21 → 1.0.0

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.
@@ -0,0 +1,360 @@
1
+ import { DynamicArrayBuffer } from './buffer';
2
+ import { Vec2 } from './math';
3
+ import { Rapid } from './render';
4
+ export interface ITransformOptions {
5
+ /** Whether to push a save before applying transforms. Default: true. */
6
+ saveTransform?: boolean;
7
+ /** Called immediately after the save (if any). */
8
+ afterSave?: () => void;
9
+ x?: number;
10
+ y?: number;
11
+ position?: Vec2;
12
+ rotation?: number;
13
+ scale?: Vec2 | number;
14
+ offsetX?: number;
15
+ offsetY?: number;
16
+ offset?: Vec2;
17
+ /** Normalized anchor point (0~1). Number applies uniformly; Vec2 applies per-axis. */
18
+ origin?: number | Vec2;
19
+ }
20
+ /**
21
+ * A highly optimized store for a collection of 2D 3x3 matrices (stored as 6 elements: a, b, c, d, tx, ty).
22
+ * Matrices are stored flat in a dynamic Float32Array to improve memory locality and cache performance.
23
+ */
24
+ export declare class MatrixStore {
25
+ /** Total number of matrices currently allocated in the store. */
26
+ matrixCount: number;
27
+ /** The dynamic buffer used to hold matrix data. */
28
+ buffer: DynamicArrayBuffer;
29
+ /** The raw floating-point data of all matrices. */
30
+ data: Float32Array;
31
+ /**
32
+ * Creates a new MatrixStore.
33
+ * @param capacity - The initial capacity of the matrix store (default is 10).
34
+ */
35
+ constructor(capacity?: number);
36
+ /**
37
+ * Allocates a new matrix and initializes it to the identity matrix.
38
+ * @returns The index of the newly allocated matrix.
39
+ */
40
+ alloc(): number;
41
+ /**
42
+ * Allocates a new matrix without initializing its elements.
43
+ * @returns The index of the newly allocated matrix.
44
+ */
45
+ allocDirty(): number;
46
+ /**
47
+ * Resets the store, clearing all allocated matrices.
48
+ */
49
+ reset(): void;
50
+ /**
51
+ * Sets the matrix at the given index to the identity matrix.
52
+ * @param index - The index of the matrix to modify.
53
+ */
54
+ identity(index: number): void;
55
+ /**
56
+ * Translates the matrix at the given index by x and y.
57
+ * @param index - The index of the matrix to modify.
58
+ * @param x - The x translation.
59
+ * @param y - The y translation.
60
+ */
61
+ translate(index: number, x: number, y: number): void;
62
+ /**
63
+ * Scales the matrix at the given index by scaleX and scaleY.
64
+ * @param index - The index of the matrix to modify.
65
+ * @param scaleX - The scale factor along the x-axis.
66
+ * @param scaleY - The scale factor along the y-axis.
67
+ */
68
+ scale(index: number, scaleX: number, scaleY: number): void;
69
+ /**
70
+ * Rotates the matrix at the given index by the specified radians.
71
+ * @param index - The index of the matrix to modify.
72
+ * @param radians - The rotation angle in radians.
73
+ */
74
+ rotate(index: number, radians: number): void;
75
+ /**
76
+ * Rotates the matrix at the given index around a local offset point (pivot).
77
+ *
78
+ * This is equivalent to:
79
+ * 1. Translating by `(offsetX, offsetY)` to move the pivot to the origin.
80
+ * 2. Rotating by `radians`.
81
+ * 3. Translating back by `(-offsetX, -offsetY)`.
82
+ *
83
+ * Useful for rotating a sprite around a point other than its own origin,
84
+ * e.g. a character's limb rotating around its joint.
85
+ *
86
+ * @param index - The index of the matrix to modify.
87
+ * @param radians - The rotation angle in radians.
88
+ * @param offsetX - The x component of the pivot point in local space.
89
+ * @param offsetY - The y component of the pivot point in local space.
90
+ */
91
+ rotateWithOffset(index: number, radians: number, offsetX: number, offsetY: number): void;
92
+ /**
93
+ * Copies the elements from the source matrix to the destination matrix.
94
+ * @param dst - The index of the destination matrix.
95
+ * @param src - The index of the source matrix.
96
+ */
97
+ copy(dst: number, src: number): void;
98
+ /**
99
+ * Multiplies the destination matrix by the source matrix and stores the result in the destination.
100
+ * @param dst - The index of the destination matrix.
101
+ * @param src - The index of the source matrix.
102
+ */
103
+ multiply(dst: number, src: number): void;
104
+ /**
105
+ * Multiplies matrix A by matrix B and stores the result in the output matrix.
106
+ * @param out - The index of the output matrix.
107
+ * @param aIdx - The index of matrix A.
108
+ * @param bIdx - The index of matrix B.
109
+ */
110
+ multiplyOut(out: number, aIdx: number, bIdx: number): void;
111
+ /**
112
+ * Inverts the matrix at the given index. If the matrix is not invertible, it defaults to the identity matrix.
113
+ * @param index - The index of the matrix to invert.
114
+ */
115
+ invert(index: number): void;
116
+ /**
117
+ * Transforms a point by the matrix at the given index.
118
+ * @param index - The index of the transformation matrix.
119
+ * @param x - The x coordinate of the point.
120
+ * @param y - The y coordinate of the point.
121
+ * @returns The transformed point {x, y}.
122
+ */
123
+ transformPoint(index: number, x: number, y: number): {
124
+ x: number;
125
+ y: number;
126
+ };
127
+ /**
128
+ * Transforms a point from world coordinates to local coordinates using the matrix at the specified index.
129
+ * Useful for hit testing against objects placed in world space.
130
+ * @param index - The index of the world transformation matrix.
131
+ * @param x - World x coordinate.
132
+ * @param y - World y coordinate.
133
+ * @returns The transformed point in local coordinates.
134
+ */
135
+ worldToLocal(index: number, x: number, y: number): {
136
+ x: number;
137
+ y: number;
138
+ };
139
+ /**
140
+ * Transforms a point from local coordinates to world coordinates.
141
+ * @param index - The index of the local transformation matrix.
142
+ * @param x - Local x coordinate.
143
+ * @param y - Local y coordinate.
144
+ * @returns The transformed point in world coordinates.
145
+ */
146
+ localToWorld(index: number, x: number, y: number): {
147
+ x: number;
148
+ y: number;
149
+ };
150
+ /**
151
+ * Extracts the global position (translation) from the matrix at the given index.
152
+ * @param index - The index of the matrix.
153
+ * @returns An object containing `x` and `y` global coordinates.
154
+ */
155
+ getPosition(index: number): {
156
+ x: number;
157
+ y: number;
158
+ };
159
+ /**
160
+ * Extracts the global scale from the matrix at the given index.
161
+ * @param index - The index of the matrix.
162
+ * @returns An object containing `x` and `y` global scale factors.
163
+ */
164
+ getScale(index: number): {
165
+ x: number;
166
+ y: number;
167
+ };
168
+ /**
169
+ * Extracts the global rotation (in radians) from the matrix at the given index.
170
+ * @param index - The index of the matrix.
171
+ * @returns The global rotation in radians.
172
+ */
173
+ getRotation(index: number): number;
174
+ /**
175
+ * Converts the matrix at the given index to a CSS matrix string.
176
+ * @param index - The index of the matrix.
177
+ * @param scaleX - Extra scale applied to the a/c/tx components (e.g. to convert logic pixels to CSS pixels).
178
+ * @param scaleY - Extra scale applied to the b/d/ty components.
179
+ * @returns A CSS matrix string.
180
+ */
181
+ toCSSMatrix(index: number, scaleX?: number, scaleY?: number): string;
182
+ /**
183
+ * Retrieves a copy of the 6 elements [a, b, c, d, tx, ty] for the matrix at the specified index.
184
+ * Note: This uses `slice` to return a new Float32Array instance, ensuring the original data remains safely isolated.
185
+ *
186
+ * @param index - The index of the matrix.
187
+ * @returns A new Float32Array containing the 6 elements of the matrix.
188
+ */
189
+ getMatrix(index: number): Float32Array;
190
+ /**
191
+ * Retrieves a direct reference (view) to the 6 elements [a, b, c, d, tx, ty] for the matrix at the specified index.
192
+ * Note: This uses `subarray`. Any modifications made to the returned array will directly affect the underlying MatrixStore data.
193
+ *
194
+ * @param index - The index of the matrix.
195
+ * @returns A Float32Array view pointing directly to the matrix's data in memory.
196
+ */
197
+ getMatrixRef(index: number): Float32Array;
198
+ /**
199
+ * Overwrites the matrix at the specified index with the provided 6 elements [a, b, c, d, tx, ty].
200
+ *
201
+ * @param index - The index of the matrix to modify.
202
+ * @param f - An array (Float32Array or standard number array) containing the 6 new elements.
203
+ */
204
+ setMatrix(index: number, f: Float32Array | number[]): void;
205
+ }
206
+ /**
207
+ * A highly performant MatrixStack useful for hierarchal scene graphs.
208
+ * Handles both local and world transformations automatically.
209
+ */
210
+ export declare class MatrixStack {
211
+ /** The underlying store for matrices. */
212
+ matrix: MatrixStore;
213
+ /** The current step or depth in the transformation hierarchy. */
214
+ step: number;
215
+ /** Internal stack maintaining structural information. */
216
+ stack: DynamicArrayBuffer;
217
+ /** Records the world matrices generated at each step. */
218
+ stepWorldM: DynamicArrayBuffer;
219
+ /** Records actions (push/pop) taken during the traversal. */
220
+ stepAction: DynamicArrayBuffer;
221
+ /** Records the parent world matrix for each step (used by updateMatrix). */
222
+ stepParentM: DynamicArrayBuffer;
223
+ /** Buffer used during hierarchy traversal updates. */
224
+ parentStack: DynamicArrayBuffer;
225
+ /** The index of the current local matrix in the matrix store. */
226
+ curLocalM: number;
227
+ /** The index of the current world matrix in the matrix store. */
228
+ curWorldM: number;
229
+ rapid: Rapid;
230
+ /**
231
+ * Creates a new MatrixStack and initializes its state.
232
+ */
233
+ constructor(rapid: Rapid);
234
+ /**
235
+ * Saves the current matrix state and pushes it onto the stack.
236
+ * Equivalent to context.save().
237
+ * @returns The current step counter before saving.
238
+ */
239
+ save(): {
240
+ world: number;
241
+ local: number;
242
+ step: number;
243
+ };
244
+ /**
245
+ * Restores the matrix state from the top of the stack.
246
+ * Equivalent to context.restore().
247
+ */
248
+ restore(): void;
249
+ /**
250
+ * Evaluates and updates matrices from the given step. Used primarily for deferred transformation.
251
+ * @param step - The initial step to update matrices from.
252
+ */
253
+ updateMatrix(step: number | {
254
+ step: number;
255
+ }): void;
256
+ /**
257
+ * Translates the current local and world matrices by x and y.
258
+ * @param x - Translation along the x-axis.
259
+ * @param y - Translation along the y-axis.
260
+ */
261
+ translate(x: number, y: number): void;
262
+ /**
263
+ * Scales the current local and world matrices by scaleX and scaleY.
264
+ * @param scaleX - Scaling factor along the x-axis.
265
+ * @param scaleY - Scaling factor along the y-axis.
266
+ */
267
+ scale(scaleX: number, scaleY?: number): void;
268
+ /**
269
+ * Rotates the current local and world matrices by the given radians.
270
+ * @param radians - The rotation angle in radians.
271
+ */
272
+ rotate(radians: number): void;
273
+ /**
274
+ * Rotates the current local and world matrices around a pivot point
275
+ * that is offset from the matrix origin by `(offsetX, offsetY)`.
276
+ *
277
+ * This is a convenience wrapper around the common translate → rotate → translate-back
278
+ * pattern, avoiding manual coordinate juggling at the call site.
279
+ *
280
+ * @example
281
+ * ```ts
282
+ * // Rotate a 64×64 sprite around its centre
283
+ * stack.rotateWithOffset(angle, 32, 32);
284
+ * ```
285
+ *
286
+ * @param radians - The rotation angle in radians.
287
+ * @param offsetX - The x component of the pivot point in local space.
288
+ * @param offsetY - The y component of the pivot point in local space.
289
+ */
290
+ rotateWithOffset(radians: number, offsetX: number, offsetY: number): void;
291
+ /**
292
+ * Sets the current local and world matrices to the identity matrix.
293
+ */
294
+ identity(): void;
295
+ /**
296
+ * Resets the entire stack state context, clearing matrices and step actions.
297
+ */
298
+ reset(): void;
299
+ /**
300
+ * Transforms a point from local coordinates to world coordinates.
301
+ * Uses the current world matrix to apply the transformation.
302
+ * @param x - Local x coordinate.
303
+ * @param y - Local y coordinate.
304
+ * @returns The transformed point in world coordinates.
305
+ */
306
+ localToWorld(x: number, y: number): {
307
+ x: number;
308
+ y: number;
309
+ };
310
+ /**
311
+ * Transforms a point from world coordinates to local coordinates.
312
+ * Useful for hit testing against objects placed in world space.
313
+ * @param x - World x coordinate.
314
+ * @param y - World y coordinate.
315
+ * @returns The transformed point in local coordinates.
316
+ */
317
+ worldToLocal(x: number, y: number): {
318
+ x: number;
319
+ y: number;
320
+ };
321
+ /**
322
+ * Extracts the global position (translation) from the current world matrix.
323
+ * @returns An object containing `x` and `y` global coordinates.
324
+ */
325
+ getGlobalPosition(): {
326
+ x: number;
327
+ y: number;
328
+ };
329
+ /**
330
+ * Extracts the global scale from the current world matrix.
331
+ * @returns An object containing `x` and `y` global scale factors.
332
+ */
333
+ getGlobalScale(): {
334
+ x: number;
335
+ y: number;
336
+ };
337
+ /**
338
+ * Extracts the global rotation (in radians) from the current world matrix.
339
+ * @returns The global rotation in radians.
340
+ */
341
+ getGlobalRotation(): number;
342
+ toCSSMatrix(): string;
343
+ /**
344
+ * Returns the current world matrix as Float32Array [a, b, c, d, tx, ty].
345
+ */
346
+ getTransform(): Float32Array;
347
+ /**
348
+ * Directly overwrites the current world matrix with the given 6-element 2D transform.
349
+ */
350
+ setTransform(f: Float32Array): void;
351
+ transformPoint(x: number, y: number): {
352
+ x: number;
353
+ y: number;
354
+ };
355
+ /**
356
+ * Applies a transform options object to the current matrix state.
357
+ * Optionally saves the matrix first (saveTransform defaults to true).
358
+ */
359
+ applyTransform(transform: ITransformOptions, width?: number, height?: number): void;
360
+ }
@@ -1,11 +1,126 @@
1
- import Rapid from "./render";
2
- import { IParticleOptions, ITransformOptions } from "./interface";
3
- import { Vec2 } from "./math";
1
+ import { Color } from './color';
2
+ import { Vec2 } from './math';
3
+ import { Rapid } from './render';
4
+ import { Texture } from './texture';
5
+ export type ParticleAttributeTypes = number | Vec2 | Color;
4
6
  /**
5
- * Particle emitter for creating and managing particle systems
7
+ * Describes an animated attribute: it transitions from `start` to `end`
8
+ * over the particle's lifetime, optionally with a per-second damping factor.
6
9
  */
7
- export declare class ParticleEmitter {
10
+ export interface ParticleAttribute<T extends ParticleAttributeTypes> {
11
+ /** Starting value (scalar, range tuple, or fixed value). */
12
+ start?: T | [T, T];
13
+ /** Ending value. Defaults to `start` if omitted (no change over time). */
14
+ end?: T | [T, T];
15
+ /**
16
+ * Multiplicative damping applied each second.
17
+ * e.g. 0.9 means the value is multiplied by 0.9^deltaTime every frame.
18
+ */
19
+ damping?: number;
20
+ /**
21
+ * Explicit per-second delta override. If omitted it is derived from
22
+ * start/end/lifetime automatically.
23
+ */
24
+ delta?: T;
25
+ }
26
+ /** Internal resolved state of one animated attribute. */
27
+ export interface ParticleAttributeData<T extends ParticleAttributeTypes> {
28
+ value: T;
29
+ delta?: T;
30
+ damping?: number;
31
+ }
32
+ export declare enum ParticleShape {
33
+ POINT = "point",
34
+ CIRCLE = "circle",
35
+ RECT = "rect"
36
+ }
37
+ export interface IParticleAnimation {
38
+ /** Directional speed along the rotation axis (pixels/sec). */
39
+ speed?: ParticleAttribute<number> | number;
40
+ /** Rotation angle in radians. */
41
+ rotation?: ParticleAttribute<number> | number;
42
+ /** Uniform scale. */
43
+ scale?: ParticleAttribute<number> | number;
44
+ /** Tint color (0-255 components, uses engine Color class). */
45
+ color?: ParticleAttribute<Color> | Color;
46
+ /** Additive velocity vector (pixels/sec). */
47
+ velocity?: ParticleAttribute<Vec2> | Vec2;
48
+ /** Acceleration vector added to velocity each second (pixels/sec²). */
49
+ acceleration?: ParticleAttribute<Vec2> | Vec2;
50
+ }
51
+ export interface IParticleOptions {
52
+ /** Texture(s) to pick from. Pass a weighted tuple `[Texture, weight][]` for weighted random. */
53
+ texture: Texture | Texture[] | [Texture, number][];
54
+ /** Particle lifetime in seconds, or a [min, max] range. */
55
+ life: number | [number, number];
56
+ /** Animation / per-attribute configuration. */
57
+ animation: IParticleAnimation;
58
+ /** Emit shape. */
59
+ emitShape?: ParticleShape;
60
+ /** Radius used when emitShape === CIRCLE. */
61
+ emitRadius?: number;
62
+ /** Dimensions used when emitShape === RECT. */
63
+ emitRect?: {
64
+ width: number;
65
+ height: number;
66
+ };
67
+ /** Maximum simultaneous particles (default: unlimited). */
68
+ maxParticles?: number;
69
+ /** Particles emitted per second (continuous) or per interval (when emitTime > 0). */
70
+ emitRate?: number;
71
+ /**
72
+ * If > 0, particles are emitted in bursts every `emitTime` seconds
73
+ * rather than continuously.
74
+ */
75
+ emitTime?: number;
76
+ /** Whether particles are positioned relative to the emitter (default: true). */
77
+ localSpace?: boolean;
78
+ /** World-space position of the emitter (used when localSpace is false). */
79
+ position?: Vec2;
80
+ origin?: Vec2;
81
+ }
82
+ export declare class Particle {
83
+ private life;
84
+ private maxLife;
85
+ private texture;
86
+ private options;
87
+ private position;
88
+ private datas;
8
89
  private rapid;
90
+ constructor(rapid: Rapid, options: IParticleOptions);
91
+ private processAttribute;
92
+ private updateNumberAttribute;
93
+ private updateVec2Attribute;
94
+ private updateColorAttribute;
95
+ private updateAttributes;
96
+ private getDelta;
97
+ /**
98
+ * Updates particle state.
99
+ * @param deltaTime - Seconds elapsed since last frame
100
+ * @returns `true` while the particle is alive, `false` when it should be removed
101
+ */
102
+ update(deltaTime: number): boolean;
103
+ /**
104
+ * Renders the particle using the Rapid engine's matrixStack + drawSprite.
105
+ * The emitter is responsible for calling save/restore around a batch of particles.
106
+ */
107
+ render(): void;
108
+ private initializePosition;
109
+ }
110
+ /**
111
+ * Creates and manages a pool of Particle instances.
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * const emitter = new ParticleEmitter(rapid, { ... });
116
+ * emitter.start();
117
+ *
118
+ * // inside your game loop:
119
+ * emitter.update(dt);
120
+ * emitter.render();
121
+ * ```
122
+ */
123
+ export declare class ParticleEmitter {
9
124
  private particles;
10
125
  private options;
11
126
  private emitting;
@@ -13,61 +128,56 @@ export declare class ParticleEmitter {
13
128
  private emitRate;
14
129
  private emitTime;
15
130
  private emitTimeCounter;
131
+ /** Whether spawned particles are positioned in local emitter space (default: true). */
16
132
  localSpace: boolean;
133
+ /** World position of the emitter. Used for both local-space transform and world-space spawn offset. */
17
134
  position: Vec2;
135
+ private rapid;
136
+ gameObject?: unknown;
18
137
  /**
19
- * Creates a new particle emitter
20
- * @param rapid - The Rapid renderer instance
138
+ * Creates a new particle emitter.
139
+ * @param rapid - The Rapid renderer instance
21
140
  * @param options - Emitter configuration options
22
141
  */
23
142
  constructor(rapid: Rapid, options: IParticleOptions);
143
+ /** Replaces the emitter's texture at runtime. */
144
+ setTexture(texture: Texture): void;
24
145
  /**
25
- * Gets the transform options
26
- */
27
- getTransform(): ITransformOptions;
28
- /**
29
- * Sets particle emission rate
30
- * @param rate - Particles per second
146
+ * Creates a new emitter sharing the same options object.
147
+ * Particle state is NOT copied.
31
148
  */
149
+ clone(): ParticleEmitter;
150
+ /** Sets particles-per-second emission rate (continuous mode). */
32
151
  setEmitRate(rate: number): void;
33
- /**
34
- * Sets time interval between emissions
35
- * @param time - Time interval in seconds
36
- */
152
+ /** Sets the burst interval in seconds (0 = continuous). */
37
153
  setEmitTime(time: number): void;
38
- /**
39
- * Starts emitting particles
40
- */
154
+ /** Starts continuous particle emission. */
41
155
  start(): void;
42
- /**
43
- * Stops emitting new particles but allows existing ones to complete their lifecycle
44
- */
156
+ /** Stops new particle emission; existing particles finish their lifecycle. */
45
157
  stop(): void;
46
- /**
47
- * Clears all particles and resets the emitter
48
- */
158
+ /** Removes all particles and resets timers. */
49
159
  clear(): void;
50
160
  /**
51
- * Emits specified number of particles
52
- * @param count - Number of particles to emit
161
+ * Spawns `count` particles immediately.
162
+ * Respects `maxParticles` if set.
53
163
  */
54
164
  emit(count: number): void;
55
165
  /**
56
- * Updates particle emitter state
57
- * @param deltaTime - Time in seconds since last update
166
+ * Updates the emitter and all live particles.
167
+ * @param deltaTime - Seconds elapsed since last frame
58
168
  */
59
169
  update(deltaTime: number): void;
60
170
  /**
61
- * Renders all particles
171
+ * Renders all live particles.
172
+ * In local-space mode the emitter's own transform is applied around the batch.
62
173
  */
63
174
  render(): void;
64
- /**
65
- * Gets current particle count
66
- */
175
+ /** Returns the current number of live particles. */
67
176
  getParticleCount(): number;
177
+ /** Returns `true` if the emitter is running or still has live particles. */
178
+ isActive(): boolean;
68
179
  /**
69
- * Checks if the particle emitter is active (has particles or is emitting)
180
+ * Convenience: emit `emitRate` particles in one shot (fire-and-forget burst).
70
181
  */
71
- isActive(): boolean;
72
182
  oneShot(): void;
73
183
  }