62 for (
int i = 0; i < 256; i++)
65 for (
int i = 255; i > 0; i--) {
66 s = s * 1664525u + 1013904223u;
67 int j = (int)((s >> 16) % (u32)(i + 1));
72 for (
int i = 0; i < 256; i++) {
79 int xi = ((int)
floorf(
x)) & 255;
80 int yi = ((int)
floorf(
y)) & 255;
88 int bb =
perm[
perm[xi + 1] + yi + 1];
89 float x1 =
lerp(
grad(aa, xf, yf),
grad(ba, xf - 1.0f, yf), u);
90 float x2 =
lerp(
grad(ab, xf, yf - 1.0f),
91 grad(bb, xf - 1.0f, yf - 1.0f), u);
92 return lerp(x1, x2, v);
139 return r < 0.0f ? r + m : r;
143 return (v < lo) ? lo : (v > hi) ? hi : v;
167 float rad = diam * 0.5f;
172 for (
int y = y0;
y <= y1;
y++) {
173 for (
int x = x0;
x <= x1;
x++) {
174 float dx = (
x + 0.5f) - cx;
175 float dy = (
y + 0.5f) - cy;
176 float dist =
sqrtf(dx * dx + dy * dy);
177 float cov =
clampf(rad + 0.5f - dist, 0.0f, 1.0f);
180 float inv = 1.0f - cov;
182 mR[i] =
mR[i] * inv + cr * cov;
183 mG[i] =
mG[i] * inv + cg * cov;
184 mB[i] =
mB[i] * inv + cb * cov;
196 float invSteps = 1.0f / (float)
steps;
198 for (
int i = 0; i <=
steps; i++) {
199 float u = i * invSteps;
200 float px = x0 + dx * u;
201 float py = y0 + dy * u;
210 (1.0f - fx) * (1.0f - fy),
215 int offX[4] = {0, 1, 0, 1};
216 int offY[4] = {0, 0, 1, 1};
218 for (
int j = 0; j < 4; j++) {
219 int cx = ix + offX[j];
220 int cy = iy + offY[j];
221 if (cx < 0 || cx >= w || cy < 0 || cy >= h)
223 float wt = weights[j];
226 int gi =
idx(cy, cx);
227 float inv = 1.0f - wt;
228 mR[gi] =
mR[gi] * inv + c.r * wt;
229 mG[gi] =
mG[gi] * inv + c.g * wt;
230 mB[gi] =
mB[gi] * inv + c.b * wt;
238 float cx = (w - 1) * 0.5f;
239 float cy = (h - 1) * 0.5f;
240 float s =
mParams.endpoint_speed;
243 float x1 = cx + cx * 0.742f *
sinf(
t * s * 1.13f + 0.20f);
244 float y1 = cy + cy * 0.677f *
sinf(
t * s * 1.71f + 1.30f);
245 float x2 = cx + cx * 0.774f *
sinf(
t * s * 1.89f + 2.20f);
246 float y2 = cy + cy * 0.710f *
sinf(
t * s * 1.37f + 0.70f);
252 float discDiam = 1.7f;
253 drawDot(x1, y1, discDiam, endA.r, endA.g, endA.b);
254 drawDot(x2, y2, discDiam, endB.r, endB.g, endB.b);
263 float ocx = w * 0.5f - 0.5f;
264 float ocy = h * 0.5f - 0.5f;
265 float orad = minDim * 0.35f;
266 float base =
t * 3.0f;
267 float dotDiam = 1.5f;
268 for (
int i = 0; i < n; i++) {
269 float a = base + i * (2.0f *
FL_PI / fn);
270 float cx = ocx +
cosf(a) * orad;
271 float cy = ocy +
sinf(a) * orad;
273 drawDot(cx, cy, dotDiam, c.r, c.g, c.b);
280 const float kBaseFreq = 0.23f;
282 for (
int i = 0; i < w; i++) {
289 if (
mParams.reverse_x_profile) {
290 for (
int i = 0; i < w / 2; i++) {
297 for (
int i = 0; i < h; i++) {
305 for (
int i = 0; i < w; i++) {
308 for (
int i = 0; i < h; i++) {
317 float fade =
powf(0.5f, dt / halfLife);
318 float shift =
mParams.flow_shift;
321 for (
int y = 0;
y < h;
y++) {
323 for (
int x = 0;
x < w;
x++) {
324 float sx =
fmodPos((
float)
x - sh, (
float)w);
325 int ix0 = (int)
floorf(sx) % w;
326 int ix1 = (ix0 + 1) % w;
327 float f = sx -
floorf(sx);
328 float inv = 1.0f - f;
329 int src0 =
idx(
y, ix0);
330 int src1 =
idx(
y, ix1);
332 mTR[dst] =
mR[src0] * inv +
mR[src1] * f;
333 mTG[dst] =
mG[src0] * inv +
mG[src1] * f;
334 mTB[dst] =
mB[src0] * inv +
mB[src1] * f;
339 for (
int x = 0;
x < w;
x++) {
341 for (
int y = 0;
y < h;
y++) {
342 float sy =
fmodPos((
float)
y - sh, (
float)h);
343 int iy0 = (int)
floorf(sy) % h;
344 int iy1 = (iy0 + 1) % h;
345 float f = sy -
floorf(sy);
346 float inv = 1.0f - f;
347 int src0 =
idx(iy0,
x);
348 int src1 =
idx(iy1,
x);
362 auto plotTile = [&](
const CRGB &color,
float px,
float py,
366 float fx = px - (float)ix;
367 float fy = py - (float)iy;
372 tile.at(0, 0) = (
u8)((1.0f - fy) * 255.0f);
374 tile.at(0, 1) = (
u8)(fy * 255.0f);
378 tile.at(0, 0) = (
u8)((1.0f - fx) * 255.0f);
379 tile.at(1, 0) = (
u8)(fx * 255.0f);
387 constexpr float amp = 0.3f;
391 CRGB xColor(0, 255, 255);
392 float centerY = (float)(h - 1) * 0.5f;
394 for (
int x = 0;
x < w;
x++) {
396 float py = centerY - val * amp * centerY;
397 plotTile(xColor, (
float)
x, py,
true);
399 float dy = py - prevPy;
400 int gap = (int)
fabsf(dy);
401 for (
int s = 1; s < gap; s++) {
402 float t = (float)s / (
float)gap;
403 float midY = prevPy + dy *
t;
404 float midX = (float)(
x - 1) +
t;
405 plotTile(xColor, midX, midY,
true);
413 CRGB yColor(255, 255, 0);
414 float centerX = (float)(w - 1) * 0.5f;
416 for (
int y = 0;
y < h;
y++) {
418 float px = centerX + val * amp * centerX;
419 plotTile(yColor, px, (
float)
y,
false);
421 float dx = px - prevPx;
422 int gap = (int)
fabsf(dx);
423 for (
int s = 1; s < gap; s++) {
424 float t = (float)s / (
float)gap;
425 float midX = prevPx + dx *
t;
426 float midY = (float)(
y - 1) +
t;
427 plotTile(yColor, midX, midY,
false);
435 float dt = dt_ms * 0.001f;
436 float t = t_ms * 0.001f;
439 switch (
mParams.emitter_mode) {
458 for (
int y = 0;
y < h;
y++) {
459 for (
int x = 0;
x < w;
x++) {
460 int ledIdx =
mXyMap.mapToIndex(
x,
y);
468 if (
mParams.show_flow_vectors) {
492 for (
int i = 0; i < 256; i++)
495 for (
int i = 255; i > 0; i--) {
496 s = s * 1664525u + 1013904223u;
497 int j = (int)((s >> 16) % (u32)(i + 1));
517 if (!
mState.fade_lut_initialized) {
519 mState.fade_lut_initialized =
true;
538 return (v < lo) ? lo : (v > hi) ? hi : v;
542 i32 integer = v >> 16;
543 if (integer < 0)
return 0;
544 if (integer > 255)
return 255;
549 constexpr s16x16 one(1.0f);
550 constexpr s16x16 fp_255(255.0f);
557 u8 hue_u8 = (
u8)hue_int;
558 CHSV hsv(hue_u8, 255, 255);
572 constexpr s16x16 half(0.5f);
573 constexpr s16x16 one(1.0f);
581 s16x16 rad_plus_half = rad + half;
583 i32 threshold_sq_raw = (rad_plus_half * rad_plus_half).raw();
584 i32 cr_raw =
static_cast<i32
>(cr) << 16;
585 i32 cg_raw =
static_cast<i32
>(cg) << 16;
586 i32 cb_raw =
static_cast<i32
>(cb) << 16;
587 i32 *__restrict__ rp =
mState.r.data();
588 i32 *__restrict__ gp =
mState.g.data();
589 i32 *__restrict__ bp =
mState.b.data();
591 for (
int y = y0;
y <= y1;
y++) {
593 i32 dy_sq_raw = (dy * dy).raw();
595 if (dy_sq_raw >= threshold_sq_raw)
continue;
596 int row_base =
y * w;
597 for (
int x = x0;
x <= x1;
x++) {
599 i32 dist_sq_raw = dy_sq_raw + (dx * dx).raw();
600 if (dist_sq_raw >= threshold_sq_raw)
604 if (cov.
raw() <= 0)
continue;
605 int i = row_base +
x;
607 i32 cov_q16 = cov.
raw();
608 rp[i] +=
static_cast<i32
>((
static_cast<i64>(cr_raw - rp[i]) * cov_q16) >> 16);
609 gp[i] +=
static_cast<i32
>((
static_cast<i64>(cg_raw - gp[i]) * cov_q16) >> 16);
610 bp[i] +=
static_cast<i32
>((
static_cast<i64>(cb_raw - bp[i]) * cov_q16) >> 16);
625 i32 *__restrict__ rp =
mState.r.data();
626 i32 *__restrict__ gp =
mState.g.data();
627 i32 *__restrict__ bp =
mState.b.data();
630 s16x16 dx_step = dx * invSteps;
631 s16x16 dy_step = dy * invSteps;
636 for (
int i = 0; i <=
steps; i++, u = u + invSteps, px = px + dx_step, py = py + dy_step) {
643 constexpr s16x16 one(1.0f);
648 (inv_fx * inv_fy).raw(),
655 i32 cr_raw =
static_cast<i32
>(c.r) << 16;
656 i32 cg_raw =
static_cast<i32
>(c.g) << 16;
657 i32 cb_raw =
static_cast<i32
>(c.b) << 16;
659 int offX[4] = {0, 1, 0, 1};
660 int offY[4] = {0, 0, 1, 1};
662 for (
int j = 0; j < 4; j++) {
663 int cx = ix + offX[j];
664 int cy = iy + offY[j];
665 if (cx < 0 || cx >= w || cy < 0 || cy >= h)
667 i32 wt_q16 = weights[j];
668 if (wt_q16 <= 0)
continue;
669 int gi = cy * w + cx;
671 rp[gi] +=
static_cast<i32
>((
static_cast<i64>(cr_raw - rp[gi]) * wt_q16) >> 16);
672 gp[gi] +=
static_cast<i32
>((
static_cast<i64>(cg_raw - gp[gi]) * wt_q16) >> 16);
673 bp[gi] +=
static_cast<i32
>((
static_cast<i64>(cb_raw - bp[gi]) * wt_q16) >> 16);
681 constexpr s16x16 half(0.5f);
689 constexpr s16x16 k_0742(0.742f);
690 constexpr s16x16 k_0677(0.677f);
691 constexpr s16x16 k_0774(0.774f);
692 constexpr s16x16 k_0710(0.710f);
693 s16x16 cx_r1 = cx * k_0742;
694 s16x16 cy_r1 = cy * k_0677;
695 s16x16 cx_r2 = cx * k_0774;
696 s16x16 cy_r2 = cy * k_0710;
699 constexpr s16x16 k_113(1.13f);
700 constexpr s16x16 k_171(1.71f);
701 constexpr s16x16 k_189(1.89f);
702 constexpr s16x16 k_137(1.37f);
703 constexpr s16x16 k_020(0.20f);
704 constexpr s16x16 k_130(1.30f);
705 constexpr s16x16 k_220(2.20f);
706 constexpr s16x16 k_070(0.70f);
717 constexpr s16x16 discDiam(1.7f);
718 drawDot(x1, y1, discDiam, endA.r, endA.g, endA.b);
719 drawDot(x2, y2, discDiam, endB.r, endB.g, endB.b);
727 constexpr s16x16 half(0.5f);
728 constexpr s16x16 two_pi(6.2831853f);
735 constexpr s16x16 dotDiam(1.5f);
738 for (
int i = 0; i < n; i++) {
742 s16x16 cx = ocx + cos_a * orad;
743 s16x16 cy = ocy + sin_a * orad;
745 drawDot(cx, cy, dotDiam, c.r, c.g, c.b);
756 constexpr s16x16 kBaseFreq(0.23f);
757 constexpr s16x16 neg_one(-1.0f);
758 constexpr s16x16 one(1.0f);
760 const i32 *fade_lut =
mState.fade_lut;
766 for (
int i = 0; i < w; i++) {
775 if (
mParams.reverse_x_profile) {
776 for (
int i = 0; i < w / 2; i++) {
777 i32 tmp =
mState.x_prof[i];
779 mState.x_prof[w - 1 - i] = tmp;
787 for (
int i = 0; i < h; i++) {
797 for (
int i = 0; i < w; i++) {
800 neg_one.
raw(), one.
raw());
802 for (
int i = 0; i < h; i++) {
805 neg_one.
raw(), one.
raw());
818 constexpr s16x16 half_fp(0.5f);
819 constexpr s16x16 min_persistence(0.001f);
828 i32 w_q16 =
static_cast<i32
>(w) << 16;
829 i32 h_q16 =
static_cast<i32
>(h) << 16;
832 i32 *__restrict__ r =
mState.r.data();
833 i32 *__restrict__ g =
mState.g.data();
834 i32 *__restrict__ b =
mState.b.data();
835 i32 *__restrict__ tr =
mState.tr.data();
836 i32 *__restrict__ tg =
mState.tg.data();
837 i32 *__restrict__ tb =
mState.tb.data();
842 for (
int y = 0;
y < h;
y++) {
843 i32 sh =
static_cast<i32
>((
static_cast<i64>(
mState.y_prof[
y]) * shift_raw) >> 16);
844 int row_base =
y * w;
845 for (
int x = 0;
x < w;
x++) {
846 i32 sx_raw = (
static_cast<i32
>(
x) << 16) - sh;
848 if (sx_raw < 0) sx_raw += w_q16;
849 else if (sx_raw >= w_q16) sx_raw -= w_q16;
851 if (sx_raw < 0) sx_raw += w_q16;
852 if (sx_raw >= w_q16) sx_raw -= w_q16;
854 int ix0 = sx_raw >> 16;
855 int ix1 = (ix0 + 1 < w) ? ix0 + 1 : 0;
856 i32 f = sx_raw & 0xFFFF;
858 int src0 = row_base + ix0;
859 int src1 = row_base + ix1;
860 int dst = row_base +
x;
862 tr[dst] = r[src0] +
static_cast<i32
>((
static_cast<i64>(r[src1] - r[src0]) * f) >> 16);
863 tg[dst] = g[src0] +
static_cast<i32
>((
static_cast<i64>(g[src1] - g[src0]) * f) >> 16);
864 tb[dst] = b[src0] +
static_cast<i32
>((
static_cast<i64>(b[src1] - b[src0]) * f) >> 16);
870 for (
int x = 0;
x < w;
x++) {
871 i32 sh =
static_cast<i32
>((
static_cast<i64>(
mState.x_prof[
x]) * shift_raw) >> 16);
872 for (
int y = 0;
y < h;
y++) {
873 i32 sy_raw = (
static_cast<i32
>(
y) << 16) - sh;
874 if (sy_raw < 0) sy_raw += h_q16;
875 else if (sy_raw >= h_q16) sy_raw -= h_q16;
876 if (sy_raw < 0) sy_raw += h_q16;
877 if (sy_raw >= h_q16) sy_raw -= h_q16;
879 int iy0 = sy_raw >> 16;
880 int iy1 = (iy0 + 1 < h) ? iy0 + 1 : 0;
881 i32 f = sy_raw & 0xFFFF;
883 int src0 = iy0 * w +
x;
884 int src1 = iy1 * w +
x;
888 i32 interp_r = tr[src0] +
static_cast<i32
>((
static_cast<i64>(tr[src1] - tr[src0]) * f) >> 16);
889 i32 interp_g = tg[src0] +
static_cast<i32
>((
static_cast<i64>(tg[src1] - tg[src0]) * f) >> 16);
890 i32 interp_b = tb[src0] +
static_cast<i32
>((
static_cast<i64>(tb[src1] - tb[src0]) * f) >> 16);
892 r[dst] =
static_cast<i32
>((
static_cast<i64>(interp_r) *
fade_raw) >> 16);
893 g[dst] =
static_cast<i32
>((
static_cast<i64>(interp_g) *
fade_raw) >> 16);
894 b[dst] =
static_cast<i32
>((
static_cast<i64>(interp_b) *
fade_raw) >> 16);
909 auto plotTile = [&](
const CRGB &color,
float px,
float py,
913 float fx = px - (float)ix;
914 float fy = py - (float)iy;
918 tile.at(0, 0) = (
u8)((1.0f - fy) * 255.0f);
920 tile.at(0, 1) = (
u8)(fy * 255.0f);
923 tile.at(0, 0) = (
u8)((1.0f - fx) * 255.0f);
924 tile.at(1, 0) = (
u8)(fx * 255.0f);
932 constexpr float amp = 0.3f;
936 CRGB xColor(0, 255, 255);
937 float centerY = (float)(h - 1) * 0.5f;
939 for (
int x = 0;
x < w;
x++) {
941 float py = centerY - val.
to_float() * amp * centerY;
942 plotTile(xColor, (
float)
x, py,
true);
944 float dy = py - prevPy;
945 int gap = (int)
fabsf(dy);
946 for (
int s = 1; s < gap; s++) {
947 float t = (float)s / (
float)gap;
948 float midY = prevPy + dy *
t;
949 float midX = (float)(
x - 1) +
t;
950 plotTile(xColor, midX, midY,
true);
958 CRGB yColor(255, 255, 0);
959 float centerX = (float)(w - 1) * 0.5f;
961 for (
int y = 0;
y < h;
y++) {
963 float px = centerX + val.
to_float() * amp * centerX;
964 plotTile(yColor, px, (
float)
y,
false);
966 float dx = px - prevPx;
967 int gap = (int)
fabsf(dx);
968 for (
int s = 1; s < gap; s++) {
969 float t = (float)s / (
float)gap;
970 float midX = prevPx + dx *
t;
971 float midY = (float)(
y - 1) +
t;
972 plotTile(yColor, midX, midY,
false);
989 i32 dt_raw = dt.
raw();
992 switch (
mParams.emitter_mode) {
1012 const i32 *rp =
mState.r.data();
1013 const i32 *gp =
mState.g.data();
1014 const i32 *bp =
mState.b.data();
1016 for (
int y = 0;
y < h;
y++) {
1017 int row_base =
y * w;
1018 for (
int x = 0;
x < w;
x++) {
1019 int i = row_base +
x;
1020 u16 ledIdx =
mXyMap.mapToIndex(
static_cast<u16
>(
x),
static_cast<u16
>(
y));
1027 if (
mParams.show_flow_vectors) {
fl::UISlider colorShift("Color Shift", 0.04f, 0.0f, 0.5f, 0.01f)
void noisePunchX(float center, float width, float amplitude=1.0f, BumpShape shape=BumpShape::HalfSine)
Trigger a noise punch on the X axis (columns).
void noisePunchY(float center, float width, float amplitude=1.0f, BumpShape shape=BumpShape::HalfSine)
Trigger a noise punch on the Y axis (rows).
void draw(DrawContext context) override
Handles timing, then delegates to drawImpl().
virtual void drawImpl(DrawContext context, u32 dt_ms, u32 t_ms)=0
Subclasses implement rendering given the time delta and total time.
FlowField(const XYMap &xyMap, const Params ¶ms=Params())
void noisePunch(float amplitude=1.0f, BumpShape shape=BumpShape::HalfSine)
Trigger a noise punch on both axes at center with proportional width.
void drawAALine(s16x16 x0, s16x16 y0, s16x16 x1, s16x16 y1, s16x16 t, s16x16 colorShift)
FlowFieldFP(const XYMap &xyMap, const Params ¶ms=Params())
void drawDot(s16x16 cx, s16x16 cy, s16x16 diam, u8 cr, u8 cg, u8 cb)
static i32 clamp_q16(i32 v, i32 lo, i32 hi)
void flowAdvect(i32 dt_raw)
static CRGB rainbow(s16x16 t, s16x16 speed, s16x16 phase)
void flowPrepare(s16x16 t)
static u8 q16_to_u8(i32 v)
void emitLissajousLine(s16x16 t)
void drawImpl(DrawContext context, u32 dt_ms, u32 t_ms) override
Subclasses implement rendering given the time delta and total time.
void emitOrbitalDots(s16x16 t)
static void initPerm256(u8 *perm, u32 seed)
void drawFlowVectors(fl::span< CRGB > leds)
float noise(float x, float y) const
static float grad(int h, float x, float y)
void drawAALine(float x0, float y0, float x1, float y1, float t, float colorShift)
fl::vector< float > mYProf
Per-row values; drives horizontal shift.
void drawDot(float cx, float cy, float diam, u8 cr, u8 cg, u8 cb)
static CRGB rainbow(float t, float speed, float phase)
void drawFlowVectors(fl::span< CRGB > leds)
static float clampf(float v, float lo, float hi)
FlowFieldFloat(const XYMap &xyMap, const Params ¶ms=Params())
void flowAdvect(float dt)
void drawImpl(DrawContext context, u32 dt_ms, u32 t_ms) override
Subclasses implement rendering given the time delta and total time.
fl::vector< float > mXProf
Per-column values; drives vertical shift.
void emitOrbitalDots(float t)
void flowPrepare(float t)
void emitLissajousLine(float t)
int idx(int y, int x) const
static float fmodPos(float x, float m)
u16 xyMap(u16 x, u16 y) const
void setOrigin(u16 x, u16 y)
constexpr float to_float() const FL_NOEXCEPT
static constexpr i32 SCALE
static FASTLED_FORCE_INLINE void sincos(s16x16 angle, s16x16 &out_sin, s16x16 &out_cos) FL_NOEXCEPT
static constexpr FASTLED_FORCE_INLINE s16x16 mod(s16x16 a, s16x16 b) FL_NOEXCEPT
static constexpr FASTLED_FORCE_INLINE s16x16 clamp(s16x16 x, s16x16 lo, s16x16 hi) FL_NOEXCEPT
static constexpr FASTLED_FORCE_INLINE s16x16 ceil(s16x16 x) FL_NOEXCEPT
constexpr FASTLED_FORCE_INLINE s16x16 floor() const FL_NOEXCEPT
constexpr FASTLED_FORCE_INLINE s16x16 sqrt() const FL_NOEXCEPT
constexpr i32 to_int() const FL_NOEXCEPT
constexpr FASTLED_FORCE_INLINE s16x16 fract() const FL_NOEXCEPT
static constexpr FASTLED_FORCE_INLINE s16x16 floor(s16x16 x) FL_NOEXCEPT
static constexpr FASTLED_FORCE_INLINE s16x16 from_raw(i32 raw) FL_NOEXCEPT
constexpr i32 raw() const FL_NOEXCEPT
static constexpr FASTLED_FORCE_INLINE s16x16 abs(s16x16 x) FL_NOEXCEPT
FASTLED_FORCE_INLINE s16x16 sin() const FL_NOEXCEPT
static FASTLED_FORCE_INLINE s16x16 pow(s16x16 base, s16x16 exp) FL_NOEXCEPT
fl::UISlider steps("Steps", 100.0f, 1.0f, 200.0f, 1.0f)
2D flow field visualization: emitters paint color, noise advects it
CRGB hsv2rgb_rainbow(const CHSV &hsv)
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NOEXCEPT
float sqrtf(float value) FL_NOEXCEPT
constexpr common_type_t< T, U > max(T a, U b) FL_NOEXCEPT
float powf(float base, float exponent) FL_NOEXCEPT
float floorf(float value) FL_NOEXCEPT
float sinf(float value) FL_NOEXCEPT
static constexpr i32 FP_ONE
void fade_raw(CRGB *leds, fl::u16 num_leds, fl::u8 fadeBy)
FASTLED_FORCE_INLINE float fade(float t)
float ceilf(float value) FL_NOEXCEPT
float fmodf(float x, float y) FL_NOEXCEPT
float fabsf(float value) FL_NOEXCEPT
static constexpr i32 FP_255
constexpr enable_if< is_fixed_point< T >::value, T >::type step(T edge, T x) FL_NOEXCEPT
BumpShape
Shape function for NoiseBias triggers.
FASTLED_FORCE_INLINE float grad(int hash, float x, float y, float z)
float cosf(float value) FL_NOEXCEPT
FASTLED_FORCE_INLINE float lerp(float t, float a, float b)
Base definition for an LED controller.
#define FL_OPTIMIZATION_LEVEL_O3_BEGIN
#define FL_OPTIMIZATION_LEVEL_O3_END
Representation of an 8-bit RGB pixel (Red, Green, Blue)
static fl::i32 pnoise2d_raw(fl::i32 fx_raw, fl::i32 fy_raw, const fl::i32 *fade_lut, const fl::u8 *perm)
static void init_fade_lut(fl::i32 *table)