textmode.js 0.8.1 → 0.9.0-beta.2

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.
Files changed (32) hide show
  1. package/dist/textmode.esm.js +2841 -2345
  2. package/dist/textmode.umd.js +18 -16
  3. package/dist/types/exports/conversion.d.ts +1 -0
  4. package/dist/types/exports/filters.d.ts +1 -0
  5. package/dist/types/exports/input.d.ts +1 -0
  6. package/dist/types/exports/layering.d.ts +1 -0
  7. package/dist/types/exports/loadables.d.ts +1 -0
  8. package/dist/types/exports/loading.d.ts +1 -0
  9. package/dist/types/exports/plugins.d.ts +1 -0
  10. package/dist/types/index.d.ts +35 -1
  11. package/dist/types/rendering/webgl/core/Framebuffer.d.ts +1 -1
  12. package/dist/types/rendering/webgl/core/Shader.d.ts +17 -3
  13. package/dist/types/rendering/webgl/core/interfaces/IFramebuffer.d.ts +1 -8
  14. package/dist/types/textmode/AnimationController.d.ts +29 -0
  15. package/dist/types/textmode/Grid.d.ts +2 -0
  16. package/dist/types/textmode/Textmodifier.d.ts +8 -15
  17. package/dist/types/textmode/interfaces/ITextmodifier.d.ts +3 -11
  18. package/dist/types/textmode/layers/Camera3D.d.ts +205 -0
  19. package/dist/types/textmode/layers/Layer3DCompositor.d.ts +152 -0
  20. package/dist/types/textmode/layers/LayerManager.d.ts +70 -25
  21. package/dist/types/textmode/layers/TextmodeLayer.d.ts +12 -52
  22. package/dist/types/textmode/layers/index.d.ts +4 -0
  23. package/dist/types/textmode/layers/interfaces/ILayerManager.d.ts +52 -0
  24. package/dist/types/textmode/layers/interfaces/ITextmodeLayer.d.ts +49 -2
  25. package/dist/types/textmode/managers/PluginManager.d.ts +155 -7
  26. package/dist/types/textmode/mixins/interfaces/IAnimationMixin.d.ts +133 -0
  27. package/dist/types/textmode/mixins/interfaces/IRenderingMixin.d.ts +80 -0
  28. package/dist/types/textmode/types.d.ts +4 -3
  29. package/dist/types/utils/TextmodeCollection.d.ts +262 -0
  30. package/dist/types/utils/mat3.d.ts +149 -0
  31. package/dist/types/utils/math.d.ts +26 -0
  32. package/package.json +36 -1
