@flare-engine/math 0.2.1 → 0.3.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.
package/dist/index.d.ts CHANGED
@@ -1,244 +1,177 @@
1
- /** Clamps value between min and max. */
2
- declare function clamp(value: number, min: number, max: number): number;
3
- /** Linearly interpolates between a and b by t (unclamped). */
4
- declare function lerp(a: number, b: number, t: number): number;
5
- /** Returns the interpolation factor of value between a and b. */
6
- declare function inverseLerp(a: number, b: number, value: number): number;
7
- /** Maps value from [inMin, inMax] to [outMin, outMax]. */
8
- declare function map(value: number, inMin: number, inMax: number, outMin: number, outMax: number): number;
9
- /** Converts degrees to radians. */
10
- declare function degToRad(degrees: number): number;
11
- /** Converts radians to degrees. */
12
- declare function radToDeg(radians: number): number;
13
- /** Returns true if a and b are approximately equal within epsilon. */
14
- declare function approxEquals(a: number, b: number, epsilon?: number): boolean;
15
- /** Wraps value into [min, max) range. */
16
- declare function wrap(value: number, min: number, max: number): number;
17
- /** PingPong — bounces value back and forth in [0, length]. */
18
- declare function pingPong(t: number, length: number): number;
19
- /** Hermite smooth interpolation (0→1) with zero first-derivative at edges. */
20
- declare function smoothStep(edge0: number, edge1: number, x: number): number;
21
- /** Returns -1, 0, or 1. Unlike Math.sign, returns 0 for NaN. */
22
- declare function sign(value: number): number;
23
- /** Shortest signed angle delta a - b, wrapped to [-pi, pi] (closed both ends — strict comparisons
24
- * leave exact +/-pi unwrapped). Branch form (single +/-2pi correction)
25
- * — byte-identical to hand-rolled aim/homing turn math; do NOT swap for a modulo form (it shifts
26
- * results by ULPs at the +/-pi boundary). */
27
- declare function angleDelta(a: number, b: number): number;
28
- /** Rotates angle cur toward target by at most maxStep radians, shortest direction. Returns the new
29
- * angle (NOT re-wrapped). Branch-form step clamp — byte-identical to hand-rolled homing steering. */
30
- declare function rotateTowards(cur: number, target: number, maxStep: number): number;
31
-
32
- /** Creates a Vec2 plain object. */
33
- declare function vec2(x?: number, y?: number): Vec2;
1
+ //#region src/vec2.d.ts
34
2
  /** Vec2 plain object type — no class, no GC pressure. */
35
3
  type Vec2 = {
36
- x: number;
37
- y: number;
4
+ x: number;
5
+ y: number;
38
6
  };
