FastLED 3.9.15
Loading...
Searching...
No Matches
perlin_q16.cpp.hpp
Go to the documentation of this file.
1#pragma once
2// allow-include-after-namespace
3
4// 2D Perlin noise Q16 implementation
5// Implementation file - included from perlin_q16.h
6
9
11
12namespace fl {
13
14void perlin_q16::init_fade_lut(fl::i32 *table) {
15 for (int i = 0; i <= 256; i++) {
16 fl::i32 t = (i * HP_ONE) / 256;
17 fl::i32 t2 = static_cast<fl::i32>((static_cast<fl::i64>(t) * t) >> HP_BITS);
18 fl::i32 t3 = static_cast<fl::i32>((static_cast<fl::i64>(t2) * t) >> HP_BITS);
19 fl::i32 inner = static_cast<fl::i32>((static_cast<fl::i64>(t) * (6 * HP_ONE)) >> HP_BITS);
20 inner -= 15 * HP_ONE;
21 inner = static_cast<fl::i32>((static_cast<fl::i64>(t) * inner) >> HP_BITS);
22 inner += 10 * HP_ONE;
23 table[i] = static_cast<fl::i32>((static_cast<fl::i64>(t3) * inner) >> HP_BITS);
24 }
25}
26
28 const fl::i32 *fade_lut,
29 const fl::u8 *perm) {
31 pnoise2d_raw(fx.raw(), fy.raw(), fade_lut, perm));
32}
33
34fl::i32 perlin_q16::pnoise2d_raw(fl::i32 fx_raw, fl::i32 fy_raw,
35 const fl::i32 *fade_lut,
36 const fl::u8 *perm) {
37 int X, Y;
38 fl::i32 x, y;
39 floor_frac(fx_raw, X, x);
40 floor_frac(fy_raw, Y, y);
41 X &= 255;
42 Y &= 255;
43
44 fl::i32 u = fade(x, fade_lut);
45 fl::i32 v = fade(y, fade_lut);
46
47 int A = perm[X & 255] + Y;
48 int AA = perm[A & 255];
49 int AB = perm[(A + 1) & 255];
50 int B = perm[(X + 1) & 255] + Y;
51 int BA = perm[B & 255];
52 int BB = perm[(B + 1) & 255];
53
54 fl::i32 result = lerp(v,
55 lerp(u, grad(perm[AA & 255], x, y),
56 grad(perm[BA & 255], x - HP_ONE, y)),
57 lerp(u, grad(perm[AB & 255], x, y - HP_ONE),
58 grad(perm[BB & 255], x - HP_ONE, y - HP_ONE)));
59
60 // No shift needed: already in Q16 format, matches s16x16::FRAC_BITS
61 return result;
62}
63
64FASTLED_FORCE_INLINE void perlin_q16::floor_frac(fl::i32 fp16, int &ifloor,
65 fl::i32 &frac16) {
66 ifloor = fp16 >> FP_BITS;
67 frac16 = fp16 & (FP_ONE - 1); // Already Q16, no shift needed
68}
69
70FASTLED_FORCE_INLINE fl::i32 perlin_q16::fade(fl::i32 t, const fl::i32 *table) {
71 fl::u32 idx = static_cast<fl::u32>(t) >> 8; // Q16 → 8-bit index
72 fl::i32 frac = t & 0xFF;
73 fl::i32 a = table[idx];
74 fl::i32 b = table[idx + 1];
75 // Lerp in Q16: frac is 8 bits, expand to 16 for precision
76 return a + static_cast<fl::i32>(
77 (static_cast<fl::i32>(frac << 8) * (b - a)) >> 16);
78}
79
80FASTLED_FORCE_INLINE fl::i32 perlin_q16::lerp(fl::i32 t, fl::i32 a, fl::i32 b) {
81 // All values in Q16, result stays Q16
82 return a + static_cast<fl::i32>(
83 (static_cast<fl::i64>(t) * (b - a)) >> HP_BITS);
84}
85
86FASTLED_FORCE_INLINE fl::i32 perlin_q16::grad(int hash, fl::i32 x, fl::i32 y) {
87 struct GradCoeff { fl::i8 cx; fl::i8 cy; };
88 constexpr GradCoeff lut[16] = {
89 { 1, 1}, {-1, 1}, { 1, -1}, {-1, -1},
90 { 1, 0}, {-1, 0}, { 1, 0}, {-1, 0},
91 { 0, 1}, { 0, -1}, { 0, 1}, { 0, -1},
92 { 1, 1}, { 0, -1}, {-1, 1}, { 0, -1},
93 };
94 const GradCoeff &g = lut[hash & 15];
95 return g.cx * x + g.cy * y;
96}
97
98} // namespace fl
99
static constexpr FASTLED_FORCE_INLINE s16x16 from_raw(i32 raw) FL_NOEXCEPT
Definition s16x16.h:54
constexpr i32 raw() const FL_NOEXCEPT
Definition s16x16.h:60
unsigned char u8
Definition s16x16x4.h:132
signed char i8
Definition s16x16x4.h:131
FL_DISABLE_WARNING_PUSH unsigned char * B
fl::i64 i64
Definition s16x16x4.h:222
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_OPTIMIZATION_LEVEL_O3_BEGIN
#define FASTLED_FORCE_INLINE
#define FL_OPTIMIZATION_LEVEL_O3_END
static constexpr int HP_BITS
Definition perlin_q16.h:15
static FASTLED_FORCE_INLINE fl::i32 grad(int hash, fl::i32 x, fl::i32 y)
static fl::i32 pnoise2d_raw(fl::i32 fx_raw, fl::i32 fy_raw, const fl::i32 *fade_lut, const fl::u8 *perm)
static FASTLED_FORCE_INLINE fl::i32 lerp(fl::i32 t, fl::i32 a, fl::i32 b)
static constexpr fl::i32 FP_ONE
Definition perlin_q16.h:33
static constexpr int FP_BITS
Definition perlin_q16.h:32
static void init_fade_lut(fl::i32 *table)
static FASTLED_FORCE_INLINE fl::i32 fade(fl::i32 t, const fl::i32 *table)
static constexpr fl::i32 HP_ONE
Definition perlin_q16.h:16
static FASTLED_FORCE_INLINE void floor_frac(fl::i32 fp16, int &ifloor, fl::i32 &frac16)
static fl::s16x16 pnoise2d(fl::s16x16 fx, fl::s16x16 fy, const fl::i32 *fade_lut, const fl::u8 *perm)