@@ -23,6 +23,139 @@ export interface IAnimationMixin {
23
23
  * ```
24
24
  */
25
25
  frameRate(fps?: number): number | void;
26
+ /**
27
+ * Get the number of milliseconds since the sketch started running.
28
+ *
29
+ * `millis` keeps track of how long a sketch has been running in milliseconds
30
+ * (thousandths of a second). This information is often helpful for timing events
31
+ * and animations.
32
+ *
33
+ * Time tracking begins before the code in {@link setup} runs. If loading screen is
34
+ * enabled, `millis` begins tracking as soon as the loading screen starts.
35
+ *
36
+ * This property is connected to {@link secs} - setting one will affect the other.
37
+ *
38
+ * @returns Number of milliseconds since starting the sketch.
39
+ *
40
+ * @example
41
+ * ```javascript
42
+ * const t = textmode.create({ width: 800, height: 600 });
43
+ *
44
+ * t.draw(() => {
45
+ * t.background(0);
46
+ *
47
+ * // Get the number of seconds the sketch has run
48
+ * const seconds = t.millis / 1000;
49
+ *
50
+ * t.text(`Running time: ${seconds.toFixed(1)} sec`, 10, 10);
51
+ * });
52
+ * ```
53
+ *
54
+ * @example
55
+ * ```javascript
56
+ * const t = textmode.create({ width: 800, height: 600 });
57
+ *
58
+ * t.draw(() => {
59
+ * t.background(0);
60
+ *
61
+ * // Use millis for smooth animation
62
+ * const time = t.millis / 1000;
63
+ * const x = Math.sin(time) * 20 + 40;
64
+ *
65
+ * t.char('O', Math.floor(x), 10);
66
+ * });
67
+ * ```
68
+ *
69
+ * @example
70
+ * ```javascript
71
+ * const t = textmode.create({ width: 800, height: 600 });
72
+ *
73
+ * // Seek to a specific time in the animation
74
+ * t.millis = 5000; // Jump to 5 seconds
75
+ * ```
76
+ */
77
+ get millis(): number;
78
+ /**
79
+ * Set the elapsed milliseconds by adjusting the internal start time.
80
+ *
81
+ * This allows seeking/scrubbing in animations. Setting `millis` will also
82
+ * affect the value returned by {@link secs} since they are connected.
83
+ *
84
+ * @param value The new elapsed time in milliseconds
85
+ */
86
+ set millis(value: number);
87
+ /**
88
+ * Get the number of seconds since the sketch started running.
89
+ *
90
+ * `secs` is a convenience property that returns the elapsed time in seconds
91
+ * instead of milliseconds. Equivalent to `millis / 1000`.
92
+ *
93
+ * Time tracking begins before the code in {@link setup} runs. If loading screen is
94
+ * enabled, `secs` begins tracking as soon as the loading screen starts.
95
+ *
96
+ * This property is connected to {@link millis} - setting one will affect the other.
97
+ *
98
+ * @returns Number of seconds since starting the sketch.
99
+ *
100
+ * @example
101
+ * ```javascript
102
+ * const t = textmode.create({ width: 800, height: 600 });
103
+ *
104
+ * t.draw(() => {
105
+ * t.background(0);
106
+ *
107
+ * // Use secs for smooth time-based animations
108
+ * const angle = t.secs * Math.PI;
109
+ * const x = Math.sin(angle) * 10;
110
+ *
111
+ * t.text(`X: ${x.toFixed(2)}`, 10, 10);
112
+ * });
113
+ * ```
114
+ *
115
+ * @example
116
+ * ```javascript
117
+ * const t = textmode.create({ width: 800, height: 600 });
118
+ *
119
+ * // Seek to a specific time in the animation
120
+ * t.secs = 10; // Jump to 10 seconds (equivalent to t.millis = 10000)
121
+ * ```
122
+ */
123
+ get secs(): number;
124
+ /**
125
+ * Set the elapsed seconds by adjusting the internal start time.
126
+ *
127
+ * This allows seeking/scrubbing in animations. Setting `secs` will also
128
+ * affect the value returned by {@link millis} since they are connected.
129
+ *
130
+ * @param value The new elapsed time in seconds
131
+ */
132
+ set secs(value: number);
133
+ /**
134
+ * Returns the time in milliseconds between the current frame and the previous frame.
135
+ *
136
+ * `deltaTime()` is useful for creating frame-rate-independent animations. By multiplying
137
+ * velocities and movements by `deltaTime()`, animations will run at consistent speeds
138
+ * regardless of the actual frame rate.
139
+ *
140
+ * @returns Time elapsed between current and previous frame in milliseconds.
141
+ *
142
+ * @example
143
+ * ```javascript
144
+ * const t = textmode.create({ width: 800, height: 600 });
145
+ * let x = 0;
146
+ * const speed = 0.1; // units per millisecond
147
+ *
148
+ * t.draw(() => {
149
+ * t.background(0);
150
+ *
151
+ * // Move at consistent speed regardless of frame rate
152
+ * x += speed * t.deltaTime();
153
+ *
154
+ * t.text(`X: ${x.toFixed(2)}`, 10, 10);
155
+ * });
156
+ * ```
157
+ */
158
+ deltaTime(): number;
26
159
  /**
27
160
  * Stop the automatic rendering loop.
28
161
  *
@@ -314,6 +314,14 @@ export interface IRenderingMixin {
314
314
  * ```
315
315
  */
316
316
  createFilterShader(fragmentSource: string): Promise<GLShader>;
317
+ /**
318
+ * Create a shader from vertex and fragment source code or file paths.
319
+ * Accepts inline shader source or file paths (e.g. './shader.frag', './shader.vert', '.frag', '.vert').
320
+ * @param vertexSource The vertex shader source code or a file path
321
+ * @param fragmentSource The fragment shader source code or a file path
322
+ * @returns A Promise that resolves to a compiled shader
323
+ */
324
+ createShader(vertexSource: string, fragmentSource: string): Promise<GLShader>;
317
325
  /**
318
326
  * Sets the rotation angles for subsequent shape rendering operations.
319
327
  *
@@ -1068,4 +1076,76 @@ export interface IRenderingMixin {
1068
1076
  * ```
1069
1077
  */
1070
1078
  arc(width: number, height: number, startAngle: number, endAngle: number): void;
1079
+ /**
1080
+ * Set the rendering mode to 2D (traditional ASCII compositing) or 3D (voxel raymarching).
1081
+ *
1082
+ * In 2D mode, each layer is individually converted to ASCII and then composited.
1083
+ * In 3D mode, layer data is stacked in depth and rendered through a voxel raymarching shader.
1084
+ *
1085
+ * @param mode The rendering mode: '2d' or '3d'.
1086
+ *
1087
+ * @example
1088
+ * ```javascript
1089
+ * const t = textmode.create({ width: 800, height: 600 });
1090
+ *
1091
+ * t.draw(() => {
1092
+ * t.renderMode('3d');
1093
+ * t.rotation3D(t.frameCount * 0.5, t.frameCount * 0.3, 0);
1094
+ *
1095
+ * t.background(0);
1096
+ * t.char('@');
1097
+ * t.charColor(255, 100, 50);
1098
+ * t.rect(10, 10);
1099
+ * });
1100
+ * ```
1101
+ */
1102
+ renderMode(mode: '2d' | '3d'): void;
1103
+ /**
1104
+ * Set the 3D rotation angles for voxel rendering (only applies in '3d' mode).
1105
+ *
1106
+ * @param x Rotation around the X axis in degrees.
1107
+ * @param y Rotation around the Y axis in degrees.
1108
+ * @param z Rotation around the Z axis in degrees.
1109
+ *
1110
+ * @example
1111
+ * ```javascript
1112
+ * const t = textmode.create({ width: 800, height: 600 });
1113
+ *
1114
+ * t.draw(() => {
1115
+ * t.renderMode('3d');
1116
+ * t.rotation3D(30, t.frameCount, 0); // Tilt and spin
1117
+ * t.background(0);
1118
+ * t.char('#');
1119
+ * t.rect(15, 15);
1120
+ * });
1121
+ * ```
1122
+ */
1123
+ rotation(x: number, y?: number, z?: number): void;
1124
+ /**
1125
+ * Set the 3D translation offset for voxel rendering (only applies in '3d' mode).
1126
+ *
1127
+ * @param x Translation along the X axis.
1128
+ * @param y Translation along the Y axis.
1129
+ * @param z Translation along the Z axis.
1130
+ */
1131
+ translation3D(x: number, y?: number, z?: number): void;
1132
+ /**
1133
+ * Set the 3D zoom level for voxel rendering (only applies in '3d' mode).
1134
+ *
1135
+ * @param zoom Zoom factor (1 = no zoom, >1 = zoom in, <1 = zoom out).
1136
+ *
1137
+ * @example
1138
+ * ```javascript
1139
+ * const t = textmode.create({ width: 800, height: 600 });
1140
+ *
1141
+ * t.draw(() => {
1142
+ * t.renderMode('3d');
1143
+ * t.zoom3D(1.5 + Math.sin(t.frameCount * 0.02) * 0.5);
1144
+ * t.background(0);
1145
+ * t.char('*');
1146
+ * t.rect(10, 10);
1147
+ * });
1148
+ * ```
1149
+ */
1150
+ zoom3D(zoom: number): void;
1071
1151
  }
