FastLED 3.9.15
Loading...
Searching...
No Matches
wave_simulation.h
Go to the documentation of this file.
1/*
2This is the WaveSimulation API. These classes allow flexible super sampling
3to achieve much better visual quality. They will also run the simulator
4update multiple times in order to achieve consistent speed between super
5sampling factors.
6
7A super sampling value of 2x will give the best results for the CPU consumption
8as most artifacts will be averaged out at this resolution.
9
10Based on works and code by Shawn Silverman.
11*/
12
13#pragma once
14
15#include <stdint.h>
16
17#include "fl/math_macros.h" // if needed for MAX/MIN macros
18#include "fl/namespace.h"
19#include "fl/scoped_ptr.h"
20#include "fl/warn.h"
22
23#include "fl/ptr.h"
24#include "fl/supersample.h"
25#include "fl/xymap.h"
26#include "fx/fx.h"
27#include "fx/fx2d.h"
28
29namespace fl {
30
35
36// -----------------------------------------------------------------------------
37// New supersampled 1D simulation class.
38//
39// This class mimics the supersampling logic of WaveSimulation2D.
40// The constructor accepts the desired downsampled length and a supersampling
41// multiplier (via a SuperSample enum). Internally, it creates a high-resolution
42// simulation of size (multiplier * length), and its accessor methods average
43// over or replicate across the corresponding block of high-res cells.
45 public:
46 // Constructor:
47 // - length: desired downsampled grid length.
48 // - factor: supersampling multiplier (e.g., 1x, 2x, 4x, or 8x).
49 // Higher values yield better quality but are more cpu intensive.
50 // - speed and dampening are passed on to the internal simulation.
51 WaveSimulation1D(uint32_t length,
53 float speed = 0.16f, int dampening = 6);
54
55 void init(uint32_t length, SuperSample factor, float speed, int dampening);
56
58 if (uint32_t(factor) == multiplier) {
59 return;
60 }
61 init(outerLength, factor, sim->getSpeed(), sim->getDampenening());
62 }
63
64 // Only applies to getu8().
65 void setEasingMode(U8EasingFunction mode) { mU8Mode = mode; }
66
67 ~WaveSimulation1D() = default;
68
69 // Delegate methods to the internal simulation.
70 void setSpeed(float speed);
71 void setDampening(int damp);
72 int getDampenening() const;
73 float getSpeed() const;
74
75 // Runs the simulator faster by updating it multiple times.
76 void setExtraFrames(uint8_t extra);
77
78 // Downsampled getter for the floating point value at index x.
79 // It averages over the corresponding 'multiplier'-sized block in the
80 // high-res simulation.
81 float getf(size_t x) const;
82
83 // Downsampled getter for the Q15 (fixed point) value at index x.
84 // It averages the multiplier cells of Q15 values.
85 int16_t geti16(size_t x) const;
86 int16_t geti16Previous(size_t x) const;
87
88 bool geti16All(size_t x, int16_t *curr, int16_t *prev, int16_t *diff) const;
89
90 // Downsampled getters for the 8-bit representations.
91 int8_t geti8(size_t x) const;
92
93 uint8_t getu8(size_t x) const;
94
95 // Check if x is within the bounds of the outer (downsampled) simulation.
96 bool has(size_t x) const;
97
98 // Upsampling setter: set the value at an outer grid cell x by replicating
99 // it to the corresponding multiplier cells in the high-res simulation.
100 void setf(size_t x, float value);
101
102
103 void setHalfDuplex(bool on) {
104 sim->setHalfDuplex(on);
105 }
106
107 // Advance the simulation one time step.
108 void update();
109
110 // Get the outer (downsampled) grid length.
111 uint32_t getLength() const;
112
114
115 private:
116 uint32_t outerLength; // Length of the downsampled simulation.
117 uint8_t extraFrames = 0;
118 uint32_t multiplier; // Supersampling multiplier (e.g., 2, 4, or 8).
120 // Internal high-resolution simulation.
122};
123
125 public:
126 // Constructor:
127 // - W and H specify the desired inner grid size of the downsampled
128 // simulation.
129 // - 'factor' selects the supersampling multiplier (e.g., 2x, 4x, or 8x).
130 // Higher values yield better quality but are more cpu intensive.
131 // - Internally, the simulation is created with dimensions (factor*W x
132 // factor*H).
133 // - 'speed' and 'dampening' parameters are passed on to the internal
134 // simulation.
135 WaveSimulation2D(uint32_t W, uint32_t H,
137 float speed = 0.16f, float dampening = 6.0f);
138
139 void init(uint32_t width, uint32_t height, SuperSample factor, float speed, int dampening);
140
141 ~WaveSimulation2D() = default;
142
143 // Delegated simulation methods.
144 void setSpeed(float speed);
145
146 void setExtraFrames(uint8_t extra);
147
148 void setDampening(int damp);
149
151
152 int getDampenening() const;
153
154 float getSpeed() const;
155
157 if (uint32_t(factor) == multiplier) {
158 return;
159 }
160 init(outerWidth, outerHeight, factor, sim->getSpeed(),
161 sim->getDampenening());
162 }
163
164 // Downsampled getter for the floating point value at (x,y) in the outer
165 // grid. It averages over the corresponding multiplier×multiplier block in
166 // the high-res simulation.
167 float getf(size_t x, size_t y) const;
168
169 // Downsampled getter for the Q15 (fixed point) value at (x,y).
170 // It averages the multiplier×multiplier block of Q15 values.
171 int16_t geti16(size_t x, size_t y) const;
172 int16_t geti16Previous(size_t x, size_t y) const;
173
174 bool geti16All(size_t x, size_t y, int16_t *curr, int16_t *prev,
175 int16_t *diff) const;
176
177 // Downsampled getters for the 8-bit representations.
178 int8_t geti8(size_t x, size_t y) const;
179
180 // Special function to get the value as a uint8_t for drawing / gradients.
181 // Ease out functions are applied to this when in half duplex mode.
182 uint8_t getu8(size_t x, size_t y) const;
183
184 // Check if (x,y) is within the bounds of the outer (downsampled) grid.
185 bool has(size_t x, size_t y) const;
186
187 // Upsampling setter: set the value at an outer grid cell (x,y) by
188 // replicating it to all cells of the corresponding multiplier×multiplier
189 // block in the high-res simulation.
190 void setf(size_t x, size_t y, float value);
191
192 void seti16(size_t x, size_t y, int16_t value);
193
194 void setHalfDuplex(bool on) {
195 sim->setHalfDuplex(on);
196 }
197
198 // Advance the simulation one time step.
199 void update();
200
201 // Get the outer grid dimensions.
202 uint32_t getWidth() const;
203 uint32_t getHeight() const;
204
206
207 private:
208 uint32_t outerWidth; // Width of the downsampled (outer) grid.
209 uint32_t outerHeight; // Height of the downsampled (outer) grid.
210 uint8_t extraFrames = 0;
211 uint32_t multiplier; // Supersampling multiplier (e.g., 2, 4, or 8).
213 // Internal high-resolution simulation.
215};
216
217} // namespace fl
uint32_t x[NUM_LAYERS]
Definition Fire2023.ino:80
uint32_t y[NUM_LAYERS]
Definition Fire2023.ino:81
uint16_t speed
Definition Noise.ino:63
UISlider dampening("Dampening", 6.0f, 0.0f, 10.0f, 0.1f)
void setf(size_t x, float value)
WaveSimulation1D_Real & real()
void init(uint32_t length, SuperSample factor, float speed, int dampening)
void setEasingMode(U8EasingFunction mode)
WaveSimulation1D(uint32_t length, SuperSample factor=SuperSample::SUPER_SAMPLE_NONE, float speed=0.16f, int dampening=6)
int8_t geti8(size_t x) const
int16_t geti16(size_t x) const
bool has(size_t x) const
float getf(size_t x) const
~WaveSimulation1D()=default
void setSpeed(float speed)
U8EasingFunction mU8Mode
void setDampening(int damp)
void setSuperSample(SuperSample factor)
void setExtraFrames(uint8_t extra)
uint8_t getu8(size_t x) const
fl::scoped_ptr< WaveSimulation1D_Real > sim
int16_t geti16Previous(size_t x) const
bool geti16All(size_t x, int16_t *curr, int16_t *prev, int16_t *diff) const
uint32_t getLength() const
void setHalfDuplex(bool on)
void setSuperSample(SuperSample factor)
int16_t geti16(size_t x, size_t y) const
uint32_t getWidth() const
void init(uint32_t width, uint32_t height, SuperSample factor, float speed, int dampening)
void setExtraFrames(uint8_t extra)
uint32_t getHeight() const
int8_t geti8(size_t x, size_t y) const
void setSpeed(float speed)
WaveSimulation2D_Real & real()
void setEasingMode(U8EasingFunction mode)
bool geti16All(size_t x, size_t y, int16_t *curr, int16_t *prev, int16_t *diff) const
float getf(size_t x, size_t y) const
uint8_t getu8(size_t x, size_t y) const
void seti16(size_t x, size_t y, int16_t value)
fl::scoped_ptr< WaveSimulation2D_Real > sim
void setf(size_t x, size_t y, float value)
U8EasingFunction mU8Mode
bool has(size_t x, size_t y) const
void setDampening(int damp)
~WaveSimulation2D()=default
WaveSimulation2D(uint32_t W, uint32_t H, SuperSample factor=SuperSample::SUPER_SAMPLE_NONE, float speed=0.16f, float dampening=6.0f)
int16_t geti16Previous(size_t x, size_t y) const
void setHalfDuplex(bool on)
Implements the FastLED namespace macros.
U8EasingFunction
@ WAVE_U8_MODE_LINEAR
@ WAVE_U8_MODE_SQRT
SuperSample
Definition supersample.h:4
@ SUPER_SAMPLE_NONE
Definition supersample.h:5
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16