From e3def22b07f7bd0547ded1c00d2026bdd4d7bbaf Mon Sep 17 00:00:00 2001 From: fishbone-git Date: Sat, 28 Dec 2019 15:43:55 +0100 Subject: [PATCH 1/7] add multi fireworks starburst effect --- wled00/FX.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++ wled00/FX.h | 9 ++-- 2 files changed, 122 insertions(+), 3 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index c862a0854..a9fc1f039 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -2348,3 +2348,119 @@ uint16_t WS2812FX::mode_candle() return FRAMETIME; } + +typedef struct Particle { + CRGB color; + uint32_t birth =0; + uint32_t last =0; + double vel =0; + uint16_t pos =0; + float fragment[40]; +} star; + +uint16_t WS2812FX::mode_starburst(void) { + uint32_t it = millis(); + + boolean Blend = true; + const uint8_t numStars = 10; + const uint8_t maxFrag = 15; + static star stars[numStars]; + float MaxSpeed = 375.0f; // Max velocity + int NewParticleProbability = 2; // Odds of new particle (out of 255) + float ParticlePreignitonTime = 0.0f; // How long to "wink" + float ParticleIgnition = 0.15f; // How long to "flash" + float ParticleHoldTime = 0.0f; // Main lifecycle time + float ParticleFadeTime = 1.4f; // Fade out time + float ParticleSize = 0.00f; // Size of the particle + + for (int j = 0; j < numStars; j++) + { + if (random8((265-SEGMENT.speed)/2) < NewParticleProbability && stars[j].birth==0) + { + // Pick a random color and location. + uint16_t startPos = random8(SEGLEN-1); + CRGB color = col_to_crgb(color_wheel(random8())); + double multiplier = (double)(random8())/255.0 * 0.5; + + stars[j].color = color; + stars[j].pos = startPos; + stars[j].vel = MaxSpeed * (double)(random16())/65535.0 * multiplier; + stars[j].birth = it; + stars[j].last = it; + int num = 10+SEGMENT.intensity * random8(5,maxFrag)/255; + + for (int i=0; i<=maxFrag; i++) { + if (i < num) stars[j].fragment[i] = startPos; + else stars[j].fragment[i] = -1; + } + } + } + + fill(BLACK); + + for (int j=0; j 0) { + float dt = (it-stars[j].last)/1000.0; + + for (int i=0; i<=maxFrag; i++) { + int var = i/2; + if (stars[j].fragment[i] > 0) { + if (i % 2) { + stars[j].fragment[i] -= stars[j].vel * dt * (float)var/6.0; + } else { + stars[j].fragment[i] += stars[j].vel * dt * (float)var/6.0; + } + } + } + stars[j].last = it; + stars[j].vel -= 2*stars[j].vel*dt; + stars[j].color = stars[j].color.nscale8_video(235); + } + + CRGB c = stars[j].color; + + // If the star is brand new, it flashes white briefly. + // Otherwise it just fades over time. + float fade = 0.0f; + float age = (it-stars[j].birth)/1000.0; + + if (age > ParticlePreignitonTime && age < ParticleIgnition + ParticlePreignitonTime) { + c = CRGB(WHITE); + } else { + // Figure out how much to fade and shrink the star based on + // its age relative to its lifetime + if (age < ParticlePreignitonTime) { + fade = 1.0 - (age / ParticlePreignitonTime); + } else { + age -= ParticlePreignitonTime; + if (age < ParticleHoldTime + ParticleIgnition) { + fade = 0.0f; // Just born + } else if (age > ParticleHoldTime + ParticleIgnition + ParticleFadeTime) { + fade = 1.0f; // Black hole, all faded out + stars[j].birth = 0; + } else { + age -= (ParticleHoldTime + ParticleIgnition); + fade = (age / ParticleFadeTime); // Fading star + } + } + c = c.nscale8_video(255-int(255.0*fade)); + } + ParticleSize = (1 - fade) * 5; + + for (int i=0; i<=maxFrag; i++) { + if (stars[j].fragment[i] > 0) { + int start = stars[j].fragment[i] - int(ParticleSize/2); + if (start<0) start = 0; + int end = stars[j].fragment[i] + int(ParticleSize/2); + if (end>SEGLEN-1) end = SEGLEN-1; + for (int p=start; p<=end; p++) { + setPixelColor(SEGMENT.start+p, c.r, c.g, c.b); + } + } + } + + } + + return FRAMETIME; +} \ No newline at end of file diff --git a/wled00/FX.h b/wled00/FX.h index 9ba70357d..f61cb4005 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -84,7 +84,7 @@ #define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE ) #define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED ) -#define MODE_COUNT 89 +#define MODE_COUNT 90 #define FX_MODE_STATIC 0 #define FX_MODE_BLINK 1 @@ -175,6 +175,7 @@ #define FX_MODE_SPOTS_FADE 86 #define FX_MODE_GLITTER 87 #define FX_MODE_CANDLE 88 +#define FX_MODE_STARBURST 89 class WS2812FX { @@ -321,6 +322,7 @@ class WS2812FX { _mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade; _mode[FX_MODE_GLITTER] = &WS2812FX::mode_glitter; _mode[FX_MODE_CANDLE] = &WS2812FX::mode_candle; + _mode[FX_MODE_STARBURST] = &WS2812FX::mode_starburst; _brightness = DEFAULT_BRIGHTNESS; currentPalette = CRGBPalette16(CRGB::Black); @@ -503,7 +505,8 @@ class WS2812FX { mode_spots(void), mode_spots_fade(void), mode_glitter(void), - mode_candle(void); + mode_candle(void), + mode_starburst(void); private: @@ -577,7 +580,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([ "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", "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 Starburst" ])====="; From 5efd1f3a918d1e90678ada1eb826fba268727ee9 Mon Sep 17 00:00:00 2001 From: fishbone-git Date: Mon, 30 Dec 2019 00:04:56 +0100 Subject: [PATCH 2/7] add comment for source and description --- wled00/FX.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index a9fc1f039..48048339d 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -2349,6 +2349,12 @@ uint16_t WS2812FX::mode_candle() return FRAMETIME; } + +/* +/ Fireworks in starburst effect +/ based on the video: https://www.reddit.com/r/arduino/comments/c3sd46/i_made_this_fireworks_effect_for_my_led_strips/ +/ Speed sets frequency of new starbursts, intensity is the intensity of the burst +*/ typedef struct Particle { CRGB color; uint32_t birth =0; From f187d7258b73013ae8605b7379eabe80c4c7114b Mon Sep 17 00:00:00 2001 From: fishbone-git Date: Mon, 30 Dec 2019 00:08:49 +0100 Subject: [PATCH 3/7] rework for slightly better visuals --- wled00/FX.cpp | 63 +++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 48048339d..501995ffb 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -2360,7 +2360,7 @@ typedef struct Particle { uint32_t birth =0; uint32_t last =0; double vel =0; - uint16_t pos =0; + uint16_t pos =-1; float fragment[40]; } star; @@ -2368,34 +2368,36 @@ uint16_t WS2812FX::mode_starburst(void) { uint32_t it = millis(); boolean Blend = true; - const uint8_t numStars = 10; - const uint8_t maxFrag = 15; + const uint8_t numStars = 12; + const uint8_t maxFrag = 20; static star stars[numStars]; float MaxSpeed = 375.0f; // Max velocity int NewParticleProbability = 2; // Odds of new particle (out of 255) float ParticlePreignitonTime = 0.0f; // How long to "wink" - float ParticleIgnition = 0.15f; // How long to "flash" + float ParticleIgnition = 0.06f; // How long to "flash" float ParticleHoldTime = 0.0f; // Main lifecycle time - float ParticleFadeTime = 1.4f; // Fade out time + float ParticleFadeTime = 2.6f; // Fade out time float ParticleSize = 0.00f; // Size of the particle for (int j = 0; j < numStars; j++) { - if (random8((265-SEGMENT.speed)/2) < NewParticleProbability && stars[j].birth==0) + // speed to adjust chance of a burst, max is nearly always. + if (random8((263-SEGMENT.speed)/2) < NewParticleProbability && stars[j].birth==0) { // Pick a random color and location. uint16_t startPos = random8(SEGLEN-1); CRGB color = col_to_crgb(color_wheel(random8())); - double multiplier = (double)(random8())/255.0 * 0.5; + double multiplier = (float)(random8())/255.0 * 1.0; stars[j].color = color; stars[j].pos = startPos; - stars[j].vel = MaxSpeed * (double)(random16())/65535.0 * multiplier; + stars[j].vel = MaxSpeed * (float)(random8())/255.0 * multiplier; stars[j].birth = it; stars[j].last = it; - int num = 10+SEGMENT.intensity * random8(5,maxFrag)/255; + // more fragments means larger burst effect + int num = random8(5,10 + (SEGMENT.intensity * maxFrag/255)); - for (int i=0; i<=maxFrag; i++) { + for (int i=0; i<40; i++) { if (i < num) stars[j].fragment[i] = startPos; else stars[j].fragment[i] = -1; } @@ -2406,12 +2408,14 @@ uint16_t WS2812FX::mode_starburst(void) { for (int j=0; j 0) { + if (stars[j].birth != 0) { float dt = (it-stars[j].last)/1000.0; for (int i=0; i<=maxFrag; i++) { int var = i/2; + if (stars[j].fragment[i] > 0) { + // spplit fragments half to each side with some travelling further if (i % 2) { stars[j].fragment[i] -= stars[j].vel * dt * (float)var/6.0; } else { @@ -2420,8 +2424,8 @@ uint16_t WS2812FX::mode_starburst(void) { } } stars[j].last = it; - stars[j].vel -= 2*stars[j].vel*dt; - stars[j].color = stars[j].color.nscale8_video(235); + stars[j].vel -= 3*stars[j].vel*dt; + stars[j].color = stars[j].color.nscale8(235); } CRGB c = stars[j].color; @@ -2430,7 +2434,7 @@ uint16_t WS2812FX::mode_starburst(void) { // Otherwise it just fades over time. float fade = 0.0f; float age = (it-stars[j].birth)/1000.0; - + if (age > ParticlePreignitonTime && age < ParticleIgnition + ParticlePreignitonTime) { c = CRGB(WHITE); } else { @@ -2439,34 +2443,33 @@ uint16_t WS2812FX::mode_starburst(void) { if (age < ParticlePreignitonTime) { fade = 1.0 - (age / ParticlePreignitonTime); } else { - age -= ParticlePreignitonTime; - if (age < ParticleHoldTime + ParticleIgnition) { - fade = 0.0f; // Just born - } else if (age > ParticleHoldTime + ParticleIgnition + ParticleFadeTime) { - fade = 1.0f; // Black hole, all faded out - stars[j].birth = 0; - } else { - age -= (ParticleHoldTime + ParticleIgnition); - fade = (age / ParticleFadeTime); // Fading star - } + age -= ParticlePreignitonTime; + if (age < ParticleHoldTime + ParticleIgnition) { + fade = 0.0f; // Just born + } else if (age > ParticleHoldTime + ParticleIgnition + ParticleFadeTime) { + fade = 1.0f; // Black hole, all faded out + stars[j].birth = 0; + } else { + age -= (ParticleHoldTime + ParticleIgnition); + fade = (age / ParticleFadeTime); // Fading star + } } - c = c.nscale8_video(255-int(255.0*fade)); + + c = c.nscale8(255-int(255.0*fade)/2); } - ParticleSize = (1 - fade) * 5; + ParticleSize = (1 - fade) * 4; for (int i=0; i<=maxFrag; i++) { if (stars[j].fragment[i] > 0) { - int start = stars[j].fragment[i] - int(ParticleSize/2); + int start = int(stars[j].fragment[i]) - int(ParticleSize/2); if (start<0) start = 0; - int end = stars[j].fragment[i] + int(ParticleSize/2); + int end = int(stars[j].fragment[i]) + int(ParticleSize/2); if (end>SEGLEN-1) end = SEGLEN-1; for (int p=start; p<=end; p++) { setPixelColor(SEGMENT.start+p, c.r, c.g, c.b); } } } - } - return FRAMETIME; } \ No newline at end of file From 1671c782609257ef9c84b630913c3c1010577ab3 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 31 Dec 2019 12:35:18 +0100 Subject: [PATCH 4/7] First working state --- wled00/FX.cpp | 29 ++++++++++++++--------------- wled00/wled00.ino | 2 +- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 193adfacc..a5a207336 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -2444,21 +2444,21 @@ uint16_t WS2812FX::mode_candle() / based on the video: https://www.reddit.com/r/arduino/comments/c3sd46/i_made_this_fireworks_effect_for_my_led_strips/ / Speed sets frequency of new starbursts, intensity is the intensity of the burst */ +#define STARBURST_MAX_FRAG 20 + typedef struct Particle { CRGB color; uint32_t birth =0; uint32_t last =0; double vel =0; uint16_t pos =-1; - float fragment[40]; + float fragment[STARBURST_MAX_FRAG]; } star; uint16_t WS2812FX::mode_starburst(void) { uint32_t it = millis(); - boolean Blend = true; const uint8_t numStars = 12; - const uint8_t maxFrag = 20; static star stars[numStars]; float MaxSpeed = 375.0f; // Max velocity int NewParticleProbability = 2; // Odds of new particle (out of 255) @@ -2466,15 +2466,14 @@ uint16_t WS2812FX::mode_starburst(void) { float ParticleIgnition = 0.06f; // How long to "flash" float ParticleHoldTime = 0.0f; // Main lifecycle time float ParticleFadeTime = 2.6f; // Fade out time - float ParticleSize = 0.00f; // Size of the particle for (int j = 0; j < numStars; j++) { // speed to adjust chance of a burst, max is nearly always. - if (random8((263-SEGMENT.speed)/2) < NewParticleProbability && stars[j].birth==0) + if (random8((263-SEGMENT.speed)>>1) < NewParticleProbability && stars[j].birth==0) { // Pick a random color and location. - uint16_t startPos = random8(SEGLEN-1); + uint16_t startPos = random16(SEGLEN-1); CRGB color = col_to_crgb(color_wheel(random8())); double multiplier = (float)(random8())/255.0 * 1.0; @@ -2484,9 +2483,9 @@ uint16_t WS2812FX::mode_starburst(void) { stars[j].birth = it; stars[j].last = it; // more fragments means larger burst effect - int num = random8(5,10 + (SEGMENT.intensity * maxFrag/255)); + int num = random8(5,10 + (SEGMENT.intensity * STARBURST_MAX_FRAG/255)); - for (int i=0; i<40; i++) { + for (int i=0; i < STARBURST_MAX_FRAG; i++) { if (i < num) stars[j].fragment[i] = startPos; else stars[j].fragment[i] = -1; } @@ -2500,7 +2499,7 @@ uint16_t WS2812FX::mode_starburst(void) { if (stars[j].birth != 0) { float dt = (it-stars[j].last)/1000.0; - for (int i=0; i<=maxFrag; i++) { + for (int i=0; i < STARBURST_MAX_FRAG; i++) { int var = i/2; if (stars[j].fragment[i] > 0) { @@ -2525,7 +2524,7 @@ uint16_t WS2812FX::mode_starburst(void) { float age = (it-stars[j].birth)/1000.0; if (age > ParticlePreignitonTime && age < ParticleIgnition + ParticlePreignitonTime) { - c = CRGB(WHITE); + c = CRGB(ULTRAWHITE); } else { // Figure out how much to fade and shrink the star based on // its age relative to its lifetime @@ -2546,19 +2545,19 @@ uint16_t WS2812FX::mode_starburst(void) { c = c.nscale8(255-int(255.0*fade)/2); } - ParticleSize = (1 - fade) * 4; + float ParticleSize = (1 - fade) * 4; - for (int i=0; i<=maxFrag; i++) { + for (int i=0; i < STARBURST_MAX_FRAG; i++) { if (stars[j].fragment[i] > 0) { int start = int(stars[j].fragment[i]) - int(ParticleSize/2); if (start<0) start = 0; int end = int(stars[j].fragment[i]) + int(ParticleSize/2); - if (end>SEGLEN-1) end = SEGLEN-1; - for (int p=start; p<=end; p++) { + if (end > SEGLEN) end = SEGLEN; + for (int p = start; p < end; p++) { setPixelColor(SEGMENT.start+p, c.r, c.g, c.b); } } } } return FRAMETIME; -} \ No newline at end of file +} diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 6a1a7b072..c77eae7ac 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -98,7 +98,7 @@ //version code in format yymmddb (b = daily build) -#define VERSION 1912311 +#define VERSION 1912312 char versionString[] = "0.9.0-b2"; From 8b6366688a37151b9e7ba1b75dd359eb50f2d180 Mon Sep 17 00:00:00 2001 From: fishbone-git Date: Tue, 31 Dec 2019 13:47:17 +0100 Subject: [PATCH 5/7] minor updates for cleanup --- wled00/FX.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 501995ffb..fa4bbef09 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -2359,25 +2359,23 @@ typedef struct Particle { CRGB color; uint32_t birth =0; uint32_t last =0; - double vel =0; + float vel =0; uint16_t pos =-1; - float fragment[40]; + float fragment[30]; } star; uint16_t WS2812FX::mode_starburst(void) { uint32_t it = millis(); - boolean Blend = true; - const uint8_t numStars = 12; - const uint8_t maxFrag = 20; + const uint8_t numStars = 12; // max starburtsts at one time + const uint8_t maxFrag = 20; // max fragments from each burst static star stars[numStars]; - float MaxSpeed = 375.0f; // Max velocity + int MaxSpeed = 375; // Max velocity int NewParticleProbability = 2; // Odds of new particle (out of 255) float ParticlePreignitonTime = 0.0f; // How long to "wink" - float ParticleIgnition = 0.06f; // How long to "flash" + float ParticleIgnition = 0.06f; // How long to "flash" float ParticleHoldTime = 0.0f; // Main lifecycle time float ParticleFadeTime = 2.6f; // Fade out time - float ParticleSize = 0.00f; // Size of the particle for (int j = 0; j < numStars; j++) { @@ -2387,7 +2385,7 @@ uint16_t WS2812FX::mode_starburst(void) { // Pick a random color and location. uint16_t startPos = random8(SEGLEN-1); CRGB color = col_to_crgb(color_wheel(random8())); - double multiplier = (float)(random8())/255.0 * 1.0; + float multiplier = (float)(random8())/255.0 * 1.0; stars[j].color = color; stars[j].pos = startPos; @@ -2397,7 +2395,7 @@ uint16_t WS2812FX::mode_starburst(void) { // more fragments means larger burst effect int num = random8(5,10 + (SEGMENT.intensity * maxFrag/255)); - for (int i=0; i<40; i++) { + for (int i=0; i<30; i++) { if (i < num) stars[j].fragment[i] = startPos; else stars[j].fragment[i] = -1; } @@ -2457,7 +2455,7 @@ uint16_t WS2812FX::mode_starburst(void) { c = c.nscale8(255-int(255.0*fade)/2); } - ParticleSize = (1 - fade) * 4; + float ParticleSize = (1 - fade) * 4; for (int i=0; i<=maxFrag; i++) { if (stars[j].fragment[i] > 0) { From 446e2c123f9ad0235ad37974bc12feb414467d5f Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 31 Dec 2019 16:37:44 +0100 Subject: [PATCH 6/7] More improvements --- wled00/FX.cpp | 61 ++++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index a5a207336..ebd22f679 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -2458,28 +2458,24 @@ typedef struct Particle { uint16_t WS2812FX::mode_starburst(void) { uint32_t it = millis(); - const uint8_t numStars = 12; + const uint8_t numStars = 4; static star stars[numStars]; - float MaxSpeed = 375.0f; // Max velocity - int NewParticleProbability = 2; // Odds of new particle (out of 255) - float ParticlePreignitonTime = 0.0f; // How long to "wink" - float ParticleIgnition = 0.06f; // How long to "flash" - float ParticleHoldTime = 0.0f; // Main lifecycle time - float ParticleFadeTime = 2.6f; // Fade out time + float maxSpeed = 375.0f; // Max velocity + float ParticleIgnition = 250.0f; // How long to "flash" + float ParticleFadeTime = 1500.0f; // Fade out time for (int j = 0; j < numStars; j++) { // speed to adjust chance of a burst, max is nearly always. - if (random8((263-SEGMENT.speed)>>1) < NewParticleProbability && stars[j].birth==0) + if (random8((144-(SEGMENT.speed >> 1))) == 0 && stars[j].birth == 0) { // Pick a random color and location. uint16_t startPos = random16(SEGLEN-1); - CRGB color = col_to_crgb(color_wheel(random8())); double multiplier = (float)(random8())/255.0 * 1.0; - stars[j].color = color; + stars[j].color = col_to_crgb(color_wheel(random8())); stars[j].pos = startPos; - stars[j].vel = MaxSpeed * (float)(random8())/255.0 * multiplier; + stars[j].vel = maxSpeed * (float)(random8())/255.0 * multiplier; stars[j].birth = it; stars[j].last = it; // more fragments means larger burst effect @@ -2492,7 +2488,7 @@ uint16_t WS2812FX::mode_starburst(void) { } } - fill(BLACK); + fill(SEGCOLOR(1)); for (int j=0; j> 1; if (stars[j].fragment[i] > 0) { // spplit fragments half to each side with some travelling further @@ -2513,7 +2509,6 @@ uint16_t WS2812FX::mode_starburst(void) { } stars[j].last = it; stars[j].vel -= 3*stars[j].vel*dt; - stars[j].color = stars[j].color.nscale8(235); } CRGB c = stars[j].color; @@ -2521,37 +2516,33 @@ uint16_t WS2812FX::mode_starburst(void) { // If the star is brand new, it flashes white briefly. // Otherwise it just fades over time. float fade = 0.0f; - float age = (it-stars[j].birth)/1000.0; + float age = it-stars[j].birth; - if (age > ParticlePreignitonTime && age < ParticleIgnition + ParticlePreignitonTime) { - c = CRGB(ULTRAWHITE); + if (age < ParticleIgnition) { + c = col_to_crgb(color_blend(ULTRAWHITE, crgb_to_col(c), 254.5f*((age / ParticleIgnition)))); } else { // Figure out how much to fade and shrink the star based on // its age relative to its lifetime - if (age < ParticlePreignitonTime) { - fade = 1.0 - (age / ParticlePreignitonTime); + if (age > ParticleIgnition + ParticleFadeTime) { + fade = 1.0f; // Black hole, all faded out + stars[j].birth = 0; + c = col_to_crgb(SEGCOLOR(1)); } else { - age -= ParticlePreignitonTime; - if (age < ParticleHoldTime + ParticleIgnition) { - fade = 0.0f; // Just born - } else if (age > ParticleHoldTime + ParticleIgnition + ParticleFadeTime) { - fade = 1.0f; // Black hole, all faded out - stars[j].birth = 0; - } else { - age -= (ParticleHoldTime + ParticleIgnition); - fade = (age / ParticleFadeTime); // Fading star - } + age -= ParticleIgnition; + fade = (age / ParticleFadeTime); // Fading star + byte f = 254.5f*fade; + c = col_to_crgb(color_blend(crgb_to_col(c), SEGCOLOR(1), f)); } - - c = c.nscale8(255-int(255.0*fade)/2); } - float ParticleSize = (1 - fade) * 4; + + float ParticleSize = (1.0 - fade) * 2; for (int i=0; i < STARBURST_MAX_FRAG; i++) { if (stars[j].fragment[i] > 0) { - int start = int(stars[j].fragment[i]) - int(ParticleSize/2); - if (start<0) start = 0; - int end = int(stars[j].fragment[i]) + int(ParticleSize/2); + int start = int(stars[j].fragment[i]) - int(ParticleSize); + if (start < 0) start = 0; + int end = int(stars[j].fragment[i]) + int(ParticleSize); + if (start == end) end++; if (end > SEGLEN) end = SEGLEN; for (int p = start; p < end; p++) { setPixelColor(SEGMENT.start+p, c.r, c.g, c.b); From 21b498fecec35a7fc5389a84f78106c3881b1629 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 31 Dec 2019 19:01:37 +0100 Subject: [PATCH 7/7] Memory optimizations --- wled00/FX.cpp | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index ebd22f679..3d8399954 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -2444,9 +2444,9 @@ uint16_t WS2812FX::mode_candle() / based on the video: https://www.reddit.com/r/arduino/comments/c3sd46/i_made_this_fireworks_effect_for_my_led_strips/ / Speed sets frequency of new starbursts, intensity is the intensity of the burst */ -#define STARBURST_MAX_FRAG 20 +#define STARBURST_MAX_FRAG 12 -typedef struct Particle { +typedef struct particle { CRGB color; uint32_t birth =0; uint32_t last =0; @@ -2458,11 +2458,11 @@ typedef struct Particle { uint16_t WS2812FX::mode_starburst(void) { uint32_t it = millis(); - const uint8_t numStars = 4; + const uint8_t numStars = 15; static star stars[numStars]; float maxSpeed = 375.0f; // Max velocity - float ParticleIgnition = 250.0f; // How long to "flash" - float ParticleFadeTime = 1500.0f; // Fade out time + float particleIgnition = 250.0f; // How long to "flash" + float particleFadeTime = 1500.0f; // Fade out time for (int j = 0; j < numStars; j++) { @@ -2471,7 +2471,7 @@ uint16_t WS2812FX::mode_starburst(void) { { // Pick a random color and location. uint16_t startPos = random16(SEGLEN-1); - double multiplier = (float)(random8())/255.0 * 1.0; + float multiplier = (float)(random8())/255.0 * 1.0; stars[j].color = col_to_crgb(color_wheel(random8())); stars[j].pos = startPos; @@ -2479,7 +2479,7 @@ uint16_t WS2812FX::mode_starburst(void) { stars[j].birth = it; stars[j].last = it; // more fragments means larger burst effect - int num = random8(5,10 + (SEGMENT.intensity * STARBURST_MAX_FRAG/255)); + int num = random8(3,6 + (SEGMENT.intensity >> 5)); for (int i=0; i < STARBURST_MAX_FRAG; i++) { if (i < num) stars[j].fragment[i] = startPos; @@ -2499,12 +2499,8 @@ uint16_t WS2812FX::mode_starburst(void) { int var = i >> 1; if (stars[j].fragment[i] > 0) { - // spplit fragments half to each side with some travelling further - if (i % 2) { - stars[j].fragment[i] -= stars[j].vel * dt * (float)var/6.0; - } else { - stars[j].fragment[i] += stars[j].vel * dt * (float)var/6.0; - } + //all fragments travel right, will be mirrored on other side + stars[j].fragment[i] += stars[j].vel * dt * (float)var/3.0; } } stars[j].last = it; @@ -2518,30 +2514,34 @@ uint16_t WS2812FX::mode_starburst(void) { float fade = 0.0f; float age = it-stars[j].birth; - if (age < ParticleIgnition) { - c = col_to_crgb(color_blend(ULTRAWHITE, crgb_to_col(c), 254.5f*((age / ParticleIgnition)))); + if (age < particleIgnition) { + c = col_to_crgb(color_blend(WHITE, crgb_to_col(c), 254.5f*((age / particleIgnition)))); } else { // Figure out how much to fade and shrink the star based on // its age relative to its lifetime - if (age > ParticleIgnition + ParticleFadeTime) { + if (age > particleIgnition + particleFadeTime) { fade = 1.0f; // Black hole, all faded out stars[j].birth = 0; c = col_to_crgb(SEGCOLOR(1)); } else { - age -= ParticleIgnition; - fade = (age / ParticleFadeTime); // Fading star + age -= particleIgnition; + fade = (age / particleFadeTime); // Fading star byte f = 254.5f*fade; c = col_to_crgb(color_blend(crgb_to_col(c), SEGCOLOR(1), f)); } } - float ParticleSize = (1.0 - fade) * 2; + float particleSize = (1.0 - fade) * 2; - for (int i=0; i < STARBURST_MAX_FRAG; i++) { + for (uint8_t index=0; index < STARBURST_MAX_FRAG*2; index++) { + bool mirrored = index & 0x1; + uint8_t i = index >> 1; if (stars[j].fragment[i] > 0) { - int start = int(stars[j].fragment[i]) - int(ParticleSize); + float loc = stars[j].fragment[i]; + if (mirrored) loc -= (loc-stars[j].pos)*2; + int start = loc - particleSize; + int end = loc + particleSize; if (start < 0) start = 0; - int end = int(stars[j].fragment[i]) + int(ParticleSize); if (start == end) end++; if (end > SEGLEN) end = SEGLEN; for (int p = start; p < end; p++) {