Bugfix in vertical panel ledmap generation.
2D implementation of Fire 2012
This commit is contained in:
parent
cf189663a7
commit
b2409ac708
@ -1850,38 +1850,48 @@ uint16_t WS2812FX::mode_palette()
|
||||
uint16_t WS2812FX::mode_fire_2012()
|
||||
{
|
||||
uint32_t it = now >> 5; //div 32
|
||||
uint16_t nFlames = SEGMENT.virtualHeight();
|
||||
uint16_t q = SEGLEN>>2; // a quarter of segment
|
||||
|
||||
if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed
|
||||
if (!SEGENV.allocateData(SEGLEN*nFlames)) return mode_static(); //allocation failed
|
||||
|
||||
byte* heat = SEGENV.data;
|
||||
|
||||
if (it != SEGENV.step)
|
||||
{
|
||||
uint8_t ignition = max(7,SEGLEN/10); // ignition area: 10% of segment length or minimum 7 pixels
|
||||
for (uint16_t f = 0; f < nFlames; f++) {
|
||||
if (it != SEGENV.step) {
|
||||
uint8_t ignition = max(3,SEGLEN/10); // ignition area: 10% of segment length or minimum 3 pixels
|
||||
|
||||
// Step 1. Cool down every cell a little
|
||||
for (uint16_t i = 0; i < SEGLEN; i++) {
|
||||
uint8_t temp = qsub8(heat[i], random8(0, (((20 + SEGMENT.speed /3) * 10) / SEGLEN) + 2));
|
||||
heat[i] = (temp==0 && i<ignition) ? 16 : temp; // prevent ignition area from becoming black
|
||||
// Step 1. Cool down every cell a little
|
||||
for (uint16_t i = 0; i < SEGLEN; i++) {
|
||||
uint8_t cool = (((20 + SEGMENT.speed /3) * 10) / SEGLEN);
|
||||
// 2D enhancement: cool sides of the flame a bit more
|
||||
if (nFlames>1) {
|
||||
if (i < q) cool += (uint16_t)((cool * (q-i))/SEGLEN); // cool sides a bit more
|
||||
if (i > 3*q) cool += (uint16_t)((cool * (SEGLEN-i))/SEGLEN); // cool sides a bit more
|
||||
}
|
||||
uint8_t temp = qsub8(heat[i+SEGLEN*f], random8(0, cool + 2));
|
||||
heat[i+SEGLEN*f] = (temp==0 && i<ignition) ? 16 : temp; // prevent ignition area from becoming black
|
||||
}
|
||||
|
||||
// Step 2. Heat from each cell drifts 'up' and diffuses a little
|
||||
for (uint16_t k= SEGLEN -1; k > 1; k--) {
|
||||
heat[k+SEGLEN*f] = (heat[k+SEGLEN*f - 1] + (heat[k+SEGLEN*f - 2]<<1) ) / 3; // heat[k-2] multiplied by 2
|
||||
}
|
||||
|
||||
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
|
||||
if (random8() <= SEGMENT.intensity) {
|
||||
uint8_t y = random8(ignition);
|
||||
if (y < SEGLEN) heat[y+SEGLEN*f] = qadd8(heat[y+SEGLEN*f], random8(160,255));
|
||||
}
|
||||
SEGENV.step = it;
|
||||
}
|
||||
|
||||
// Step 2. Heat from each cell drifts 'up' and diffuses a little
|
||||
for (uint16_t k= SEGLEN -1; k > 1; k--) {
|
||||
heat[k] = (heat[k - 1] + (heat[k - 2]<<1) ) / 3; // heat[k-2] multiplied by 2
|
||||
// Step 4. Map from heat cells to LED colors
|
||||
for (uint16_t j = 0; j < SEGLEN; j++) {
|
||||
CRGB color = ColorFromPalette(currentPalette, MIN(heat[j],240), 255, LINEARBLEND);
|
||||
if (nFlames==1) setPixelColor(j, color);
|
||||
else setPixelColorXY(j, f, color);
|
||||
}
|
||||
|
||||
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
|
||||
if (random8() <= SEGMENT.intensity) {
|
||||
uint8_t y = random8(ignition);
|
||||
if (y < SEGLEN) heat[y] = qadd8(heat[y], random8(160,255));
|
||||
}
|
||||
SEGENV.step = it;
|
||||
}
|
||||
|
||||
// Step 4. Map from heat cells to LED colors
|
||||
for (uint16_t j = 0; j < SEGLEN; j++) {
|
||||
CRGB color = ColorFromPalette(currentPalette, MIN(heat[j],240), 255, LINEARBLEND);
|
||||
setPixelColor(j, color.red, color.green, color.blue);
|
||||
}
|
||||
return FRAMETIME;
|
||||
}
|
||||
|
@ -71,18 +71,15 @@ void WS2812FX::setUpMatrix() {
|
||||
startL = (matrix.vertical ? y : x) * panelW + (matrix.vertical ? x : y) * matrixWidth * panelH; // logical index (top-left corner)
|
||||
startP = p * panelW * panelH; // physical index (top-left corner)
|
||||
|
||||
for (uint16_t l=0; l<panelH; l++) {
|
||||
y = panel[h*j + i].bottomStart ? (panelH - l - 1) : l;
|
||||
for (uint16_t k=0; k<panelW; k++) {
|
||||
x = panel[h*j + i].rightStart ? (panelW - k - 1) : k;
|
||||
if (panel[h*j + i].vertical) {
|
||||
y = (panel[h*j + i].serpentine && x%2) ? (panelH - y - 1) : y;
|
||||
offset = y + x * panelH;
|
||||
} else {
|
||||
x = (panel[h*j + i].serpentine && y%2) ? (panelW - x - 1) : x;
|
||||
offset = x + y * panelW;
|
||||
}
|
||||
customMappingTable[startL + k + l * matrixWidth] = startP + offset;
|
||||
uint8_t H = panel[h*j + i].vertical ? panelW : panelH;
|
||||
uint8_t W = panel[h*j + i].vertical ? panelH : panelW;
|
||||
for (uint16_t l=0, q=0; l<H; l++) {
|
||||
for (uint16_t k=0; k<W; k++, q++) {
|
||||
y = (panel[h*j + i].vertical ? panel[h*j + i].rightStart : panel[h*j + i].bottomStart) ? H - l - 1 : l;
|
||||
x = (panel[h*j + i].vertical ? panel[h*j + i].bottomStart : panel[h*j + i].rightStart) ? W - k - 1 : k;
|
||||
x = (panel[h*j + i].serpentine && l%2) ? (W - x - 1) : x;
|
||||
offset = (panel[h*j + i].vertical ? y : x) + (panel[h*j + i].vertical ? x : y) * matrixWidth;
|
||||
customMappingTable[startL + offset] = startP + q;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user