FastLED 3.10.8
Loading...
Searching...
No Matches

◆ flowAdvect()

void fl::FlowFieldFP::flowAdvect ( i32 dt_raw)
private

Definition at line 814 of file flowfield.cpp.hpp.

814 {
815 int w = mState.width;
816 int h = mState.height;
817
818 // fade = pow(0.5, dt / halfLife) — pure fixed-point
819 constexpr s16x16 half_fp(0.5f);
820 constexpr s16x16 min_persistence(0.001f);
821 s16x16 dt_fp = s16x16::from_raw(dt_raw);
822 s16x16 halfLife_fp = mPersistence_fp.raw() > min_persistence.raw()
824 : min_persistence;
825 i32 fade_raw = s16x16::pow(half_fp, dt_fp / halfLife_fp).raw();
826
827 i32 shift_raw = mFlowShift_fp.raw();
828
829 i32 w_q16 = static_cast<i32>(w) << 16;
830 i32 h_q16 = static_cast<i32>(h) << 16;
831
832 // Grab raw array pointers — avoids vector operator[] overhead in hot loops.
833 i32 *__restrict__ r = mState.r.data();
834 i32 *__restrict__ g = mState.g.data();
835 i32 *__restrict__ b = mState.b.data();
836 i32 *__restrict__ tr = mState.tr.data();
837 i32 *__restrict__ tg = mState.tg.data();
838 i32 *__restrict__ tb = mState.tb.data();
839
840 // Pass 1: horizontal row shift
841 // Lerp: a + ((b-a)*f >> 16) uses 1 i64 mul instead of 2.
842 // Note: f = (-sh) & 0xFFFF is constant per row; the compiler hoists it at -O3.
843 for (int y = 0; y < h; y++) {
844 i32 sh = static_cast<i32>((static_cast<i64>(mState.y_prof[y]) * shift_raw) >> 16);
845 int row_base = y * w;
846 for (int x = 0; x < w; x++) {
847 i32 sx_raw = (static_cast<i32>(x) << 16) - sh;
848 // Modular wrap (single iteration sufficient for typical shift values)
849 if (sx_raw < 0) sx_raw += w_q16;
850 else if (sx_raw >= w_q16) sx_raw -= w_q16;
851 // Safety for extreme shift values
852 if (sx_raw < 0) sx_raw += w_q16;
853 if (sx_raw >= w_q16) sx_raw -= w_q16;
854
855 int ix0 = sx_raw >> 16; // Already in [0, w-1] after wrap
856 int ix1 = (ix0 + 1 < w) ? ix0 + 1 : 0;
857 i32 f = sx_raw & 0xFFFF;
858
859 int src0 = row_base + ix0;
860 int src1 = row_base + ix1;
861 int dst = row_base + x;
862
863 tr[dst] = r[src0] + static_cast<i32>((static_cast<i64>(r[src1] - r[src0]) * f) >> 16);
864 tg[dst] = g[src0] + static_cast<i32>((static_cast<i64>(g[src1] - g[src0]) * f) >> 16);
865 tb[dst] = b[src0] + static_cast<i32>((static_cast<i64>(b[src1] - b[src0]) * f) >> 16);
866 }
867 }
868
869 // Pass 2: vertical column shift + fade
870 // Note: f = (-sh) & 0xFFFF is constant per column; the compiler hoists it at -O3.
871 for (int x = 0; x < w; x++) {
872 i32 sh = static_cast<i32>((static_cast<i64>(mState.x_prof[x]) * shift_raw) >> 16);
873 for (int y = 0; y < h; y++) {
874 i32 sy_raw = (static_cast<i32>(y) << 16) - sh;
875 if (sy_raw < 0) sy_raw += h_q16;
876 else if (sy_raw >= h_q16) sy_raw -= h_q16;
877 if (sy_raw < 0) sy_raw += h_q16;
878 if (sy_raw >= h_q16) sy_raw -= h_q16;
879
880 int iy0 = sy_raw >> 16;
881 int iy1 = (iy0 + 1 < h) ? iy0 + 1 : 0;
882 i32 f = sy_raw & 0xFFFF;
883
884 int src0 = iy0 * w + x;
885 int src1 = iy1 * w + x;
886 int dst = y * w + x;
887
888 // Lerp + fade in two steps (2 i64 muls per channel instead of 3)
889 i32 interp_r = tr[src0] + static_cast<i32>((static_cast<i64>(tr[src1] - tr[src0]) * f) >> 16);
890 i32 interp_g = tg[src0] + static_cast<i32>((static_cast<i64>(tg[src1] - tg[src0]) * f) >> 16);
891 i32 interp_b = tb[src0] + static_cast<i32>((static_cast<i64>(tb[src1] - tb[src0]) * f) >> 16);
892
893 r[dst] = static_cast<i32>((static_cast<i64>(interp_r) * fade_raw) >> 16);
894 g[dst] = static_cast<i32>((static_cast<i64>(interp_g) * fade_raw) >> 16);
895 b[dst] = static_cast<i32>((static_cast<i64>(interp_b) * fade_raw) >> 16);
896 }
897 }
898}
FlowFieldFPState mState
Definition flowfield.h:400
s16x16 mFlowShift_fp
Definition flowfield.h:406
s16x16 mPersistence_fp
Definition flowfield.h:408
constexpr i32 raw() const FL_NO_EXCEPT
Definition s16x16.h:62
static constexpr FASTLED_FORCE_INLINE s16x16 from_raw(i32 raw) FL_NO_EXCEPT
Definition s16x16.h:56
static FASTLED_FORCE_INLINE s16x16 pow(s16x16 base, s16x16 exp) FL_NO_EXCEPT
Definition s16x16.h:279
void fade_raw(CRGB *leds, fl::u16 num_leds, fl::u8 fadeBy) FL_NO_EXCEPT
InputGamut g
Definition rgbw.h:125
fl::i64 i64
Definition stdint.h:221

References fl::fade_raw(), fl::FL_NO_EXCEPT, fl::s16x16::from_raw(), fl::g, mFlowShift_fp, mPersistence_fp, mState, fl::s16x16::pow(), fl::s16x16::raw(), fl::x, and fl::y.

Referenced by drawImpl().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: