From 03ff31067ac67aeec7a6bed1dcf9d5cf26a0c4e1 Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Wed, 6 Jul 2022 21:11:19 +0200 Subject: [PATCH] Added (untested) RacerAnimation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port of codemonk’s Python script. --- include/Animation/AllAnimations.h | 1 + include/Animation/AnimationController.h | 4 +- include/Animation/RacerAnimation.h | 49 ++++++++++ include/Fader.h | 9 +- src/Animation/AnimationController.cpp | 4 + src/Animation/RacerAnimation.cpp | 116 ++++++++++++++++++++++++ src/Fader.cpp | 21 ++++- 7 files changed, 200 insertions(+), 4 deletions(-) create mode 100644 include/Animation/RacerAnimation.h create mode 100644 src/Animation/RacerAnimation.cpp diff --git a/include/Animation/AllAnimations.h b/include/Animation/AllAnimations.h index c373a1a..0846c38 100644 --- a/include/Animation/AllAnimations.h +++ b/include/Animation/AllAnimations.h @@ -12,3 +12,4 @@ #include "SnowfallAnimation.h" #include "StellarAnimation.h" #include "ChristmasGlitterAnimation.h" +#include "RacerAnimation.h" diff --git a/include/Animation/AnimationController.h b/include/Animation/AnimationController.h index 78d1fc0..6f850e2 100644 --- a/include/Animation/AnimationController.h +++ b/include/Animation/AnimationController.h @@ -22,6 +22,7 @@ class AnimationController RGBW_SINUS = 7, RGBW_PSYCHEDELIC = 8, CHRISTMAS_GLITTER = 9, + RACERS = 10, NUM_DEFAULT_ANIMATIONS }; @@ -42,7 +43,8 @@ class AnimationController "Twinkling Sky", "RGBW Sinus", "RGBW Psychedelic", - "Christmas Glitter" + "Christmas Glitter", + "Racers" }; AnimationController(Fader *fader); diff --git a/include/Animation/RacerAnimation.h b/include/Animation/RacerAnimation.h new file mode 100644 index 0000000..1a1f015 --- /dev/null +++ b/include/Animation/RacerAnimation.h @@ -0,0 +1,49 @@ +// vim: sw=4 ts=4 sts=4 expandtab + +#pragma once + +#include +#include + +#include "Animation.h" + +#include "fasttrigon.h" + +class RacerAnimation : public Animation +{ + public: + RacerAnimation(Fader *fader, uint32_t racer_count); + + void loop(uint64_t frame) override; + + void stop(void) override + { + m_stopping = true; + } + + void reset(void) override; + + private: + class Racer + { + public: + Racer(Fader *fader, int32_t pos, int32_t speed, const Fader::Color &color); + + void move(void); + void render(void) const; + + private: + Fader *m_fader; + + int32_t m_speed; // in 1/256 LEDs + int32_t m_pos; // in 1/256 LEDs + + Fader::Color m_color; + }; + + std::vector m_racers; + + std::default_random_engine m_gen; + + bool m_stopping; +}; diff --git a/include/Fader.h b/include/Fader.h index cd1713b..226e196 100644 --- a/include/Fader.h +++ b/include/Fader.h @@ -12,6 +12,8 @@ class Fader Color(int16_t ir = 0, int16_t ig = 0, int16_t ib = 0, int16_t iw = 0) : r(ir), g(ig), b(ib), w(iw) {} + Color(const Color &c) : r(c.r), g(c.g), b(c.b), w(c.w) {} + void operator += (const Color &color) { this->r += color.r; @@ -63,6 +65,11 @@ class Fader std::size_t modules_per_strip(void) { return m_modulesPerStrip; } std::size_t strips(void) { return m_strips; } + uint32_t make_module_idx(uint32_t strip, uint32_t module) const; + + uint32_t get_led_idx(uint32_t module_pos) const; + uint32_t get_strip_idx(uint32_t module_pos) const; + private: /*! * Fade the colour value in cur towards target. @@ -73,8 +80,6 @@ class Fader */ bool update_fade(int16_t *cur, const int16_t *target); - inline uint32_t make_module_idx(uint32_t strip, uint32_t module); - std::size_t m_strips; std::size_t m_modulesPerStrip; uint8_t m_fadestep; diff --git a/src/Animation/AnimationController.cpp b/src/Animation/AnimationController.cpp index 2b59a7c..d51b53c 100644 --- a/src/Animation/AnimationController.cpp +++ b/src/Animation/AnimationController.cpp @@ -86,6 +86,10 @@ void AnimationController::changeAnimation(AnimationController::DefaultAnimation anim.reset(new ChristmasGlitterAnimation(m_fader)); break; + case RACERS: + anim.reset(new RacerAnimation(m_fader, m_fader->strips() * m_fader->modules_per_strip() / 10)); + break; + default: return; // unknown id, do nothing } diff --git a/src/Animation/RacerAnimation.cpp b/src/Animation/RacerAnimation.cpp new file mode 100644 index 0000000..bade0c2 --- /dev/null +++ b/src/Animation/RacerAnimation.cpp @@ -0,0 +1,116 @@ +#include + +#include "Animation/RacerAnimation.h" + +/********* Racer *********/ + +RacerAnimation::Racer::Racer(Fader *fader, int32_t pos, int32_t speed, const Fader::Color &color) + : m_fader(fader), + m_speed(speed), + m_pos(pos), + m_color(color) +{ +} + +void RacerAnimation::Racer::move(void) +{ + int32_t maxpos = m_fader->strips() * m_fader->modules_per_strip() * 256; + + m_pos += m_speed; + + if(m_pos >= maxpos) { + m_pos = maxpos - (m_pos % maxpos); + m_speed = -m_speed; + } else if(m_pos < 0) { + m_pos = -m_pos; + m_speed = -m_speed; + } +} + +void RacerAnimation::Racer::render(void) const +{ + int32_t idx1 = m_pos / 256; + int32_t idx2 = m_pos / 256 + 1; + + uint32_t strip1 = m_fader->get_strip_idx(idx1); + uint32_t led1 = m_fader->get_led_idx(idx1); + uint32_t strip2 = m_fader->get_strip_idx(idx2); + uint32_t led2 = m_fader->get_led_idx(idx2); + + int32_t scale1 = (idx2 * 256) - m_pos; + int32_t scale2 = m_pos - (idx1 * 256); + + m_fader->add_color(strip1, led1, + Fader::Color{ + static_cast(m_color.r * scale1 / 256), + static_cast(m_color.g * scale1 / 256), + static_cast(m_color.b * scale1 / 256), + static_cast(m_color.w * scale1 / 256) + }); + + m_fader->add_color(strip2, led2, + Fader::Color{ + static_cast(m_color.r * scale2 / 256), + static_cast(m_color.g * scale2 / 256), + static_cast(m_color.b * scale2 / 256), + static_cast(m_color.w * scale2 / 256) + }); +} + +/********* RacerAnimation *********/ + +RacerAnimation::RacerAnimation(Fader *fader, uint32_t racer_count) + : Animation(fader) +{ + reset(); + + int32_t maxpos = m_fader->strips() * m_fader->modules_per_strip() * 256; + std::uniform_int_distribution posRng(0, maxpos); + std::uniform_int_distribution speedRng(-256, 256); + std::uniform_int_distribution colorRng(0, 255); + std::uniform_int_distribution whiteRng(0, 64); + + m_racers.reserve(racer_count); + for(size_t i = 0; i < racer_count; i++) { + m_racers.emplace_back(Racer{ + fader, + posRng(m_gen), + speedRng(m_gen), + Fader::Color{ + colorRng(m_gen), + colorRng(m_gen), + colorRng(m_gen), + whiteRng(m_gen), + } + }); + } +} + +void RacerAnimation::loop(uint64_t frame) +{ + if(!m_stopping) { + // clear the frame buffer + m_fader->set_color(Fader::Color{0, 0, 0, 0}); + + // move snow flakes and render + for(auto &flake: m_racers) { + flake.move(); + flake.render(); + } + } else { + m_fader->set_fadestep(4); + m_fader->fade_color(Fader::Color{0, 0, 0, 0}); + } + + m_fader->update(); + + if(m_stopping && !m_fader->something_changed()) { + m_running = false; + } +} + +void RacerAnimation::reset(void) +{ + m_stopping = false; + m_running = true; +} diff --git a/src/Fader.cpp b/src/Fader.cpp index 7bc1fdb..62d8247 100644 --- a/src/Fader.cpp +++ b/src/Fader.cpp @@ -109,7 +109,7 @@ void Fader::update(void) } } -uint32_t Fader::make_module_idx(uint32_t strip, uint32_t module) +uint32_t Fader::make_module_idx(uint32_t strip, uint32_t module) const { strip = (strip + STRIP_OFFSET) % m_strips; @@ -119,3 +119,22 @@ uint32_t Fader::make_module_idx(uint32_t strip, uint32_t module) } return strip * m_modulesPerStrip + module; } + +uint32_t Fader::get_strip_idx(uint32_t module_pos) const +{ + return ((module_pos / m_strips) + m_strips - STRIP_OFFSET) % m_strips; +} + +uint32_t Fader::get_led_idx(uint32_t module_pos) const +{ + uint32_t strip = get_strip_idx(module_pos); + + uint32_t led = module_pos % m_modulesPerStrip; + + bool flip = m_flipStripsMask & (1 << strip); + if(flip) { + led = m_modulesPerStrip - led - 1; + } + + return led; +}