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.
- package/dist/textmode.esm.js +2841 -2345
- package/dist/textmode.umd.js +18 -16
- package/dist/types/exports/conversion.d.ts +1 -0
- package/dist/types/exports/filters.d.ts +1 -0
- package/dist/types/exports/input.d.ts +1 -0
- package/dist/types/exports/layering.d.ts +1 -0
- package/dist/types/exports/loadables.d.ts +1 -0
- package/dist/types/exports/loading.d.ts +1 -0
- package/dist/types/exports/plugins.d.ts +1 -0
- package/dist/types/index.d.ts +35 -1
- package/dist/types/rendering/webgl/core/Framebuffer.d.ts +1 -1
- package/dist/types/rendering/webgl/core/Shader.d.ts +17 -3
- package/dist/types/rendering/webgl/core/interfaces/IFramebuffer.d.ts +1 -8
- package/dist/types/textmode/AnimationController.d.ts +29 -0
- package/dist/types/textmode/Grid.d.ts +2 -0
- package/dist/types/textmode/Textmodifier.d.ts +8 -15
- package/dist/types/textmode/interfaces/ITextmodifier.d.ts +3 -11
- package/dist/types/textmode/layers/Camera3D.d.ts +205 -0
- package/dist/types/textmode/layers/Layer3DCompositor.d.ts +152 -0
- package/dist/types/textmode/layers/LayerManager.d.ts +70 -25
- package/dist/types/textmode/layers/TextmodeLayer.d.ts +12 -52
- package/dist/types/textmode/layers/index.d.ts +4 -0
- package/dist/types/textmode/layers/interfaces/ILayerManager.d.ts +52 -0
- package/dist/types/textmode/layers/interfaces/ITextmodeLayer.d.ts +49 -2
- package/dist/types/textmode/managers/PluginManager.d.ts +155 -7
- package/dist/types/textmode/mixins/interfaces/IAnimationMixin.d.ts +133 -0
- package/dist/types/textmode/mixins/interfaces/IRenderingMixin.d.ts +80 -0
- package/dist/types/textmode/types.d.ts +4 -3
- package/dist/types/utils/TextmodeCollection.d.ts +262 -0
- package/dist/types/utils/mat3.d.ts +149 -0
- package/dist/types/utils/math.d.ts +26 -0
- package/package.json +36 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../textmode/conversion';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../textmode/filters';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../textmode/managers';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../textmode/layers';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../textmode/loadables';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../textmode/loading';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { TextmodePlugin, TextmodePluginAPI, TextmodePluginHook, LayerLifecycleHook, LayerRenderHook, SetupLifecycleHook, } from '../textmode/managers/PluginManager';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -16,7 +16,40 @@ export type { TextmodeFramebufferOptions } from './rendering/webgl';
|
|
|
16
16
|
* but custom strategies can be registered via {@link TextmodeConversionManager.register}.
|
|
17
17
|
*/
|
|
18
18
|
export * as conversion from './textmode/conversion';
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Plugin system types for extending textmode.js functionality.
|
|
21
|
+
*
|
|
22
|
+
* Plugins can:
|
|
23
|
+
* - Add methods to TextmodeLayer instances (e.g., `.synth()`)
|
|
24
|
+
* - Hook into the render lifecycle (pre/post draw, per-layer rendering)
|
|
25
|
+
* - React to layer creation and disposal events
|
|
26
|
+
* - Access the WebGL renderer, framebuffers, and other internals
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* import type { TextmodePlugin, TextmodePluginAPI } from 'textmode.js/plugins';
|
|
31
|
+
*
|
|
32
|
+
* const MyPlugin: TextmodePlugin = {
|
|
33
|
+
* name: 'my-plugin',
|
|
34
|
+
* version: '1.0.0',
|
|
35
|
+
* install(textmodifier, api) {
|
|
36
|
+
* // Extend layers with a new method
|
|
37
|
+
* api.extendLayer('myMethod', function(value) {
|
|
38
|
+
* this.setPluginState('my-plugin', { value });
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* // Hook into layer rendering
|
|
42
|
+
* api.registerLayerPreRenderHook((layer, ctx) => {
|
|
43
|
+
* const state = layer.getPluginState('my-plugin');
|
|
44
|
+
* if (state) {
|
|
45
|
+
* // Render plugin content to layer.drawFramebuffer
|
|
46
|
+
* }
|
|
47
|
+
* });
|
|
48
|
+
* }
|
|
49
|
+
* };
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export * as plugins from './textmode/managers/PluginManager';
|
|
20
53
|
/**
|
|
21
54
|
* All filter related modules and types.
|
|
22
55
|
*
|
|
@@ -28,6 +61,7 @@ export type { TextmodePlugin, TextmodePluginAPI } from './textmode/managers/Plug
|
|
|
28
61
|
*/
|
|
29
62
|
export * as filters from './textmode/filters';
|
|
30
63
|
export { TextmodeErrorLevel } from './errors/ErrorHandler';
|
|
64
|
+
export { GLShader as TextmodeShader } from './rendering/webgl/core/Shader';
|
|
31
65
|
export { Textmode as textmode } from './Textmode';
|
|
32
66
|
/** All loading screen related modules and types. */
|
|
33
67
|
export * as loading from './textmode/loading';
|
|
@@ -4,8 +4,13 @@ import { GLFramebuffer } from './Framebuffer';
|
|
|
4
4
|
*/
|
|
5
5
|
export type UniformValue = number | boolean | number[] | number[][] | Float32Array | Int32Array | GLFramebuffer | WebGLTexture;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
*
|
|
8
|
+
* Shader class for managing WebGL shader programs initialized via {@link Textmodifier.createFilterShader} or {@link Textmodifier.createShader}.
|
|
9
|
+
*
|
|
10
|
+
* Use shaders and set uniforms via {@link Textmodifier.shader}, {@link Textmodifier.setUniform}, and {@link Textmodifier.setUniforms}.
|
|
11
|
+
*
|
|
12
|
+
* With a shader active, the next {@link Textmodifier.rect} call will use the shader for rendering,
|
|
13
|
+
* and automatically unuse it afterwards.
|
|
9
14
|
*/
|
|
10
15
|
export declare class GLShader {
|
|
11
16
|
private _gl;
|
|
@@ -28,22 +33,31 @@ export declare class GLShader {
|
|
|
28
33
|
private _createShader;
|
|
29
34
|
/**
|
|
30
35
|
* Use this shader program
|
|
36
|
+
* @ignore
|
|
31
37
|
*/
|
|
32
38
|
$use(): void;
|
|
33
39
|
/**
|
|
34
40
|
* Reset texture unit counter and other state
|
|
35
41
|
*/
|
|
36
42
|
private _resetState;
|
|
43
|
+
/**
|
|
44
|
+
* Set multiple uniform values at once.
|
|
45
|
+
* @param uniforms An object mapping uniform names to their values.
|
|
46
|
+
* @ignore
|
|
47
|
+
*/
|
|
37
48
|
$setUniforms(uniforms: Record<string, any>): void;
|
|
38
49
|
/**
|
|
39
50
|
* Set a single uniform value with automatic texture unit management and proper type detection
|
|
51
|
+
* @param name The name of the uniform variable in the shader
|
|
52
|
+
* @param value The value to set for the uniform
|
|
53
|
+
* @ignore
|
|
40
54
|
*/
|
|
41
55
|
$setUniform(name: string, value: UniformValue): void;
|
|
42
56
|
private _acquireTextureUnit;
|
|
43
57
|
/**
|
|
44
58
|
* Get the WebGL program
|
|
45
59
|
*/
|
|
46
|
-
get
|
|
60
|
+
get program(): WebGLProgram;
|
|
47
61
|
/**
|
|
48
62
|
* Dispose of WebGL resources used by this shader.
|
|
49
63
|
*/
|
|
@@ -89,15 +89,8 @@ export interface IFramebuffer {
|
|
|
89
89
|
/**
|
|
90
90
|
* Dispose of WebGL resources used by this framebuffer.
|
|
91
91
|
*
|
|
92
|
-
* This releases:
|
|
93
|
-
* - The WebGL framebuffer object
|
|
94
|
-
* - All associated texture objects
|
|
95
|
-
* - Any cached pixel data
|
|
96
|
-
*
|
|
97
92
|
* This method is idempotent and safe to call multiple times.
|
|
98
93
|
* After disposal, the framebuffer should not be used for rendering.
|
|
99
|
-
*
|
|
100
|
-
* @ignore
|
|
101
94
|
*/
|
|
102
|
-
|
|
95
|
+
dispose(): void;
|
|
103
96
|
}
|
|
@@ -11,7 +11,9 @@ export declare class AnimationController {
|
|
|
11
11
|
private _lastRenderTime;
|
|
12
12
|
private _frameTimeHistory;
|
|
13
13
|
private _frameTimeHistorySize;
|
|
14
|
+
private _deltaTime;
|
|
14
15
|
private _frameCount;
|
|
16
|
+
private _millisStart;
|
|
15
17
|
/**
|
|
16
18
|
* Creates an AnimationController instance.
|
|
17
19
|
* @param frameRateLimit Maximum frames per second. Defaults to 60.
|
|
@@ -68,4 +70,31 @@ export declare class AnimationController {
|
|
|
68
70
|
* Should be called on each render to track total frames rendered.
|
|
69
71
|
*/
|
|
70
72
|
$incrementFrame(): void;
|
|
73
|
+
/**
|
|
74
|
+
* Get the number of milliseconds since the animation started.
|
|
75
|
+
* Returns 0 if the animation has not started yet.
|
|
76
|
+
*/
|
|
77
|
+
get $millis(): number;
|
|
78
|
+
/**
|
|
79
|
+
* Set the elapsed milliseconds by adjusting the start time.
|
|
80
|
+
* This allows seeking/scrubbing in animations.
|
|
81
|
+
* @param value The new elapsed time in milliseconds
|
|
82
|
+
*/
|
|
83
|
+
set $millis(value: number);
|
|
84
|
+
/**
|
|
85
|
+
* Get the number of seconds since the animation started.
|
|
86
|
+
* Returns 0 if the animation has not started yet.
|
|
87
|
+
*/
|
|
88
|
+
get $secs(): number;
|
|
89
|
+
/**
|
|
90
|
+
* Set the elapsed seconds by adjusting the start time.
|
|
91
|
+
* This allows seeking/scrubbing in animations.
|
|
92
|
+
* @param value The new elapsed time in seconds
|
|
93
|
+
*/
|
|
94
|
+
set $secs(value: number);
|
|
95
|
+
/**
|
|
96
|
+
* Get the time in milliseconds between the current frame and the last frame.
|
|
97
|
+
* Useful for frame-rate-independent animations.
|
|
98
|
+
*/
|
|
99
|
+
get $deltaTime(): number;
|
|
71
100
|
}
|
|
@@ -80,6 +80,8 @@ export declare class TextmodeGrid {
|
|
|
80
80
|
get offsetY(): number;
|
|
81
81
|
/**
|
|
82
82
|
* Restores responsive sizing so subsequent `t.resizeCanvas` calls recompute cols/rows.
|
|
83
|
+
*
|
|
84
|
+
* A grid becomes non-responsive when either `cols` or `rows` is manually set.
|
|
83
85
|
*/
|
|
84
86
|
responsive(): void;
|
|
85
87
|
/**
|
|
@@ -7,8 +7,8 @@ import { AnimationController } from './AnimationController';
|
|
|
7
7
|
import { MouseManager } from './managers/MouseManager';
|
|
8
8
|
import { KeyboardManager } from './managers/KeyboardManager';
|
|
9
9
|
import { TouchManager } from './managers/TouchManager';
|
|
10
|
+
import { TextmodePluginManager } from './managers/PluginManager';
|
|
10
11
|
import type { ITextmodifier } from './interfaces';
|
|
11
|
-
import type { GLShader } from '../rendering';
|
|
12
12
|
import type { TextmodeOptions } from './types';
|
|
13
13
|
import type { IAnimationMixin } from './mixins/interfaces/IAnimationMixin';
|
|
14
14
|
import type { IRenderingMixin } from './mixins/interfaces/IRenderingMixin';
|
|
@@ -17,8 +17,8 @@ import type { ITouchMixin } from './mixins/interfaces/ITouchMixin';
|
|
|
17
17
|
import type { IMouseMixin } from './mixins/interfaces/IMouseMixin';
|
|
18
18
|
import { LoadingScreenManager } from './loading/LoadingScreenManager';
|
|
19
19
|
import { LayerManager } from './layers/LayerManager';
|
|
20
|
-
import type { TextmodeLayerManager } from './layers';
|
|
21
|
-
import { TextmodeFilterManager } from './filters';
|
|
20
|
+
import type { TextmodeLayer, TextmodeLayerManager } from './layers';
|
|
21
|
+
import type { TextmodeFilterManager } from './filters';
|
|
22
22
|
import type { FilterName, BuiltInFilterName, BuiltInFilterParams } from './filters';
|
|
23
23
|
import { TextmodeConversionManager } from './conversion';
|
|
24
24
|
declare const Textmodifier_base: {
|
|
@@ -40,23 +40,16 @@ export declare class Textmodifier extends Textmodifier_base implements ITextmodi
|
|
|
40
40
|
_touchManager: TouchManager;
|
|
41
41
|
_keyboardManager: KeyboardManager;
|
|
42
42
|
_loading: LoadingScreenManager;
|
|
43
|
-
_textmodeConversionShader: GLShader;
|
|
44
|
-
_presentShader: GLShader;
|
|
45
43
|
_layerManager: TextmodeLayerManager;
|
|
46
|
-
|
|
47
|
-
_activeGrid?: TextmodeGrid;
|
|
48
|
-
_filterManager: TextmodeFilterManager;
|
|
44
|
+
_activeLayer?: TextmodeLayer;
|
|
49
45
|
_conversionManager: TextmodeConversionManager;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
private _postFilterFramebuffer;
|
|
53
|
-
private _pluginManager;
|
|
46
|
+
/** @ignore */
|
|
47
|
+
_pluginManager: TextmodePluginManager;
|
|
54
48
|
private _destroyRequested;
|
|
55
49
|
private _isRenderingFrame;
|
|
56
50
|
private _isDisposed;
|
|
57
51
|
private _setupComplete;
|
|
58
52
|
private _setupCallback;
|
|
59
|
-
private _drawCallback;
|
|
60
53
|
private _resizedCallback;
|
|
61
54
|
private _windowResizeListener;
|
|
62
55
|
private _resizeObserver?;
|
|
@@ -81,17 +74,16 @@ export declare class Textmodifier extends Textmodifier_base implements ITextmodi
|
|
|
81
74
|
private _performDestroy;
|
|
82
75
|
filter<T extends BuiltInFilterName>(name: T, params?: BuiltInFilterParams[T]): void;
|
|
83
76
|
filter(name: FilterName, params?: unknown): void;
|
|
77
|
+
draw(callback: () => void): void;
|
|
84
78
|
loadFont(fontSource: string): Promise<TextmodeFont>;
|
|
85
79
|
fontSize(size: number): void;
|
|
86
80
|
inputGrid(target?: 'topmost' | TextmodeGrid): 'topmost' | TextmodeGrid | void;
|
|
87
81
|
/**
|
|
88
82
|
* Get the grid used for input coordinate mapping.
|
|
89
83
|
* Returns the override grid/layer's grid if set, otherwise the topmost visible layer's grid.
|
|
90
|
-
* @ignore
|
|
91
84
|
*/
|
|
92
85
|
private _getInputGrid;
|
|
93
86
|
setup(callback: () => void | Promise<void>): Promise<void>;
|
|
94
|
-
draw(callback: () => void): void;
|
|
95
87
|
windowResized(callback: () => void): void;
|
|
96
88
|
get grid(): TextmodeGrid | undefined;
|
|
97
89
|
get font(): TextmodeFont;
|
|
@@ -104,6 +96,7 @@ export declare class Textmodifier extends Textmodifier_base implements ITextmodi
|
|
|
104
96
|
get layers(): LayerManager;
|
|
105
97
|
get filters(): TextmodeFilterManager;
|
|
106
98
|
get conversions(): TextmodeConversionManager;
|
|
99
|
+
get isRenderingFrame(): boolean;
|
|
107
100
|
}
|
|
108
101
|
export interface Textmodifier extends IRenderingMixin, IAnimationMixin, IMouseMixin, ITouchMixin, IKeyboardMixin {
|
|
109
102
|
}
|
|
@@ -3,7 +3,6 @@ import type { TextmodeFont } from '../loadables/font';
|
|
|
3
3
|
import type { TextmodeImage } from '../loadables/TextmodeImage';
|
|
4
4
|
import type { TextmodeCanvas } from '../Canvas';
|
|
5
5
|
import type { AnimationController } from '../AnimationController';
|
|
6
|
-
import type { GLShader } from '../../rendering';
|
|
7
6
|
import type { GLRenderer } from '../../rendering/webgl/core/Renderer';
|
|
8
7
|
import type { MouseManager } from '../managers/MouseManager';
|
|
9
8
|
import type { KeyboardManager } from '../managers/KeyboardManager';
|
|
@@ -15,6 +14,7 @@ import type { IMouseMixin } from '../mixins/interfaces/IMouseMixin';
|
|
|
15
14
|
import type { IAnimationMixin } from '../mixins/interfaces/IAnimationMixin';
|
|
16
15
|
import type { LoadingScreenManager } from '../loading/LoadingScreenManager';
|
|
17
16
|
import type { TextmodeLayerManager } from '../layers';
|
|
17
|
+
import type { TextmodeLayer } from '../layers/TextmodeLayer';
|
|
18
18
|
import type { BuiltInFilterName, BuiltInFilterParams, TextmodeFilterManager, FilterName } from '../filters';
|
|
19
19
|
import type { TextmodeConversionManager } from '../conversion';
|
|
20
20
|
/**
|
|
@@ -38,22 +38,14 @@ export interface ITextmodifier extends IRenderingMixin, IAnimationMixin, IMouseM
|
|
|
38
38
|
readonly _touchManager: TouchManager;
|
|
39
39
|
/** Keyboard interaction manager @ignore */
|
|
40
40
|
readonly _keyboardManager: KeyboardManager;
|
|
41
|
-
/** Shader used for converting pixels to textmode grid format @ignore */
|
|
42
|
-
readonly _textmodeConversionShader: GLShader;
|
|
43
|
-
/** Shader used for final presentation to the screen @ignore */
|
|
44
|
-
readonly _presentShader: GLShader;
|
|
45
41
|
/** Loading screen manager for boot-time UX @ignore */
|
|
46
42
|
readonly _loading: LoadingScreenManager;
|
|
47
43
|
/** Conversion manager for image-to-ASCII conversion @ignore */
|
|
48
44
|
readonly _conversionManager: TextmodeConversionManager;
|
|
49
|
-
/** Filter manager for applying post-processing effects @ignore */
|
|
50
|
-
readonly _filterManager: TextmodeFilterManager;
|
|
51
45
|
/** Layer manager for handling multiple layers @ignore */
|
|
52
46
|
readonly _layerManager: TextmodeLayerManager;
|
|
53
|
-
/** Active
|
|
54
|
-
|
|
55
|
-
/** Active grid based on layer currently being rendered @ignore */
|
|
56
|
-
_activeGrid?: TextmodeGrid;
|
|
47
|
+
/** Active layer currently being rendered @ignore */
|
|
48
|
+
_activeLayer?: TextmodeLayer;
|
|
57
49
|
/** Main render method @ignore */
|
|
58
50
|
$render(): void;
|
|
59
51
|
/**
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A 3D camera/transform controller for the voxel raymarching system.
|
|
3
|
+
*
|
|
4
|
+
* This class encapsulates the 3D transformation state (rotation, translation, zoom)
|
|
5
|
+
* used when rendering layers in 3D mode. It provides a clean separation between
|
|
6
|
+
* camera/viewport concerns and layer management.
|
|
7
|
+
*
|
|
8
|
+
* The camera operates in a right-handed coordinate system where:
|
|
9
|
+
* - X axis points right
|
|
10
|
+
* - Y axis points up
|
|
11
|
+
* - Z axis points toward the viewer (out of the screen)
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const camera = new Camera3D();
|
|
16
|
+
*
|
|
17
|
+
* // Set rotation (degrees)
|
|
18
|
+
* camera.rotation(45, 30, 0);
|
|
19
|
+
*
|
|
20
|
+
* // Get current rotation
|
|
21
|
+
* const [rx, ry, rz] = camera.rotation();
|
|
22
|
+
*
|
|
23
|
+
* // Animate
|
|
24
|
+
* camera.rotateY(camera.rotation()[1] + 1);
|
|
25
|
+
*
|
|
26
|
+
* // Reset to defaults
|
|
27
|
+
* camera.reset();
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare class Camera3D {
|
|
31
|
+
private _rotation;
|
|
32
|
+
private _translation;
|
|
33
|
+
private _zoom;
|
|
34
|
+
private _rotationMatrixCache;
|
|
35
|
+
/**
|
|
36
|
+
* Create a new Camera3D with default values.
|
|
37
|
+
*
|
|
38
|
+
* @param options Initial camera configuration
|
|
39
|
+
*/
|
|
40
|
+
constructor(options?: Camera3DOptions);
|
|
41
|
+
/**
|
|
42
|
+
* Set or get the rotation angles in degrees.
|
|
43
|
+
*
|
|
44
|
+
* When called with arguments, sets the rotation and returns void.
|
|
45
|
+
* When called without arguments, returns the current rotation.
|
|
46
|
+
*
|
|
47
|
+
* @param x Rotation around X axis in degrees
|
|
48
|
+
* @param y Rotation around Y axis in degrees (defaults to 0 if x provided)
|
|
49
|
+
* @param z Rotation around Z axis in degrees (defaults to 0 if x provided)
|
|
50
|
+
* @returns Current rotation as [x, y, z] tuple if no arguments provided
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* camera.rotation(45, 30, 0); // Set rotation
|
|
55
|
+
* const rot = camera.rotation(); // Get [45, 30, 0]
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
rotation(x?: number, y?: number, z?: number): [number, number, number] | void;
|
|
59
|
+
/**
|
|
60
|
+
* Set or get rotation around the X axis only.
|
|
61
|
+
*
|
|
62
|
+
* @param degrees Rotation in degrees, or undefined to get current value
|
|
63
|
+
* @returns Current X rotation if no argument provided
|
|
64
|
+
*/
|
|
65
|
+
rotateX(degrees?: number): number | void;
|
|
66
|
+
/**
|
|
67
|
+
* Set or get rotation around the Y axis only.
|
|
68
|
+
*
|
|
69
|
+
* @param degrees Rotation in degrees, or undefined to get current value
|
|
70
|
+
* @returns Current Y rotation if no argument provided
|
|
71
|
+
*/
|
|
72
|
+
rotateY(degrees?: number): number | void;
|
|
73
|
+
/**
|
|
74
|
+
* Set or get rotation around the Z axis only.
|
|
75
|
+
*
|
|
76
|
+
* @param degrees Rotation in degrees, or undefined to get current value
|
|
77
|
+
* @returns Current Z rotation if no argument provided
|
|
78
|
+
*/
|
|
79
|
+
rotateZ(degrees?: number): number | void;
|
|
80
|
+
/**
|
|
81
|
+
* Set or get the translation offset in world units.
|
|
82
|
+
*
|
|
83
|
+
* @param x Translation along X axis
|
|
84
|
+
* @param y Translation along Y axis (defaults to 0 if x provided)
|
|
85
|
+
* @param z Translation along Z axis (defaults to 0 if x provided)
|
|
86
|
+
* @returns Current translation as [x, y, z] tuple if no arguments provided
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* camera.translation(10, 5, 0); // Set translation
|
|
91
|
+
* const pos = camera.translation(); // Get [10, 5, 0]
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
translation(x?: number, y?: number, z?: number): [number, number, number] | void;
|
|
95
|
+
/**
|
|
96
|
+
* Set or get translation along the X axis only.
|
|
97
|
+
*
|
|
98
|
+
* @param units Translation amount, or undefined to get current value
|
|
99
|
+
* @returns Current X translation if no argument provided
|
|
100
|
+
*/
|
|
101
|
+
translateX(units?: number): number | void;
|
|
102
|
+
/**
|
|
103
|
+
* Set or get translation along the Y axis only.
|
|
104
|
+
*
|
|
105
|
+
* @param units Translation amount, or undefined to get current value
|
|
106
|
+
* @returns Current Y translation if no argument provided
|
|
107
|
+
*/
|
|
108
|
+
translateY(units?: number): number | void;
|
|
109
|
+
/**
|
|
110
|
+
* Set or get translation along the Z axis only.
|
|
111
|
+
*
|
|
112
|
+
* @param units Translation amount, or undefined to get current value
|
|
113
|
+
* @returns Current Z translation if no argument provided
|
|
114
|
+
*/
|
|
115
|
+
translateZ(units?: number): number | void;
|
|
116
|
+
/**
|
|
117
|
+
* Set or get the zoom level.
|
|
118
|
+
*
|
|
119
|
+
* Values greater than 1 zoom in, values less than 1 zoom out.
|
|
120
|
+
* The minimum zoom level is 0.001 to prevent division by zero.
|
|
121
|
+
*
|
|
122
|
+
* @param factor Zoom factor (1 = no zoom)
|
|
123
|
+
* @returns Current zoom if no argument provided
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* camera.zoom(2); // Zoom in 2x
|
|
128
|
+
* const z = camera.zoom(); // Get 2
|
|
129
|
+
* camera.zoom(0.5); // Zoom out 50%
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
zoom(factor?: number): number | void;
|
|
133
|
+
/**
|
|
134
|
+
* Reset the camera to default values.
|
|
135
|
+
*
|
|
136
|
+
* - Rotation: [0, 0, 0]
|
|
137
|
+
* - Translation: [0, 0, 0]
|
|
138
|
+
* - Zoom: 1
|
|
139
|
+
*/
|
|
140
|
+
reset(): void;
|
|
141
|
+
/**
|
|
142
|
+
* Copy values from another Camera3D instance.
|
|
143
|
+
*
|
|
144
|
+
* @param other The camera to copy from
|
|
145
|
+
*/
|
|
146
|
+
copyFrom(other: Camera3D): void;
|
|
147
|
+
/**
|
|
148
|
+
* Create a clone of this camera.
|
|
149
|
+
*
|
|
150
|
+
* @returns A new Camera3D instance with the same values
|
|
151
|
+
*/
|
|
152
|
+
clone(): Camera3D;
|
|
153
|
+
/**
|
|
154
|
+
* Get the rotation matrix as a Float32Array for GPU upload.
|
|
155
|
+
*
|
|
156
|
+
* The matrix is computed from the current Euler angles and transposed
|
|
157
|
+
* (inverted) for use in the shader. The result is cached and only
|
|
158
|
+
* recomputed when rotation values change.
|
|
159
|
+
*
|
|
160
|
+
* @returns Transposed 3x3 rotation matrix as Float32Array
|
|
161
|
+
*/
|
|
162
|
+
getRotationMatrix(): Float32Array;
|
|
163
|
+
/**
|
|
164
|
+
* Get all transform parameters in a format ready for shader uniforms.
|
|
165
|
+
*
|
|
166
|
+
* @returns Object containing all transform data for GPU upload
|
|
167
|
+
*/
|
|
168
|
+
getShaderUniforms(): Camera3DShaderUniforms;
|
|
169
|
+
/**
|
|
170
|
+
* Invalidate the cached rotation matrix.
|
|
171
|
+
* Called whenever rotation values change.
|
|
172
|
+
*/
|
|
173
|
+
private _invalidateRotationCache;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Options for creating a new Camera3D instance.
|
|
177
|
+
*/
|
|
178
|
+
export interface Camera3DOptions {
|
|
179
|
+
/**
|
|
180
|
+
* Initial rotation in degrees around X, Y, Z axes.
|
|
181
|
+
* @default [0, 0, 0]
|
|
182
|
+
*/
|
|
183
|
+
rotation?: [number, number, number];
|
|
184
|
+
/**
|
|
185
|
+
* Initial translation offset in world units.
|
|
186
|
+
* @default [0, 0, 0]
|
|
187
|
+
*/
|
|
188
|
+
translation?: [number, number, number];
|
|
189
|
+
/**
|
|
190
|
+
* Initial zoom factor. Values > 1 zoom in, < 1 zoom out.
|
|
191
|
+
* @default 1
|
|
192
|
+
*/
|
|
193
|
+
zoom?: number;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Shader uniforms generated by Camera3D for GPU upload.
|
|
197
|
+
*/
|
|
198
|
+
export interface Camera3DShaderUniforms {
|
|
199
|
+
/** Transposed 3x3 rotation matrix */
|
|
200
|
+
rotation: Float32Array;
|
|
201
|
+
/** Translation offset [x, y, z] */
|
|
202
|
+
translation: [number, number, number];
|
|
203
|
+
/** Zoom factor */
|
|
204
|
+
zoom: number;
|
|
205
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { GLRenderer, GLFramebuffer } from '../../rendering';
|
|
2
|
+
import type { TextmodeLayer } from './TextmodeLayer';
|
|
3
|
+
import type { TextmodeFont } from '../loadables/font';
|
|
4
|
+
import type { TextmodeGrid } from '../Grid';
|
|
5
|
+
import type { Camera3D } from './Camera3D';
|
|
6
|
+
/**
|
|
7
|
+
* 3D rendering options for the voxel raymarching system.
|
|
8
|
+
*/
|
|
9
|
+
export interface Layer3DOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Camera containing rotation, translation, and zoom.
|
|
12
|
+
* If provided, rotation/translation/zoom properties below are ignored.
|
|
13
|
+
*/
|
|
14
|
+
camera?: Camera3D;
|
|
15
|
+
/**
|
|
16
|
+
* Index of a specific layer to render in isolation.
|
|
17
|
+
* Set to -1 to render all layers.
|
|
18
|
+
* @default -1
|
|
19
|
+
*/
|
|
20
|
+
isolatedLayer?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Custom normal vectors for each voxel face (for lighting effects).
|
|
23
|
+
*/
|
|
24
|
+
normals?: {
|
|
25
|
+
right?: [number, number, number];
|
|
26
|
+
left?: [number, number, number];
|
|
27
|
+
top?: [number, number, number];
|
|
28
|
+
bottom?: [number, number, number];
|
|
29
|
+
front?: [number, number, number];
|
|
30
|
+
back?: [number, number, number];
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parameters for the 3D composite operation.
|
|
35
|
+
*/
|
|
36
|
+
export interface Composite3DParams {
|
|
37
|
+
/** The base layer's draw framebuffer. */
|
|
38
|
+
baseDrawFramebuffer: GLFramebuffer;
|
|
39
|
+
/** The target framebuffer to render the final result into. */
|
|
40
|
+
targetFramebuffer: GLFramebuffer;
|
|
41
|
+
/** The background color as RGBA values (0-1 range). */
|
|
42
|
+
backgroundColor: [number, number, number, number];
|
|
43
|
+
/** The base layer configuration. */
|
|
44
|
+
baseLayer: TextmodeLayer;
|
|
45
|
+
/** The array of user layers to stack. */
|
|
46
|
+
layers: readonly TextmodeLayer[];
|
|
47
|
+
/** The font used for character texture lookup (from base layer). */
|
|
48
|
+
font: TextmodeFont;
|
|
49
|
+
/** The grid with the largest dimensions (cols × rows) to use as reference. */
|
|
50
|
+
grid: TextmodeGrid;
|
|
51
|
+
/** Canvas width in pixels. */
|
|
52
|
+
canvasWidth: number;
|
|
53
|
+
/** Canvas height in pixels. */
|
|
54
|
+
canvasHeight: number;
|
|
55
|
+
/** 3D rendering options. */
|
|
56
|
+
options3D?: Layer3DOptions;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Handles the compositing of multiple layers using 3D voxel raymarching.
|
|
60
|
+
*
|
|
61
|
+
* This class is responsible for:
|
|
62
|
+
* - Combining all layer draw framebuffers into a single stacked atlas texture
|
|
63
|
+
* - Rendering the stacked layers as a 3D voxel grid using raymarching
|
|
64
|
+
* - Supporting rotation, zoom, and other 3D transformations
|
|
65
|
+
*
|
|
66
|
+
* @internal
|
|
67
|
+
*
|
|
68
|
+
* @remarks
|
|
69
|
+
* The compositor creates a stacked texture atlas where each layer's draw data
|
|
70
|
+
* is placed vertically in the texture. The 3D shader interprets this as a
|
|
71
|
+
* voxel grid with depth equal to the number of layers.
|
|
72
|
+
*
|
|
73
|
+
* Atlas layout:
|
|
74
|
+
* - Width: grid.cols
|
|
75
|
+
* - Height: grid.rows * (1 + numUserLayers)
|
|
76
|
+
* - Layer 0 (z=0, front): base layer at top
|
|
77
|
+
* - Layer N (z=N): user layers stacked below
|
|
78
|
+
*/
|
|
79
|
+
export declare class Layer3DCompositor {
|
|
80
|
+
private readonly _renderer;
|
|
81
|
+
private readonly _shaderGBuffer;
|
|
82
|
+
private readonly _shaderShade;
|
|
83
|
+
private _stackedAsciiBuffer;
|
|
84
|
+
private _stackedPrimaryBuffer;
|
|
85
|
+
private _stackedSecondaryBuffer;
|
|
86
|
+
private _gBuffer;
|
|
87
|
+
private _currentLayerCount;
|
|
88
|
+
private _canvasWidth;
|
|
89
|
+
private _canvasHeight;
|
|
90
|
+
private _maxCols;
|
|
91
|
+
private _maxRows;
|
|
92
|
+
/**
|
|
93
|
+
* Create a new Layer3DCompositor.
|
|
94
|
+
* @param renderer The WebGL renderer instance.
|
|
95
|
+
*/
|
|
96
|
+
constructor(renderer: GLRenderer);
|
|
97
|
+
/**
|
|
98
|
+
* Initialize the compositor's framebuffers.
|
|
99
|
+
* @param maxCols Maximum columns across all layers.
|
|
100
|
+
* @param maxRows Maximum rows across all layers.
|
|
101
|
+
* @param totalLayers Total number of layers (1 base + N user layers).
|
|
102
|
+
* @ignore
|
|
103
|
+
*/
|
|
104
|
+
$initialize(maxCols: number, maxRows: number, totalLayers?: number): void;
|
|
105
|
+
/**
|
|
106
|
+
* Resize the stacked atlas buffers to accommodate new dimensions.
|
|
107
|
+
* @param maxCols Maximum columns across all layers.
|
|
108
|
+
* @param maxRows Maximum rows across all layers.
|
|
109
|
+
* @param totalLayers Total number of layers.
|
|
110
|
+
* @ignore
|
|
111
|
+
*/
|
|
112
|
+
$resize(maxCols: number, maxRows: number, totalLayers?: number): void;
|
|
113
|
+
/**
|
|
114
|
+
* Composite all layers into a 3D voxel render.
|
|
115
|
+
* @param params The composite parameters.
|
|
116
|
+
*/
|
|
117
|
+
$composite(params: Composite3DParams): void;
|
|
118
|
+
/**
|
|
119
|
+
* Build the stacked atlas by copying each layer's draw data.
|
|
120
|
+
* Each layer is centered within the max dimensions.
|
|
121
|
+
*/
|
|
122
|
+
private _buildStackedAtlas;
|
|
123
|
+
/**
|
|
124
|
+
* Copy a source texture into a region of the target atlas framebuffer.
|
|
125
|
+
* Uses blitFramebuffer for efficient GPU-side copies.
|
|
126
|
+
*/
|
|
127
|
+
private _copyTextureToAtlas;
|
|
128
|
+
/**
|
|
129
|
+
* Render the 3D voxel scene using two-pass deferred rendering.
|
|
130
|
+
* Pass 1: G-Buffer generation (raymarching, outputs voxel coords + surface data)
|
|
131
|
+
* Pass 2: Shading (reads G-buffer, samples textures, applies character rendering)
|
|
132
|
+
*/
|
|
133
|
+
private _render3D;
|
|
134
|
+
/**
|
|
135
|
+
* Ensure the G-buffer exists and is correctly sized.
|
|
136
|
+
* Uses RGBA8 textures with normalized encoding for maximum compatibility.
|
|
137
|
+
*/
|
|
138
|
+
private _ensureGBuffer;
|
|
139
|
+
/**
|
|
140
|
+
* Dispose of all compositor resources.
|
|
141
|
+
* @ignore
|
|
142
|
+
*/
|
|
143
|
+
$dispose(): void;
|
|
144
|
+
/**
|
|
145
|
+
* Get the current maximum columns in the stacked atlas.
|
|
146
|
+
*/
|
|
147
|
+
get $maxCols(): number;
|
|
148
|
+
/**
|
|
149
|
+
* Get the current maximum rows per layer in the stacked atlas.
|
|
150
|
+
*/
|
|
151
|
+
get $maxRows(): number;
|
|
152
|
+
}
|