7
+ /** Creates a Vec2 plain object. */
8
+ declare function vec2(x?: number, y?: number): Vec2;
39
9
  declare const Vec2: {
40
- /** Returns { 0, 0 }. */
41
- readonly zero: () => Vec2;
42
- /** Returns { 1, 1 }. */
43
- readonly one: () => Vec2;
44
- /** Returns { 0, -1 }. */
45
- readonly up: () => Vec2;
46
- /** Returns { 0, 1 }. */
47
- readonly down: () => Vec2;
48
- /** Returns { -1, 0 }. */
49
- readonly left: () => Vec2;
50
- /** Returns { 1, 0 }. */
51
- readonly right: () => Vec2;
52
- /** Component-wise addition. Writes into out if provided. */
53
- readonly add: (a: Vec2, b: Vec2, out?: Vec2) => Vec2;
54
- /** Component-wise subtraction a - b. */
55
- readonly sub: (a: Vec2, b: Vec2, out?: Vec2) => Vec2;
56
- /** Scales a vector by a scalar. */
57
- readonly scale: (v: Vec2, s: number, out?: Vec2) => Vec2;
58
- /** Returns a unit vector. Returns zero vector if length is 0. */
59
- readonly normalize: (v: Vec2, out?: Vec2) => Vec2;
60
- /** Zero-alloc; writes into `out`. Mandatory `out` so callers avoid temporaries in hot paths. */
61
- readonly normalizeOut: (dx: number, dy: number, speed: number, out: Vec2) => Vec2;
62
- /** Dot product. */
63
- readonly dot: (a: Vec2, b: Vec2) => number;
64
- /** 2D cross product (z-component of the 3D cross). */
65
- readonly cross: (a: Vec2, b: Vec2) => number;
66
- /** Linearly interpolates between a and b (unclamped). */
67
- readonly lerp: (a: Vec2, b: Vec2, t: number, out?: Vec2) => Vec2;
68
- /** Spherical linear interpolation for unit vectors. */
69
- readonly slerp: (a: Vec2, b: Vec2, t: number, out?: Vec2) => Vec2;
70
- /** Euclidean distance between two points. */
71
- readonly distance: (a: Vec2, b: Vec2) => number;
72
- /** Squared distance (avoids sqrt). */
73
- readonly distanceSq: (a: Vec2, b: Vec2) => number;
74
- /** Length of a vector. */
75
- readonly length: (v: Vec2) => number;
76
- /** Squared length (avoids sqrt). */
77
- readonly lengthSq: (v: Vec2) => number;
78
- /** Angle of vector in radians (atan2). */
79
- readonly angle: (v: Vec2) => number;
80
- /** Rotates a vector by angle (radians) around origin. */
81
- readonly rotate: (v: Vec2, angle: number, out?: Vec2) => Vec2;
82
- /** Component-wise approximate equality. */
83
- readonly equals: (a: Vec2, b: Vec2, epsilon?: number) => boolean;
84
- /** Returns a copy of the vector. */
85
- readonly clone: (v: Vec2) => Vec2;
86
- /** Clamps the length of a vector to maxLength. */
87
- readonly clampLength: (v: Vec2, maxLength: number, out?: Vec2) => Vec2;
88
- /** Zero-alloc homing steer: rotate velocity (vx,vy) toward direction (dx,dy) by at most maxStep
89
- * radians, preserving speed; writes into out. Mandatory out. Byte-identical to hand-rolled
90
- * homing-bullet steering (Math.hypot speed + atan2 + branch-form turn + cos/sin * speed). */
91
- readonly turnVelocityToward: (vx: number, vy: number, dx: number, dy: number, maxStep: number, out: Vec2) => Vec2;
10
+ /** Returns { 0, 0 }. */
11
+ readonly zero: () => Vec2;
12
+ /** Returns { 1, 1 }. */
13
+ readonly one: () => Vec2;
14
+ /** Returns { 0, -1 }. */
15
+ readonly up: () => Vec2;
16
+ /** Returns { 0, 1 }. */
17
+ readonly down: () => Vec2;
18
+ /** Returns { -1, 0 }. */
19
+ readonly left: () => Vec2;
20
+ /** Returns { 1, 0 }. */
21
+ readonly right: () => Vec2;
22
+ /** Component-wise addition. Writes into out if provided. */
23
+ readonly add: (a: Vec2, b: Vec2, out?: Vec2) => Vec2;
24
+ /** Component-wise subtraction a - b. */
25
+ readonly sub: (a: Vec2, b: Vec2, out?: Vec2) => Vec2;
26
+ /** Scales a vector by a scalar. */
27
+ readonly scale: (v: Vec2, s: number, out?: Vec2) => Vec2;
28
+ /** Returns a unit vector. Returns zero vector if length is 0. */
29
+ readonly normalize: (v: Vec2, out?: Vec2) => Vec2;
30
+ /** Zero-alloc; writes into `out`. Mandatory `out` so callers avoid temporaries in hot paths. */
31
+ readonly normalizeOut: (dx: number, dy: number, speed: number, out: Vec2) => Vec2;
32
+ /** Dot product. */
33
+ readonly dot: (a: Vec2, b: Vec2) => number;
34
+ /** 2D cross product (z-component of the 3D cross). */
35
+ readonly cross: (a: Vec2, b: Vec2) => number;
36
+ /** Perpendicular: (-y, x). In this engine's y-down screen space this is a 90° clockwise turn,
37
+ * matching the Skia rotation convention used by `@flare-engine/render`. Writes into out if
38
+ * provided. */
39
+ readonly perp: (v: Vec2, out?: Vec2) => Vec2;
40
+ /** Scalar × vector cross product: s × v = (-s·y, s·x). Writes into out if provided. */
41
+ readonly crossSV: (s: number, v: Vec2, out?: Vec2) => Vec2;
42
+ /** Linearly interpolates between a and b (unclamped). */
43
+ readonly lerp: (a: Vec2, b: Vec2, t: number, out?: Vec2) => Vec2;
44
+ /** Spherical linear interpolation for unit vectors. */
45
+ readonly slerp: (a: Vec2, b: Vec2, t: number, out?: Vec2) => Vec2;
46
+ /** Euclidean distance between two points. */
47
+ readonly distance: (a: Vec2, b: Vec2) => number;
48
+ /** Squared distance (avoids sqrt). */
49
+ readonly distanceSq: (a: Vec2, b: Vec2) => number;
50
+ /** Length of a vector. */
51
+ readonly length: (v: Vec2) => number;
52
+ /** Squared length (avoids sqrt). */
53
+ readonly lengthSq: (v: Vec2) => number;
54
+ /** Angle of vector in radians (atan2). */
55
+ readonly angle: (v: Vec2) => number;
56
+ /** Rotates a vector by angle (radians) around origin. */
57
+ readonly rotate: (v: Vec2, angle: number, out?: Vec2) => Vec2;
58
+ /** Component-wise approximate equality. */
59
+ readonly equals: (a: Vec2, b: Vec2, epsilon?: number) => boolean;
60
+ /** Returns a copy of the vector. */
61
+ readonly clone: (v: Vec2) => Vec2;
62
+ /** Clamps the length of a vector to maxLength. */
63
+ readonly clampLength: (v: Vec2, maxLength: number, out?: Vec2) => Vec2;
64
+ /** Zero-alloc homing steer: rotate velocity (vx,vy) toward direction (dx,dy) by at most maxStep
65
+ * radians, preserving speed; writes into out. Mandatory out. Byte-identical to hand-rolled
66
+ * homing-bullet steering (Math.hypot speed + atan2 + branch-form turn + cos/sin * speed). */
67
+ readonly turnVelocityToward: (vx: number, vy: number, dx: number, dy: number, maxStep: number, out: Vec2) => Vec2;
92
68
  };
