mirror of
https://github.com/xoseperez/espurna.git
synced 2026-03-06 16:27:12 +01:00
garland: updates (#2412)
- Update README.md - add garland description - Add new animation - Dolphins
This commit is contained in:
@@ -80,18 +80,15 @@ Palette pals[] = {
|
||||
Palette("Lime", {0x51f000, 0x6fff00, 0x96ff00, 0xc9ff00, 0xf0ff00}),
|
||||
|
||||
// Pastel: Pastel Fruity Mixture
|
||||
Palette("Pastel", {0x75aa68, 0x5960ae, 0xe4be6c, 0xca5959, 0x8366ac}),
|
||||
|
||||
// Green: Vibrant greens
|
||||
Palette("Green", {0x89ff01, 0x42c501, 0x349404, 0x0f6902, 0x004208})};
|
||||
Palette("Pastel", {0x75aa68, 0x5960ae, 0xe4be6c, 0xca5959, 0x8366ac})};
|
||||
|
||||
constexpr size_t palsSize() { return sizeof(pals)/sizeof(pals[0]); }
|
||||
|
||||
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(GARLAND_LEDS, GARLAND_D_PIN, NEO_GRB + NEO_KHZ800);
|
||||
Scene scene(&pixels);
|
||||
|
||||
Anim* anims[] = {new AnimStart(), new AnimPixieDust(), new AnimSparkr(), new AnimRun(), new AnimStars(),
|
||||
new AnimSpread(), new AnimRandCyc(), new AnimFly(), new AnimComets(), new AnimAssemble()};
|
||||
Anim* anims[] = {new AnimStart(), new AnimPixieDust(), new AnimSparkr(), new AnimRun(), new AnimStars(), new AnimSpread(),
|
||||
new AnimRandCyc(), new AnimFly(), new AnimComets(), new AnimAssemble(), new AnimDolphins(), new AnimSalut()};
|
||||
|
||||
constexpr size_t animsSize() { return sizeof(anims)/sizeof(anims[0]); }
|
||||
|
||||
@@ -434,12 +431,12 @@ void Anim::Setup(Palette* palette, uint16_t numLeds, Color* leds, Color* ledstmp
|
||||
}
|
||||
|
||||
void Anim::initSeq() {
|
||||
for (int i = 0; i < numLeds; i++)
|
||||
for (int i = 0; i < numLeds; ++i)
|
||||
seq[i] = i;
|
||||
}
|
||||
|
||||
void Anim::shuffleSeq() {
|
||||
for (int i = 0; i < numLeds; i++) {
|
||||
for (int i = 0; i < numLeds; ++i) {
|
||||
byte ind = (unsigned int)(rngb() * numLeds / 256);
|
||||
if (ind != i) {
|
||||
std::swap(seq[ind], seq[i]);
|
||||
|
||||
@@ -19,7 +19,7 @@ class AnimAssemble : public Anim {
|
||||
}
|
||||
|
||||
int p = 0;
|
||||
for (int i = 0; i < numLeds; i++) {
|
||||
for (int i = 0; i < numLeds; ++i) {
|
||||
leds[i] = 0;
|
||||
Color c = palette->getCachedPalColor((byte)p);
|
||||
ledstmp[i] = c;
|
||||
|
||||
@@ -19,7 +19,7 @@ class AnimComets : public Anim {
|
||||
}
|
||||
|
||||
void Run() override {
|
||||
for (int i = 0; i < numLeds; i++) leds[i] = 0;
|
||||
for (int i = 0; i < numLeds; ++i) leds[i] = 0;
|
||||
|
||||
for (auto& c : comets) {
|
||||
int tail = c.head + c.len * -c.dir;
|
||||
|
||||
118
code/espurna/garland/animations/anim_dolphins.h
Normal file
118
code/espurna/garland/animations/anim_dolphins.h
Normal file
@@ -0,0 +1,118 @@
|
||||
#if GARLAND_SUPPORT
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../anim.h"
|
||||
#include "../color.h"
|
||||
#include "../palette.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class AnimDolphins : public Anim {
|
||||
public:
|
||||
AnimDolphins() : Anim("Dolphins") {
|
||||
cycleFactor = 3;
|
||||
}
|
||||
|
||||
void SetupImpl() override {
|
||||
dolphins.clear();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
dolphins.emplace_back(palette, numLeds);
|
||||
}
|
||||
|
||||
void Run() override {
|
||||
for (int i = 0; i < numLeds; ++i) {
|
||||
leds[i] = 0;
|
||||
seq[i] = 0;
|
||||
}
|
||||
|
||||
// Run dolphins animation. Fill seq (accupied space)
|
||||
for (auto& d : dolphins)
|
||||
d.Run(leds, seq);
|
||||
|
||||
// Try to recreate dolphins that have been done
|
||||
for (auto& d : dolphins) {
|
||||
if (d.done) {
|
||||
for (int i = 1; i < 5; ++i) {
|
||||
Dolphin new_dolphin(palette, numLeds);
|
||||
if (new_dolphin.HaveEnoughSpace(seq)) {
|
||||
std::swap(d, new_dolphin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct Dolphin {
|
||||
bool done = false;
|
||||
int len = secureRandom(10, 20);
|
||||
int speed = secureRandom(1, 3);
|
||||
int dir = 1;
|
||||
int head = 0;
|
||||
int start;
|
||||
Color color;
|
||||
std::vector<Color> points;
|
||||
Dolphin(Palette* pal, uint16_t numLeds) : start(secureRandom(0, numLeds - len)), color(pal->getRndInterpColor()), points(len) {
|
||||
// DEBUG_MSG_P(PSTR("[GARLAND] Dolphin created start = %d len = %d dir = %d cr = %d cg = %d cb = %d\n"), start, len, dir, color.r, color.g, color.b);
|
||||
if (secureRandom(10) > 5) {
|
||||
start = numLeds - start;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
int halflen = len / 2;
|
||||
for (int i = 0; i < halflen; ++i) {
|
||||
points[i] = points[len-i-1] = Color((byte)(color.r * i / halflen), (byte)(color.g * i / halflen), (byte)(color.b * i / halflen));
|
||||
// DEBUG_MSG_P(PSTR("[GARLAND] Dolphin i=%d cr = %d cg = %d cb = %d\n"), i, points[i].r, points[i].g, points[i].b);
|
||||
}
|
||||
if (len > halflen * 2) {
|
||||
points[halflen] = color;
|
||||
}
|
||||
}
|
||||
|
||||
bool Run(Color* leds, byte* seq) {
|
||||
if (done)
|
||||
return false;
|
||||
|
||||
int p = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
p = head - i;
|
||||
if (p >= 0 && p < len) {
|
||||
leds[start + p * dir] = points[i];
|
||||
}
|
||||
}
|
||||
|
||||
head += speed;
|
||||
|
||||
// if tail moved out of len then dolphin is done
|
||||
if (p >= len) {
|
||||
done = true;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// dolphin accupy space for future movement
|
||||
int s = p < 0 ? 0 : p;
|
||||
for (int i = s; i < len; ++i) {
|
||||
seq[start + i * dir] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Decide that dolphin have ehough space if seq of len before it is empty
|
||||
bool HaveEnoughSpace(byte* seq) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (seq[start + i * dir] != 0) {
|
||||
// DEBUG_MSG_P(PSTR("[GARLAND] Dolphin chaven't enouhg space to move.\n"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<Dolphin> dolphins;
|
||||
};
|
||||
|
||||
#endif // GARLAND_SUPPORT
|
||||
@@ -27,7 +27,7 @@ class AnimPixieDust : public Anim {
|
||||
|
||||
void Run() override {
|
||||
if (inc > 0) {
|
||||
for (int i = 0; i < numLeds; i++) {
|
||||
for (int i = 0; i < numLeds; ++i) {
|
||||
leds[i] = (i > phase) ? prevColor : curColor;
|
||||
glowForEachLed(i);
|
||||
}
|
||||
@@ -38,7 +38,7 @@ class AnimPixieDust : public Anim {
|
||||
curColor = palette->getRndInterpColor();
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < numLeds; i++) {
|
||||
for (int i = 0; i < numLeds; ++i) {
|
||||
leds[i] = (i < phase) ? prevColor : curColor;
|
||||
glowForEachLed(i);
|
||||
}
|
||||
|
||||
@@ -10,12 +10,12 @@ class AnimRandCyc : public Anim {
|
||||
}
|
||||
|
||||
void SetupImpl() override {
|
||||
for (int i = 0; i < numLeds; i++)
|
||||
for (int i = 0; i < numLeds; ++i)
|
||||
seq[i] = rngb();
|
||||
}
|
||||
|
||||
void Run() override {
|
||||
for (int i = 0; i < numLeds; i++) {
|
||||
for (int i = 0; i < numLeds; ++i) {
|
||||
leds[i] = palette->getCachedPalColor(seq[i]);
|
||||
seq[i] += rngb() >> 6;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class AnimRun : public Anim {
|
||||
|
||||
void Run() override {
|
||||
int p = pos;
|
||||
for (int i = 0; i < numLeds; i++) {
|
||||
for (int i = 0; i < numLeds; ++i) {
|
||||
Color c = palette->getCachedPalColor((byte)p);
|
||||
leds[i] = c;
|
||||
|
||||
|
||||
92
code/espurna/garland/animations/anim_salut.h
Normal file
92
code/espurna/garland/animations/anim_salut.h
Normal file
@@ -0,0 +1,92 @@
|
||||
#if GARLAND_SUPPORT
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../anim.h"
|
||||
#include "../color.h"
|
||||
#include "../palette.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class AnimSalut : public Anim {
|
||||
public:
|
||||
AnimSalut() : Anim("Salut") {
|
||||
}
|
||||
|
||||
void SetupImpl() override {
|
||||
shots.clear();
|
||||
// There can be more then one shot at the moment
|
||||
// but looks like one is enough
|
||||
// for (int i = 0; i < 3; ++i)
|
||||
shots.emplace_back(palette, numLeds);
|
||||
}
|
||||
|
||||
void Run() override {
|
||||
for (int i = 0; i < numLeds; ++i) leds[i] = 0;
|
||||
|
||||
for (auto& c : shots) {
|
||||
if (!c.Run(leds)) {
|
||||
Shot new_shot(palette, numLeds);
|
||||
std::swap(c, new_shot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct Shot {
|
||||
private:
|
||||
struct Spark {
|
||||
bool done = false;
|
||||
float speed = ((float)secureRandom(1, 25)) / 10;
|
||||
float speed_dec = ((float)secureRandom(1, 3)) / 10;
|
||||
float pos;
|
||||
int dir;
|
||||
Color color;
|
||||
uint16_t numLeds;
|
||||
Spark(int pos, Palette* pal, uint16_t numLeds) : pos(pos), dir(secureRandom(10) > 5 ? -1 : 1), color(pal->getRndInterpColor()), numLeds(numLeds) {}
|
||||
void Run(Color* leds) {
|
||||
if (pos >= 0 && pos < numLeds) {
|
||||
leds[(int)pos] = color;
|
||||
if (speed > 0) {
|
||||
pos += speed * dir;
|
||||
speed -= speed_dec;
|
||||
} else {
|
||||
color.fade(5);
|
||||
if (color.empty()) {
|
||||
if (secureRandom(10) > 8)
|
||||
leds[(int)pos] = 0xFFFFFF;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
int spark_num = secureRandom(30, 40);
|
||||
int center;
|
||||
std::vector<Spark> sparks;
|
||||
Shot(Palette* pal, uint16_t numLeds) : center(secureRandom(15, numLeds - 15)) {
|
||||
// DEBUG_MSG_P(PSTR("[GARLAND] Shot created center = %d spark_num = %d\n"), center, spark_num);
|
||||
sparks.reserve(spark_num);
|
||||
for (int i = 0; i < spark_num; ++i) {
|
||||
sparks.emplace_back(center, pal, numLeds);
|
||||
}
|
||||
}
|
||||
bool Run(Color* leds) {
|
||||
bool done = true;
|
||||
for (auto& s : sparks) {
|
||||
if (!s.done) {
|
||||
done = false;
|
||||
s.Run(leds);
|
||||
}
|
||||
}
|
||||
return !done;
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<Shot> shots;
|
||||
};
|
||||
|
||||
#endif // GARLAND_SUPPORT
|
||||
@@ -21,7 +21,7 @@ class AnimSparkr : public Anim {
|
||||
}
|
||||
|
||||
void Run() override {
|
||||
for (int i = 0; i < numLeds; i++) {
|
||||
for (int i = 0; i < numLeds; ++i) {
|
||||
byte pos = seq[i];
|
||||
|
||||
leds[pos] = (i > phase) ? prevColor
|
||||
|
||||
@@ -35,15 +35,15 @@ class AnimSpread : public Anim {
|
||||
void SetupImpl() override {
|
||||
inc = secureRandom(2, 4);
|
||||
// DEBUG_MSG_P(PSTR("[GARLAND] AnimSpread inc = %d\n"), inc);
|
||||
for (int i = 0; i < numLeds; i++)
|
||||
for (int i = 0; i < numLeds; ++i)
|
||||
seq[i] = 0;
|
||||
}
|
||||
|
||||
void Run() override {
|
||||
for (int i = 0; i < numLeds; i++)
|
||||
for (int i = 0; i < numLeds; ++i)
|
||||
leds[i] = 0;
|
||||
|
||||
for (int i = 0; i < numLeds; i++) {
|
||||
for (int i = 0; i < numLeds; ++i) {
|
||||
if (seq[i] > 0) {
|
||||
byte width = maxWidth - seq[i];
|
||||
for (int j = i - width; j <= (i + width); j++) {
|
||||
|
||||
@@ -18,7 +18,7 @@ class AnimStars : public Anim {
|
||||
inc = secureRandom(2, 5);
|
||||
|
||||
//reset all phases
|
||||
for (int i = 0; i < numLeds; i++)
|
||||
for (int i = 0; i < numLeds; ++i)
|
||||
seq[i] = 255;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@ class AnimStart : public Anim {
|
||||
leds[phase].r = 255;
|
||||
leds[phase].g = 255;
|
||||
leds[phase].b = 255;
|
||||
for (int i = 0; i < numLeds; i++) {
|
||||
for (int i = 0; i < numLeds; ++i) {
|
||||
leds[i].fade(50);
|
||||
}
|
||||
} else if (phase >= numLeds) {
|
||||
for (int i = 0; i < numLeds; i++) {
|
||||
for (int i = 0; i < numLeds; ++i) {
|
||||
short r = numLeds + 255 - phase + rngb();
|
||||
r = min(r, (short)255);
|
||||
leds[i].r = (byte)max(r, (short)0);
|
||||
|
||||
@@ -15,10 +15,12 @@ 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_dolphins.h"
|
||||
#include "animations/anim_fly.h"
|
||||
#include "animations/anim_pixiedust.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"
|
||||
#include "animations/anim_stars.h"
|
||||
|
||||
Reference in New Issue
Block a user