diff --git a/include/Animation/AllAnimations.h b/include/Animation/AllAnimations.h index 3bf2f13..1176eeb 100644 --- a/include/Animation/AllAnimations.h +++ b/include/Animation/AllAnimations.h @@ -2,9 +2,11 @@ #include "ConnectingAnimation.h" #include "ConnectionEstablishedAnimation.h" -#include "FireAnimation.h" -#include "SnowfallAnimation.h" #include "FadeToColorAnimation.h" +#include "FireAnimation.h" +#include "FireworkAnimation.h" #include "ImageScrollerAnimation.h" #include "MatrixCodeAnimation.h" -#include "FireworkAnimation.h" +#include "RgbwSinusAnimation.h" +#include "SnowfallAnimation.h" +#include "StellarAnimation.h" diff --git a/include/Animation/AnimationController.h b/include/Animation/AnimationController.h index 769aa61..943d4f2 100644 --- a/include/Animation/AnimationController.h +++ b/include/Animation/AnimationController.h @@ -18,6 +18,8 @@ class AnimationController FONT_TEST = 3, MATRIX_CODE = 4, FIREWORK = 5, + STELLAR = 6, + RGBW_SINUS = 7, NUM_DEFAULT_ANIMATIONS }; @@ -34,7 +36,9 @@ class AnimationController "Snowfall", "Font Test", "Matrix Code", - "Fireworks" + "Fireworks", + "Twinkling Sky", + "RGBW Sinus" }; AnimationController(Fader *fader); diff --git a/include/Animation/RgbwSinusAnimation.h b/include/Animation/RgbwSinusAnimation.h new file mode 100644 index 0000000..487647a --- /dev/null +++ b/include/Animation/RgbwSinusAnimation.h @@ -0,0 +1,37 @@ +#pragma once + +#include + +#include "Animation.h" + +#include "fasttrigon.h" + +class RgbwSinusAnimation : public Animation +{ + public: + typedef std::array rgbw_val_array; + RgbwSinusAnimation(Fader *fader, + const rgbw_val_array &speeds = {2273, 2281, 2287, 2293}, + uint32_t speed_divider = 1024, + uint16_t brightness_scale = 64); // max: 255 + + void loop(uint64_t frame) override; + + void stop(void) override + { + m_stopping = true; + } + + void reset(void) override; + + private: + bool m_stopping; + + rgbw_val_array m_speeds; + uint32_t m_speedDivider; + uint16_t m_brightnessScale; + + rgbw_val_array m_phi; + + uint32_t m_overflowInterval; +}; diff --git a/include/Animation/StellarAnimation.h b/include/Animation/StellarAnimation.h new file mode 100644 index 0000000..20f9599 --- /dev/null +++ b/include/Animation/StellarAnimation.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#include "Animation.h" + +class StellarAnimation : public Animation +{ + public: + StellarAnimation(Fader *fader, + const Fader::Color &background_color = Fader::Color{0x00, 0x02, 0x0c, 0x00}, + const Fader::Color &star_color = Fader::Color{0x60, 0x30, 0x00, 0x60}, + int fadestep = 1, int spawn_interval_frames = 12); + + void loop(uint64_t frame) override; + + void stop(void) override + { + m_stopping = true; + } + + void reset(void) override; + + private: + std::default_random_engine m_gen; + + Fader::Color m_backgroundColor; + Fader::Color m_starColor; + + int m_fadestep; + int m_spawnInterval; // in frames + + bool m_stopping; +}; diff --git a/src/Animation/AnimationController.cpp b/src/Animation/AnimationController.cpp index 19c3d2f..16643d6 100644 --- a/src/Animation/AnimationController.cpp +++ b/src/Animation/AnimationController.cpp @@ -70,6 +70,14 @@ void AnimationController::changeAnimation(AnimationController::DefaultAnimation } break; + case STELLAR: + anim.reset(new StellarAnimation(m_fader)); + break; + + case RGBW_SINUS: + anim.reset(new RgbwSinusAnimation(m_fader)); + break; + default: return; // unknown id, do nothing } diff --git a/src/Animation/RgbwSinusAnimation.cpp b/src/Animation/RgbwSinusAnimation.cpp new file mode 100644 index 0000000..aef2f12 --- /dev/null +++ b/src/Animation/RgbwSinusAnimation.cpp @@ -0,0 +1,58 @@ +#include + +#include "Animation/RgbwSinusAnimation.h" + +RgbwSinusAnimation::RgbwSinusAnimation(Fader *fader, + const rgbw_val_array &speeds, + uint32_t speed_divider, + uint16_t brightness_scale) + : Animation(fader), + m_speeds(speeds), + m_speedDivider(speed_divider), + m_brightnessScale(brightness_scale), + m_phi{0,0,0,0}, + m_overflowInterval(fasttrigon::LUT_SIZE * speed_divider) +{ + reset(); +} + +void RgbwSinusAnimation::loop(uint64_t frame) +{ + std::size_t nled = m_fader->modules_per_strip(); + std::size_t nstrip = m_fader->strips(); + + if(!m_stopping) { + for(unsigned i = 0; i < m_speeds.size(); i++) { + m_phi[i] += m_speeds[i]; + + if(m_phi[i] > m_overflowInterval) { + m_phi[i] -= m_overflowInterval; + } + } + + for(std::size_t led = 0; led < nled; led++) { + for(std::size_t strip = 0; strip < nstrip; strip++) { + uint32_t pixelphase = led * fasttrigon::LUT_SIZE / nstrip + strip * fasttrigon::LUT_SIZE / nstrip; + + Fader::Color color{ + static_cast(((127 + fasttrigon::fastsin(m_phi[0] / m_speedDivider + pixelphase)) * m_brightnessScale) >> 8), + static_cast(((127 + fasttrigon::fastsin(m_phi[1] / m_speedDivider + pixelphase)) * m_brightnessScale) >> 8), + static_cast(((127 + fasttrigon::fastsin(m_phi[2] / m_speedDivider + pixelphase)) * m_brightnessScale) >> 8), + static_cast(((127 + fasttrigon::fastsin(m_phi[3] / m_speedDivider + pixelphase)) * m_brightnessScale) >> 9)}; // white is too bright otherwise + + m_fader->set_color(strip, led, color); + } + } + } else { + m_fader->fade_color(Fader::Color{0, 0, 0, 0}); + } + + m_fader->update(); + m_running = !m_stopping || m_fader->something_changed(); +} + +void RgbwSinusAnimation::reset(void) +{ + m_stopping = false; + m_running = true; +} diff --git a/src/Animation/StellarAnimation.cpp b/src/Animation/StellarAnimation.cpp new file mode 100644 index 0000000..7623899 --- /dev/null +++ b/src/Animation/StellarAnimation.cpp @@ -0,0 +1,47 @@ +#include "Animation/StellarAnimation.h" + +#include + +StellarAnimation::StellarAnimation(Fader *fader, + const Fader::Color &background_color, const Fader::Color &star_color, + int fadestep, int spawn_interval_frames) + : Animation(fader), + m_backgroundColor(background_color), + m_starColor(star_color), + m_fadestep(fadestep), + m_spawnInterval(spawn_interval_frames) +{ + reset(); +} + +void StellarAnimation::loop(uint64_t frame) +{ + int nled = m_fader->modules_per_strip(); + int nstrip = m_fader->strips(); + + if(frame == 0) { + m_fader->set_fadestep(m_fadestep); + m_fader->fade_color(m_backgroundColor); + } + + if(!m_stopping && ((frame % m_spawnInterval) == 0)) { + // create new pixels + std::uniform_int_distribution stripRng(0, nstrip-1); + std::uniform_int_distribution ledRng(0, nled-1); + + int strip = stripRng(m_gen); + int led = ledRng(m_gen); + + m_fader->add_color(strip, led, m_starColor); + m_fader->fade_color(strip, led, m_backgroundColor); + } + + m_fader->update(); + m_running = !m_stopping || m_fader->something_changed(); +} + +void StellarAnimation::reset(void) +{ + m_stopping = false; + m_running = true; +}