@tableslayer/ui 0.1.3 → 0.1.4
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/package.json +2 -13
- package/src/lib/components/Avatar/Avatar.svelte +82 -0
- package/src/lib/components/Avatar/AvatarFileInput.svelte +85 -0
- package/src/lib/components/Avatar/AvatarPopover.svelte +34 -0
- package/src/lib/components/Avatar/index.ts +4 -0
- package/src/lib/components/Avatar/types.ts +24 -0
- package/src/lib/components/BrushSizeSlider/BrushSizeSlider.svelte +174 -0
- package/src/lib/components/BrushSizeSlider/index.ts +1 -0
- package/src/lib/components/Button/Button.svelte +182 -0
- package/src/lib/components/Button/ConfirmActionButton.svelte +98 -0
- package/src/lib/components/Button/IconButton.svelte +121 -0
- package/src/lib/components/Button/RadioButton.svelte +93 -0
- package/src/lib/components/Button/index.ts +5 -0
- package/src/lib/components/Button/types.ts +54 -0
- package/src/lib/components/CardFan/CardFan.svelte +165 -0
- package/src/lib/components/CardFan/index.ts +2 -0
- package/src/lib/components/CardFan/types.ts +6 -0
- package/src/lib/components/CodeBlock/Code.svelte +7 -0
- package/src/lib/components/CodeBlock/CodeBlock.svelte +102 -0
- package/src/lib/components/CodeBlock/index.ts +3 -0
- package/src/lib/components/CodeBlock/types.ts +10 -0
- package/src/lib/components/ColorMode/ColorMode.svelte +8 -0
- package/src/lib/components/ColorMode/index.ts +2 -0
- package/src/lib/components/ColorMode/types.ts +12 -0
- package/src/lib/components/ColorPicker/ColorPicker.svelte +838 -0
- package/src/lib/components/ColorPicker/ColorPickerSwatch.svelte +32 -0
- package/src/lib/components/ColorPicker/index.ts +3 -0
- package/src/lib/components/ColorPicker/types.ts +51 -0
- package/src/lib/components/ContextMenu/ContextMenu.svelte +86 -0
- package/src/lib/components/ContextMenu/index.ts +2 -0
- package/src/lib/components/ContextMenu/types.ts +15 -0
- package/src/lib/components/DrawingSliders/DrawingSliders.svelte +379 -0
- package/src/lib/components/DrawingSliders/index.ts +1 -0
- package/src/lib/components/Editor/Editor.svelte +825 -0
- package/src/lib/components/Editor/index.ts +1 -0
- package/src/lib/components/FogSliders/FogSliders.svelte +33 -0
- package/src/lib/components/FogSliders/index.ts +1 -0
- package/src/lib/components/Hr/Hr.svelte +15 -0
- package/src/lib/components/Hr/index.ts +1 -0
- package/src/lib/components/Icon/Icon.svelte +6 -0
- package/src/lib/components/Icon/index.ts +2 -0
- package/src/lib/components/Icon/types.ts +20 -0
- package/src/lib/components/Input/DualInputSlider.svelte +126 -0
- package/src/lib/components/Input/FileInput.svelte +176 -0
- package/src/lib/components/Input/FormControl.svelte +150 -0
- package/src/lib/components/Input/FormError.svelte +37 -0
- package/src/lib/components/Input/Input.svelte +56 -0
- package/src/lib/components/Input/InputCheckbox.svelte +99 -0
- package/src/lib/components/Input/InputSlider.svelte +86 -0
- package/src/lib/components/Input/Label.svelte +19 -0
- package/src/lib/components/Input/index.ts +9 -0
- package/src/lib/components/Input/types.ts +39 -0
- package/src/lib/components/Link/Link.svelte +41 -0
- package/src/lib/components/Link/LinkBox.svelte +20 -0
- package/src/lib/components/Link/LinkOverlay.svelte +23 -0
- package/src/lib/components/Link/index.ts +4 -0
- package/src/lib/components/Link/types.ts +17 -0
- package/src/lib/components/Loading/Loader.svelte +60 -0
- package/src/lib/components/Loading/Skeleton.svelte +9 -0
- package/src/lib/components/Loading/index.ts +2 -0
- package/src/lib/components/Logo/Logo.svelte +16 -0
- package/src/lib/components/Logo/index.ts +1 -0
- package/src/lib/components/MarkerTooltip/MarkerTooltip.svelte +435 -0
- package/src/lib/components/MarkerTooltip/index.ts +1 -0
- package/src/lib/components/Menu/SelectorMenu.svelte +280 -0
- package/src/lib/components/Menu/index.ts +2 -0
- package/src/lib/components/Menu/types.ts +17 -0
- package/src/lib/components/MyCounterButton.svelte +11 -0
- package/src/lib/components/Panel/index.ts +2 -0
- package/src/lib/components/Panel/panel.svelte +18 -0
- package/src/lib/components/Panel/types.ts +8 -0
- package/src/lib/components/PersistButton/PersistButton.svelte +100 -0
- package/src/lib/components/PersistButton/index.ts +1 -0
- package/src/lib/components/Popover/Popover.svelte +81 -0
- package/src/lib/components/Popover/index.ts +2 -0
- package/src/lib/components/Popover/types.ts +19 -0
- package/src/lib/components/PropsTable/PropsTable.svelte +107 -0
- package/src/lib/components/RadialMenu/EffectPreview.svelte +36 -0
- package/src/lib/components/RadialMenu/EffectPreviewScene.svelte +194 -0
- package/src/lib/components/RadialMenu/RadialMenu.svelte +503 -0
- package/src/lib/components/RadialMenu/RadialMenuItem.svelte +176 -0
- package/src/lib/components/RadialMenu/index.ts +2 -0
- package/src/lib/components/RadialMenu/types.ts +35 -0
- package/src/lib/components/Select/Select.svelte +342 -0
- package/src/lib/components/Select/index.ts +2 -0
- package/src/lib/components/Select/types.ts +22 -0
- package/src/lib/components/Spacer/Spacer.svelte +14 -0
- package/src/lib/components/Spacer/index.ts +2 -0
- package/src/lib/components/Spacer/types.ts +5 -0
- package/src/lib/components/Stage/components/AnnotationLayer/AnnotationLayer.svelte +445 -0
- package/src/lib/components/Stage/components/AnnotationLayer/AnnotationMaterial.svelte +167 -0
- package/src/lib/components/Stage/components/AnnotationLayer/types.ts +196 -0
- package/src/lib/components/Stage/components/CursorLayer/CursorLayer.svelte +148 -0
- package/src/lib/components/Stage/components/CursorLayer/cursor.svg +26 -0
- package/src/lib/components/Stage/components/CursorLayer/index.ts +2 -0
- package/src/lib/components/Stage/components/CursorLayer/types.ts +23 -0
- package/src/lib/components/Stage/components/DrawingLayer/DrawingMaterial.svelte +364 -0
- package/src/lib/components/Stage/components/DrawingLayer/types.ts +65 -0
- package/src/lib/components/Stage/components/EdgeOverlayLayer/EdgeOverlayLayer.svelte +72 -0
- package/src/lib/components/Stage/components/EdgeOverlayLayer/types.ts +34 -0
- package/src/lib/components/Stage/components/FogLayer/FogLayer.svelte +75 -0
- package/src/lib/components/Stage/components/FogLayer/types.ts +51 -0
- package/src/lib/components/Stage/components/FogOfWarLayer/FogOfWarLayer.svelte +249 -0
- package/src/lib/components/Stage/components/FogOfWarLayer/FogOfWarMaterial.svelte +200 -0
- package/src/lib/components/Stage/components/FogOfWarLayer/types.ts +116 -0
- package/src/lib/components/Stage/components/GridLayer/GridLayer.svelte +20 -0
- package/src/lib/components/Stage/components/GridLayer/GridMaterial.svelte +69 -0
- package/src/lib/components/Stage/components/GridLayer/types.ts +79 -0
- package/src/lib/components/Stage/components/LayerInput/LayerInput.svelte +300 -0
- package/src/lib/components/Stage/components/MapLayer/MapLayer.svelte +196 -0
- package/src/lib/components/Stage/components/MapLayer/dataSources/GifDataSource.ts +265 -0
- package/src/lib/components/Stage/components/MapLayer/dataSources/IMapDataSource.ts +55 -0
- package/src/lib/components/Stage/components/MapLayer/dataSources/ImageDataSource.ts +87 -0
- package/src/lib/components/Stage/components/MapLayer/dataSources/VideoDataSource.ts +150 -0
- package/src/lib/components/Stage/components/MapLayer/dataSources/dataSourceFactory.ts +48 -0
- package/src/lib/components/Stage/components/MapLayer/dataSources/index.ts +16 -0
- package/src/lib/components/Stage/components/MapLayer/types.ts +58 -0
- package/src/lib/components/Stage/components/MarkerLayer/MarkerLayer.svelte +398 -0
- package/src/lib/components/Stage/components/MarkerLayer/MarkerToken.svelte +262 -0
- package/src/lib/components/Stage/components/MarkerLayer/types.ts +126 -0
- package/src/lib/components/Stage/components/MeasurementLayer/MeasurementLayer.svelte +364 -0
- package/src/lib/components/Stage/components/MeasurementLayer/MeasurementManager.svelte +473 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/BaseMeasurement.ts +427 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/BeamMeasurement.ts +105 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/CircleMeasurement.ts +98 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/ConeMeasurement.ts +163 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/LineMeasurement.ts +102 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/RectangleMeasurement.ts +120 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/index.ts +7 -0
- package/src/lib/components/Stage/components/MeasurementLayer/types.ts +94 -0
- package/src/lib/components/Stage/components/MeasurementLayer/utils/canvasDrawing.ts +357 -0
- package/src/lib/components/Stage/components/MeasurementLayer/utils/distanceCalculations.ts +170 -0
- package/src/lib/components/Stage/components/ParticleSystem/ParticleSystem.svelte +220 -0
- package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/ash.png +0 -0
- package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/leaves.png +0 -0
- package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/rain.png +0 -0
- package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/snow.png +0 -0
- package/src/lib/components/Stage/components/ParticleSystem/rng.js +20 -0
- package/src/lib/components/Stage/components/ParticleSystem/types.ts +95 -0
- package/src/lib/components/Stage/components/PerformanceDebugger/PerformanceDebugger.svelte +144 -0
- package/src/lib/components/Stage/components/PerformanceDebugger/index.ts +1 -0
- package/src/lib/components/Stage/components/PerformanceOverlay/PerformanceOverlay.svelte +208 -0
- package/src/lib/components/Stage/components/PerformanceOverlay/index.ts +1 -0
- package/src/lib/components/Stage/components/PointerInputManager/PointerInputManager.svelte +201 -0
- package/src/lib/components/Stage/components/Scene/Scene.svelte +651 -0
- package/src/lib/components/Stage/components/Scene/luts.ts +24 -0
- package/src/lib/components/Stage/components/Scene/types.ts +225 -0
- package/src/lib/components/Stage/components/Stage/Stage.svelte +332 -0
- package/src/lib/components/Stage/components/Stage/types.ts +136 -0
- package/src/lib/components/Stage/components/WeatherLayer/WeatherLayer.svelte +135 -0
- package/src/lib/components/Stage/components/WeatherLayer/presets/AshPreset.ts +71 -0
- package/src/lib/components/Stage/components/WeatherLayer/presets/LeavesPreset.ts +70 -0
- package/src/lib/components/Stage/components/WeatherLayer/presets/RainPreset.ts +68 -0
- package/src/lib/components/Stage/components/WeatherLayer/presets/SnowPreset.ts +70 -0
- package/src/lib/components/Stage/components/WeatherLayer/presets/index.ts +6 -0
- package/src/lib/components/Stage/components/WeatherLayer/types.ts +35 -0
- package/src/lib/components/Stage/helpers/clippingPlaneStore.svelte.ts +28 -0
- package/src/lib/components/Stage/helpers/debugState.svelte.ts +18 -0
- package/src/lib/components/Stage/helpers/grid.ts +548 -0
- package/src/lib/components/Stage/helpers/lazyBrush.ts +171 -0
- package/src/lib/components/Stage/helpers/performanceMetrics.svelte.ts +220 -0
- package/src/lib/components/Stage/helpers/utils.ts +21 -0
- package/src/lib/components/Stage/index.ts +49 -0
- package/src/lib/components/Stage/shaders/AnnotationEffects.frag +1070 -0
- package/src/lib/components/Stage/shaders/Annotations.frag +29 -0
- package/src/lib/components/Stage/shaders/Drawing.frag +83 -0
- package/src/lib/components/Stage/shaders/Drawing.vert +5 -0
- package/src/lib/components/Stage/shaders/Fog.frag +147 -0
- package/src/lib/components/Stage/shaders/FractalNoise.frag +96 -0
- package/src/lib/components/Stage/shaders/GridShader.frag +174 -0
- package/src/lib/components/Stage/shaders/Overlay.frag +23 -0
- package/src/lib/components/Stage/shaders/Overlay.vert +0 -0
- package/src/lib/components/Stage/shaders/Particles.frag +27 -0
- package/src/lib/components/Stage/shaders/Particles.vert +51 -0
- package/src/lib/components/Stage/shaders/ToolOutline.frag +59 -0
- package/src/lib/components/Stage/shaders/default.vert +8 -0
- package/src/lib/components/Stage/types.ts +4 -0
- package/src/lib/components/Table/Table.svelte +16 -0
- package/src/lib/components/Table/Td.svelte +17 -0
- package/src/lib/components/Table/Th.svelte +18 -0
- package/src/lib/components/Table/index.ts +4 -0
- package/src/lib/components/Table/types.ts +14 -0
- package/src/lib/components/Text/Text.svelte +23 -0
- package/src/lib/components/Text/index.ts +2 -0
- package/src/lib/components/Text/types.ts +12 -0
- package/src/lib/components/Title/Title.svelte +54 -0
- package/src/lib/components/Title/index.ts +2 -0
- package/src/lib/components/Title/types.ts +9 -0
- package/src/lib/components/Toast/Toast.svelte +155 -0
- package/src/lib/components/Toast/index.ts +5 -0
- package/src/lib/components/Toast/toastCookie.ts +24 -0
- package/src/lib/components/Toast/types.ts +6 -0
- package/src/lib/components/ToolTip/ToolTip.svelte +70 -0
- package/src/lib/components/ToolTip/index.ts +2 -0
- package/src/lib/components/ToolTip/types.ts +14 -0
- package/src/lib/components/index.ts +32 -0
- package/src/lib/components/types.ts +0 -0
- package/src/lib/index.ts +2 -0
- package/src/lib/styles/globals.css +108 -0
- package/src/lib/styles/normalize.css +9 -0
- package/src/lib/styles/reset.css +133 -0
- package/src/lib/styles/utilities.css +179 -0
- package/src/lib/styles/vars.css +1103 -0
- package/src/lib/types/awareness.ts +17 -0
- package/src/lib/utils/rle.ts +217 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { T, useThrelte, useLoader } from '@threlte/core';
|
|
4
|
+
import { DrawMode, type DrawingLayerProps, InitialState } from './types';
|
|
5
|
+
import { onDestroy, untrack } from 'svelte';
|
|
6
|
+
import type { Size } from '../../types';
|
|
7
|
+
import { RenderMode } from './types';
|
|
8
|
+
import { encodeRLE, decodeRLE } from '../../../../utils/rle';
|
|
9
|
+
|
|
10
|
+
import drawVertexShader from '../../shaders/Drawing.vert?raw';
|
|
11
|
+
import drawFragmentShader from '../../shaders/Drawing.frag?raw';
|
|
12
|
+
|
|
13
|
+
interface Props {
|
|
14
|
+
props: DrawingLayerProps;
|
|
15
|
+
size: Size | null;
|
|
16
|
+
initialState: InitialState;
|
|
17
|
+
onRender: (texture: THREE.Texture) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const { props, size, initialState, onRender }: Props = $props();
|
|
21
|
+
const { renderer } = useThrelte();
|
|
22
|
+
|
|
23
|
+
// This shader is used for drawing the fog of war on the GPU
|
|
24
|
+
const drawMaterial = new THREE.ShaderMaterial({
|
|
25
|
+
uniforms: {
|
|
26
|
+
uPreviousState: { value: null },
|
|
27
|
+
uBrushTexture: { value: null },
|
|
28
|
+
uStart: { value: new THREE.Vector2(Infinity, Infinity) }, // Initialize off-screen
|
|
29
|
+
uEnd: { value: new THREE.Vector2(Infinity, Infinity) }, // Initialize off-screen
|
|
30
|
+
uBrushSize: { value: props.tool.size },
|
|
31
|
+
uBrushFalloff: { value: 50.0 },
|
|
32
|
+
uTextureSize: { value: new THREE.Vector2() },
|
|
33
|
+
uBrushColor: { value: new THREE.Vector4() },
|
|
34
|
+
uIsRevertOperation: { value: false },
|
|
35
|
+
uIsClearOperation: { value: false },
|
|
36
|
+
uIsFillOperation: { value: false },
|
|
37
|
+
uShapeType: { value: 0 }
|
|
38
|
+
},
|
|
39
|
+
vertexShader: drawVertexShader,
|
|
40
|
+
fragmentShader: drawFragmentShader
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Options for the render targets
|
|
44
|
+
const options = {
|
|
45
|
+
format: THREE.RGBAFormat,
|
|
46
|
+
type: THREE.UnsignedByteType,
|
|
47
|
+
minFilter: THREE.LinearMipMapLinearFilter,
|
|
48
|
+
magFilter: THREE.LinearFilter,
|
|
49
|
+
generateMipmaps: true,
|
|
50
|
+
depthBuffer: false,
|
|
51
|
+
alpha: true
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
let imageUrl: string | null = $state(null);
|
|
55
|
+
|
|
56
|
+
const loader = useLoader(THREE.TextureLoader);
|
|
57
|
+
|
|
58
|
+
// Double-buffered render targets
|
|
59
|
+
let tempTarget = new THREE.WebGLRenderTarget(1, 1, options);
|
|
60
|
+
let persistedTarget = new THREE.WebGLRenderTarget(1, 1, options);
|
|
61
|
+
|
|
62
|
+
// Setup the quad that the fog of war is drawn on
|
|
63
|
+
let scene = new THREE.Scene();
|
|
64
|
+
let camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
|
65
|
+
const quad = new THREE.Mesh();
|
|
66
|
+
|
|
67
|
+
onDestroy(() => {
|
|
68
|
+
tempTarget?.dispose();
|
|
69
|
+
persistedTarget?.dispose();
|
|
70
|
+
drawMaterial?.dispose();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Map size changed
|
|
74
|
+
$effect(() => {
|
|
75
|
+
if (!size) return;
|
|
76
|
+
|
|
77
|
+
// If map size changed, update the render target sizes
|
|
78
|
+
if (size.width !== tempTarget.width || size.height !== tempTarget.height) {
|
|
79
|
+
tempTarget.setSize(size.width, size.height);
|
|
80
|
+
persistedTarget.setSize(size.width, size.height);
|
|
81
|
+
// Use .set() to avoid allocating new Vector2
|
|
82
|
+
drawMaterial.uniforms.uTextureSize.value.set(size.width, size.height);
|
|
83
|
+
|
|
84
|
+
// If an image is provided, load it, otherwise reset the fog state
|
|
85
|
+
if (props.url) {
|
|
86
|
+
loadImage(props.url);
|
|
87
|
+
untrack(() => (imageUrl = props.url));
|
|
88
|
+
} else {
|
|
89
|
+
if (initialState === InitialState.Fill) {
|
|
90
|
+
render(RenderMode.Fill, true);
|
|
91
|
+
} else {
|
|
92
|
+
render(RenderMode.Clear, true);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
$effect(() => {
|
|
99
|
+
// If fog image is changed, reload the image
|
|
100
|
+
if (props.url && props.url !== imageUrl) {
|
|
101
|
+
loadImage(props.url);
|
|
102
|
+
untrack(() => (imageUrl = props.url));
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Track previous values to avoid unnecessary rerenders
|
|
107
|
+
let prevToolType = props.tool.type;
|
|
108
|
+
let prevToolMode = props.tool.mode;
|
|
109
|
+
|
|
110
|
+
// Whenever the fog of war props change, we need to update the material
|
|
111
|
+
$effect(() => {
|
|
112
|
+
drawMaterial.uniforms.uEnd.value.copy(drawMaterial.uniforms.uStart.value);
|
|
113
|
+
drawMaterial.uniforms.uShapeType.value = props.tool.type;
|
|
114
|
+
drawMaterial.uniforms.uBrushSize.value = props.tool.size;
|
|
115
|
+
|
|
116
|
+
// Use .set() to avoid allocating new Vector4
|
|
117
|
+
if (props.tool.mode === DrawMode.Erase) {
|
|
118
|
+
drawMaterial.uniforms.uBrushColor.value.set(0, 0, 0, 0);
|
|
119
|
+
} else {
|
|
120
|
+
drawMaterial.uniforms.uBrushColor.value.set(1, 1, 1, 1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Only revert and redraw if tool type or mode changed, not size
|
|
124
|
+
const toolTypeOrModeChanged = prevToolType !== props.tool.type || prevToolMode !== props.tool.mode;
|
|
125
|
+
|
|
126
|
+
if (toolTypeOrModeChanged) {
|
|
127
|
+
// Discard the current buffer by copying the previous buffer to the current buffer
|
|
128
|
+
render(RenderMode.Revert, true);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Always redraw to show the updated tool overlay (including size changes)
|
|
132
|
+
render(RenderMode.Draw);
|
|
133
|
+
|
|
134
|
+
// Update previous values
|
|
135
|
+
prevToolType = props.tool.type;
|
|
136
|
+
prevToolMode = props.tool.mode;
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Loads an image into the current buffer
|
|
141
|
+
* @param url The URL of the image to load
|
|
142
|
+
*/
|
|
143
|
+
function loadImage(url: string) {
|
|
144
|
+
loader.load(url).then((texture) => render(RenderMode.Revert, true, texture));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Swaps the current and previous buffers to persist the current state
|
|
149
|
+
*/
|
|
150
|
+
function swapBuffers() {
|
|
151
|
+
const temp = tempTarget;
|
|
152
|
+
tempTarget = persistedTarget;
|
|
153
|
+
persistedTarget = temp;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function clear() {
|
|
157
|
+
render(RenderMode.Clear, true);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function fill() {
|
|
161
|
+
render(RenderMode.Fill, true);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function revert() {
|
|
165
|
+
render(RenderMode.Revert, true);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Resets the cursor position to hide it
|
|
170
|
+
*/
|
|
171
|
+
export function resetCursor() {
|
|
172
|
+
// Set both start and end to a far off-screen position
|
|
173
|
+
const offScreen = new THREE.Vector2(Infinity, Infinity);
|
|
174
|
+
drawMaterial.uniforms.uStart.value.copy(offScreen);
|
|
175
|
+
drawMaterial.uniforms.uEnd.value.copy(offScreen);
|
|
176
|
+
// Re-render to clear the cursor from the texture
|
|
177
|
+
render(RenderMode.Revert, false);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Renders the to the current buffer
|
|
182
|
+
* @param operation The operation to perform. 'fill' will reset the fog of war to the initial state, 'revert' will copy the current state to the previous state, 'clear' will clear the current state, and 'draw' will draw the current state
|
|
183
|
+
* @param persist Whether to persist the current state
|
|
184
|
+
* @param lastTexture The texture to use for the previous state
|
|
185
|
+
*/
|
|
186
|
+
export function render(operation: RenderMode, persist: boolean = false, lastTexture: THREE.Texture | null = null) {
|
|
187
|
+
// If no previous state is provided, use the last target
|
|
188
|
+
drawMaterial.uniforms.uPreviousState.value = lastTexture ?? persistedTarget.texture;
|
|
189
|
+
|
|
190
|
+
drawMaterial.uniforms.uIsRevertOperation.value = operation === RenderMode.Revert;
|
|
191
|
+
drawMaterial.uniforms.uIsFillOperation.value = operation === RenderMode.Fill;
|
|
192
|
+
drawMaterial.uniforms.uIsClearOperation.value = operation === RenderMode.Clear;
|
|
193
|
+
|
|
194
|
+
scene.visible = true;
|
|
195
|
+
renderer.setRenderTarget(tempTarget);
|
|
196
|
+
renderer.render(scene, camera);
|
|
197
|
+
scene.visible = false;
|
|
198
|
+
|
|
199
|
+
onRender(tempTarget.texture);
|
|
200
|
+
|
|
201
|
+
drawMaterial.uniforms.uIsRevertOperation.value = false;
|
|
202
|
+
drawMaterial.uniforms.uIsFillOperation.value = false;
|
|
203
|
+
drawMaterial.uniforms.uIsClearOperation.value = false;
|
|
204
|
+
|
|
205
|
+
renderer.setRenderTarget(null);
|
|
206
|
+
|
|
207
|
+
if (persist) {
|
|
208
|
+
swapBuffers();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Draws a path on the current buffer
|
|
214
|
+
* @param start The start position of the path
|
|
215
|
+
* @param last The last position of the path
|
|
216
|
+
* @param persist Whether to persist the current state
|
|
217
|
+
*/
|
|
218
|
+
export function drawPath(start: THREE.Vector2, last: THREE.Vector2 | null, persist: boolean) {
|
|
219
|
+
drawMaterial.uniforms.uStart.value.copy(start);
|
|
220
|
+
drawMaterial.uniforms.uEnd.value.copy(last ?? start);
|
|
221
|
+
render(RenderMode.Draw, persist);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Gets the current texture
|
|
226
|
+
* @returns The current texture
|
|
227
|
+
*/
|
|
228
|
+
export function getTexture() {
|
|
229
|
+
return tempTarget.texture;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Serializes the current fog of war state to a binary buffer
|
|
234
|
+
* @returns A binary buffer representation of the fog of war texture
|
|
235
|
+
*/
|
|
236
|
+
export async function toPng(): Promise<Blob> {
|
|
237
|
+
// Create a temporary canvas to draw the texture
|
|
238
|
+
const canvas = new OffscreenCanvas(persistedTarget.width, persistedTarget.height);
|
|
239
|
+
const ctx = canvas.getContext('2d')!;
|
|
240
|
+
|
|
241
|
+
// Read pixels from WebGL render target
|
|
242
|
+
const pixels = new Uint8Array(4 * persistedTarget.width * persistedTarget.height);
|
|
243
|
+
renderer.readRenderTargetPixels(persistedTarget, 0, 0, persistedTarget.width, persistedTarget.height, pixels);
|
|
244
|
+
|
|
245
|
+
// Draw pixels to canvas
|
|
246
|
+
const imageData = ctx.createImageData(persistedTarget.width, persistedTarget.height);
|
|
247
|
+
imageData.data.set(pixels);
|
|
248
|
+
ctx.putImageData(imageData, 0, 0);
|
|
249
|
+
|
|
250
|
+
// The pixel data is flipped vertically when read from the WebGL render target, so we need to flip it back
|
|
251
|
+
const flippedCanvas = document.createElement('canvas');
|
|
252
|
+
flippedCanvas.width = canvas.width;
|
|
253
|
+
flippedCanvas.height = canvas.height;
|
|
254
|
+
const flippedCtx = flippedCanvas.getContext('2d')!;
|
|
255
|
+
|
|
256
|
+
flippedCtx.scale(1, -1);
|
|
257
|
+
flippedCtx.translate(0, -canvas.height);
|
|
258
|
+
flippedCtx.drawImage(canvas, 0, 0);
|
|
259
|
+
|
|
260
|
+
// Convert to blob with lossless PNG compression
|
|
261
|
+
return new Promise((resolve) => {
|
|
262
|
+
flippedCanvas.toBlob((blob) => resolve(blob!), 'image/png');
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Exports the current state as RLE-encoded data
|
|
268
|
+
* @returns RLE encoded Uint8Array with dimensions prepended
|
|
269
|
+
*/
|
|
270
|
+
export async function toRLE(): Promise<Uint8Array> {
|
|
271
|
+
const width = persistedTarget.width;
|
|
272
|
+
const height = persistedTarget.height;
|
|
273
|
+
|
|
274
|
+
// Read pixels from WebGL render target
|
|
275
|
+
const pixels = new Uint8Array(4 * width * height);
|
|
276
|
+
renderer.readRenderTargetPixels(persistedTarget, 0, 0, width, height, pixels);
|
|
277
|
+
|
|
278
|
+
// Extract alpha channel and flip vertically
|
|
279
|
+
const binaryData = new Uint8Array(width * height);
|
|
280
|
+
for (let y = 0; y < height; y++) {
|
|
281
|
+
for (let x = 0; x < width; x++) {
|
|
282
|
+
const srcIndex = (y * width + x) * 4 + 3; // Alpha channel
|
|
283
|
+
const dstIndex = (height - 1 - y) * width + x; // Flip vertically
|
|
284
|
+
binaryData[dstIndex] = pixels[srcIndex] > 127 ? 255 : 0;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const rleData = encodeRLE(binaryData);
|
|
289
|
+
|
|
290
|
+
// Prepend dimensions to the RLE data (4 bytes for width, 4 bytes for height)
|
|
291
|
+
const result = new Uint8Array(8 + rleData.length);
|
|
292
|
+
const view = new DataView(result.buffer);
|
|
293
|
+
view.setUint32(0, width, true); // little-endian
|
|
294
|
+
view.setUint32(4, height, true); // little-endian
|
|
295
|
+
result.set(rleData, 8);
|
|
296
|
+
|
|
297
|
+
return result;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Loads RLE-encoded data into the drawing buffer
|
|
302
|
+
* @param rleData RLE encoded data (with dimensions prepended)
|
|
303
|
+
* @param width Image width (ignored if dimensions are in data)
|
|
304
|
+
* @param height Image height (ignored if dimensions are in data)
|
|
305
|
+
*/
|
|
306
|
+
export async function fromRLE(rleData: Uint8Array, width?: number, height?: number) {
|
|
307
|
+
// Check if dimensions are prepended (new format)
|
|
308
|
+
let actualWidth = width || 1024;
|
|
309
|
+
let actualHeight = height || 1024;
|
|
310
|
+
let rleStart = 0;
|
|
311
|
+
|
|
312
|
+
if (rleData.length > 8) {
|
|
313
|
+
const view = new DataView(rleData.buffer, rleData.byteOffset, rleData.byteLength);
|
|
314
|
+
const possibleWidth = view.getUint32(0, true);
|
|
315
|
+
const possibleHeight = view.getUint32(4, true);
|
|
316
|
+
|
|
317
|
+
// Sanity check - dimensions should be reasonable
|
|
318
|
+
if (possibleWidth > 0 && possibleWidth <= 4096 && possibleHeight > 0 && possibleHeight <= 4096) {
|
|
319
|
+
actualWidth = possibleWidth;
|
|
320
|
+
actualHeight = possibleHeight;
|
|
321
|
+
rleStart = 8;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Extract the actual RLE data
|
|
326
|
+
const actualRleData = rleStart > 0 ? rleData.slice(rleStart) : rleData;
|
|
327
|
+
|
|
328
|
+
// Decode RLE to binary
|
|
329
|
+
const binaryData = decodeRLE(actualRleData, actualWidth * actualHeight);
|
|
330
|
+
|
|
331
|
+
// Create texture from binary data - flip vertically to match WebGL coordinate system
|
|
332
|
+
const rgba = new Uint8Array(actualWidth * actualHeight * 4);
|
|
333
|
+
for (let y = 0; y < actualHeight; y++) {
|
|
334
|
+
for (let x = 0; x < actualWidth; x++) {
|
|
335
|
+
const srcIndex = y * actualWidth + x;
|
|
336
|
+
const dstIndex = (actualHeight - 1 - y) * actualWidth + x; // Flip vertically
|
|
337
|
+
const idx = dstIndex * 4;
|
|
338
|
+
rgba[idx] = 0; // R
|
|
339
|
+
rgba[idx + 1] = 0; // G
|
|
340
|
+
rgba[idx + 2] = 0; // B
|
|
341
|
+
rgba[idx + 3] = binaryData[srcIndex]; // A
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Create texture
|
|
346
|
+
const texture = new THREE.DataTexture(rgba, actualWidth, actualHeight, THREE.RGBAFormat);
|
|
347
|
+
texture.needsUpdate = true;
|
|
348
|
+
|
|
349
|
+
// Load into buffer
|
|
350
|
+
render(RenderMode.Revert, true, texture);
|
|
351
|
+
|
|
352
|
+
// Dispose the temporary texture after rendering to buffer
|
|
353
|
+
texture.dispose();
|
|
354
|
+
}
|
|
355
|
+
</script>
|
|
356
|
+
|
|
357
|
+
<!-- Hidden scene that renders to the render target -->
|
|
358
|
+
<T.Scene is={scene} visible={false}>
|
|
359
|
+
<T.OrthographicCamera is={camera} />
|
|
360
|
+
<T.Mesh is={quad}>
|
|
361
|
+
<T.ShaderMaterial is={drawMaterial} />
|
|
362
|
+
<T.PlaneGeometry args={[2, 2]} />
|
|
363
|
+
</T.Mesh>
|
|
364
|
+
</T.Scene>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export enum InitialState {
|
|
2
|
+
Clear = 0,
|
|
3
|
+
Fill = 1
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export enum ToolType {
|
|
7
|
+
Brush = 1,
|
|
8
|
+
Rectangle = 2,
|
|
9
|
+
Ellipse = 3
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export enum DrawMode {
|
|
13
|
+
Erase = 0,
|
|
14
|
+
Draw = 1
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export enum RenderMode {
|
|
18
|
+
Draw = 'draw',
|
|
19
|
+
Clear = 'clear',
|
|
20
|
+
Revert = 'revert',
|
|
21
|
+
Fill = 'fill'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The properties for a drawing layer
|
|
26
|
+
*/
|
|
27
|
+
export interface DrawingLayerProps {
|
|
28
|
+
/**
|
|
29
|
+
* The URL of the texture to use for the drawing layer
|
|
30
|
+
*/
|
|
31
|
+
url: string | null;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Version timestamp for mask data changes (for real-time sync)
|
|
35
|
+
*/
|
|
36
|
+
maskVersion?: number;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The opacity of the drawing layer
|
|
40
|
+
*/
|
|
41
|
+
opacity: {
|
|
42
|
+
dm: number;
|
|
43
|
+
player: number;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The tool settings
|
|
48
|
+
*/
|
|
49
|
+
tool: {
|
|
50
|
+
/**
|
|
51
|
+
* The current drawing mode (`DrawMode.Erase` or `DrawMode.Draw`)
|
|
52
|
+
*/
|
|
53
|
+
mode: DrawMode;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* When `toolType = ToolType.Brush`, setting this controls the brush size
|
|
57
|
+
*/
|
|
58
|
+
size: number;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The type of drawing tool currently selected
|
|
62
|
+
*/
|
|
63
|
+
type: ToolType;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { T, useLoader, type Props as ThrelteProps } from '@threlte/core';
|
|
4
|
+
import { TextureLoader } from 'three';
|
|
5
|
+
import type { EdgeOverlayProps } from './types';
|
|
6
|
+
import type { DisplayProps } from '../Stage/types';
|
|
7
|
+
import { SceneLayer } from '../Scene/types';
|
|
8
|
+
|
|
9
|
+
import vertexShader from '../../shaders/default.vert?raw';
|
|
10
|
+
import fragmentShader from '../../shaders/Overlay.frag?raw';
|
|
11
|
+
|
|
12
|
+
interface Props extends ThrelteProps<typeof THREE.Mesh> {
|
|
13
|
+
props: EdgeOverlayProps;
|
|
14
|
+
display: DisplayProps;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const { props, display, ...meshProps }: Props = $props();
|
|
18
|
+
const loader = useLoader(TextureLoader);
|
|
19
|
+
let texture: THREE.Texture | undefined = $state();
|
|
20
|
+
|
|
21
|
+
// Load texture when URL changes
|
|
22
|
+
$effect(() => {
|
|
23
|
+
if (!props.url) return;
|
|
24
|
+
|
|
25
|
+
loader
|
|
26
|
+
.load(props.url, {
|
|
27
|
+
transform: (tex) => {
|
|
28
|
+
tex.colorSpace = THREE.SRGBColorSpace;
|
|
29
|
+
return tex;
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
.then((tex) => {
|
|
33
|
+
texture?.dispose();
|
|
34
|
+
texture = tex;
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const material = new THREE.ShaderMaterial({
|
|
39
|
+
uniforms: {
|
|
40
|
+
uTexture: { value: null },
|
|
41
|
+
uResolution: { value: new THREE.Vector2(display.resolution.x, display.resolution.y) },
|
|
42
|
+
uOpacity: { value: props.opacity },
|
|
43
|
+
uFadeStart: { value: props.fadeStart },
|
|
44
|
+
uFadeEnd: { value: props.fadeEnd },
|
|
45
|
+
uScale: { value: props.scale }
|
|
46
|
+
},
|
|
47
|
+
vertexShader,
|
|
48
|
+
fragmentShader,
|
|
49
|
+
transparent: true,
|
|
50
|
+
depthWrite: false,
|
|
51
|
+
depthTest: false
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Update uniforms when props change
|
|
55
|
+
$effect(() => {
|
|
56
|
+
material.uniforms.uTexture.value = texture;
|
|
57
|
+
material.uniforms.uOpacity.value = props.opacity;
|
|
58
|
+
material.uniforms.uFadeStart.value = props.fadeStart;
|
|
59
|
+
material.uniforms.uFadeEnd.value = props.fadeEnd;
|
|
60
|
+
material.uniforms.uScale.value = props.scale;
|
|
61
|
+
});
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<T.Mesh
|
|
65
|
+
name="gridLayer"
|
|
66
|
+
scale={[display.resolution.x, display.resolution.y, 1]}
|
|
67
|
+
layers={[SceneLayer.Overlay]}
|
|
68
|
+
{...meshProps}
|
|
69
|
+
>
|
|
70
|
+
<T.ShaderMaterial is={material} />
|
|
71
|
+
<T.PlaneGeometry />
|
|
72
|
+
</T.Mesh>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Props for the EdgeOverlayLayer component
|
|
3
|
+
*/
|
|
4
|
+
export interface EdgeOverlayProps {
|
|
5
|
+
/**
|
|
6
|
+
* Whether the edge overlay is enabled
|
|
7
|
+
*/
|
|
8
|
+
enabled: boolean;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* URL of the overlay texture
|
|
12
|
+
*/
|
|
13
|
+
url: string | null;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Opacity of the overlay
|
|
17
|
+
*/
|
|
18
|
+
opacity: number;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Texture scale of the overlay
|
|
22
|
+
*/
|
|
23
|
+
scale: number;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Distance from center where fade starts (0-1)
|
|
27
|
+
*/
|
|
28
|
+
fadeStart: number;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Distance from center where fade ends (0-1)
|
|
32
|
+
*/
|
|
33
|
+
fadeEnd: number;
|
|
34
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { T, useTask, type Props as ThrelteProps, useThrelte } from '@threlte/core';
|
|
4
|
+
import type { Size } from '../../types';
|
|
5
|
+
import type { FogLayerProps } from './types';
|
|
6
|
+
import { clippingPlaneStore } from '../../helpers/clippingPlaneStore.svelte';
|
|
7
|
+
|
|
8
|
+
import vertexShader from '../../shaders/default.vert?raw';
|
|
9
|
+
import fragmentShader from '../../shaders/FractalNoise.frag?raw';
|
|
10
|
+
|
|
11
|
+
interface Props extends ThrelteProps<typeof THREE.Mesh> {
|
|
12
|
+
props: FogLayerProps;
|
|
13
|
+
mapSize: Size | null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { props, mapSize, ...meshProps }: Props = $props();
|
|
17
|
+
|
|
18
|
+
const { renderStage } = useThrelte();
|
|
19
|
+
|
|
20
|
+
const aspectRatio = $derived((mapSize?.width ?? 1) / (mapSize?.height ?? 1));
|
|
21
|
+
|
|
22
|
+
const material = new THREE.ShaderMaterial({
|
|
23
|
+
uniforms: {
|
|
24
|
+
uTime: { value: 0.0 },
|
|
25
|
+
uAspectRatio: { value: 1 },
|
|
26
|
+
uFogColor: { value: new THREE.Color(props.color) },
|
|
27
|
+
uOpacity: { value: props.opacity },
|
|
28
|
+
uFogSpeed: { value: props.speed },
|
|
29
|
+
uPersistence: { value: props.persistence },
|
|
30
|
+
uLacunarity: { value: props.lacunarity },
|
|
31
|
+
uFrequency: { value: props.frequency },
|
|
32
|
+
uOffset: { value: props.offset },
|
|
33
|
+
uAmplitude: { value: props.amplitude },
|
|
34
|
+
uLevels: { value: props.levels },
|
|
35
|
+
uClippingPlanes: new THREE.Uniform(
|
|
36
|
+
clippingPlaneStore.value.map((p) => new THREE.Vector4(p.normal.x, p.normal.y, p.normal.z, p.constant))
|
|
37
|
+
)
|
|
38
|
+
},
|
|
39
|
+
vertexShader,
|
|
40
|
+
fragmentShader,
|
|
41
|
+
transparent: true,
|
|
42
|
+
depthWrite: false,
|
|
43
|
+
depthTest: false
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Update uniforms when props change
|
|
47
|
+
$effect(() => {
|
|
48
|
+
material.uniforms.uFogColor.value.set(props.color);
|
|
49
|
+
material.uniforms.uAspectRatio.value = aspectRatio;
|
|
50
|
+
material.uniforms.uOpacity.value = props.opacity;
|
|
51
|
+
material.uniforms.uFogSpeed.value = props.speed;
|
|
52
|
+
material.uniforms.uPersistence.value = props.persistence;
|
|
53
|
+
material.uniforms.uLacunarity.value = props.lacunarity;
|
|
54
|
+
material.uniforms.uFrequency.value = props.frequency;
|
|
55
|
+
material.uniforms.uOffset.value = props.offset;
|
|
56
|
+
material.uniforms.uAmplitude.value = props.amplitude;
|
|
57
|
+
material.uniforms.uLevels.value = props.levels;
|
|
58
|
+
|
|
59
|
+
material.uniforms.uClippingPlanes.value = clippingPlaneStore.value.map(
|
|
60
|
+
(p) => new THREE.Vector4(p.normal.x, p.normal.y, p.normal.z, p.constant)
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
useTask(
|
|
65
|
+
(dt) => {
|
|
66
|
+
material.uniforms.uTime.value += dt;
|
|
67
|
+
},
|
|
68
|
+
{ stage: renderStage }
|
|
69
|
+
);
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<T.Mesh {...meshProps}>
|
|
73
|
+
<T.ShaderMaterial is={material} />
|
|
74
|
+
<T.PlaneGeometry />
|
|
75
|
+
</T.Mesh>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface FogLayerProps {
|
|
2
|
+
/**
|
|
3
|
+
* Whether the fog layer is enabled
|
|
4
|
+
*/
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Color of the fog
|
|
9
|
+
*/
|
|
10
|
+
color: string;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Overall opacity of the fog layer
|
|
14
|
+
*/
|
|
15
|
+
opacity: number;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Speed of fog movement
|
|
19
|
+
*/
|
|
20
|
+
speed: number;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* How quickly the amplitude decreases for each octave
|
|
24
|
+
*/
|
|
25
|
+
persistence: number;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* How quickly the frequency increases for each octave
|
|
29
|
+
*/
|
|
30
|
+
lacunarity: number;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Base frequency of the noise
|
|
34
|
+
*/
|
|
35
|
+
frequency: number;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Vertical offset of the noise
|
|
39
|
+
*/
|
|
40
|
+
offset: number;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Overall amplitude of the noise
|
|
44
|
+
*/
|
|
45
|
+
amplitude: number;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Number of octaves to use
|
|
49
|
+
*/
|
|
50
|
+
levels: number;
|
|
51
|
+
}
|