add exploding fireworks

This commit is contained in:
fishbone-git 2019-12-27 20:58:06 +01:00
parent 6122a8371a
commit 50082043ef
2 changed files with 131 additions and 3 deletions

View File

@ -2348,3 +2348,125 @@ uint16_t WS2812FX::mode_candle()
return FRAMETIME; return FRAMETIME;
} }
/*
* Exploding fireworks effect
* adapted from: http://www.anirama.com/1000leds/1d-fireworks/
*/
#define NUM_SPARKS 60 // max number (could be NUM_LEDS / 2);
uint16_t WS2812FX::mode_exploding_fireworks(void)
{
if (SEGENV.aux1==0) { // manage states using params
flare();
} else {
explode();
}
return FRAMETIME;
}
static float sparkPos[NUM_SPARKS];
static float sparkVel[NUM_SPARKS];
static float sparkCol[NUM_SPARKS];
static float flarePos;
static float flareVel;
static float brightness;
void WS2812FX::flare() {
float gravity = -0.02 - (SEGMENT.speed/10000.0); // m/s/s
if (SEGENV.aux0 == 0) { //use aux0 for initialization flag
flarePos = 0;
flareVel = float(random16(150, 190)) / (75+SEGMENT.intensity/4); // trial and error to get reasonable range
brightness = 1;
Serial.printf("%3.1f %3.3f %3d",flareVel,gravity,SEGMENT.intensity);
Serial.println("");
// initialize launch sparks
for (int i = 0; i < 5; i++) {
sparkPos[i] = 0;
sparkVel[i] = (float(random8(100,255)) / 255.0) * (flareVel/ 3.0); // random around 20% of flare velocity
sparkCol[i] = sparkVel[i] * 1000.0;
sparkCol[i] = constrain(sparkCol[i], 0, 255);
}
SEGENV.aux0=1;
}
// launch
if (flareVel >= -.3) {
// sparks
for (int i = 0; i < 5; i++) {
sparkPos[i] += sparkVel[i];
sparkPos[i] = constrain(sparkPos[i], 0, SEGLEN-1);
sparkVel[i] += gravity;
sparkCol[i] += -.8;
sparkCol[i] = constrain(sparkCol[i], 0, 255);
CRGB color = HeatColor(sparkCol[i]);
setPixelColor(SEGMENT.stop - int(sparkPos[i]),color.red,color.green,color.blue);
}
// flare
fade_out(255);
setPixelColor(SEGMENT.stop - int(flarePos),brightness*255,brightness*255,brightness*255);
flarePos += flareVel;
flarePos = constrain(flarePos, 0, SEGLEN-1);
flareVel += gravity;
brightness *= .975;
} else {
SEGENV.aux0=0; // allow next state to init
SEGENV.aux1=1; // ready to explode
}
}
/*
* Explode!
*
* Explosion happens where the flare ended.
* Size is proportional to the height.
*/
void WS2812FX::explode() {
int nSparks = flarePos / 2; // works out to look about right
nSparks = constrain(nSparks,0,NUM_SPARKS);
static float dying_gravity;
float gravity = -0.02 - (SEGMENT.speed/10000.0);
float c1=120;
float c2=50;
// initialize sparks
if (SEGENV.aux0==0) {
for (int i = 0; i < nSparks; i++) {
sparkPos[i] = flarePos;
sparkVel[i] = (float(random16(0, 20000)) / 10000.0) - 1.0; // from -1 to 1
sparkCol[i] = abs(sparkVel[i] * 500.0); // set colors before scaling velocity to keep them bright
sparkCol[i] = constrain(sparkCol[i], 0, 255);
sparkVel[i] *= flarePos / SEGLEN; // proportional to height
}
sparkCol[0] = 255; // this will be our known spark
dying_gravity = gravity;
SEGENV.aux0=1;
}
if (sparkCol[0] > c2/10 ) {//&& sparkPos[0] > 0) { // as long as our known spark is lit, work with all the sparks
fade_out(255);
for (int i = 0; i < nSparks; i++) {
sparkPos[i] += sparkVel[i];
sparkPos[i] = constrain(sparkPos[i], 0, SEGLEN-1);
sparkVel[i] += dying_gravity;
sparkCol[i] *= .97;
sparkCol[i] = constrain(sparkCol[i], 0, 255); // red cross dissolve
if(sparkCol[i] > c1) { // fade white to yellow
setPixelColor(SEGMENT.stop - sparkPos[i],255, 255, (255 * (sparkCol[i] - c1)) / (255 - c1));
} else if (sparkCol[i] < c2) { // fade from red to black
setPixelColor(SEGMENT.stop - sparkPos[i],(255 * sparkCol[i]) / c2, 0, 0);
} else { // fade from yellow to red
setPixelColor(SEGMENT.stop - sparkPos[i],255, (255 * (sparkCol[i] - c2)) / (c1 - c2), 0);
}
}
dying_gravity *= .995; // as sparks burn out they fall slower
} else {
SEGENV.aux0=0;
SEGENV.aux1=0;
}
}

View File

@ -84,7 +84,7 @@
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE ) #define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED ) #define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
#define MODE_COUNT 89 #define MODE_COUNT 90
#define FX_MODE_STATIC 0 #define FX_MODE_STATIC 0
#define FX_MODE_BLINK 1 #define FX_MODE_BLINK 1
@ -175,6 +175,7 @@
#define FX_MODE_SPOTS_FADE 86 #define FX_MODE_SPOTS_FADE 86
#define FX_MODE_GLITTER 87 #define FX_MODE_GLITTER 87
#define FX_MODE_CANDLE 88 #define FX_MODE_CANDLE 88
#define FX_MODE_EXPLODING_FIREWORKS 89
class WS2812FX { class WS2812FX {
@ -321,6 +322,8 @@ class WS2812FX {
_mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade; _mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade;
_mode[FX_MODE_GLITTER] = &WS2812FX::mode_glitter; _mode[FX_MODE_GLITTER] = &WS2812FX::mode_glitter;
_mode[FX_MODE_CANDLE] = &WS2812FX::mode_candle; _mode[FX_MODE_CANDLE] = &WS2812FX::mode_candle;
_mode[FX_MODE_EXPLODING_FIREWORKS] = &WS2812FX::mode_exploding_fireworks;
_brightness = DEFAULT_BRIGHTNESS; _brightness = DEFAULT_BRIGHTNESS;
currentPalette = CRGBPalette16(CRGB::Black); currentPalette = CRGBPalette16(CRGB::Black);
@ -359,6 +362,8 @@ class WS2812FX {
resetSegments(), resetSegments(),
setPixelColor(uint16_t n, uint32_t c), setPixelColor(uint16_t n, uint32_t c),
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
flare(void),
explode(void),
show(void); show(void);
bool bool
@ -503,7 +508,8 @@ class WS2812FX {
mode_spots(void), mode_spots(void),
mode_spots_fade(void), mode_spots_fade(void),
mode_glitter(void), mode_glitter(void),
mode_candle(void); mode_candle(void),
mode_exploding_fireworks(void);
private: private:
@ -577,7 +583,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([
"Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet", "Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
"Dual Scanner","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise", "Dual Scanner","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Smooth Meteor","Railway","Ripple", "Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Smooth Meteor","Railway","Ripple",
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle" "Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks 1D"
])====="; ])=====";