From 8ee5f7edb20d892d6c224397192ad8d632d6ba13 Mon Sep 17 00:00:00 2001 From: Dmitry Blinov Date: Tue, 19 Dec 2023 12:09:45 +0200 Subject: [PATCH] garland: combine all wave-based anims; add wave comet anim --- code/espurna/garland.cpp | 9 +- .../garland/animations/anim_crossing.h | 48 ---------- code/espurna/garland/animations/anim_run.h | 32 ------- code/espurna/garland/animations/anim_waves.h | 92 +++++++++++++++++-- code/espurna/garland/animations/color_wave.h | 32 +++++-- code/espurna/garland/scene.h | 2 - 6 files changed, 113 insertions(+), 102 deletions(-) delete mode 100644 code/espurna/garland/animations/anim_crossing.h delete mode 100644 code/espurna/garland/animations/anim_run.h diff --git a/code/espurna/garland.cpp b/code/espurna/garland.cpp index 6966fb32..186e6485 100644 --- a/code/espurna/garland.cpp +++ b/code/espurna/garland.cpp @@ -156,12 +156,11 @@ constexpr neoPixelType GarlandPixelType { NEO_GRB + NEO_KHZ800 }; Adafruit_NeoPixel pixels(GarlandLeds, GarlandPin, GarlandPixelType); Scene scene(&pixels); -std::array anims { +std::array anims { new AnimStart(), new AnimGlow(), new AnimPixieDust(), new AnimSparkr(), - new AnimRun(), new AnimStars(), new AnimSpread(), new AnimRandCyc(), @@ -171,9 +170,11 @@ std::array anims { new AnimDolphins(), new AnimSalut(), new AnimFountain(), - new AnimWaves(), new AnimRandRun(), - new AnimCrossing() + new AnimWaves(AnimWaves::Type::LongWaves), + new AnimWaves(AnimWaves::Type::ShortWaves), + new AnimWaves(AnimWaves::Type::Comets), + new AnimWaves(AnimWaves::Type::CrossWaves), }; #define START_ANIMATION 0 diff --git a/code/espurna/garland/animations/anim_crossing.h b/code/espurna/garland/animations/anim_crossing.h deleted file mode 100644 index e02c9a38..00000000 --- a/code/espurna/garland/animations/anim_crossing.h +++ /dev/null @@ -1,48 +0,0 @@ -#if GARLAND_SUPPORT - -#include "../anim.h" -#include "../color.h" -#include "../palette.h" -#include "color_wave.h" - -//------------------------------------------------------------------------------ -class AnimCrossing : public Anim { - public: - AnimCrossing() : Anim("Crossing") { - } - - void SetupImpl() override { - - wave1 = generateWave(1, ledstmp); - wave2 = generateWave(-1); - } - - void Run() override { - for (auto i = 0; i < numLeds; ++i) { - leds[i] = wave1.getLedColor(i); - leds[i] = leds[i].interpolate(wave2.getLedColor(i), 0.5); - } - - wave1.move(); - wave2.move(); - } - - private: - - - ColorWave generateWave(int dir, Color* pixelCache = nullptr) { - unsigned int waveLen = secureRandom(10, 50); - bool cleanColors = fiftyFifty(); - bool startEmpty = fiftyFifty(); - float speed = secureRandom(5, 20) / 10.0; - byte fade = fiftyFifty() ? 0 : palette->bright() ? secureRandom(180, 220) : 120; - Palette* wavePal = &pals[secureRandom(palsNum)]; - - return ColorWave(numLeds, wavePal, waveLen, cleanColors, fade, pixelCache, speed, dir, startEmpty); - } - - ColorWave wave1; - ColorWave wave2; -}; - -#endif // GARLAND_SUPPORT diff --git a/code/espurna/garland/animations/anim_run.h b/code/espurna/garland/animations/anim_run.h deleted file mode 100644 index b7732206..00000000 --- a/code/espurna/garland/animations/anim_run.h +++ /dev/null @@ -1,32 +0,0 @@ -#if GARLAND_SUPPORT - -#include "../anim.h" -#include "../color.h" -#include "../palette.h" -#include "color_wave.h" - -//------------------------------------------------------------------------------ -class AnimRun : public Anim { - public: - AnimRun() : Anim("Run") { - } - - void SetupImpl() override { - unsigned int waveLen = secureRandom(10, 30); - bool cleanColors = secureRandom(10) > 7; - byte fade = palette->bright() ? secureRandom(180, 220) : 0; - wave = ColorWave(numLeds, palette, waveLen, cleanColors, fade, ledstmp); - } - - void Run() override { - for (auto i = 0; i < numLeds; ++i) { - leds[i] = wave.getLedColor(i); - } - - wave.move(); - } - - ColorWave wave; -}; - -#endif // GARLAND_SUPPORT diff --git a/code/espurna/garland/animations/anim_waves.h b/code/espurna/garland/animations/anim_waves.h index b80cfcd8..a0b585be 100644 --- a/code/espurna/garland/animations/anim_waves.h +++ b/code/espurna/garland/animations/anim_waves.h @@ -7,29 +7,101 @@ //------------------------------------------------------------------------------ class AnimWaves : public Anim { public: - AnimWaves() : Anim("Waves") { + enum Type { + LongWaves, + ShortWaves, + Comets, + CrossWaves, + }; + + AnimWaves(Type _type) : Anim("Waves"), type(_type) { } void SetupImpl() override { - unsigned int waveLen = secureRandom(50, 100); - bool cleanColors = secureRandom(10) > 7; - byte fade = palette->bright() ? secureRandom(180, 220) : 0; - wave = ColorWave(numLeds, palette, waveLen, cleanColors, fade, ledstmp); + switch (type) { + case LongWaves: + wave1 = generateLongWave(); + break; + case ShortWaves: + wave1 = generateShortWave(); + break; + case Comets: + wave1 = generateCometWave(); + break; + case CrossWaves: + WaveType wave1Type = secureRandom(100) > 70 ? WaveType::Comet : WaveType::Wave; + wave1 = generateCrossingWave(1, wave1Type, ledstmp); + + WaveType wave2Type = secureRandom(100) > 60 ? WaveType::Comet : WaveType::Wave; + + // if first wave is comet - inverse second wave probability to be comer to 60% + if (wave1Type == WaveType::Comet) { + wave2Type = wave2Type == WaveType::Comet ? WaveType::Wave : WaveType::Comet; + } + + // we have only one pixel array for cache + wave2 = generateCrossingWave(-1, wave2Type, nullptr); + break; + } glowSetUp(); } void Run() override { for (auto i = 0; i < numLeds; ++i) { - leds[i] = wave.getLedColor(i); - glowForEachLed(i); + leds[i] = wave1.getLedColor(i); + + if (type == LongWaves) { + glowForEachLed(i); + } + } + + wave1.move(); + + if (type == LongWaves) { + glowRun(); + } else if (type == CrossWaves) { + for (auto i = 0; i < numLeds; ++i) { + leds[i] = leds[i].interpolate(wave2.getLedColor(i), 0.5); + } + + wave2.move(); } + } + + private: + ColorWave generateLongWave() { + unsigned int waveLen = secureRandom(50, 100); + bool cleanColors = secureRandom(10) > 7; + return ColorWave(numLeds, palette, waveLen, cleanColors, 0, ledstmp); + } + + ColorWave generateShortWave() { + unsigned int waveLen = secureRandom(10, 30); + bool cleanColors = secureRandom(10) > 7; + byte fade = palette->bright() ? secureRandom(180, 220) : 0; + return ColorWave(numLeds, palette, waveLen, cleanColors, fade, ledstmp); + } + + ColorWave generateCometWave() { + unsigned int waveLen = secureRandom(10, 40); + bool cleanColors = secureRandom(10) > 5; + return ColorWave(numLeds, palette, waveLen, cleanColors, 0, ledstmp, WaveType::Comet); + } - wave.move(); + ColorWave generateCrossingWave(int dir, WaveType waveType, Color* pixelCache) { + unsigned int waveLen = secureRandom(10, 50); + bool cleanColors = fiftyFifty(); + bool startEmpty = fiftyFifty(); + float speed = secureRandom(5, 20) / 10.0; + byte fade = fiftyFifty() ? 0 : palette->bright() ? secureRandom(180, 220) : 120; + Palette* wavePal = &pals[secureRandom(palsNum)]; - glowRun(); + return ColorWave(numLeds, wavePal, waveLen, cleanColors, fade, pixelCache, waveType, speed, dir, startEmpty); } - ColorWave wave; + Type type; + ColorWave wave1; + ColorWave wave2; }; #endif // GARLAND_SUPPORT diff --git a/code/espurna/garland/animations/color_wave.h b/code/espurna/garland/animations/color_wave.h index 1175a359..30ea6f69 100644 --- a/code/espurna/garland/animations/color_wave.h +++ b/code/espurna/garland/animations/color_wave.h @@ -1,5 +1,10 @@ #pragma once +enum WaveType { + Wave, + Comet +}; + class ColorWave { public: ColorWave() = default; @@ -9,6 +14,7 @@ class ColorWave { _waveLen - wave length in leds (for clean colors - length of one color), also fade length _cleanColors - if true - use clean colors from palette, else - use interpolated colors _fade - wave fade deep: 0 - no fade, 255 - fade to black + _pixelCache - pointer to array of Color with numLeds size, if not null - use it for caching colors _speed - wave moving speed (0.5 - 2.0) _dir - moving direction (1 or -1) _startEmpty - if true - start wave from empty leds, else - start from full leds @@ -20,20 +26,26 @@ class ColorWave { bool _cleanColors, byte _fade = 0, Color* _pixelCache = nullptr, + WaveType _type = WaveType::Wave, float _speed = secureRandom(5, 15) / 10.0, int _dir = randDir(), bool _startEmpty = false) - : numLeds(_numLeds), palette(_palette), waveLen(_waveLen), cleanColors(_cleanColors), fade(_fade), pixelCache(_pixelCache), speed(_speed), dir(_dir) { + : numLeds(_numLeds), palette(_palette), waveLen(_waveLen), cleanColors(_cleanColors), fade(_fade), pixelCache(_pixelCache), type(_type), speed(_speed), dir(_dir) { if (speed < 0) { speed = -speed; dir = -dir; } head = _startEmpty ? 0 : numLeds - 1; - fade_step = fade * 2 / waveLen; - DEBUG_MSG_P(PSTR("[GARLAND] Wave: waveLen = %d Pal: %-8s fade = %d cleanColors = %d speed = %d\n"), - waveLen, palette->name(), fade, cleanColors, (int)(speed * 10.0)); + if (type == WaveType::Wave) { + fade_step = fade * 2 / waveLen; + } else { + fade_step = 255 / waveLen; + } + + DEBUG_MSG_P(PSTR("[GARLAND] Wave: waveLen = %d Pal: %-8s fade = %d cleanColors = %d speed = %d, type = %d\n"), + waveLen, palette->name(), fade, cleanColors, (int)(speed * 10.0), type); if (pixelCache) { for (auto i = 0; i < numLeds; ++i) { @@ -57,8 +69,15 @@ class ColorWave { Color c = cleanColors ? palette->getCleanColor(dist_to_head / waveLen) : palette->getCachedPalColor(dist_to_head * 256 * 20 / waveLen / numLeds); if (fade_step > 0) { - byte fadeFactor = 255 - abs(waveLen / 2 - (dist_to_head % waveLen)) * fade_step; - c = c.brightness(fadeFactor); + byte bright = 255; + + if (type == WaveType::Wave) { + bright -= fade_step * abs(waveLen / 2 - (dist_to_head % waveLen)); + } else { + bright -= fade_step * (dist_to_head % waveLen); + } + + c = c.brightness(bright); } if (pixelCache) { @@ -91,6 +110,7 @@ class ColorWave { bool cleanColors; byte fade; Color* pixelCache; + WaveType type; float speed; int dir; float head; diff --git a/code/espurna/garland/scene.h b/code/espurna/garland/scene.h index a597f963..10d50cd1 100644 --- a/code/espurna/garland/scene.h +++ b/code/espurna/garland/scene.h @@ -10,7 +10,6 @@ Inspired by https://github.com/Vasil-Pahomov/ArWs2812 (currently https://github. #include "anim.h" #include "animations/anim_assemble.h" #include "animations/anim_comets.h" -#include "animations/anim_crossing.h" #include "animations/anim_dolphins.h" #include "animations/anim_fountain.h" #include "animations/anim_fly.h" @@ -18,7 +17,6 @@ Inspired by https://github.com/Vasil-Pahomov/ArWs2812 (currently https://github. #include "animations/anim_pixiedust.h" #include "animations/anim_randrun.h" #include "animations/anim_randcyc.h" -#include "animations/anim_run.h" #include "animations/anim_salut.h" #include "animations/anim_sparkr.h" #include "animations/anim_spread.h"