diff --git a/wled00/FX.cpp b/wled00/FX.cpp index ba8d3cd8..65a583e6 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -8430,8 +8430,7 @@ uint16_t mode_GEQLASER(void) { } uint16_t horizon = map(SEGMENT.custom1,0,255,rows-1,0); - uint16_t distance = map8(SEGMENT.custom2,1,rows-1); - if (SEGMENT.custom2 == 255) distance = UINT16_MAX; + uint8_t depth = SEGMENT.custom2; // depth of perspective. 255 = infinite ("laser") for (int i=0; i<=split; i++) { // paint right vertical faces and top - LEFT to RIGHT @@ -8446,7 +8445,7 @@ uint16_t mode_GEQLASER(void) { int pPos = linex+(cols/NUM_BANDS)-1; for (int y = (i= pPos)) { // draw if above horizon AND not directly under projector (special case later) for (uint_fast8_t x=linex; x<=pPos;x++) { - SEGMENT.drawLine(x,rows-heights[i]-2,*projector,horizon,ledColorTemp,false,distance); // top perspective + SEGMENT.drawLine(x,rows-heights[i]-2,*projector,horizon,ledColorTemp,false,depth); // top perspective } } @@ -8476,7 +8475,7 @@ uint16_t mode_GEQLASER(void) { ledColorTemp = color_fade(ledColor,32,true); for (uint_fast8_t y = (i>0) ? heights[i-1] : 0; y <= heights[i]; y++) { // don't bother drawing what we'll hide anyway - SEGMENT.drawLine(linex,rows-y-1,*projector,horizon,ledColorTemp,false,distance); // left side perspective + SEGMENT.drawLine(linex,rows-y-1,*projector,horizon,ledColorTemp,false,depth); // left side perspective } ledColorTemp = color_fade(ledColor,128,true); @@ -8484,7 +8483,7 @@ uint16_t mode_GEQLASER(void) { if (heights[i] < rows-horizon && (*projector <=linex || *projector >= pPos)) { // draw if above horizon AND not directly under projector (special case later) for (uint_fast8_t x=linex; x<=pPos;x++) { - SEGMENT.drawLine(x,rows-heights[i]-2,*projector,horizon,ledColorTemp,false,distance); // top perspective + SEGMENT.drawLine(x,rows-heights[i]-2,*projector,horizon,ledColorTemp,false,depth); // top perspective } } @@ -8509,7 +8508,7 @@ uint16_t mode_GEQLASER(void) { ledColorTemp = color_fade(ledColor,128,true); for (uint_fast8_t x=linex; x<=pPos;x++) { - SEGMENT.drawLine(x,rows-heights[i]-2,*projector,horizon,ledColorTemp,false,distance); // top perspective + SEGMENT.drawLine(x,rows-heights[i]-2,*projector,horizon,ledColorTemp,false,depth); // top perspective } } @@ -8546,7 +8545,7 @@ uint16_t mode_GEQLASER(void) { return FRAMETIME; } -static const char _data_FX_MODE_GEQLASER[] PROGMEM = "GEQ 3D ☾@Speed,Front Fill,Horizon,Distance,Num Bands,Borders,,;!,,Peaks;!;2f;sx=255,ix=255,c1=255,c2=255,c3=255,pal=11"; +static const char _data_FX_MODE_GEQLASER[] PROGMEM = "GEQ 3D ☾@Speed,Front Fill,Horizon,Depth,Num Bands,Borders,,;!,,Peaks;!;2f;sx=255,ix=255,c1=255,c2=255,c3=255,pal=11"; #endif // WLED_DISABLE_2D diff --git a/wled00/FX.h b/wled00/FX.h index fbc84737..af707b41 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -697,8 +697,8 @@ typedef struct Segment { inline void drawCircle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c, bool soft = false) { drawCircle(cx, cy, radius, RGBW32(c.r,c.g,c.b,0), soft); } void fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t c, bool soft = false); inline void fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c, bool soft = false) { fillCircle(cx, cy, radius, RGBW32(c.r,c.g,c.b,0), soft); } - void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c, bool soft = false, uint16_t distance = UINT16_MAX); - inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, bool soft = false, uint16_t distance = UINT16_MAX) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0), soft, distance); } // automatic inline + void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c, bool soft = false, uint8_t depth = UINT8_MAX); + inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, bool soft = false, uint8_t depth = UINT8_MAX) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0), soft, depth); } // automatic inline void drawArc(uint16_t x0, uint16_t y0, uint16_t radius, uint32_t color, uint32_t fillColor = 0); inline void drawArc(uint16_t x0, uint16_t y0, uint16_t radius, CRGB color, CRGB fillColor = BLACK) { drawArc(x0, y0, radius, RGBW32(color.r,color.g,color.b,0), RGBW32(fillColor.r,fillColor.g,fillColor.b,0)); } // automatic inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2 = 0); diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 95786b8d..0a79a856 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -676,7 +676,7 @@ void Segment::nscale8(uint8_t scale) { //WLEDMM: use fast types } //line function -void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c, bool soft, uint16_t distance) { +void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c, bool soft, uint8_t depth) { if (!isActive()) return; // not active // if (Segment::maxHeight==1) return; // not a matrix set-up const int cols = virtualWidth(); @@ -693,6 +693,17 @@ void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint3 if (_bri_t < 255) scaled_col = color_fade(c, _bri_t); } + // WLEDMM shorten line according to depth + if (depth < UINT8_MAX) { + if (depth<2) {x1 = x0; y1=y0; } // single pixel + else { + int dx1 = ((int(x1) - int(x0)) * int(depth)) / 255; // X distance, scaled down by depth + int dy1 = ((int(y1) - int(y0)) * int(depth)) / 255; // Y distance, scaled down by depth + x1 = x0 + dx1; + y1 = y0 + dy1; + } + } + const int dx = abs(x1-x0), sx = x0dy ? dx : -dy)/2; // error direction - for (uint_fast16_t d=0; d= cols || y0 >= rows) break; // WLEDMM we hit the edge - should never happen if (simpleSegment) setPixelColorXY_fast(x0, y0, c, scaled_col, cols, rows); else setPixelColorXY(x0, y0, c);