From 776718b73454f3a084be4c31efb44911a793260d Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:30:43 +0100 Subject: [PATCH] 2D drift improvements for large panel sizes speedup, accuracy improvements and enhancements: * separated calculations in float from integer * improved time resolution * slow down effect on for dimensions >32 * added original "twin" option * added customizable blur (thanks dedehai) --- wled00/FX.cpp | 43 +++++++++++++++++++++++++++++++------------ wled00/wled.h | 2 +- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 08699dc3..fa66eda5 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -5137,6 +5137,7 @@ static const char _data_FX_MODE_2DDNASPIRAL[] PROGMEM = "DNA Spiral@Scroll speed // 2D Drift // ///////////////////////// uint16_t mode_2DDrift() { // By: Stepko https://editor.soulmatelights.com/gallery/884-drift , Modified by: Andrew Tuline + // optimized for large panels by @softhack007 if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); @@ -5147,22 +5148,40 @@ uint16_t mode_2DDrift() { // By: Stepko https://editor.soulmateli SEGMENT.fill(BLACK); } - SEGMENT.fadeToBlackBy(128); + if (SEGMENT.intensity > 1) SEGMENT.fadeToBlackBy(128); + else SEGMENT.fill(BLACK); // WLEDMM fill is faster than fade + const float maxDim = max(cols, rows)/2.0f; - const uint16_t maxDim = MAX(cols, rows)/2; - unsigned long t = strip.now / (32 - (SEGMENT.speed>>3)); - unsigned long t_20 = t/20; // softhack007: pre-calculating this gives about 10% speedup - for (float i = 1; i < maxDim; i += 0.25) { - float angle = radians(t * (maxDim - i)); - uint16_t myX = (cols>>1) + (uint16_t)(sinf(angle) * i) + (cols%2); - uint16_t myY = (rows>>1) + (uint16_t)(cosf(angle) * i) + (rows%2); - SEGMENT.setPixelColorXY(myX, myY, ColorFromPalette(SEGPALETTE, (i * 20) + t_20, 255, LINEARBLEND)); + // WLEDMM calculate timebase in float, so we don't need to worry about rounding + const float strip_now = strip.now & 0x003FFFFF; // float can exactly represent numbers up to 22bit + float t; + if (maxDim < 6.0f) t = strip_now / float(16U - (SEGMENT.speed>>4)); // up to 12 (faster) + else if (maxDim <= 16.0f) t = strip_now / float(32U - (SEGMENT.speed>>3)); // 12..32 (standard) + else if (maxDim <= 32.0f) t = strip_now / float(64U - (SEGMENT.speed>>2)); // 32..64 (slower) + else t = strip_now / float(256U - SEGMENT.speed); // above 64 (slowest) + + // WLEDMM pre-calculate some values to speed up the main loop + const int colsCenter = (cols >> 1) + (cols % 2); + const int rowsCenter = (rows >> 1) + (rows % 2); + unsigned t_20 = t/20.0f; // softhack007: pre-calculating this gives about 10% speedup + const float step = (maxDim < 6.0f) ? 0.52f : (maxDim > 24.0f) ? 0.16666666f : 0.25f; // WLEDMM more detail on larger panels + + for (float i = 1.0f; i <= maxDim; i += step) { + unsigned i_20 = i * 20.0f; + float t_maxdim = t * (maxDim - i); + float angle = float(DEG_TO_RAD) * t_maxdim; + int mySin = sinf(angle) * i; + int myCos = cosf(angle) * i; + + if ((unsigned(colsCenter+mySin) < cols) && (unsigned(rowsCenter+myCos) < rows)) // don't draw invisible pixels + SEGMENT.setPixelColorXY(colsCenter+mySin, rowsCenter+myCos, ColorFromPalette(SEGPALETTE, i_20 + t_20, 255, LINEARBLEND)); + if ((SEGMENT.check1) && (unsigned(colsCenter+myCos) < cols) && (unsigned(rowsCenter+mySin) < rows)) + SEGMENT.setPixelColorXY(colsCenter+myCos, rowsCenter+mySin, ColorFromPalette(SEGPALETTE, i_20 + t_20, 255, LINEARBLEND)); // twin mode } - SEGMENT.blur(SEGMENT.intensity>>3); - + SEGMENT.blur(SEGMENT.intensity>>((!SEGMENT.check2) * 3), SEGMENT.check2); // user-defined blur - thanks @dedehai return FRAMETIME; } // mode_2DDrift() -static const char _data_FX_MODE_2DDRIFT[] PROGMEM = "Drift@Rotation speed,Blur amount;;!;2"; +static const char _data_FX_MODE_2DDRIFT[] PROGMEM = "Drift@Rotation speed,Blur,,,,Twin,Smear;;!;2;ix=0"; ////////////////////////// diff --git a/wled00/wled.h b/wled00/wled.h index ce0cc151..0993f8c0 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2411130 +#define VERSION 2411140 // WLEDMM - you can check for this define in usermods, to only enabled WLEDMM specific code in the "right" fork. Its not defined in AC WLED. #define _MoonModules_WLED_