93
-
69
+ //#endregion
70
+ //#region src/rect.d.ts
94
71
  /** Axis-aligned bounding box. */
95
72
  type Rect = {
96
- x: number;
97
- y: number;
98
- width: number;
99
- height: number;
73
+ x: number;
74
+ y: number;
75
+ width: number;
76
+ height: number;
100
77
  };
101
78
  declare const Rect: {
102
- /** Returns true if point is inside rect (inclusive). */
103
- readonly contains: (r: Rect, p: Vec2) => boolean;
104
- /** Returns true if two rects overlap (share area). */
105
- readonly intersects: (a: Rect, b: Rect) => boolean;
106
- /** Returns the overlapping rect, or null if no overlap. */
107
- readonly intersection: (a: Rect, b: Rect) => Rect | null;
108
- /** Returns the smallest rect containing both rects. */
109
- readonly union: (a: Rect, b: Rect) => Rect;
110
- /** Creates a rect from an array of points (bounding box). */
111
- readonly fromPoints: (points: readonly Vec2[]) => Rect;
112
- /** Returns the center point of the rect. */
113
- readonly center: (r: Rect) => Vec2;
114
- /** Returns a new rect expanded by amount on each side. */
115
- readonly expand: (r: Rect, amount: number) => Rect;
79
+ /** Returns true if point is inside rect (inclusive). */
80
+ readonly contains: (r: Rect, p: Vec2) => boolean;
81
+ /** Returns true if two rects overlap (share area). */
82
+ readonly intersects: (a: Rect, b: Rect) => boolean;
83
+ /** Returns the overlapping rect, or null if no overlap. */
84
+ readonly intersection: (a: Rect, b: Rect) => Rect | null;
85
+ /** Returns the smallest rect containing both rects. */
86
+ readonly union: (a: Rect, b: Rect) => Rect;
87
+ /** Creates a rect from an array of points (bounding box). */
88
+ readonly fromPoints: (points: readonly Vec2[]) => Rect;
89
+ /** Returns the center point of the rect. */
90
+ readonly center: (r: Rect) => Vec2;
91
+ /** Returns a new rect expanded by amount on each side. */
92
+ readonly expand: (r: Rect, amount: number) => Rect;
116
93
  };
