better handling of perspective
drawLine parameter "depth" shortens a line by a fraction - useful for VP perspective (vanishing point)
This commit is contained in:
@@ -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<NUM_BANDS-1) ? heights[i+1] : 0; y <= heights[i]; y++) { // don't bother drawing what we'll hide anyway
|
||||
SEGMENT.drawLine(pPos,rows-y-1,*projector,horizon,ledColorTemp,false,distance); // right side perspective
|
||||
SEGMENT.drawLine(pPos,rows-y-1,*projector,horizon,ledColorTemp,false,depth); // right side perspective
|
||||
}
|
||||
|
||||
ledColorTemp = color_fade(ledColor,128,true);
|
||||
@@ -8454,7 +8453,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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 = x0<x1 ? 1 : -1; // x distance & step
|
||||
const int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; // y distance & step
|
||||
|
||||
@@ -732,7 +743,7 @@ void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint3
|
||||
} else {
|
||||
// Bresenham's algorithm
|
||||
int err = (dx>dy ? dx : -dy)/2; // error direction
|
||||
for (uint_fast16_t d=0; d<distance; d++) {
|
||||
for (;;) {
|
||||
// if (x0 >= 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);
|
||||
|
||||
Reference in New Issue
Block a user