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 uint8_t get_custom_ramp_default_value(auto& ctx)
65 {
66 // start at rainbow palette
67 return 0;
68 }
69
70 static void on_enter_mode(auto& ctx)
71 {
72 ctx.state.isResetted = true;
73
74 ctx.state.positionX = UINT32_MAX / 2 + random16() / 2;
75 ctx.state.positionY = UINT32_MAX / 2 + random16() / 2;
76 ctx.state.positionZ = UINT32_MAX / 2 + random16() / 2;
77
78 ctx.state.speedX = random8();
79 ctx.state.speedY = random8();
80 ctx.state.speedZ = random8();
81 ctx.state.scale = 600;
82
83 ctx.state.ihue = 0;
84
85 ctx.template set_config_bool<ConfigKeys::rampSaturates>(false);
86 // this ramps should be slow
87 ctx.template set_config_u32<ConfigKeys::customRampStepSpeedMs>(ctx.state.maxPalettesCount / 255.0f * 850);
88
89 ctx.lamp.template fillTempBuffer<bufferIndexToUse>(0);
90
91 custom_ramp_update(ctx, ctx.get_active_custom_ramp());
92 }
93
95 static void custom_ramp_update(auto& ctx, uint8_t rampValue)
96 {
97 auto& state = ctx.state;
98
99 const uint8_t rampIndex =
100 std::min<float>(floorf(rampValue / 255.0f * state.maxPalettesCount), state.maxPalettesCount - 1.0f);
101 state.selectedPalette = state._palettes[rampIndex];
102 }
103
112 static int16_t get_next_speed(auto& ctx, const uint32_t position, int16_t speed)
113 {
114 static constexpr float speedDivider = ctx.lamp.frameDurationMs / 25.0f;
115 static constexpr int16_t speedBleedof = 25 * speedDivider;
116 static constexpr int16_t acceleration = 25 * speedDivider;
117 static constexpr uint16_t maxSpeed = ctx.state.maxSpeed * speedDivider;
118 static constexpr uint16_t minSpeed = ctx.state.minSpeed * speedDivider;
119
120 static constexpr uint32_t confortZone = UINT32_MAX / 200000;
121
122 // close to zero, set mostly positive speeds
123 if (position < confortZone)
124 {
125 // bleed off speed to zero
126 if (speed < 0)
127 speed += speedBleedof;
128 else
129 speed = lmpd_constrain<int16_t>(speed + lmpd_map<int16_t>(random8(), 0, 255, 0, acceleration * 2), 0, maxSpeed);
130 }
131 else if (position > (UINT32_MAX - confortZone))
132 {
133 // bleed off speed to zero
134 if (speed > 0)
135 speed -= speedBleedof;
136 else
137 speed = lmpd_constrain<int16_t>(
138 speed + lmpd_map<int16_t>(random8(), 0, 255, -acceleration * 2, 0), -maxSpeed, 0);
139 }
140 else
141 {
142 // free range x speed
143 speed = lmpd_constrain<int16_t>(
144 speed + lmpd_map<int16_t>(random8(), 0, 255, -acceleration, acceleration), -maxSpeed, maxSpeed);
145 // prevent too slow speed
146 if (speed < 0 and speed > -minSpeed)
147 speed = -minSpeed;
148 else if (speed > 0 and speed < minSpeed)
149 speed = minSpeed;
150 }
151
152 return speed;
153 }
154
155 static void loop(auto& ctx)
156 {
157 if (ctx.state.isResetted)
158 {
159 ctx.state.isResetted = false;
160
161 // load animation
162 for (uint32_t i = 0; i <= everyNIndex; ++i)
163 {
164 perlin_display(ctx, i);
165 }
166 return;
167 }
168
169 perlin_display(ctx, ctx.lamp.tick);
170 }
171
172 static void perlin_display(auto& ctx, const uint32_t tick)
173 {
174 auto& state = ctx.state;
175 auto& lamp = ctx.lamp;
176 if (!state.selectedPalette)
177 return;
178
179 // reference to a value buffer
180 static auto noiseBuffer = lamp.template getTempBuffer<bufferIndexToUse>();
181
182 // copy to prevent a ramp update mid animation
183 const colors::PaletteTy palette = *(state.selectedPalette);
184
185 const auto x = state.positionX;
186 const auto y = state.positionY;
187 const auto z = state.positionZ;
188 const auto scale = state.scale;
189
190 const size_t firstIndex = tick % everyNIndex;
191
192 // update noise values
193 for (size_t i = firstIndex; i < lamp.ledCount; i += everyNIndex)
194 {
195 const auto res = modes::strip_to_helix_unconstraint(i);
196 uint16_t data = noise16::inoise(x + scale * res.x, y + scale * res.y, z + scale * res.z);
197
198 // smooth over time to prevent suddent jumps
199 noiseBuffer[i] = data;
200 }
201
202 // apply slow drift to X and Y, just for visual variation.
203 state.positionX += state.speedX;
204 state.positionY += state.speedY;
205 state.positionZ += state.speedZ;
206
207 // vary speed
208 state.speedX = get_next_speed(ctx, state.positionX, state.speedX);
209 state.speedY = get_next_speed(ctx, state.positionY, state.speedY);
210 state.speedZ = get_next_speed(ctx, state.positionZ, state.speedZ);
211
212 for (size_t i = firstIndex; i < lamp.ledCount; i += everyNIndex)
213 {
214 uint16_t index = noiseBuffer[i];
215 uint8_t bri = noiseBuffer[lamp.ledCount - 1 - i] >> 8;
216
217 // if this palette is a 'loop', add a slowly-changing base value
218 index += state.ihue;
219
220 // brighten up, as the color palette itself often contains the
221 // light/dark dynamic range desired
222 if (bri > 127)
223 {
224 bri = 255;
225 }
226 else
227 {
228 bri = dim8_raw(bri * 2);
229 }
230
231 lamp.setPixelColor(i, colors::from_palette(index, palette, bri));
232 }
233
234 state.ihue += 1;
235 }
236};
237
238} // namespace lampda::modes::default_modes
239
240#endif
static constexpr uint32_t from_palette(const UIntTy index, const PaletteTy &palette, const 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:1182
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:95
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:112
void LMBD_INLINE setPixelColor(uint16_t n, uint32_t color)
(indexable) Set the n-th LED color
Definition: lamp_type.hpp:878
static constexpr uint16_t ledCount
(indexable) Count of indexable LEDs on the lamp
Definition: lamp_type.hpp:357