Browse Source

garland: combine all wave-based anims; add wave comet anim

pull/2600/head
Dmitry Blinov 5 months ago
parent
commit
8ee5f7edb2
6 changed files with 113 additions and 102 deletions
  1. +5
    -4
      code/espurna/garland.cpp
  2. +0
    -48
      code/espurna/garland/animations/anim_crossing.h
  3. +0
    -32
      code/espurna/garland/animations/anim_run.h
  4. +82
    -10
      code/espurna/garland/animations/anim_waves.h
  5. +26
    -6
      code/espurna/garland/animations/color_wave.h
  6. +0
    -2
      code/espurna/garland/scene.h

+ 5
- 4
code/espurna/garland.cpp View File

@ -156,12 +156,11 @@ constexpr neoPixelType GarlandPixelType { NEO_GRB + NEO_KHZ800 };
Adafruit_NeoPixel pixels(GarlandLeds, GarlandPin, GarlandPixelType);
Scene<GarlandLeds> scene(&pixels);
std::array<Anim*, 17> anims {
std::array<Anim*, 18> anims {
new AnimStart(),
new AnimGlow(),
new AnimPixieDust(),
new AnimSparkr(),
new AnimRun(),
new AnimStars(),
new AnimSpread(),
new AnimRandCyc(),
@ -171,9 +170,11 @@ std::array<Anim*, 17> 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


+ 0
- 48
code/espurna/garland/animations/anim_crossing.h View File

@ -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

+ 0
- 32
code/espurna/garland/animations/anim_run.h View File

@ -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

+ 82
- 10
code/espurna/garland/animations/anim_waves.h View File

@ -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

+ 26
- 6
code/espurna/garland/animations/color_wave.h View File

@ -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;


+ 0
- 2
code/espurna/garland/scene.h View File

@ -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"


Loading…
Cancel
Save