Add Dancing Shadows effect
This commit is contained in:
parent
a8c530a3a9
commit
aee9c4a193
149
wled00/FX.cpp
149
wled00/FX.cpp
@ -3564,3 +3564,152 @@ uint16_t WS2812FX::mode_chunchun(void)
|
|||||||
}
|
}
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct Spotlight {
|
||||||
|
float speed;
|
||||||
|
uint8_t colorIdx;
|
||||||
|
int16_t position;
|
||||||
|
unsigned long lastUpdateTime;
|
||||||
|
uint8_t width;
|
||||||
|
uint8_t type;
|
||||||
|
} spotlight;
|
||||||
|
|
||||||
|
static const uint8_t SPOT_TYPE_SOLID = 0;
|
||||||
|
static const uint8_t SPOT_TYPE_GRADIENT = 1;
|
||||||
|
static const uint8_t SPOT_TYPE_2X_GRADIENT = 2;
|
||||||
|
static const uint8_t SPOT_TYPE_2X_DOT = 3;
|
||||||
|
static const uint8_t SPOT_TYPE_3X_DOT = 4;
|
||||||
|
static const uint8_t SPOT_TYPE_4X_DOT = 5;
|
||||||
|
static const uint8_t SPOT_TYPES_COUNT = 6;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Blends the specified color with the existing pixel color.
|
||||||
|
*/
|
||||||
|
void WS2812FX::blendPixelColor(uint16_t n, uint32_t color, uint8_t blend)
|
||||||
|
{
|
||||||
|
setPixelColor(n, color_blend(getPixelColor(n), color, blend));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Spotlights moving back and forth that cast dancing shadows.
|
||||||
|
* Shine this through tree branches/leaves or other close-up objects that cast
|
||||||
|
* interesting shadows onto a ceiling or tarp.
|
||||||
|
*
|
||||||
|
* By Steve Pomeroy @xxv
|
||||||
|
*/
|
||||||
|
uint16_t WS2812FX::mode_dancing_shadows(void)
|
||||||
|
{
|
||||||
|
uint8_t numSpotlights = map(SEGMENT.intensity, 0, 255, 2, 50);
|
||||||
|
bool initialize = SEGENV.aux0 != numSpotlights;
|
||||||
|
SEGENV.aux0 = numSpotlights;
|
||||||
|
|
||||||
|
uint16_t dataSize = sizeof(spotlight) * numSpotlights;
|
||||||
|
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||||
|
Spotlight* spotlights = reinterpret_cast<Spotlight*>(SEGENV.data);
|
||||||
|
|
||||||
|
fill(BLACK);
|
||||||
|
|
||||||
|
unsigned long time = millis();
|
||||||
|
bool respawn = false;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < numSpotlights; i++) {
|
||||||
|
if (!initialize) {
|
||||||
|
// advance the position of the spotlight
|
||||||
|
int16_t delta = (float)(time - spotlights[i].lastUpdateTime) *
|
||||||
|
(spotlights[i].speed * ((1.0 + SEGMENT.speed)/100.0));
|
||||||
|
|
||||||
|
if (abs(delta) >= 1) {
|
||||||
|
spotlights[i].position += delta;
|
||||||
|
spotlights[i].lastUpdateTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
respawn = (spotlights[i].speed > 0.0 && spotlights[i].position > (SEGLEN + 2))
|
||||||
|
|| (spotlights[i].speed < 0.0 && spotlights[i].position < -(spotlights[i].width + 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initialize || respawn) {
|
||||||
|
spotlights[i].colorIdx = random8();
|
||||||
|
spotlights[i].width = random8(1, 10);
|
||||||
|
|
||||||
|
spotlights[i].speed = 1.0/random8(4, 50);
|
||||||
|
|
||||||
|
if (initialize) {
|
||||||
|
spotlights[i].position = random16(SEGLEN);
|
||||||
|
spotlights[i].speed *= random8(2) ? 1.0 : -1.0;
|
||||||
|
} else {
|
||||||
|
if (random8(2)) {
|
||||||
|
spotlights[i].position = SEGLEN + spotlights[i].width;
|
||||||
|
spotlights[i].speed *= -1.0;
|
||||||
|
}else {
|
||||||
|
spotlights[i].position = -spotlights[i].width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spotlights[i].lastUpdateTime = time;
|
||||||
|
spotlights[i].type = random8(SPOT_TYPES_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t color = color_from_palette(spotlights[i].colorIdx, false, false, 0);
|
||||||
|
int start = spotlights[i].position;
|
||||||
|
|
||||||
|
if (spotlights[i].width <= 1) {
|
||||||
|
if (start >= 0 && start < SEGLEN) {
|
||||||
|
blendPixelColor(start, color, 128);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (spotlights[i].type) {
|
||||||
|
case SPOT_TYPE_SOLID:
|
||||||
|
for (uint8_t j = 0; j < spotlights[i].width; j++) {
|
||||||
|
if ((start + j) >= 0 && (start + j) < SEGLEN) {
|
||||||
|
blendPixelColor(start + j, color, 128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPOT_TYPE_GRADIENT:
|
||||||
|
for (uint8_t j = 0; j < spotlights[i].width; j++) {
|
||||||
|
if ((start + j) >= 0 && (start + j) < SEGLEN) {
|
||||||
|
blendPixelColor(start + j, color,
|
||||||
|
cubicwave8(map(j, 0, spotlights[i].width - 1, 0, 255)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPOT_TYPE_2X_GRADIENT:
|
||||||
|
for (uint8_t j = 0; j < spotlights[i].width; j++) {
|
||||||
|
if ((start + j) >= 0 && (start + j) < SEGLEN) {
|
||||||
|
blendPixelColor(start + j, color,
|
||||||
|
cubicwave8(2 * map(j, 0, spotlights[i].width - 1, 0, 255)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPOT_TYPE_2X_DOT:
|
||||||
|
for (uint8_t j = 0; j < spotlights[i].width; j += 2) {
|
||||||
|
if ((start + j) >= 0 && (start + j) < SEGLEN) {
|
||||||
|
blendPixelColor(start + j, color, 128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPOT_TYPE_3X_DOT:
|
||||||
|
for (uint8_t j = 0; j < spotlights[i].width; j += 3) {
|
||||||
|
if ((start + j) >= 0 && (start + j) < SEGLEN) {
|
||||||
|
blendPixelColor(start + j, color, 128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPOT_TYPE_4X_DOT:
|
||||||
|
for (uint8_t j = 0; j < spotlights[i].width; j += 4) {
|
||||||
|
if ((start + j) >= 0 && (start + j) < SEGLEN) {
|
||||||
|
blendPixelColor(start + j, color, 128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FRAMETIME;
|
||||||
|
}
|
||||||
|
11
wled00/FX.h
11
wled00/FX.h
@ -101,7 +101,7 @@
|
|||||||
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
||||||
#define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED )
|
#define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED )
|
||||||
|
|
||||||
#define MODE_COUNT 112
|
#define MODE_COUNT 113
|
||||||
|
|
||||||
#define FX_MODE_STATIC 0
|
#define FX_MODE_STATIC 0
|
||||||
#define FX_MODE_BLINK 1
|
#define FX_MODE_BLINK 1
|
||||||
@ -215,6 +215,7 @@
|
|||||||
#define FX_MODE_PHASEDNOISE 109
|
#define FX_MODE_PHASEDNOISE 109
|
||||||
#define FX_MODE_FLOW 110
|
#define FX_MODE_FLOW 110
|
||||||
#define FX_MODE_CHUNCHUN 111
|
#define FX_MODE_CHUNCHUN 111
|
||||||
|
#define FX_MODE_DANCING_SHADOWS 112
|
||||||
|
|
||||||
class WS2812FX {
|
class WS2812FX {
|
||||||
typedef uint16_t (WS2812FX::*mode_ptr)(void);
|
typedef uint16_t (WS2812FX::*mode_ptr)(void);
|
||||||
@ -418,6 +419,7 @@ class WS2812FX {
|
|||||||
_mode[FX_MODE_PHASEDNOISE] = &WS2812FX::mode_phased_noise;
|
_mode[FX_MODE_PHASEDNOISE] = &WS2812FX::mode_phased_noise;
|
||||||
_mode[FX_MODE_FLOW] = &WS2812FX::mode_flow;
|
_mode[FX_MODE_FLOW] = &WS2812FX::mode_flow;
|
||||||
_mode[FX_MODE_CHUNCHUN] = &WS2812FX::mode_chunchun;
|
_mode[FX_MODE_CHUNCHUN] = &WS2812FX::mode_chunchun;
|
||||||
|
_mode[FX_MODE_DANCING_SHADOWS] = &WS2812FX::mode_dancing_shadows;
|
||||||
|
|
||||||
_brightness = DEFAULT_BRIGHTNESS;
|
_brightness = DEFAULT_BRIGHTNESS;
|
||||||
currentPalette = CRGBPalette16(CRGB::Black);
|
currentPalette = CRGBPalette16(CRGB::Black);
|
||||||
@ -613,7 +615,8 @@ class WS2812FX {
|
|||||||
mode_sinewave(void),
|
mode_sinewave(void),
|
||||||
mode_phased_noise(void),
|
mode_phased_noise(void),
|
||||||
mode_flow(void),
|
mode_flow(void),
|
||||||
mode_chunchun(void);
|
mode_chunchun(void),
|
||||||
|
mode_dancing_shadows(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NeoPixelWrapper *bus;
|
NeoPixelWrapper *bus;
|
||||||
@ -666,6 +669,8 @@ class WS2812FX {
|
|||||||
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat);
|
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat);
|
||||||
CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff);
|
CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff);
|
||||||
|
|
||||||
|
void blendPixelColor(uint16_t n, uint32_t color, uint8_t blend);
|
||||||
|
|
||||||
uint32_t _lastPaletteChange = 0;
|
uint32_t _lastPaletteChange = 0;
|
||||||
uint32_t _lastShow = 0;
|
uint32_t _lastShow = 0;
|
||||||
|
|
||||||
@ -701,7 +706,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
|||||||
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst",
|
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst",
|
||||||
"Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent","Ripple Rainbow",
|
"Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent","Ripple Rainbow",
|
||||||
"Heartbeat","Pacifica","Candle Multi", "Solid Glitter","Sunrise","Phased","Twinkleup","Noise Pal", "Sine","Phased Noise",
|
"Heartbeat","Pacifica","Candle Multi", "Solid Glitter","Sunrise","Phased","Twinkleup","Noise Pal", "Sine","Phased Noise",
|
||||||
"Flow","Chunchun"
|
"Flow","Chunchun","Dancing Shadows"
|
||||||
])=====";
|
])=====";
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user