FastLED 3.10.8
Loading...
Searching...
No Matches
perlin_s16x16.cpp.hpp
Go to the documentation of this file.
1#pragma once
2// allow-include-after-namespace
3
4// 2D Perlin noise implementation using s16x16 fixed-point arithmetic
5// Implementation file - included from perlin_s16x16.h
6
9#include "fl/stl/noexcept.h"
10
12
13namespace fl {
14
16 for (int i = 0; i <= 256; i++) {
17 fl::i64 t = static_cast<fl::i64>(i) * (HP_ONE / 256);
18 fl::i64 t2 = (t * t) >> HP_BITS;
19 fl::i64 t3 = (t2 * t) >> HP_BITS;
20 fl::i64 inner = (t * (6LL * HP_ONE)) >> HP_BITS;
21 inner -= 15LL * HP_ONE;
22 inner = (t * inner) >> HP_BITS;
23 inner += 10LL * HP_ONE;
24 table[i] = static_cast<fl::i32>((t3 * inner) >> HP_BITS);
25 }
26}
27
29 const fl::i32 *fade_lut,
30 const fl::u8 *perm) FL_NO_EXCEPT {
32 pnoise2d_raw(fx.raw(), fy.raw(), fade_lut, perm));
33}
34
35fl::i32 perlin_s16x16::pnoise2d_raw(fl::i32 fx_raw, fl::i32 fy_raw,
36 const fl::i32 *fade_lut,
37 const fl::u8 *perm) FL_NO_EXCEPT {
38 int X, Y;
39 fl::i32 x, y;
40 floor_frac(fx_raw, X, x);
41 floor_frac(fy_raw, Y, y);
42 X &= 255;
43 Y &= 255;
44
45 fl::i32 u = fade(x, fade_lut);
46 fl::i32 v = fade(y, fade_lut);
47
48 int A = perm[X & 255] + Y;
49 int AA = perm[A & 255];
50 int AB = perm[(A + 1) & 255];
51 int B = perm[(X + 1) & 255] + Y;
52 int BA = perm[B & 255];
53 int BB = perm[(B + 1) & 255];
54
55 fl::i32 result = lerp(v,
56 lerp(u, grad(perm[AA & 255], x, y),
57 grad(perm[BA & 255], x - HP_ONE, y)),
58 lerp(u, grad(perm[AB & 255], x, y - HP_ONE),
59 grad(perm[BB & 255], x - HP_ONE, y - HP_ONE)));
60
62}
63
64 void perlin_s16x16::floor_frac(fl::i32 fp16, int &ifloor,
65 fl::i32 &frac24) FL_NO_EXCEPT {
66 ifloor = fp16 >> FP_BITS;
67 frac24 = (fp16 & (FP_ONE - 1)) << (HP_BITS - FP_BITS);
68}
69
70 fl::i32 perlin_s16x16::fade(fl::i32 t, const fl::i32 *table) FL_NO_EXCEPT {
71 fl::u32 idx = static_cast<fl::u32>(t) >> 16;
72 fl::i32 frac = t & 0xFFFF;
73 fl::i32 a = table[idx];
74 fl::i32 b = table[idx + 1];
75 return a + static_cast<fl::i32>(
76 (static_cast<fl::i64>(frac) * (b - a)) >> 16);
77}
78
79 fl::i32 perlin_s16x16::lerp(fl::i32 t, fl::i32 a, fl::i32 b) FL_NO_EXCEPT {
80 return a + static_cast<fl::i32>(
81 (static_cast<fl::i64>(t) * (b - a)) >> HP_BITS);
82}
83
84 fl::i32 perlin_s16x16::grad(int hash, fl::i32 x, fl::i32 y) FL_NO_EXCEPT {
85 struct GradCoeff { fl::i8 cx; fl::i8 cy; };
86 constexpr GradCoeff lut[16] = {
87 { 1, 1}, {-1, 1}, { 1, -1}, {-1, -1},
88 { 1, 0}, {-1, 0}, { 1, 0}, {-1, 0},
89 { 0, 1}, { 0, -1}, { 0, 1}, { 0, -1},
90 { 1, 1}, { 0, -1}, {-1, 1}, { 0, -1},
91 };
92 const GradCoeff &g = lut[hash & 15];
93 return g.cx * x + g.cy * y;
94}
95
97 const fl::i32 *fade_lut,
98 const fl::u8 *perm) FL_NO_EXCEPT {
100 pnoise3d_raw(fx.raw(), fy.raw(), fz.raw(), fade_lut, perm));
101}
102
103fl::i32 perlin_s16x16::pnoise3d_raw(fl::i32 fx_raw, fl::i32 fy_raw, fl::i32 fz_raw,
104 const fl::i32 *fade_lut,
105 const fl::u8 *perm) FL_NO_EXCEPT {
106 int X, Y, Z;
107 fl::i32 x, y, z;
108 floor_frac(fx_raw, X, x);
109 floor_frac(fy_raw, Y, y);
110 floor_frac(fz_raw, Z, z);
111 X &= 255;
112 Y &= 255;
113 Z &= 255;
114
115 fl::i32 u = fade(x, fade_lut);
116 fl::i32 v = fade(y, fade_lut);
117 fl::i32 w = fade(z, fade_lut);
118
119 int A = perm[X & 255] + Y;
120 int AA = perm[A & 255] + Z;
121 int AB = perm[(A + 1) & 255] + Z;
122 int B = perm[(X + 1) & 255] + Y;
123 int BA = perm[B & 255] + Z;
124 int BB = perm[(B + 1) & 255] + Z;
125
126 fl::i32 result = lerp(w,
127 lerp(v,
128 lerp(u, grad3d(perm[AA & 255], x, y, z),
129 grad3d(perm[BA & 255], x - HP_ONE, y, z)),
130 lerp(u, grad3d(perm[AB & 255], x, y - HP_ONE, z),
131 grad3d(perm[BB & 255], x - HP_ONE, y - HP_ONE, z))),
132 lerp(v,
133 lerp(u, grad3d(perm[(AA + 1) & 255], x, y, z - HP_ONE),
134 grad3d(perm[(BA + 1) & 255], x - HP_ONE, y, z - HP_ONE)),
135 lerp(u, grad3d(perm[(AB + 1) & 255], x, y - HP_ONE, z - HP_ONE),
136 grad3d(perm[(BB + 1) & 255], x - HP_ONE, y - HP_ONE, z - HP_ONE))));
137
139}
140
141fl::i32 perlin_s16x16::grad3d(int hash, fl::i32 x, fl::i32 y, fl::i32 z) FL_NO_EXCEPT {
142 // Matches float grad(hash, x, y, z) from perlin_float.h:
143 // h = hash & 15
144 // u = h < 8 ? x : y
145 // v = h < 4 ? y : (h == 12 || h == 14 ? x : z)
146 // return ((h&1)==0 ? u : -u) + ((h&2)==0 ? v : -v)
147 int h = hash & 15;
148 fl::i32 u = h < 8 ? x : y;
149 fl::i32 v = h < 4 ? y : (h == 12 || h == 14 ? x : z);
150 return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
151}
152
153} // namespace fl
154
uint32_t z[NUM_LAYERS]
Definition Fire2023.h:93
static constexpr int FRAC_BITS
Definition s16x16.h:24
static constexpr FASTLED_FORCE_INLINE s16x16 from_raw(i32 raw) FL_NO_EXCEPT
Definition s16x16.h:56
#define FL_OPTIMIZATION_LEVEL_O3_BEGIN
#define FL_OPTIMIZATION_LEVEL_O3_END
unsigned char u8
Definition stdint.h:131
FASTLED_FORCE_INLINE float lerp(float t, float a, float b) FL_NO_EXCEPT
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
FASTLED_FORCE_INLINE float grad(int hash, float x, float y, float z) FL_NO_EXCEPT
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
InputGamut g
Definition rgbw.h:125
FASTLED_FORCE_INLINE float fade(float t) FL_NO_EXCEPT
signed char i8
Definition stdint.h:130
Base definition for an LED controller.
Definition crgb.hpp:179
static fl::i32 grad3d(int hash, fl::i32 x, fl::i32 y, fl::i32 z) FL_NO_EXCEPT
static void floor_frac(fl::i32 fp16, int &ifloor, fl::i32 &frac24) FL_NO_EXCEPT
static constexpr fl::i32 HP_ONE
static fl::i32 fade(fl::i32 t, const fl::i32 *table) FL_NO_EXCEPT
static constexpr int HP_BITS
static fl::i32 pnoise3d_raw(fl::i32 fx_raw, fl::i32 fy_raw, fl::i32 fz_raw, const fl::i32 *fade_lut, const fl::u8 *perm) FL_NO_EXCEPT
static fl::i32 pnoise2d_raw(fl::i32 fx_raw, fl::i32 fy_raw, const fl::i32 *fade_lut, const fl::u8 *perm) FL_NO_EXCEPT
static fl::i32 grad(int hash, fl::i32 x, fl::i32 y) FL_NO_EXCEPT
static constexpr int FP_BITS
static fl::s16x16 pnoise3d(fl::s16x16 fx, fl::s16x16 fy, fl::s16x16 fz, const fl::i32 *fade_lut, const fl::u8 *perm) FL_NO_EXCEPT
static fl::i32 lerp(fl::i32 t, fl::i32 a, fl::i32 b) FL_NO_EXCEPT
static constexpr fl::i32 FP_ONE
static void init_fade_lut(fl::i32 *table) FL_NO_EXCEPT
static fl::s16x16 pnoise2d(fl::s16x16 fx, fl::s16x16 fy, const fl::i32 *fade_lut, const fl::u8 *perm) FL_NO_EXCEPT