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 "fl/stdint.h"
16
17#include "fl/math_macros.h" // if needed for MAX/MIN macros
18#include "fl/namespace.h"
19#include "fl/unique_ptr.h"
20#include "fl/warn.h"
22
23#include "fl/grid.h"
24#include "fl/memory.h"
25#include "fl/supersample.h"
26#include "fl/xymap.h"
27#include "fx/fx.h"
28#include "fx/fx2d.h"
29#include "fl/int.h"
30
31namespace fl {
32
34
35// -----------------------------------------------------------------------------
36// New supersampled 1D simulation class.
37//
38// This class mimics the supersampling logic of WaveSimulation2D.
39// The constructor accepts the desired downsampled length and a supersampling
40// multiplier (via a SuperSample enum). Internally, it creates a high-resolution
41// simulation of size (multiplier * length), and its accessor methods average
42// over or replicate across the corresponding block of high-res cells.
44 public:
45 // Constructor:
46 // - length: desired downsampled grid length.
47 // - factor: supersampling multiplier (e.g., 1x, 2x, 4x, or 8x).
48 // Higher values yield better quality but are more cpu intensive.
49 // - speed and dampening are passed on to the internal simulation.
52 float speed = 0.16f, int dampening = 6);
53
54 void init(u32 length, SuperSample factor, float speed, int dampening);
55
57 if (u32(factor) == mMultiplier) {
58 return;
59 }
60 init(mOuterLength, factor, mSim->getSpeed(), mSim->getDampenening());
61 }
62
63 // Only applies to getu8().
64 void setEasingMode(U8EasingFunction mode) { mU8Mode = mode; }
65
66 ~WaveSimulation1D() = default;
67
68 // Delegate methods to the internal simulation.
69 void setSpeed(float speed);
70 void setDampening(int damp);
71 int getDampenening() const;
72 float getSpeed() const;
73
74 // Runs the simulator faster by updating it multiple times.
75 void setExtraFrames(u8 extra);
76
77 // Downsampled getter for the floating point value at index x.
78 // It averages over the corresponding 'multiplier'-sized block in the
79 // high-res simulation.
80 float getf(fl::size x) const;
81
82 // Downsampled getter for the Q15 (fixed point) value at index x.
83 // It averages the multiplier cells of Q15 values.
84 i16 geti16(fl::size x) const;
85 i16 geti16Previous(fl::size x) const;
86
87 bool geti16All(fl::size x, i16 *curr, i16 *prev, i16 *diff) const;
88
89 // Downsampled getters for the 8-bit representations.
90 i8 geti8(fl::size x) const;
91
92 u8 getu8(fl::size x) const;
93
94 // Check if x is within the bounds of the outer (downsampled) simulation.
95 bool has(fl::size x) const;
96
97 // Upsampling setter: set the value at an outer grid cell x by replicating
98 // it to the corresponding multiplier cells in the high-res simulation.
99 void setf(fl::size x, float value);
100
101 void setHalfDuplex(bool on) { mSim->setHalfDuplex(on); }
102
103 // Advance the simulation one time step.
104 void update();
105
106 // Get the outer (downsampled) grid length.
107 u32 getLength() const;
108
110
111 private:
112 u32 mOuterLength; // Length of the downsampled simulation.
114 u32 mMultiplier; // Supersampling multiplier (e.g., 2, 4, or 8).
116 // Internal high-resolution simulation.
118};
119
121 public:
122 // Constructor:
123 // - W and H specify the desired inner grid size of the downsampled
124 // simulation.
125 // - 'factor' selects the supersampling mMultiplier (e.g., 2x, 4x, or 8x).
126 // Higher values yield better quality but are more cpu intensive.
127 // - Internally, the simulation is created with dimensions (factor*W x
128 // factor*H).
129 // - 'speed' and 'dampening' parameters are passed on to the internal
130 // simulation.
131 WaveSimulation2D(u32 W, u32 H,
133 float speed = 0.16f, float dampening = 6.0f);
134
135 void init(u32 width, u32 height, SuperSample factor, float speed,
136 int dampening);
137
138 ~WaveSimulation2D() = default;
139
140 // Delegated simulation methods.
141 void setSpeed(float speed);
142
143 void setExtraFrames(u8 extra);
144
145 void setDampening(int damp);
146
148
149 int getDampenening() const;
150
151 float getSpeed() const;
152
154 if (u32(factor) == mMultiplier) {
155 return;
156 }
157 init(mOuterWidth, mOuterHeight, factor, mSim->getSpeed(),
158 mSim->getDampenening());
159 }
160
161 void setXCylindrical(bool on) { mSim->setXCylindrical(on); }
162
163 // Downsampled getter for the floating point value at (x,y) in the outer
164 // grid. It averages over the corresponding multiplier×multiplier block in
165 // the high-res simulation.
166 float getf(fl::size x, fl::size y) const;
167
168 // Downsampled getter for the Q15 (fixed point) value at (x,y).
169 // It averages the multiplier×multiplier block of Q15 values.
170 i16 geti16(fl::size x, fl::size y) const;
171 i16 geti16Previous(fl::size x, fl::size y) const;
172
173 bool geti16All(fl::size x, fl::size y, i16 *curr, i16 *prev,
174 i16 *diff) const;
175
176 // Downsampled getters for the 8-bit representations.
177 i8 geti8(fl::size x, fl::size y) const;
178
179 // Special function to get the value as a u8 for drawing / gradients.
180 // Ease out functions are applied to this when in half duplex mode.
181 u8 getu8(fl::size x, fl::size y) const;
182
183 // Check if (x,y) is within the bounds of the outer (downsampled) grid.
184 bool has(fl::size x, fl::size y) const;
185
186 // Upsampling setter: set the value at an outer grid cell (x,y) by
187 // replicating it to all cells of the corresponding multiplier×multiplier
188 // block in the high-res simulation.
189 void setf(fl::size x, fl::size y, float value);
190
191 void seti16(fl::size x, fl::size y, i16 value);
192
193 void setHalfDuplex(bool on) { mSim->setHalfDuplex(on); }
194
195 // Advance the simulation one time step.
196 void update();
197
198 // Get the outer grid dimensions.
199 u32 getWidth() const;
200 u32 getHeight() const;
201
203
204 private:
205 u32 mOuterWidth; // Width of the downsampled (outer) grid.
206 u32 mOuterHeight; // Height of the downsampled (outer) grid.
208 u32 mMultiplier = 1; // Supersampling multiplier (e.g., 1, 2, 4, or 8).
210 // Internal high-resolution simulation.
212 fl::Grid<i16> mChangeGrid; // Needed for multiple updates.
213};
214
215} // namespace fl
int y
Definition simple.h:93
int x
Definition simple.h:92
uint16_t speed
Definition Noise.ino:63
WaveSimulation1D_Real & real()
float getf(fl::size x) const
fl::unique_ptr< WaveSimulation1D_Real > mSim
void setEasingMode(U8EasingFunction mode)
~WaveSimulation1D()=default
void setExtraFrames(u8 extra)
i16 geti16Previous(fl::size x) const
void setSpeed(float speed)
U8EasingFunction mU8Mode
void setDampening(int damp)
void setSuperSample(SuperSample factor)
bool geti16All(fl::size x, i16 *curr, i16 *prev, i16 *diff) const
u8 getu8(fl::size x) const
void init(u32 length, SuperSample factor, float speed, int dampening)
WaveSimulation1D(u32 length, SuperSample factor=SuperSample::SUPER_SAMPLE_NONE, float speed=0.16f, int dampening=6)
i8 geti8(fl::size x) const
void setHalfDuplex(bool on)
void setf(fl::size x, float value)
bool has(fl::size x) const
i16 geti16(fl::size x) const
void setSuperSample(SuperSample factor)
i8 geti8(fl::size x, fl::size y) const
WaveSimulation2D(u32 W, u32 H, SuperSample factor=SuperSample::SUPER_SAMPLE_NONE, float speed=0.16f, float dampening=6.0f)
void seti16(fl::size x, fl::size y, i16 value)
i16 geti16(fl::size x, fl::size y) const
fl::Grid< i16 > mChangeGrid
void setExtraFrames(u8 extra)
void setXCylindrical(bool on)
float getf(fl::size x, fl::size y) const
i16 geti16Previous(fl::size x, fl::size y) const
void setSpeed(float speed)
WaveSimulation2D_Real & real()
void setEasingMode(U8EasingFunction mode)
bool geti16All(fl::size x, fl::size y, i16 *curr, i16 *prev, i16 *diff) const
void setf(fl::size x, fl::size y, float value)
bool has(fl::size x, fl::size y) const
U8EasingFunction mU8Mode
void setDampening(int damp)
~WaveSimulation2D()=default
u8 getu8(fl::size x, fl::size y) const
void init(u32 width, u32 height, SuperSample factor, float speed, int dampening)
fl::unique_ptr< WaveSimulation2D_Real > mSim
void setHalfDuplex(bool on)
UISlider length("Length", 1.0f, 0.0f, 1.0f, 0.01f)
UISlider dampening("Dampening", 6.0f, 0.0f, 10.0f, 0.1f)
Implements the FastLED namespace macros.
unsigned char u8
Definition int.h:17
U8EasingFunction
@ WAVE_U8_MODE_LINEAR
@ WAVE_U8_MODE_SQRT
signed char i8
Definition int.h:16
SuperSample
Definition supersample.h:4
@ SUPER_SAMPLE_NONE
Definition supersample.h:5
IMPORTANT!
Definition crgb.h:20