diff --git a/wled00/FX.cpp b/wled00/FX.cpp index fc7a27d1..3f2fc264 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -4649,14 +4649,14 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so uint8_t rate = i * 255 / steps; byte dx = lerp8by8(x1, y1, rate); byte dy = lerp8by8(x2, y2, rate); - SEGMENT.setPixelColorXY(dx, dy, grad ? color.nscale8_video(255-rate) : color); // use addPixelColorXY for different look - //SEGMENT.addPixelColorXY(dx, dy, color); // use setPixelColorXY for different look - //if (grad) SEGMENT.fadePixelColorXY(dx, dy, rate); + //SEGMENT.setPixelColorXY(dx, dy, grad ? color.nscale8_video(255-rate) : color); // use addPixelColorXY for different look + SEGMENT.addPixelColorXY(dx, dy, color); // use setPixelColorXY for different look + if (grad) SEGMENT.fadePixelColorXY(dx, dy, rate); } if (dot) { //add white point at the ends of line - SEGMENT.addPixelColorXY(x1, x2, WHITE); - SEGMENT.addPixelColorXY(y1, y2, WHITE); + SEGMENT.setPixelColorXY(x1, x2, WHITE); + SEGMENT.setPixelColorXY(y1, y2, DARKSLATEGRAY); } } if (SEGMENT.custom3) SEGMENT.blur(SEGMENT.custom3/2); @@ -4725,7 +4725,9 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma for (size_t k = 1; k <= steps; k++) { uint8_t rate = k * 255 / steps; uint8_t dx = lerp8by8(x, x1, rate); - SEGMENT.setPixelColorXY(dx, i, ColorFromPalette(SEGPALETTE, hue, 255, LINEARBLEND).nscale8_video(rate)); + //SEGMENT.setPixelColorXY(dx, i, ColorFromPalette(SEGPALETTE, hue, 255, LINEARBLEND).nscale8_video(rate)); + SEGMENT.addPixelColorXY(dx, i, ColorFromPalette(SEGPALETTE, hue, 255, LINEARBLEND)); // use setPixelColorXY for different look + SEGMENT.fadePixelColorXY(dx, i, rate); } SEGMENT.setPixelColorXY(x, i, DARKSLATEGRAY); SEGMENT.setPixelColorXY(x1, i, WHITE); @@ -5099,11 +5101,12 @@ uint16_t mode_2DLissajous(void) { // By: Andrew Tuline for (int i=0; i < 256; i ++) { //float xlocn = float(sin8(now/4+i*(SEGMENT.speed>>5))) / 255.0f; //float ylocn = float(cos8(now/4+i*2)) / 255.0f; + //WLEDMM: stick to the original calculations of xlocn and ylocn uint8_t xlocn = sin8(strip.now/2+i*(SEGMENT.speed>>6)); uint8_t ylocn = cos8(strip.now/2+i*2); xlocn = map(xlocn,0,255,0,cols-1); ylocn = map(ylocn,0,255,0,rows-1); - SEGMENT.setPixelColorXY(xlocn, ylocn, SEGMENT.color_from_palette(strip.now/100+i, false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColorXY(xlocn, ylocn, SEGMENT.color_from_palette(millis()/100+i, false, PALETTE_SOLID_WRAP, 0)); } @@ -7336,6 +7339,61 @@ uint16_t mode_2DAkemi(void) { return FRAMETIME; } // mode_2DAkemi static const char _data_FX_MODE_2DAKEMI[] PROGMEM = "Akemi@Color speed,Dance;Head palette,Arms & Legs,Eyes & Mouth;Face palette;2f;si=0"; //beatsin + + +// Distortion waves - ldirko +// https://editor.soulmatelights.com/gallery/1089-distorsion-waves +// apated for WLD by @blazoncek +uint16_t mode_2Ddistortionwaves() { + if (!strip.isMatrix) return mode_static(); // not a 2D set-up + + const uint16_t cols = SEGMENT.virtualWidth(); + const uint16_t rows = SEGMENT.virtualHeight(); + + uint8_t speed = SEGMENT.speed/32; + uint8_t scale = SEGMENT.intensity/32; + + uint8_t w = 2; + + uint16_t a = millis()/32; + uint16_t a2 = a/2; + uint16_t a3 = a/3; + + uint16_t cx = beatsin8(10-speed,0,cols-1)*scale; + uint16_t cy = beatsin8(12-speed,0,rows-1)*scale; + uint16_t cx1 = beatsin8(13-speed,0,cols-1)*scale; + uint16_t cy1 = beatsin8(15-speed,0,rows-1)*scale; + uint16_t cx2 = beatsin8(17-speed,0,cols-1)*scale; + uint16_t cy2 = beatsin8(14-speed,0,rows-1)*scale; + + uint16_t xoffs = 0; + for (int x = 0; x < cols; x++) { + xoffs += scale; + uint16_t yoffs = 0; + + for (int y = 0; y < rows; y++) { + yoffs += scale; + + byte rdistort = cos8((cos8(((x<<3)+a )&255)+cos8(((y<<3)-a2)&255)+a3 )&255)>>1; + byte gdistort = cos8((cos8(((x<<3)-a2)&255)+cos8(((y<<3)+a3)&255)+a+32 )&255)>>1; + byte bdistort = cos8((cos8(((x<<3)+a3)&255)+cos8(((y<<3)-a) &255)+a2+64)&255)>>1; + + byte valueR = rdistort+ w* (a- ( ((xoffs - cx) * (xoffs - cx) + (yoffs - cy) * (yoffs - cy))>>7 )); + byte valueG = gdistort+ w* (a2-( ((xoffs - cx1) * (xoffs - cx1) + (yoffs - cy1) * (yoffs - cy1))>>7 )); + byte valueB = bdistort+ w* (a3-( ((xoffs - cx2) * (xoffs - cx2) + (yoffs - cy2) * (yoffs - cy2))>>7 )); + + valueR = gamma8(cos8(valueR)); + valueG = gamma8(cos8(valueG)); + valueB = gamma8(cos8(valueB)); + + SEGMENT.setPixelColorXY(x, y, RGBW32(valueR, valueG, valueB, 0)); + } + } + + return FRAMETIME; +} +static const char _data_FX_MODE_2DDISTORTIONWAVES[] PROGMEM = "Distortion Waves@!,Scale;;;2;"; + #endif // WLED_DISABLE_2D @@ -7534,6 +7592,7 @@ void WS2812FX::setupEffectData() { addEffect(FX_MODE_2DBLOBS, &mode_2Dfloatingblobs, _data_FX_MODE_2DBLOBS); addEffect(FX_MODE_2DSCROLLTEXT, &mode_2Dscrollingtext, _data_FX_MODE_2DSCROLLTEXT); addEffect(FX_MODE_2DDRIFTROSE, &mode_2Ddriftrose, _data_FX_MODE_2DDRIFTROSE); + addEffect(FX_MODE_2DDISTORTIONWAVES, &mode_2Ddistortionwaves, _data_FX_MODE_2DDISTORTIONWAVES); addEffect(FX_MODE_2DGEQ, &mode_2DGEQ, _data_FX_MODE_2DGEQ); // audio diff --git a/wled00/FX.h b/wled00/FX.h index 9898cd61..9ae94700 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -250,6 +250,7 @@ #define FX_MODE_2DBLOBS 121 //gap fill #define FX_MODE_2DSCROLLTEXT 122 //gap fill #define FX_MODE_2DDRIFTROSE 123 //gap fill +#define FX_MODE_2DDISTORTIONWAVES 124 // WLED-SR effects (SR compatible IDs !!!) #define FX_MODE_PIXELS 128 diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 0a7fee62..a6aecda3 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -173,7 +173,7 @@ void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col) //WLEDMM: if (leds) leds[XY(x,y)] = col; uint8_t _bri_t = currentBri(on ? opacity : 0); - if (!_bri_t) return; + if (!_bri_t && !transitional) return; if (_bri_t < 255) { byte r = scale8(R(col), _bri_t); byte g = scale8(G(col), _bri_t); @@ -281,7 +281,7 @@ void Segment::addPixelColorXY(int x, int y, uint32_t color) { void Segment::fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { CRGB pix = CRGB(getPixelColorXY(x,y)).nscale8_video(fade); - setPixelColor(x, y, pix); + setPixelColorXY(x, y, pix); } // blurRow: perform a blur on a row of a rectangular matrix diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 4c9c227e..52c0f04f 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -471,7 +471,7 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) { sOpt = extractModeDefaults(fx, "c1"); if (sOpt >= 0) custom1 = sOpt; sOpt = extractModeDefaults(fx, "c2"); if (sOpt >= 0) custom2 = sOpt; sOpt = extractModeDefaults(fx, "c3"); if (sOpt >= 0) custom3 = sOpt; - // sOpt = extractModeDefaults(fx, "m12"); if (sOpt >= 0) map1D2D = constrain(sOpt, 0, 7); + // sOpt = extractModeDefaults(fx, "m12"); if (sOpt >= 0) map1D2D = constrain(sOpt, 0, 7); WLEDMM: Disable for the time being as it disturbs other effects too much sOpt = extractModeDefaults(fx, "si"); if (sOpt >= 0) soundSim = constrain(sOpt, 0, 7); sOpt = extractModeDefaults(fx, "rev"); if (sOpt >= 0) reverse = (bool)sOpt; sOpt = extractModeDefaults(fx, "mi"); if (sOpt >= 0) mirror = (bool)sOpt; // NOTE: setting this option is a risky business @@ -768,8 +768,31 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col) //WLEDMM: IRAM_ATT // expand in circular fashion from center if (i==0) setPixelColorXY(0, 0, col); - else - drawArc(0, 0, i, col); //WLEDMM: drawArc will take care if drawing + else { + //WLEDMM: drawArc(0, 0, i, col); could work as alternative + + float step = HALF_PI / (2.85f*i); + for (float rad = 0.0f; rad <= HALF_PI+step/2; rad += step) { + // may want to try float version as well (with or without antialiasing) + int x = roundf(sin_t(rad) * i); + int y = roundf(cos_t(rad) * i); + setPixelColorXY(x, y, col); + } + // Bresenham’s Algorithm (may not fill every pixel) + //int d = 3 - (2*i); + //int y = i, x = 0; + //while (y >= x) { + // setPixelColorXY(x, y, col); + // setPixelColorXY(y, x, col); + // x++; + // if (d > 0) { + // y--; + // d += 4 * (x - y) + 10; + // } else { + // d += 4 * x + 6; + // } + //} + } break; case M12_pCorner: for (int x = 0; x <= i; x++) setPixelColorXY(x, i, col); @@ -824,7 +847,7 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col) //WLEDMM: IRAM_ATT uint16_t len = length(); uint8_t _bri_t = currentBri(on ? opacity : 0); - if (!_bri_t) return; + if (!_bri_t && !transitional) return; if (_bri_t < 255) { byte r = scale8(R(col), _bri_t); byte g = scale8(G(col), _bri_t); diff --git a/wled00/json.cpp b/wled00/json.cpp index eccc8ca9..2f7ee75f 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -232,13 +232,20 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) } #endif + #ifndef WLED_DISABLE_2D + bool reverse = seg.reverse; + bool mirror = seg.mirror; + #endif seg.selected = elem["sel"] | seg.selected; seg.reverse = elem["rev"] | seg.reverse; seg.mirror = elem["mi"] | seg.mirror; #ifndef WLED_DISABLE_2D - seg.reverse_y = elem["rY"] | seg.reverse_y; - seg.mirror_y = elem["mY"] | seg.mirror_y; - seg.transpose = elem[F("tp")] | seg.transpose; + bool reverse_y = seg.reverse_y; + bool mirror_y = seg.mirror_y; + seg.reverse_y = elem["rY"] | seg.reverse_y; + seg.mirror_y = elem["mY"] | seg.mirror_y; + seg.transpose = elem[F("tp")] | seg.transpose; + if (seg.is2D() && (seg.map1D2D == M12_pArc || seg.map1D2D == M12_sCircle) && (reverse != seg.reverse || reverse_y != seg.reverse_y || mirror != seg.mirror || mirror_y != seg.mirror_y)) seg.fill(BLACK); // clear entire segment (in case of Arc 1D to 2D expansion) WLEDMM: also Circle #endif byte fx = seg.mode;