@@ -1,7 +1,7 @@
1
1
  import type { TextmodePlugin } from './managers/PluginManager';
2
2
  import type { LoadingScreenOptions } from './loading/';
3
3
  /**
4
- * Options for creating a {@link Textmodifier} instance.
4
+ * Options when creating a {@link Textmodifier} instance.
5
5
  */
6
6
  export type TextmodeOptions = {
7
7
  /**
@@ -34,8 +34,9 @@ export type TextmodeOptions = {
34
34
  *
35
35
  * Useful for applying textmode conversion to p5.js sketches, YouTube videos, and sooo much more.
36
36
  *
37
- * All functionality of `textmode.js` remains available. Resizing the `textmode.js` canvas is not recommended though, since the overlay target defines the size.
38
- *
37
+ * All functionality of `textmode.js` remains available.
38
+ * Resizing the `textmode.js` canvas is not recommended though,
39
+ * since the overlay target automatically updates the size.
39
40
  */
40
41
  overlay?: boolean;
41
42
  /** List of plugins to install when the Textmodifier instance is created. */
@@ -0,0 +1,262 @@
1
+ /**
2
+ * A generic, managed collection for objects that require lifecycle management.
3
+ *
4
+ * This class provides CRUD operations (Create/Read/Update/Delete) with support for:
5
+ * - Adding and removing items
6
+ * - Reordering items (move, swap)
7
+ * - Deferred initialization via pending items
8
+ * - Automatic disposal of removed items
9
+ * - Event callbacks for lifecycle events
10
+ *
11
+ * @typeParam T - The type of items stored in the collection
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * // Create a collection with a disposal callback
16
+ * const layers = new TextmodeCollection<TextmodeLayer>({
17
+ * onDispose: (layer) => layer.$dispose(),
18
+ * onAdd: (layer) => pluginManager.notifyLayerCreated(layer),
19
+ * onRemove: (layer) => pluginManager.notifyLayerDisposed(layer),
20
+ * });
21
+ *
22
+ * // Add items
23
+ * const layer = new TextmodeLayer();
24
+ * layers.add(layer);
25
+ *
26
+ * // Iterate
27
+ * for (const layer of layers) {
28
+ * layer.draw();
29
+ * }
30
+ *
31
+ * // Remove all
32
+ * layers.clear();
33
+ * ```
34
+ */
35
+ export declare class TextmodeCollection<T> implements Iterable<T> {
36
+ private _items;
37
+ private _pendingItems;
38
+ private _isReady;
39
+ private readonly _options;
40
+ /**
41
+ * Create a new TextmodeCollection.
42
+ *
43
+ * @param options Configuration options for the collection
44
+ */
45
+ constructor(options?: TextmodeCollectionOptions<T>);
46
+ /**
47
+ * Mark the collection as ready and move all pending items to the active list.
48
+ *
49
+ * Call this after async initialization is complete. Any items added before
50
+ * this call will be moved from the pending queue to the active collection.
51
+ *
52
+ * @param initializeItem Optional async function to initialize each pending item
53
+ * @returns Promise that resolves when all pending items are initialized
54
+ */
55
+ initialize(initializeItem?: (item: T) => Promise<void>): Promise<void>;
56
+ /**
57
+ * Check if the collection has been initialized.
58
+ */
59
+ get isReady(): boolean;
60
+ /**
61
+ * Add an item to the collection.
62
+ *
63
+ * If the collection is not yet ready, the item is added to a pending queue.
64
+ * Once `initialize()` is called, pending items are moved to the active collection.
65
+ *
66
+ * @param item The item to add
67
+ * @returns The added item (for chaining)
68
+ */
69
+ add(item: T): T;
70
+ /**
71
+ * Add multiple items to the collection.
72
+ *
73
+ * @param items The items to add
74
+ * @returns The added items
75
+ */
76
+ addMany(items: T[]): T[];
77
+ /**
78
+ * Remove an item from the collection and dispose it.
79
+ *
80
+ * @param item The item to remove
81
+ * @returns true if the item was found and removed, false otherwise
82
+ */
83
+ remove(item: T): boolean;
84
+ /**
85
+ * Remove an item at a specific index.
86
+ *
87
+ * @param index The index of the item to remove
88
+ * @returns The removed item, or undefined if index is out of bounds
89
+ */
90
+ removeAt(index: number): T | undefined;
91
+ /**
92
+ * Move an item to a new index in the collection.
93
+ *
94
+ * @param item The item to move
95
+ * @param newIndex The target index
96
+ * @returns true if the item was found and moved, false otherwise
97
+ */
98
+ move(item: T, newIndex: number): boolean;
99
+ /**
100
+ * Swap the positions of two items in the collection.
101
+ *
102
+ * @param itemA The first item
103
+ * @param itemB The second item
104
+ * @returns true if both items were found and swapped, false otherwise
105
+ */
106
+ swap(itemA: T, itemB: T): boolean;
107
+ /**
108
+ * Remove and dispose all items from the collection.
109
+ *
110
+ * This clears both active and pending items.
111
+ */
112
+ clear(): void;
113
+ /**
114
+ * Dispose the collection and all its items.
115
+ *
116
+ * After calling this, the collection should not be used.
117
+ */
118
+ dispose(): void;
119
+ /**
120
+ * Get all active items as a readonly array.
121
+ */
122
+ get all(): readonly T[];
123
+ /**
124
+ * Get all pending items as a readonly array.
125
+ */
126
+ get pending(): readonly T[];
127
+ /**
128
+ * Get the number of active items.
129
+ */
130
+ get length(): number;
131
+ /**
132
+ * Get the total number of items (active + pending).
133
+ */
134
+ get totalLength(): number;
135
+ /**
136
+ * Check if the collection is empty (no active items).
137
+ */
138
+ get isEmpty(): boolean;
139
+ /**
140
+ * Get an item at a specific index.
141
+ *
142
+ * @param index The index of the item
143
+ * @returns The item, or undefined if index is out of bounds
144
+ */
145
+ get(index: number): T | undefined;
146
+ /**
147
+ * Get the first item in the collection.
148
+ */
149
+ get first(): T | undefined;
150
+ /**
151
+ * Get the last item in the collection.
152
+ */
153
+ get last(): T | undefined;
154
+ /**
155
+ * Get the index of an item.
156
+ *
157
+ * @param item The item to find
158
+ * @returns The index, or -1 if not found
159
+ */
160
+ indexOf(item: T): number;
161
+ /**
162
+ * Check if an item exists in the collection.
163
+ *
164
+ * @param item The item to check
165
+ * @returns true if the item exists (in active or pending)
166
+ */
167
+ has(item: T): boolean;
168
+ /**
169
+ * Iterate over all active items.
170
+ */
171
+ [Symbol.iterator](): Iterator<T>;
172
+ /**
173
+ * Execute a callback for each active item.
174
+ *
175
+ * @param callback Function to execute for each item
176
+ */
177
+ forEach(callback: (item: T, index: number) => void): void;
178
+ /**
179
+ * Map active items to a new array.
180
+ *
181
+ * @param callback Function to transform each item
182
+ * @returns New array with transformed items
183
+ */
184
+ map<U>(callback: (item: T, index: number) => U): U[];
185
+ /**
186
+ * Filter active items.
187
+ *
188
+ * @param predicate Function to test each item
189
+ * @returns New array with items that pass the test
190
+ */
191
+ filter(predicate: (item: T, index: number) => boolean): T[];
192
+ /**
193
+ * Find an item matching a predicate.
194
+ *
195
+ * @param predicate Function to test each item
196
+ * @returns The first matching item, or undefined
197
+ */
198
+ find(predicate: (item: T, index: number) => boolean): T | undefined;
199
+ /**
200
+ * Find the index of an item matching a predicate.
201
+ *
202
+ * @param predicate Function to test each item
203
+ * @returns The index of the first matching item, or -1
204
+ */
205
+ findIndex(predicate: (item: T, index: number) => boolean): number;
206
+ /**
207
+ * Check if any item matches a predicate.
208
+ *
209
+ * @param predicate Function to test each item
210
+ * @returns true if any item matches
211
+ */
212
+ some(predicate: (item: T, index: number) => boolean): boolean;
213
+ /**
214
+ * Check if all items match a predicate.
215
+ *
216
+ * @param predicate Function to test each item
217
+ * @returns true if all items match
218
+ */
219
+ every(predicate: (item: T, index: number) => boolean): boolean;
220
+ /**
221
+ * Reduce active items to a single value.
222
+ *
223
+ * @param callback Reducer function
224
+ * @param initialValue Initial accumulator value
225
+ * @returns The final accumulated value
226
+ */
227
+ reduce<U>(callback: (accumulator: U, item: T, index: number) => U, initialValue: U): U;
228
+ /**
229
+ * Dispose a single item using the configured disposal callback.
230
+ */
231
+ private _disposeItem;
232
+ }
233
+ /**
234
+ * Configuration options for TextmodeCollection.
235
+ *
236
+ * @typeParam T - The type of items stored in the collection
237
+ */
238
+ export interface TextmodeCollectionOptions<T> {
239
+ /**
240
+ * Called when an item is added to the active collection.
241
+ * Not called for pending items until they become active.
242
+ */
243
+ onAdd?: (item: T) => void;
244
+ /**
245
+ * Called when an item is about to be removed from the collection.
246
+ * This is called before `onDispose`.
247
+ */
248
+ onRemove?: (item: T) => void;
249
+ /**
250
+ * Called to dispose an item when it's removed from the collection.
251
+ * This is where you should clean up resources.
252
+ */
253
+ onDispose?: (item: T) => void;
254
+ /**
255
+ * Called when an item is moved to a new index.
256
+ */
257
+ onMove?: (item: T, oldIndex: number, newIndex: number) => void;
258
+ /**
259
+ * Called when two items are swapped.
260
+ */
261
+ onSwap?: (itemA: T, itemB: T, indexA: number, indexB: number) => void;
262
+ }
@@ -0,0 +1,149 @@
1
+ /**
2
+ * 3x3 Matrix utilities for 3D transformations.
3
+ *
4
+ * All matrices are stored in row-major order as flat arrays of 9 elements:
5
+ * ```
6
+ * [m00, m01, m02,
7
+ * m10, m11, m12,
8
+ * m20, m21, m22]
9
+ * ```
10
+ *
11
+ * @module utils/mat3
12
+ */
13
+ /**
14
+ * A 3x3 matrix represented as a tuple of 9 numbers in row-major order.
15
+ */
16
+ export type Mat3 = [
17
+ number,
18
+ number,
19
+ number,
20
+ number,
21
+ number,
22
+ number,
23
+ number,
24
+ number,
25
+ number
26
+ ];
27
+ /**
28
+ * Create an identity 3x3 matrix.
29
+ *
30
+ * @returns A new identity matrix
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * const identity = mat3Identity();
35
+ * // [1, 0, 0, 0, 1, 0, 0, 0, 1]
36
+ * ```
37
+ */
38
+ export declare function mat3Identity(): Mat3;
39
+ /**
40
+ * Multiply two 3x3 matrices in row-major order.
41
+ *
42
+ * @param a First matrix (left operand)
43
+ * @param b Second matrix (right operand)
44
+ * @returns The product matrix (a × b)
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * const result = mat3Multiply(rotationX, rotationY);
49
+ * ```
50
+ */
51
+ export declare function mat3Multiply(a: Mat3, b: Mat3): Mat3;
52
+ /**
53
+ * Transpose a 3x3 matrix (swap rows and columns).
54
+ *
55
+ * For orthonormal rotation matrices, the transpose equals the inverse.
56
+ *
57
+ * @param m The matrix to transpose
58
+ * @returns The transposed matrix
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * const inverse = mat3Transpose(rotationMatrix);
63
+ * ```
64
+ */
65
+ export declare function mat3Transpose(m: Mat3): Mat3;
66
+ /**
67
+ * Create a rotation matrix around the X axis.
68
+ *
69
+ * @param radians Rotation angle in radians
70
+ * @returns Rotation matrix around X axis
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * const rotX = mat3RotationX(Math.PI / 4); // 45° rotation
75
+ * ```
76
+ */
77
+ export declare function mat3RotationX(radians: number): Mat3;
78
+ /**
79
+ * Create a rotation matrix around the Y axis.
80
+ *
81
+ * @param radians Rotation angle in radians
82
+ * @returns Rotation matrix around Y axis
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * const rotY = mat3RotationY(Math.PI / 2); // 90° rotation
87
+ * ```
88
+ */
89
+ export declare function mat3RotationY(radians: number): Mat3;
90
+ /**
91
+ * Create a rotation matrix around the Z axis.
92
+ *
93
+ * @param radians Rotation angle in radians
94
+ * @returns Rotation matrix around Z axis
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * const rotZ = mat3RotationZ(Math.PI); // 180° rotation
99
+ * ```
100
+ */
101
+ export declare function mat3RotationZ(radians: number): Mat3;
102
+ /**
103
+ * Build a combined rotation matrix from Euler angles (in radians).
104
+ *
105
+ * The rotation order is: Z × Y × X (applied right-to-left,
106
+ * so X rotation is applied first to the vector).
107
+ *
108
+ * @param radiansX Rotation around X axis in radians
109
+ * @param radiansY Rotation around Y axis in radians
110
+ * @param radiansZ Rotation around Z axis in radians
111
+ * @returns Combined rotation matrix
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * import { degToRad } from './math';
116
+ * const rotation = mat3FromEuler(
117
+ * degToRad(45),
118
+ * degToRad(30),
119
+ * degToRad(0)
120
+ * );
121
+ * ```
122
+ */
123
+ export declare function mat3FromEuler(radiansX: number, radiansY: number, radiansZ: number): Mat3;
124
+ /**
125
+ * Build a rotation matrix from Euler angles in degrees.
126
+ *
127
+ * This is a convenience function that converts degrees to radians
128
+ * and returns the transposed (inverse) matrix, which is commonly
129
+ * needed for shader uniforms.
130
+ *
131
+ * @param degX Rotation around X axis in degrees
132
+ * @param degY Rotation around Y axis in degrees
133
+ * @param degZ Rotation around Z axis in degrees
134
+ * @returns Transposed rotation matrix as Float32Array (for GPU upload)
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * const modelRotation = mat3FromEulerDegrees(45, 30, 0);
139
+ * shader.setUniform('u_modelRotation', modelRotation);
140
+ * ```
141
+ */
142
+ export declare function mat3FromEulerDegrees(degX: number, degY: number, degZ: number): Float32Array;
143
+ /**
144
+ * Convert a Mat3 to a Float32Array for GPU upload.
145
+ *
146
+ * @param m The matrix to convert
147
+ * @returns Float32Array containing the matrix data
148
+ */
149
+ export declare function mat3ToFloat32Array(m: Mat3): Float32Array;
@@ -1,3 +1,29 @@
1
+ /**
2
+ * Convert degrees to radians.
3
+ *
4
+ * @param degrees Angle in degrees
5
+ * @returns Angle in radians
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * degToRad(180); // Math.PI
10
+ * degToRad(90); // Math.PI / 2
11
+ * ```
12
+ */
13
+ export declare function degToRad(degrees: number): number;
14
+ /**
15
+ * Convert radians to degrees.
16
+ *
17
+ * @param radians Angle in radians
18
+ * @returns Angle in degrees
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * radToDeg(Math.PI); // 180
23
+ * radToDeg(Math.PI / 2); // 90
24
+ * ```
25
+ */
26
+ export declare function radToDeg(radians: number): number;
1
27
  /**
2
28
  * Calculate the angle in degrees between two points.
3
29
  * @param x1 - X coordinate of the first point