Merge pull request #3961 from Brandon502/0_15
Added Pinwheel Expand 1D ->2D effect mapping mode
This commit is contained in:
@@ -355,7 +355,7 @@ typedef enum mapping1D2D {
|
|||||||
M12_jMap = 4, //WLEDMM jMap
|
M12_jMap = 4, //WLEDMM jMap
|
||||||
M12_sCircle = 5, //WLEDMM Circle
|
M12_sCircle = 5, //WLEDMM Circle
|
||||||
M12_sBlock = 6, //WLEDMM Block
|
M12_sBlock = 6, //WLEDMM Block
|
||||||
M12_sPinWheel = 7 //WLEDMM PinWheel
|
M12_sPinwheel = 7 //WLEDMM Pinwheel
|
||||||
} mapping1D2D_t;
|
} mapping1D2D_t;
|
||||||
|
|
||||||
// segment, 72 bytes
|
// segment, 72 bytes
|
||||||
|
|||||||
@@ -793,14 +793,41 @@ void Segment::deletejMap() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// WLEDMM constants for mapping mode "Pinwheel"
|
// Constants for mapping mode "Pinwheel"
|
||||||
constexpr int Pinwheel_Steps_Medium = 208; // no holes up to 32x32; 60fps
|
#ifndef WLED_DISABLE_2D
|
||||||
constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
|
constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16
|
||||||
constexpr int Pinwheel_Steps_Big = 360; // no holes expected up to 58x58; 40fps
|
constexpr int Pinwheel_Size_Small = 16; // larger than this -> use "Medium"
|
||||||
constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...208 to Radians
|
constexpr int Pinwheel_Steps_Medium = 192; // no holes up to 32x32
|
||||||
constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...360 to Radians
|
constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
|
||||||
// WLEDMM end
|
constexpr int Pinwheel_Steps_Big = 304; // no holes up to 50x50
|
||||||
|
constexpr int Pinwheel_Size_Big = 50; // larger than this -> use "XL"
|
||||||
|
constexpr int Pinwheel_Steps_XL = 368;
|
||||||
|
constexpr float Int_to_Rad_Small = (DEG_TO_RAD * 360) / Pinwheel_Steps_Small; // conversion: from 0...72 to Radians
|
||||||
|
constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...192 to Radians
|
||||||
|
constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...304 to Radians
|
||||||
|
constexpr float Int_to_Rad_XL = (DEG_TO_RAD * 360) / Pinwheel_Steps_XL; // conversion: from 0...368 to Radians
|
||||||
|
|
||||||
|
constexpr int Fixed_Scale = 512; // fixpoint scaling factor (9bit for fraction)
|
||||||
|
|
||||||
|
// Pinwheel helper function: pixel index to radians
|
||||||
|
static float getPinwheelAngle(int i, int vW, int vH) {
|
||||||
|
int maxXY = max(vW, vH);
|
||||||
|
if (maxXY <= Pinwheel_Size_Small) return float(i) * Int_to_Rad_Small;
|
||||||
|
if (maxXY <= Pinwheel_Size_Medium) return float(i) * Int_to_Rad_Med;
|
||||||
|
if (maxXY <= Pinwheel_Size_Big) return float(i) * Int_to_Rad_Big;
|
||||||
|
// else
|
||||||
|
return float(i) * Int_to_Rad_XL;
|
||||||
|
}
|
||||||
|
// Pinwheel helper function: matrix dimensions to number of rays
|
||||||
|
static int getPinwheelLength(int vW, int vH) {
|
||||||
|
int maxXY = max(vW, vH);
|
||||||
|
if (maxXY <= Pinwheel_Size_Small) return Pinwheel_Steps_Small;
|
||||||
|
if (maxXY <= Pinwheel_Size_Medium) return Pinwheel_Steps_Medium;
|
||||||
|
if (maxXY <= Pinwheel_Size_Big) return Pinwheel_Steps_Big;
|
||||||
|
// else
|
||||||
|
return Pinwheel_Steps_XL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// 1D strip
|
// 1D strip
|
||||||
uint16_t Segment::virtualLength() const {
|
uint16_t Segment::virtualLength() const {
|
||||||
@@ -831,12 +858,8 @@ uint16_t Segment::virtualLength() const {
|
|||||||
else
|
else
|
||||||
vLen = max(vW,vH) * 0.5; // get the longest dimension
|
vLen = max(vW,vH) * 0.5; // get the longest dimension
|
||||||
break;
|
break;
|
||||||
case M12_sPinWheel: //WLEDMM
|
case M12_sPinwheel:
|
||||||
//vLen = full circle
|
vLen = getPinwheelLength(vW, vH);
|
||||||
if (max(vW,vH) <= Pinwheel_Size_Medium)
|
|
||||||
vLen = Pinwheel_Steps_Medium;
|
|
||||||
else
|
|
||||||
vLen = Pinwheel_Steps_Big;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return vLen;
|
return vLen;
|
||||||
@@ -978,32 +1001,46 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col) //WLEDMM: IRAM_ATT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case M12_sPinWheel: { // WLEDMM
|
case M12_sPinwheel: {
|
||||||
// i = angle --> 0 through 359 (Big), OR 0 through 208 (Medium)
|
// i = angle --> 0 - 296 (Big), 0 - 192 (Medium), 0 - 72 (Small)
|
||||||
float centerX = roundf((vW-1) / 2.0f);
|
float centerX = roundf((vW-1) / 2.0f);
|
||||||
float centerY = roundf((vH-1) / 2.0f);
|
float centerY = roundf((vH-1) / 2.0f);
|
||||||
// int maxDistance = sqrt(centerX * centerX + centerY * centerY) + 1;
|
float angleRad = getPinwheelAngle(i, vW, vH); // angle in radians
|
||||||
float angleRad = (max(vW,vH) > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med; // angle in radians
|
|
||||||
float cosVal = cosf(angleRad);
|
float cosVal = cosf(angleRad);
|
||||||
float sinVal = sinf(angleRad);
|
float sinVal = sinf(angleRad);
|
||||||
|
|
||||||
|
// avoid re-painting the same pixel
|
||||||
|
int lastX = INT_MIN; // impossible position
|
||||||
|
int lastY = INT_MIN; // impossible position
|
||||||
// draw line at angle, starting at center and ending at the segment edge
|
// draw line at angle, starting at center and ending at the segment edge
|
||||||
// we use fixed point math for better speed. Starting distance is 0.5 for better rounding
|
// we use fixed point math for better speed. Starting distance is 0.5 for better rounding
|
||||||
constexpr int_fast32_t Fixed_Scale = 512; // fixpoint scaling factor
|
// int_fast16_t and int_fast32_t types changed to int, minimum bits commented
|
||||||
int_fast32_t posx = (centerX + 0.5f * cosVal) * Fixed_Scale; // X starting position in fixed point
|
int posx = (centerX + 0.5f * cosVal) * Fixed_Scale; // X starting position in fixed point 18 bit
|
||||||
int_fast32_t posy = (centerY + 0.5f * sinVal) * Fixed_Scale; // Y starting position in fixed point
|
int posy = (centerY + 0.5f * sinVal) * Fixed_Scale; // Y starting position in fixed point 18 bit
|
||||||
int_fast16_t inc_x = cosVal * Fixed_Scale; // X increment per step (fixed point)
|
int inc_x = cosVal * Fixed_Scale; // X increment per step (fixed point) 10 bit
|
||||||
int_fast16_t inc_y = sinVal * Fixed_Scale; // Y increment per step (fixed point)
|
int inc_y = sinVal * Fixed_Scale; // Y increment per step (fixed point) 10 bit
|
||||||
|
|
||||||
int32_t maxX = vW * Fixed_Scale; // X edge in fixedpoint
|
int32_t maxX = vW * Fixed_Scale; // X edge in fixedpoint
|
||||||
int32_t maxY = vH * Fixed_Scale; // Y edge in fixedpoint
|
int32_t maxY = vH * Fixed_Scale; // Y edge in fixedpoint
|
||||||
// draw until we hit any edge
|
|
||||||
while ((posx > 0) && (posy > 0) && (posx < maxX) && (posy < maxY)) {
|
// Odd rays start further from center if prevRay started at center.
|
||||||
|
static int prevRay = INT_MIN; // previous ray number
|
||||||
|
if ((i % 2 == 1) && (i - 1 == prevRay || i + 1 == prevRay)) {
|
||||||
|
int jump = min(vW/3, vH/3); // can add 2 if using medium pinwheel
|
||||||
|
posx += inc_x * jump;
|
||||||
|
posy += inc_y * jump;
|
||||||
|
}
|
||||||
|
prevRay = i;
|
||||||
|
|
||||||
|
// draw ray until we hit any edge
|
||||||
|
while ((posx >= 0) && (posy >= 0) && (posx < maxX) && (posy < maxY)) {
|
||||||
// scale down to integer (compiler will replace division with appropriate bitshift)
|
// scale down to integer (compiler will replace division with appropriate bitshift)
|
||||||
int x = posx / Fixed_Scale;
|
int x = posx / Fixed_Scale;
|
||||||
int y = posy / Fixed_Scale;
|
int y = posy / Fixed_Scale;
|
||||||
// set pixel
|
// set pixel
|
||||||
setPixelColorXY(x, y, col);
|
if (x != lastX || y != lastY) setPixelColorXY(x, y, col); // only paint if pixel position is different
|
||||||
|
lastX = x;
|
||||||
|
lastY = y;
|
||||||
// advance to next position
|
// advance to next position
|
||||||
posx += inc_x;
|
posx += inc_x;
|
||||||
posy += inc_y;
|
posy += inc_y;
|
||||||
@@ -1154,16 +1191,36 @@ uint32_t Segment::getPixelColor(int i)
|
|||||||
else
|
else
|
||||||
return getPixelColorXY(vW / 2, vH / 2 - i - 1);
|
return getPixelColorXY(vW / 2, vH / 2 - i - 1);
|
||||||
break;
|
break;
|
||||||
case M12_sPinWheel: //WLEDMM
|
case M12_sPinwheel:
|
||||||
// not 100% accurate, returns outer edge of circle
|
// not 100% accurate, returns pixel at outer edge
|
||||||
float distance = max(1.0f, min(vH-1, vW-1) / 2.0f);
|
// i = angle --> 0 - 296 (Big), 0 - 192 (Medium), 0 - 72 (Small)
|
||||||
float centerX = (vW - 1) / 2.0f;
|
float centerX = roundf((vW-1) / 2.0f);
|
||||||
float centerY = (vH - 1) / 2.0f;
|
float centerY = roundf((vH-1) / 2.0f);
|
||||||
float angleRad = (max(vW,vH) > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med; // angle in radians
|
float angleRad = getPinwheelAngle(i, vW, vH); // angle in radians
|
||||||
int x = roundf(centerX + distance * cosf(angleRad));
|
float cosVal = cosf(angleRad);
|
||||||
int y = roundf(centerY + distance * sinf(angleRad));
|
float sinVal = sinf(angleRad);
|
||||||
|
|
||||||
|
int posx = (centerX + 0.5f * cosVal) * Fixed_Scale; // X starting position in fixed point 18 bit
|
||||||
|
int posy = (centerY + 0.5f * sinVal) * Fixed_Scale; // Y starting position in fixed point 18 bit
|
||||||
|
int inc_x = cosVal * Fixed_Scale; // X increment per step (fixed point) 10 bit
|
||||||
|
int inc_y = sinVal * Fixed_Scale; // Y increment per step (fixed point) 10 bit
|
||||||
|
int32_t maxX = vW * Fixed_Scale; // X edge in fixedpoint
|
||||||
|
int32_t maxY = vH * Fixed_Scale; // Y edge in fixedpoint
|
||||||
|
|
||||||
|
// trace ray from center until we hit any edge - to avoid rounding problems, we use the same method as in setPixelColor
|
||||||
|
int x = INT_MIN;
|
||||||
|
int y = INT_MIN;
|
||||||
|
while ((posx >= 0) && (posy >= 0) && (posx < maxX) && (posy < maxY)) {
|
||||||
|
// scale down to integer (compiler will replace division with appropriate bitshift)
|
||||||
|
x = posx / Fixed_Scale;
|
||||||
|
y = posy / Fixed_Scale;
|
||||||
|
// advance to next position
|
||||||
|
posx += inc_x;
|
||||||
|
posy += inc_y;
|
||||||
|
}
|
||||||
return getPixelColorXY(x, y);
|
return getPixelColorXY(x, y);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user