Lamp-Da 0.1
A compact lantern project
Loading...
Searching...
No Matches
perlin_noise.hpp
Go to the documentation of this file.
1#ifndef PERLIN_NOISE_MODE_H
2#define PERLIN_NOISE_MODE_H
3
5
6#include "src/system/ext/math8.h"
7#include "src/system/ext/noise.h"
8#include "src/system/ext/random8.h"
9
11#include <cstdint>
12#include <cstdlib>
13
16
21{
23 static constexpr bool hasCustomRamp = true;
24
26 static constexpr uint8_t bufferIndexToUse = 0;
27
28 // this is too heavy to run at full, speed, display every other pixels instead of refreshing amm
29 static constexpr uint32_t everyNIndex = 2;
30
31 struct StateTy
32 {
33 uint32_t positionX;
34 uint32_t positionY;
35 uint32_t positionZ;
36
37 int16_t speedX;
38 int16_t speedY;
39 int16_t speedZ;
41 static constexpr uint16_t minSpeed = 25;
43 static constexpr uint16_t maxSpeed = 400;
45 uint16_t scale;
47 uint16_t ihue;
48
50 static constexpr uint8_t maxPalettesCount = 4;
56
59
60 // flag that we have just been reseted
61 bool isResetted = false;
62 };
63
64 static void on_enter_mode(auto& ctx)
65 {
66 ctx.state.isResetted = true;
67
68 ctx.state.positionX = UINT32_MAX / 2 + random16() / 2;
69 ctx.state.positionY = UINT32_MAX / 2 + random16() / 2;
70 ctx.state.positionZ = UINT32_MAX / 2 + random16() / 2;
71
72 ctx.state.speedX = random8();
73 ctx.state.speedY = random8();
74 ctx.state.speedZ = random8();
75 ctx.state.scale = 600;
76
77 ctx.state.ihue = 0;
78
79 ctx.template set_config_bool<ConfigKeys::rampSaturates>(false);
80 // this ramps should be slow
81 ctx.template set_config_u32<ConfigKeys::customRampStepSpeedMs>(ctx.state.maxPalettesCount / 255.0f * 850);
82
83 ctx.lamp.template fillTempBuffer<bufferIndexToUse>(0);
84
85 custom_ramp_update(ctx, ctx.get_active_custom_ramp());
86 }
87
89 static void custom_ramp_update(auto& ctx, uint8_t rampValue)
90 {
91 auto& state = ctx.state;
92
93 const uint8_t rampIndex =
94 std::min<float>(floorf(rampValue / 255.0f * state.maxPalettesCount), state.maxPalettesCount - 1.0f);
95 state.selectedPalette = state._palettes[rampIndex];
96 }
97
106 static int16_t get_next_speed(auto& ctx, const uint32_t position, int16_t speed)
107 {
108 static constexpr float speedDivider = ctx.lamp.frameDurationMs / 25.0f;
109 static constexpr int16_t speedBleedof = 25 * speedDivider;
110 static constexpr int16_t acceleration = 25 * speedDivider;
111 static constexpr uint16_t maxSpeed = ctx.state.maxSpeed * speedDivider;
112 static constexpr uint16_t minSpeed = ctx.state.minSpeed * speedDivider;
113
114 static constexpr uint32_t confortZone = UINT32_MAX / 200000;
115
116 // close to zero, set mostly positive speeds
117 if (position < confortZone)
118 {
119 // bleed off speed to zero
120 if (speed < 0)
121 speed += speedBleedof;
122 else
123 speed = lmpd_constrain<int16_t>(speed + lmpd_map<int16_t>(random8(), 0, 255, 0, acceleration * 2), 0, maxSpeed);
124 }
125 else if (position > (UINT32_MAX - confortZone))
126 {
127 // bleed off speed to zero
128 if (speed > 0)
129 speed -= speedBleedof;
130 else
131 speed = lmpd_constrain<int16_t>(
132 speed + lmpd_map<int16_t>(random8(), 0, 255, -acceleration * 2, 0), -maxSpeed, 0);
133 }
134 else
135 {
136 // free range x speed
137 speed = lmpd_constrain<int16_t>(
138 speed + lmpd_map<int16_t>(random8(), 0, 255, -acceleration, acceleration), -maxSpeed, maxSpeed);
139 // prevent too slow speed
140 if (speed < 0 and speed > -minSpeed)
141 speed = -minSpeed;
142 else if (speed > 0 and speed < minSpeed)
143 speed = minSpeed;
144 }
145
146 return speed;
147 }
148
149 static void loop(auto& ctx)
150 {
151 if (ctx.state.isResetted)
152 {
153 ctx.state.isResetted = false;
154
155 // load animation
156 for (uint32_t i = 0; i <= everyNIndex; ++i)
157 {
158 perlin_display(ctx, i);
159 }
160 return;
161 }
162
163 perlin_display(ctx, ctx.lamp.tick);
164 }
165
166 static void perlin_display(auto& ctx, const uint32_t tick)
167 {
168 auto& state = ctx.state;
169 auto& lamp = ctx.lamp;
170 if (!state.selectedPalette)
171 return;
172
173 // reference to a value buffer
174 static auto noiseBuffer = lamp.template getTempBuffer<bufferIndexToUse>();
175
176 // copy to prevent a ramp update mid animation
177 const colors::PaletteTy palette = *(state.selectedPalette);
178
179 const auto x = state.positionX;
180 const auto y = state.positionY;
181 const auto z = state.positionZ;
182 const auto scale = state.scale;
183
184 const size_t firstIndex = tick % everyNIndex;
185
186 // update noise values
187 for (size_t i = firstIndex; i < lamp.ledCount; i += everyNIndex)
188 {
189 const auto res = modes::strip_to_helix_unconstraint(i);
190 uint16_t data = noise16::inoise(x + scale * res.x, y + scale * res.y, z + scale * res.z);
191
192 // smooth over time to prevent suddent jumps
193 noiseBuffer[i] = data;
194 }
195
196 // apply slow drift to X and Y, just for visual variation.
197 state.positionX += state.speedX;
198 state.positionY += state.speedY;
199 state.positionZ += state.speedZ;
200
201 // vary speed
202 state.speedX = get_next_speed(ctx, state.positionX, state.speedX);
203 state.speedY = get_next_speed(ctx, state.positionY, state.speedY);
204 state.speedZ = get_next_speed(ctx, state.positionZ, state.speedZ);
205
206 for (size_t i = firstIndex; i < lamp.ledCount; i += everyNIndex)
207 {
208 uint16_t index = noiseBuffer[i];
209 uint8_t bri = noiseBuffer[lamp.ledCount - 1 - i] >> 8;
210
211 // if this palette is a 'loop', add a slowly-changing base value
212 index += state.ihue;
213
214 // brighten up, as the color palette itself often contains the
215 // light/dark dynamic range desired
216 if (bri > 127)
217 {
218 bri = 255;
219 }
220 else
221 {
222 bri = dim8_raw(bri * 2);
223 }
224
225 lamp.setPixelColor(i, colors::from_palette(index, palette, bri));
226 }
227
228 state.ihue += 1;
229 }
230};
231
232} // namespace lampda::modes::default_modes
233
234#endif
static constexpr uint32_t from_palette(UIntTy index, const PaletteTy &palette, uint8_t brightness=255)
Return a color from a palette.
Definition: palettes.hpp:504
static constexpr PaletteTy PaletteOceanColors
Ocean colors, blues and whites.
Definition: palettes.hpp:306
static constexpr PaletteTy PaletteLavaColors
Lava color palette.
Definition: palettes.hpp:270
std::array< uint32_t, 16 > PaletteTy
Palette types.
Definition: palettes.hpp:18
static constexpr PaletteTy PaletteForestColors
Forest colors, greens.
Definition: palettes.hpp:342
static constexpr PaletteTy PaletteRainbowColors
HSV Rainbow.
Definition: palettes.hpp:360
Basic "default" modes included with the hardware.
Definition: aurora.hpp:12
static constexpr HelixXYZTy strip_to_helix_unconstraint(const int16_t n)
convert strip index to 3D coordinates, without checks on led index. This allows to use 3D coordinates...
Definition: lamp_type.hpp:1178
GlobalSimStateTy state
Store the global simulation state.
Definition: simulator_state.cpp:7
Define some useful color palettes, and tools to use them.
Parent object for all custom user modes.
Definition: mode_type.hpp:53
static constexpr uint8_t maxPalettesCount
count of palette used
Definition: perlin_noise.hpp:50
colors::PaletteTy const * selectedPalette
store selected palette
Definition: perlin_noise.hpp:58
uint32_t positionX
position of the noise in X
Definition: perlin_noise.hpp:33
uint16_t ihue
Color grading.
Definition: perlin_noise.hpp:47
uint32_t positionY
position of the noise in X
Definition: perlin_noise.hpp:34
int16_t speedY
Speed of the noise in Y.
Definition: perlin_noise.hpp:38
uint32_t positionZ
position of the noise in X
Definition: perlin_noise.hpp:35
const colors::PaletteTy * _palettes[maxPalettesCount]
store references to palettes
Definition: perlin_noise.hpp:52
uint16_t scale
Scale of the noise.
Definition: perlin_noise.hpp:45
static constexpr uint16_t maxSpeed
Maximal speed of movement.
Definition: perlin_noise.hpp:43
int16_t speedX
Speed of the noise in X.
Definition: perlin_noise.hpp:37
int16_t speedZ
Speed of the noise in Z Minimal speed of movement.
Definition: perlin_noise.hpp:39
3D perlin noise on the lamp surface.
Definition: perlin_noise.hpp:21
static constexpr uint8_t bufferIndexToUse
index of the buffer used in this mode
Definition: perlin_noise.hpp:26
static void custom_ramp_update(auto &ctx, uint8_t rampValue)
User ramp changes the color palette.
Definition: perlin_noise.hpp:89
static constexpr bool hasCustomRamp
hint manager to save our custom ramp
Definition: perlin_noise.hpp:23
static int16_t get_next_speed(auto &ctx, const uint32_t position, int16_t speed)
compute the next speed from the current parameters. This function prevent overflow by controling the ...
Definition: perlin_noise.hpp:106
void LMBD_INLINE setPixelColor(uint16_t n, uint32_t color)
(indexable) Set the n-th LED color
Definition: lamp_type.hpp:874
static constexpr uint16_t ledCount
(indexable) Count of indexable LEDs on the lamp
Definition: lamp_type.hpp:353