117
-
94
+ //#endregion
95
+ //#region src/circle.d.ts
118
96
  /** Circle shape: center position + radius. */
119
97
  type Circle = {
120
- x: number;
121
- y: number;
122
- radius: number;
98
+ x: number;
99
+ y: number;
100
+ radius: number;
123
101
  };
124
102
  declare const Circle: {
125
- /** Returns true if point is inside or on the circle. */
126
- readonly contains: (c: Circle, p: Vec2) => boolean;
127
- /** Returns true if two circles overlap (share area). */
128
- readonly intersects: (a: Circle, b: Circle) => boolean;
129
- /** Returns true if a circle and rect overlap. */
130
- readonly intersectsRect: (c: Circle, r: Rect) => boolean;
103
+ /** Returns true if point is inside or on the circle. */
104
+ readonly contains: (c: Circle, p: Vec2) => boolean;
105
+ /** Returns true if two circles overlap (share area). */
106
+ readonly intersects: (a: Circle, b: Circle) => boolean;
107
+ /** Returns true if a circle and rect overlap. */
108
+ readonly intersectsRect: (c: Circle, r: Rect) => boolean;
131
109
  };
132
-
133
- /** 2D transform: position, rotation (radians), and scale. */
134
- type Transform2D = {
135
- position: Vec2;
136
- rotation: number;
137
- scale: Vec2;
138
- };
139
- declare const Transform2D: {
140
- /** Creates an identity transform. */
141
- readonly identity: () => Transform2D;
142
- /** Creates a transform from components. */
143
- readonly create: (x?: number, y?: number, rotation?: number, scaleX?: number, scaleY?: number) => Transform2D;
144
- /** Transforms a local-space point to world-space. */
145
- readonly localToWorld: (t: Transform2D, point: Vec2) => Vec2;
146
- /** Transforms a world-space point to local-space. */
147
- readonly worldToLocal: (t: Transform2D, point: Vec2) => Vec2;
148
- /** Returns a copy of the transform. */
149
- readonly clone: (t: Transform2D) => Transform2D;
150
- };
151
-
152
- /**
153
- * 3x3 matrix stored in column-major order on Float32Array.
154
- * Layout: [m00, m10, m20, m01, m11, m21, m02, m12, m22]
155
- *
156
- * | m00 m01 m02 | indices: | 0 3 6 |
157
- * | m10 m11 m12 | | 1 4 7 |
158
- * | m20 m21 m22 | | 2 5 8 |
159
- */
160
- type Mat3 = Float32Array;
161
- declare const Mat3: {
162
- /** Creates a new identity matrix. */
163
- readonly create: () => Mat3;
164
- /** Sets m to identity. */
165
- readonly identity: (m: Mat3) => Mat3;
166
- /** Multiplies a * b, writes into out (or allocates). */
167
- readonly multiply: (a: Mat3, b: Mat3, out?: Mat3) => Mat3;
168
- /** Creates a translation matrix. */
169
- readonly translate: (tx: number, ty: number, out?: Mat3) => Mat3;
170
- /** Creates a rotation matrix (radians). */
171
- readonly rotate: (angle: number, out?: Mat3) => Mat3;
172
- /** Creates a scale matrix. */
173
- readonly scale: (sx: number, sy: number, out?: Mat3) => Mat3;
174
- /** Inverts the matrix. Returns null if singular. */
175
- readonly invert: (m: Mat3, out?: Mat3) => Mat3 | null;
176
- /** Builds a matrix from a Transform2D (TRS order: translate * rotate * scale). */
177
- readonly fromTransform: (t: Transform2D, out?: Mat3) => Mat3;
110
+ //#endregion
111
+ //#region src/color.d.ts
112
+ /** RGBA color with components normalized to 0-1. */
113
+ type Color = {
114
+ r: number;
115
+ g: number;
116
+ b: number;
117
+ a: number;
178
118
  };
179
-
180
119
  /** OKLab perceptual color space (L 0-1, a and b unbounded in practice ±0.5). */
181
120
  type Oklab = {
182
- L: number;
183
- a: number;
184
- b: number;
121
+ L: number;
122
+ a: number;
123
+ b: number;
185
124
  };
186
125
  /** OKLCH polar form of OKLab (L 0-1, C >= 0, h degrees [0,360)). */
187
126
  type Oklch = {
188
- L: number;
189
- C: number;
190
- h: number;
191
- };
192
- /** RGBA color with components normalized to 0-1. */
193
- type Color = {
194
- r: number;
195
- g: number;
196
- b: number;
197
- a: number;
127
+ L: number;
128
+ C: number;
129
+ h: number;
198
130
  };
199
131
  declare const Color: {
200
- readonly WHITE: Color;
201
- readonly BLACK: Color;
202
- readonly TRANSPARENT: Color;
203
- /** Creates a Color from normalized 0-1 components. */
204
- readonly create: (r?: number, g?: number, b?: number, a?: number) => Color;
205
- /** Parses a hex string (#RGB, #RGBA, #RRGGBB, #RRGGBBAA). */
206
- readonly fromHex: (hex: string) => Color;
207
- /** Converts to hex string #RRGGBB or #RRGGBBAA if alpha < 1. */
208
- readonly toHex: (c: Color) => string;
209
- /** Linearly interpolates between two colors. */
210
- readonly lerp: (a: Color, b: Color, t: number) => Color;
211
- /** Component-wise multiplication. */
212
- readonly multiply: (a: Color, b: Color) => Color;
213
- /**
214
- * Converts to a Skia-compatible color number (0xAARRGGBB).
215
- * Compatible with @shopify/react-native-skia Skia.Color() format.
216
- */
217
- readonly toSkColor: (c: Color) => number;
218
- /** Converts sRGB Color to OKLab. Alpha is dropped. */
219
- readonly toOklab: (c: Color) => Oklab;
220
- /**
221
- * Converts OKLab to sRGB Color. Out-of-gamut results are clamped to [0,1];
222
- * round-trips are exact only for in-gamut colors.
223
- */
224
- readonly fromOklab: (lab: Oklab, alpha?: number) => Color;
225
- /** Converts sRGB Color to OKLCH (polar OKLab). Achromatic colors get h = 0. */
226
- readonly toOklch: (c: Color) => Oklch;
227
- /**
228
- * Converts OKLCH to sRGB Color. Hue is wrapped via ((h%360)+360)%360.
229
- * Out-of-gamut results are clamped; round-trips exact only in-gamut.
230
- */
231
- readonly fromOklch: (lch: Oklch, alpha?: number) => Color;
232
- /** Euclidean distance in OKLab space between two sRGB colors. */
233
- readonly deltaEOk: (a: Color, b: Color) => number;
234
- /** Euclidean distance between two OKLab values. */
235
- readonly deltaEOkLab: (a: Oklab, b: Oklab) => number;
236
- /** WCAG 2.x relative luminance. White = 1, black = 0. */
237
- readonly relativeLuminance: (c: Color) => number;
238
- /** WCAG 2.x contrast ratio. Order-independent; range [1, 21]. */
239
- readonly contrastRatio: (fg: Color, bg: Color) => number;
132
+ readonly WHITE: Color;
133
+ readonly BLACK: Color;
134
+ readonly TRANSPARENT: Color;
135
+ /** Creates a Color from normalized 0-1 components. */
136
+ readonly create: (r?: number, g?: number, b?: number, a?: number) => Color;
137
+ /** Parses a hex string (#RGB, #RGBA, #RRGGBB, #RRGGBBAA). */
138
+ readonly fromHex: (hex: string) => Color;
139
+ /** Converts to hex string #RRGGBB or #RRGGBBAA if alpha < 1. */
140
+ readonly toHex: (c: Color) => string;
141
+ /** Linearly interpolates between two colors. */
142
+ readonly lerp: (a: Color, b: Color, t: number) => Color;
143
+ /** Component-wise multiplication. */
144
+ readonly multiply: (a: Color, b: Color) => Color;
145
+ /**
146
+ * Converts to a Skia-compatible color number (0xAARRGGBB).
147
+ * Compatible with @shopify/react-native-skia Skia.Color() format.
148
+ */
149
+ readonly toSkColor: (c: Color) => number;
150
+ /** Converts sRGB Color to OKLab. Alpha is dropped. */
151
+ readonly toOklab: (c: Color) => Oklab;
152
+ /**
153
+ * Converts OKLab to sRGB Color. Out-of-gamut results are clamped to [0,1];
154
+ * round-trips are exact only for in-gamut colors.
155
+ */
156
+ readonly fromOklab: (lab: Oklab, alpha?: number) => Color;
157
+ /** Converts sRGB Color to OKLCH (polar OKLab). Achromatic colors get h = 0. */
158
+ readonly toOklch: (c: Color) => Oklch;
159
+ /**
160
+ * Converts OKLCH to sRGB Color. Hue is wrapped via ((h%360)+360)%360.
161
+ * Out-of-gamut results are clamped; round-trips exact only in-gamut.
162
+ */
163
+ readonly fromOklch: (lch: Oklch, alpha?: number) => Color;
164
+ /** Euclidean distance in OKLab space between two sRGB colors. */
165
+ readonly deltaEOk: (a: Color, b: Color) => number;
166
+ /** Euclidean distance between two OKLab values. */
167
+ readonly deltaEOkLab: (a: Oklab, b: Oklab) => number;
168
+ /** WCAG 2.x relative luminance. White = 1, black = 0. */
169
+ readonly relativeLuminance: (c: Color) => number;
170
+ /** WCAG 2.x contrast ratio. Order-independent; range [1, 21]. */
171
+ readonly contrastRatio: (fg: Color, bg: Color) => number;
240
172
  };
241
-
173
+ //#endregion
174
+ //#region src/easings.d.ts
242
175
  declare function linear(t: number): number;
243
176
  declare function step(t: number): number;
244
177
  declare function easeInQuad(t: number): number;
@@ -275,17 +208,85 @@ declare function springIn(t: number): number;
275
208
  declare function springOut(t: number): number;
276
209
  declare function springInOut(t: number): number;
277
210
  type EasingFn = (t: number) => number;
278
-
211
+ //#endregion
212
+ //#region src/intersection.d.ts
213
+ /** Returns true if point is inside rect (inclusive). */
214
+ declare function pointInRect(p: Vec2, r: Rect): boolean;
215
+ /** Returns true if point is inside circle (inclusive). */
216
+ declare function pointInCircle(p: Vec2, c: Circle): boolean;
217
+ /** Returns true if two rects overlap. */
218
+ declare function rectVsRect(a: Rect, b: Rect): boolean;
219
+ /** Returns true if rect and circle overlap. */
220
+ declare function rectVsCircle(r: Rect, c: Circle): boolean;
221
+ /** Returns true if two circles overlap. */
222
+ declare function circleVsCircle(a: Circle, b: Circle): boolean;
223
+ /** Line segment intersection with AABB. Uses Liang-Barsky algorithm. */
224
+ declare function lineVsRect(x1: number, y1: number, x2: number, y2: number, r: Rect): boolean;
225
+ /** Line segment intersection with circle. */
226
+ declare function lineVsCircle(x1: number, y1: number, x2: number, y2: number, c: Circle): boolean;
227
+ /** Ray intersection with AABB. Returns t (distance) or null if no hit. */
228
+ declare function rayVsRect(originX: number, originY: number, dirX: number, dirY: number, r: Rect): number | null;
229
+ //#endregion
230
+ //#region src/transform2d.d.ts
231
+ /** 2D transform: position, rotation (radians), and scale. */
232
+ type Transform2D = {
233
+ position: Vec2;
234
+ rotation: number;
235
+ scale: Vec2;
236
+ };
237
+ declare const Transform2D: {
238
+ /** Creates an identity transform. */
239
+ readonly identity: () => Transform2D;
240
+ /** Creates a transform from components. */
241
+ readonly create: (x?: number, y?: number, rotation?: number, scaleX?: number, scaleY?: number) => Transform2D;
242
+ /** Transforms a local-space point to world-space. */
243
+ readonly localToWorld: (t: Transform2D, point: Vec2) => Vec2;
244
+ /** Transforms a world-space point to local-space. */
245
+ readonly worldToLocal: (t: Transform2D, point: Vec2) => Vec2;
246
+ /** Returns a copy of the transform. */
247
+ readonly clone: (t: Transform2D) => Transform2D;
248
+ };
249
+ //#endregion
250
+ //#region src/mat3.d.ts
251
+ /**
252
+ * 3x3 matrix stored in column-major order on Float32Array.
253
+ * Layout: [m00, m10, m20, m01, m11, m21, m02, m12, m22]
254
+ *
255
+ * | m00 m01 m02 | indices: | 0 3 6 |
256
+ * | m10 m11 m12 | | 1 4 7 |
257
+ * | m20 m21 m22 | | 2 5 8 |
258
+ */
259
+ type Mat3 = Float32Array;
260
+ declare const Mat3: {
261
+ /** Creates a new identity matrix. */
262
+ readonly create: () => Mat3;
263
+ /** Sets m to identity. */
264
+ readonly identity: (m: Mat3) => Mat3;
265
+ /** Multiplies a * b, writes into out (or allocates). */
266
+ readonly multiply: (a: Mat3, b: Mat3, out?: Mat3) => Mat3;
267
+ /** Creates a translation matrix. */
268
+ readonly translate: (tx: number, ty: number, out?: Mat3) => Mat3;
269
+ /** Creates a rotation matrix (radians). */
270
+ readonly rotate: (angle: number, out?: Mat3) => Mat3;
271
+ /** Creates a scale matrix. */
272
+ readonly scale: (sx: number, sy: number, out?: Mat3) => Mat3;
273
+ /** Inverts the matrix. Returns null if singular. */
274
+ readonly invert: (m: Mat3, out?: Mat3) => Mat3 | null;
275
+ /** Builds a matrix from a Transform2D (TRS order: translate * rotate * scale). */
276
+ readonly fromTransform: (t: Transform2D, out?: Mat3) => Mat3;
277
+ };
278
+ //#endregion
279
+ //#region src/random.d.ts
279
280
  /** Seeded PRNG using mulberry32 algorithm. */
280
281
  declare class SeededRNG {
281
- private state;
282
- constructor(seed: number);
283
- /** Returns a float in [0, 1). */
284
- next(): number;
285
- /** Returns a float in [min, max). */
286
- float(min: number, max: number): number;
287
- /** Returns an integer in [min, max] (inclusive). */
288
- int(min: number, max: number): number;
282
+ private state;
283
+ constructor(seed: number);
284
+ /** Returns a float in [0, 1). */
285
+ next(): number;
286
+ /** Returns a float in [min, max). */
287
+ float(min: number, max: number): number;
288
+ /** Returns an integer in [min, max] (inclusive). */
289
+ int(min: number, max: number): number;
289
290
  }
290
291
  /** Returns a random float in [min, max). */
291
292
  declare function randomFloat(min: number, max: number): number;
@@ -327,7 +328,8 @@ declare function hashU32(seed: number): number;
327
328
  * adjacent seeds before the modulo.
328
329
  */
329
330
  declare function seededIndex(seed: number, count: number): number;
330
-
331
+ //#endregion
332
+ //#region src/reward.d.ts
331
333
  /**
332
334
  * Timed-window and capped-bonus math — pure, zero-alloc scoring helpers.
333
335
  */
@@ -356,22 +358,38 @@ declare function windowExpired(elapsed: number, lastT: number, windowSec: number
356
358
  * already counted. Clamped to 0 — never negative.
357
359
  */
358
360
  declare function remainingInWindow(awarded: number, capPerWindow: number): number;
359
-
360
- /** Returns true if point is inside rect (inclusive). */
361
- declare function pointInRect(p: Vec2, r: Rect): boolean;
362
- /** Returns true if point is inside circle (inclusive). */
363
- declare function pointInCircle(p: Vec2, c: Circle): boolean;
364
- /** Returns true if two rects overlap. */
365
- declare function rectVsRect(a: Rect, b: Rect): boolean;
366
- /** Returns true if rect and circle overlap. */
367
- declare function rectVsCircle(r: Rect, c: Circle): boolean;
368
- /** Returns true if two circles overlap. */
369
- declare function circleVsCircle(a: Circle, b: Circle): boolean;
370
- /** Line segment intersection with AABB. Uses Liang-Barsky algorithm. */
371
- declare function lineVsRect(x1: number, y1: number, x2: number, y2: number, r: Rect): boolean;
372
- /** Line segment intersection with circle. */
373
- declare function lineVsCircle(x1: number, y1: number, x2: number, y2: number, c: Circle): boolean;
374
- /** Ray intersection with AABB. Returns t (distance) or null if no hit. */
375
- declare function rayVsRect(originX: number, originY: number, dirX: number, dirY: number, r: Rect): number | null;
376
-
361
+ //#endregion
362
+ //#region src/scalar.d.ts
363
+ /** Clamps value between min and max. */
364
+ declare function clamp(value: number, min: number, max: number): number;
365
+ /** Linearly interpolates between a and b by t (unclamped). */
366
+ declare function lerp(a: number, b: number, t: number): number;
367
+ /** Returns the interpolation factor of value between a and b. */
368
+ declare function inverseLerp(a: number, b: number, value: number): number;
369
+ /** Maps value from [inMin, inMax] to [outMin, outMax]. */
370
+ declare function map(value: number, inMin: number, inMax: number, outMin: number, outMax: number): number;
371
+ /** Converts degrees to radians. */
372
+ declare function degToRad(degrees: number): number;
373
+ /** Converts radians to degrees. */
374
+ declare function radToDeg(radians: number): number;
375
+ /** Returns true if a and b are approximately equal within epsilon. */
376
+ declare function approxEquals(a: number, b: number, epsilon?: number): boolean;
377
+ /** Wraps value into [min, max) range. */
378
+ declare function wrap(value: number, min: number, max: number): number;
379
+ /** PingPong — bounces value back and forth in [0, length]. */
380
+ declare function pingPong(t: number, length: number): number;
381
+ /** Hermite smooth interpolation (0→1) with zero first-derivative at edges. */
382
+ declare function smoothStep(edge0: number, edge1: number, x: number): number;
383
+ /** Returns -1, 0, or 1. Unlike Math.sign, returns 0 for NaN. */
384
+ declare function sign(value: number): number;
385
+ /** Shortest signed angle delta a - b, wrapped to [-pi, pi] (closed both ends — strict comparisons
386
+ * leave exact +/-pi unwrapped). Branch form (single +/-2pi correction)
387
+ * — byte-identical to hand-rolled aim/homing turn math; do NOT swap for a modulo form (it shifts
388
+ * results by ULPs at the +/-pi boundary). */
389
+ declare function angleDelta(a: number, b: number): number;
390
+ /** Rotates angle cur toward target by at most maxStep radians, shortest direction. Returns the new
391
+ * angle (NOT re-wrapped). Branch-form step clamp — byte-identical to hand-rolled homing steering. */
392
+ declare function rotateTowards(cur: number, target: number, maxStep: number): number;
393
+ //#endregion
377
394
  export { Circle, Color, type EasingFn, Mat3, type Oklab, type Oklch, Rect, SeededRNG, Transform2D, Vec2, advanceWindowedStreak, angleDelta, approxEquals, cappedBonus, choose, circleVsCircle, clamp, degToRad, easeInBack, easeInBounce, easeInCirc, easeInCubic, easeInElastic, easeInExpo, easeInOutBack, easeInOutBounce, easeInOutCirc, easeInOutCubic, easeInOutElastic, easeInOutExpo, easeInOutQuad, easeInOutQuart, easeInOutQuint, easeInOutSine, easeInQuad, easeInQuart, easeInQuint, easeInSine, easeOutBack, easeOutBounce, easeOutCirc, easeOutCubic, easeOutElastic, easeOutExpo, easeOutQuad, easeOutQuart, easeOutQuint, easeOutSine, hashU32, inverseLerp, lerp, lineVsCircle, lineVsRect, linear, map, pingPong, pointInCircle, pointInRect, radToDeg, randomFloat, randomInt, randomPointInCircle, randomVec2InRect, rayVsRect, rectVsCircle, rectVsRect, remainingInWindow, rotateTowards, seededIndex, shuffle, sign, smoothStep, springIn, springInOut, springOut, step, vec2, weightedIndex, weightedIndexBy, weightedPick, windowExpired, wrap };
395
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/vec2.ts","../src/rect.ts","../src/circle.ts","../src/color.ts","../src/easings.ts","../src/intersection.ts","../src/transform2d.ts","../src/mat3.ts","../src/random.ts","../src/reward.ts","../src/scalar.ts"],"mappings":"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"}