FastLED 3.10.8
Loading...
Searching...
No Matches
perlin_i16_optimized.cpp.hpp
Go to the documentation of this file.
1#pragma once
2// allow-include-after-namespace
3
4// 2D Perlin noise i16-optimized implementation
5// Implementation file - included from perlin_i16_optimized.h
6
9#include "fl/stl/noexcept.h"
10
12
13namespace fl {
14
16 for (int i = 0; i <= 256; i++) {
17 fl::i32 t = (i * HP_ONE) / 256;
18 fl::i32 t2 = static_cast<fl::i32>((static_cast<fl::i64>(t) * t) >> HP_BITS);
19 fl::i32 t3 = static_cast<fl::i32>((static_cast<fl::i64>(t2) * t) >> HP_BITS);
20 fl::i32 inner = static_cast<fl::i32>((static_cast<fl::i64>(t) * (6 * HP_ONE)) >> HP_BITS);
21 inner -= 15 * HP_ONE;
22 inner = static_cast<fl::i32>((static_cast<fl::i64>(t) * inner) >> HP_BITS);
23 inner += 10 * HP_ONE;
24 table[i] = static_cast<fl::i32>((static_cast<fl::i64>(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_i16_optimized::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::i16 x16, y16; // i16 fractional parts!
40 floor_frac_i16(fx_raw, X, x16);
41 floor_frac_i16(fy_raw, Y, y16);
42 X &= 255;
43 Y &= 255;
44
45 // Fade values can be up to 65536, need to stay i32
46 // But we can still optimize grad and internal lerp to use i16
47 fl::i32 u = fade(x16, fade_lut);
48 fl::i32 v = fade(y16, fade_lut);
49
50 int A = perm[X & 255] + Y;
51 int AA = perm[A & 255];
52 int AB = perm[(A + 1) & 255];
53 int B = perm[(X + 1) & 255] + Y;
54 int BA = perm[B & 255];
55 int BB = perm[(B + 1) & 255];
56
57 // grad returns i16 (coordinates are i16), lerp takes i32 fade values
58 fl::i32 g00 = grad_i16(perm[AA & 255], x16, y16);
59 fl::i32 g10 = grad_i16(perm[BA & 255], x16 - HP_ONE_I16, y16);
60 fl::i32 g01 = grad_i16(perm[AB & 255], x16, y16 - HP_ONE_I16);
61 fl::i32 g11 = grad_i16(perm[BB & 255], x16 - HP_ONE_I16, y16 - HP_ONE_I16);
62
63 // Lerp with i32 (grad results fit in i16 range but lerp needs i32 for fade values)
64 fl::i32 lerp0 = lerp(u, g00, g10);
65 fl::i32 lerp1 = lerp(u, g01, g11);
66 fl::i32 result = lerp(v, lerp0, lerp1);
67
68 return result;
69}
70
71FASTLED_FORCE_INLINE void perlin_i16_optimized::floor_frac_i16(fl::i32 fp16, int &ifloor, fl::i16 &frac16) FL_NO_EXCEPT {
72 ifloor = fp16 >> FP_BITS;
73 frac16 = static_cast<fl::i16>(fp16 & (FP_ONE - 1)); // Cast to i16
74}
75
76FASTLED_FORCE_INLINE fl::i32 perlin_i16_optimized::fade(fl::i16 t, const fl::i32 *table) FL_NO_EXCEPT {
77 fl::u32 idx = static_cast<fl::u32>(t) >> 8; // i16 → 8-bit index
78 fl::i32 frac = t & 0xFF;
79 fl::i32 a = table[idx];
80 fl::i32 b = table[idx + 1];
81 return a + ((static_cast<fl::i32>(frac << 8) * (b - a)) >> 16);
82}
83
84FASTLED_FORCE_INLINE fl::i32 perlin_i16_optimized::lerp(fl::i32 t, fl::i32 a, fl::i32 b) FL_NO_EXCEPT {
85 return a + static_cast<fl::i32>(
86 (static_cast<fl::i64>(t) * (b - a)) >> HP_BITS);
87}
88
90 struct GradCoeff { fl::i8 cx; fl::i8 cy; };
91 constexpr GradCoeff lut[16] = {
92 { 1, 1}, {-1, 1}, { 1, -1}, {-1, -1},
93 { 1, 0}, {-1, 0}, { 1, 0}, {-1, 0},
94 { 0, 1}, { 0, -1}, { 0, 1}, { 0, -1},
95 { 1, 1}, { 0, -1}, {-1, 1}, { 0, -1},
96 };
97 const GradCoeff &g = lut[hash & 15];
98 // i8 × i16 → i32 (safe, result in range ±65535)
99 return static_cast<fl::i32>(g.cx * x) + static_cast<fl::i32>(g.cy * y);
100}
101
102} // namespace fl
103
static constexpr FASTLED_FORCE_INLINE s16x16 from_raw(i32 raw) FL_NO_EXCEPT
Definition s16x16.h:56
#define FL_OPTIMIZATION_LEVEL_O3_BEGIN
#define FASTLED_FORCE_INLINE
#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
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 FASTLED_FORCE_INLINE fl::i32 lerp(fl::i32 t, fl::i32 a, fl::i32 b) FL_NO_EXCEPT
static void init_fade_lut(fl::i32 *table) FL_NO_EXCEPT
static constexpr fl::i32 HP_ONE
static FASTLED_FORCE_INLINE void floor_frac_i16(fl::i32 fp16, int &ifloor, fl::i16 &frac16) FL_NO_EXCEPT
static constexpr int HP_BITS
static constexpr fl::i32 FP_ONE
static constexpr fl::i32 HP_ONE_I16
static FASTLED_FORCE_INLINE fl::i32 grad_i16(int hash, fl::i16 x, fl::i16 y) FL_NO_EXCEPT
static constexpr int FP_BITS
static FASTLED_FORCE_INLINE fl::i32 fade(fl::i16 t, const fl::i32 *table) 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::s16x16 pnoise2d(fl::s16x16 fx, fl::s16x16 fy, const fl::i32 *fade_lut, const fl::u8 *perm) FL_NO_EXCEPT