Browse Source

garland: add anim_crossing

pull/2600/head
Dmitry Blinov 5 months ago
parent
commit
eb55fe2c66
4 changed files with 132 additions and 6 deletions
  1. +8
    -5
      code/espurna/garland.cpp
  2. +97
    -0
      code/espurna/garland/animations/anim_crossing.h
  3. +25
    -1
      code/espurna/garland/palette.h
  4. +2
    -0
      code/espurna/garland/scene.h

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

@ -154,7 +154,7 @@ constexpr neoPixelType GarlandPixelType { NEO_GRB + NEO_KHZ800 };
Adafruit_NeoPixel pixels(GarlandLeds, GarlandPin, GarlandPixelType);
Scene<GarlandLeds> scene(&pixels);
std::array<Anim*, 16> anims {
std::array<Anim*, 17> anims {
new AnimStart(),
new AnimGlow(),
new AnimPixieDust(),
@ -171,6 +171,7 @@ std::array<Anim*, 16> anims {
new AnimFountain(),
new AnimWaves(),
new AnimRandRun(),
new AnimCrossing()
};
#define START_ANIMATION 0
@ -396,10 +397,12 @@ void garlandLoop(void) {
}
if (!scene_setup_done) {
Anim* newAnim = _currentAnim;
while (newAnim == _currentAnim) {
newAnim = anims[secureRandom(START_ANIMATION + 1, anims.size())];
}
// Anim* newAnim = _currentAnim;
// while (newAnim == _currentAnim) {
// newAnim = anims[secureRandom(START_ANIMATION + 1, anims.size())];
// }
Anim* newAnim = anims[16];
Palette* newPalette = _currentPalette;
while (newPalette == _currentPalette) {


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

@ -0,0 +1,97 @@
#if GARLAND_SUPPORT
#include "../anim.h"
#include "../color.h"
#include "../palette.h"
//------------------------------------------------------------------------------
class AnimCrossing : public Anim {
public:
AnimCrossing() : Anim("Crossing") {
}
void SetupImpl() override {
wave1 = generateWave();
wave2 = generateWave();
}
void Run() override {
for (int 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:
class ColorWave {
public:
uint16_t numLeds;
Palette* palette;
unsigned int waveLen; // wave length in leds (for clean colors - length of one color), also fade length
bool cleanColors; // if true - use clean colors from palette, else - use interpolated colors
int dir; // moving direction (1 or -1)
float speed; // wave moving speed
byte fade; // wave fade deep - 0 - no fade, 255 - fade to black
ColorWave() = default;
ColorWave(uint16_t _numLeds, Palette* _palette, unsigned int _waveLen, bool _cleanColors, bool _startEmpty, int _dir, float _speed, byte _fade)
: numLeds(_numLeds), palette(_palette), waveLen(_waveLen), cleanColors(_cleanColors), dir(_dir), speed(_speed), fade(_fade) {
if (_startEmpty) {
head = 0;
} else {
head = numLeds - 1;
}
fade_step = fade * 2 / waveLen;
DEBUG_MSG_P(PSTR("[GARLAND] fade_step = %d\n"), fade_step);
}
Color getLedColor(unsigned int ledNum) {
unsigned int real_led_num = dir > 0 ? ledNum : numLeds - ledNum - 1;
// DEBUG_MSG_P(PSTR("[GARLAND] real_led_num = %d, head = %d\n"), real_led_num, (unsigned int)head);
if (real_led_num > head) {
return Color();
}
if (cleanColors) {
unsigned int color_num = (head - real_led_num) / waveLen;
Color c = palette->getCleanColor(color_num);
// DEBUG_MSG_P(PSTR("[GARLAND] color_num = %d, color = %s\n"), color_num, c.to_str().c_str());
return c;
} else {
byte interp_color = (byte)((float)((uint16_t)(head - real_led_num) % numLeds) / (float)numLeds * (float)256);
return palette->getCachedPalColor(interp_color);
}
return Color();
}
void move() {
head = head + speed;
}
private:
float head;
byte fade_step;
};
ColorWave generateWave() {
unsigned int _waveLen = secureRandom(10, 30);
bool _cleanColors = secureRandom(10) > 5;
bool _startEmpty = secureRandom(10) > 5;
int _dir = secureRandom(10) > 5 ? 1 : -1;
float _speed = secureRandom(10, 30) / 10.0;
byte _fade = secureRandom(0, 256);
DEBUG_MSG_P(PSTR("[GARLAND] Wave created waveLen = %d cleanColors = %d startEmpty = %d dir = %d speed = %g fade = %d\n"), _waveLen, _cleanColors, _startEmpty, _dir, _speed, _fade);
return ColorWave(numLeds, palette, _waveLen, _cleanColors, _startEmpty, _dir, _speed, _fade);
}
ColorWave wave1;
ColorWave wave2;
};
#endif // GARLAND_SUPPORT

+ 25
- 1
code/espurna/garland/palette.h View File

@ -81,9 +81,33 @@ class Palette {
return bestColor;
}
Color getCleanColor(unsigned int i) const {
return _colors[i % _numColors];
}
Color getCloseCleanColor(const Color& refColor) const {
int bestDiff = 0;
Color bestColor;
for (unsigned int i = 0; i < _numColors; ++i) {
Color newColor = _colors[i];
int diff = refColor.howCloseTo(newColor);
if (bestDiff < diff) {
bestDiff = diff;
bestColor = newColor;
}
}
return bestColor;
}
Color getRndCleanColor() const {
return _colors[secureRandom(_numColors)];
}
private:
const char* _name;
const int _numColors;
const unsigned int _numColors;
std::vector<Color> _colors;
std::vector<Color> _cache;
};

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

@ -10,6 +10,7 @@ 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"
@ -44,6 +45,7 @@ public:
byte getBrightness() { return brightness; }
byte getSpeed() { return speed; }
float getCycleFactor(byte speed) { return (float)(GARLAND_SCENE_SPEED_MAX - speed) / GARLAND_SCENE_SPEED_FACTOR; }
const Palette* getPalette() const { return _palette; }
void setPalette(Palette* palette);
void setBrightness(byte value);


Loading…
Cancel
Save