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 int16_t speedBleedof = 25;
109 static constexpr int16_t acceleration = 25;
110 static constexpr uint32_t confortZone = UINT32_MAX / 200000;
111
112 // close to zero, set mostly positive speeds
113 if (position < confortZone)
114 {
115 // bleed off speed to zero
116 if (speed < 0)
117 speed += speedBleedof;
118 else
119 speed = lmpd_constrain<int16_t>(
120 speed + lmpd_map<int16_t>(random8(), 0, 255, 0, acceleration * 2), 0, ctx.state.maxSpeed);
121 }
122 else if (position > (UINT32_MAX - confortZone))
123 {
124 // bleed off speed to zero
125 if (speed > 0)
126 speed -= speedBleedof;
127 else
128 speed = lmpd_constrain<int16_t>(
129 speed + lmpd_map<int16_t>(random8(), 0, 255, -acceleration * 2, 0), -ctx.state.maxSpeed, 0);
130 }
131 else
132 {
133 // free range x speed
134 speed = lmpd_constrain<int16_t>(speed + lmpd_map<int16_t>(random8(), 0, 255, -acceleration, acceleration),
135 -ctx.state.maxSpeed,
136 ctx.state.maxSpeed);
137 // prevent too slow speed
138 if (speed < 0 and speed > -ctx.state.minSpeed)
139 speed = -ctx.state.minSpeed;
140 else if (speed > 0 and speed < ctx.state.minSpeed)
141 speed = ctx.state.minSpeed;
142 }
143
144 return speed;
145 }
146
147 static void loop(auto& ctx)
148 {
149 if (ctx.state.isResetted)
150 {
151 ctx.state.isResetted = false;
152
153 // load animation
154 for (uint32_t i = 0; i <= everyNIndex; ++i)
155 {
156 perlin_display(ctx, i);
157 }
158 return;
159 }
160
161 perlin_display(ctx, ctx.lamp.tick);
162 }
163
164 static void perlin_display(auto& ctx, const uint32_t tick)
165 {
166 auto& state = ctx.state;
167 auto& lamp = ctx.lamp;
168 if (!state.selectedPalette)
169 return;
170
171 // reference to a value buffer
172 static auto noiseBuffer = lamp.template getTempBuffer<bufferIndexToUse>();
173
174 // copy to prevent a ramp update mid animation
175 const colors::PaletteTy palette = *(state.selectedPalette);
176
177 const auto x = state.positionX;
178 const auto y = state.positionY;
179 const auto z = state.positionZ;
180 const auto scale = state.scale;
181
182 const size_t firstIndex = tick % everyNIndex;
183
184 // update noise values
185 for (size_t i = firstIndex; i < lamp.ledCount; i += everyNIndex)
186 {
187 const auto res = modes::strip_to_helix_unconstraint(i);
188 uint16_t data = noise16::inoise(x + scale * res.x, y + scale * res.y, z + scale * res.z);
189
190 // smooth over time to prevent suddent jumps
191 noiseBuffer[i] = data;
192 }
193
194 // apply slow drift to X and Y, just for visual variation.
195 state.positionX += state.speedX;
196 state.positionY += state.speedY;
197 state.positionZ += state.speedZ;
198
199 // vary speed
200 state.speedX = get_next_speed(ctx, state.positionX, state.speedX);
201 state.speedY = get_next_speed(ctx, state.positionY, state.speedY);
202 state.speedZ = get_next_speed(ctx, state.positionZ, state.speedZ);
203
204 for (size_t i = firstIndex; i < lamp.ledCount; i += everyNIndex)
205 {
206 uint16_t index = noiseBuffer[i];
207 uint8_t bri = noiseBuffer[lamp.ledCount - 1 - i] >> 8;
208
209 // if this palette is a 'loop', add a slowly-changing base value
210 index += state.ihue;
211
212 // brighten up, as the color palette itself often contains the
213 // light/dark dynamic range desired
214 if (bri > 127)
215 {
216 bri = 255;
217 }
218 else
219 {
220 bri = dim8_raw(bri * 2);
221 }
222
223 lamp.setPixelColor(i, colors::from_palette(index, palette, bri));
224 }
225
226 state.ihue += 1;
227 }
228};
229
230} // namespace lampda::modes::default_modes
231
232#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