Implement Animation-specific fadeout

This commit is contained in:
Thomas Kolb 2019-12-03 22:09:55 +01:00
parent e4a8c86180
commit 6131e6a687
6 changed files with 87 additions and 20 deletions

View file

@ -8,11 +8,45 @@ class Animation
{ {
public: public:
Animation(Fader *fader) Animation(Fader *fader)
: m_fader(fader) : m_fader(fader), m_running(true)
{} {}
/*!
* The animation's main function. Will be called once per frame.
*
* \param frame The current frame since the animation's start.
*/
virtual void loop(uint64_t frame) = 0; virtual void loop(uint64_t frame) = 0;
/*!
* Stop the animation. After this function is called, the animation code
* might start some transition to black (all LEDs off).
*/
virtual void stop(void)
{
m_running = false;
}
/*!
* A function for checking wether the animation has stopped. This must
* return true after the stop transition has finished.
*
* \returns True if all activity of the animation code has stopped.
*/
virtual bool finished(void)
{
return !m_running;
}
/*!
* Reset function of the animation code. This should clear any
* internal state.
*
* By default does nothing.
*/
virtual void reset(void) {};
protected: protected:
Fader *m_fader; Fader *m_fader;
bool m_running;
}; };

View file

@ -9,13 +9,15 @@ class AnimationController
public: public:
AnimationController(Fader *fader); AnimationController(Fader *fader);
void setAnimation(std::unique_ptr<Animation> anim, bool transition = true); void changeAnimation(std::unique_ptr<Animation> anim, bool transition = true);
void loop(void); void loop(void);
void restart(void);
private: private:
Fader *m_fader; Fader *m_fader;
std::unique_ptr<Animation> m_animation; std::unique_ptr<Animation> m_animation;
std::unique_ptr<Animation> m_nextAnimation;
uint32_t m_transitionTime;
uint64_t m_frame; uint64_t m_frame;
}; };

View file

@ -9,6 +9,17 @@ class ConnectingAnimation : public Animation
void loop(uint64_t frame) override; void loop(uint64_t frame) override;
void stop(void) override
{
m_stopping = true;
}
void reset(void) override
{
m_stopping = false;
m_running = true;
}
private: private:
uint32_t m_loop; bool m_stopping;
}; };

View file

@ -1,30 +1,43 @@
#include <Arduino.h>
#include "Animation/AnimationController.h" #include "Animation/AnimationController.h"
AnimationController::AnimationController(Fader *fader) AnimationController::AnimationController(Fader *fader)
: m_fader(fader), m_transitionTime(0), m_frame(0) : m_fader(fader), m_animation(nullptr), m_frame(0)
{} {}
void AnimationController::setAnimation(std::unique_ptr<Animation> anim, bool transition) void AnimationController::changeAnimation(std::unique_ptr<Animation> anim, bool transition)
{ {
if(transition && m_animation) {
m_nextAnimation = std::move(anim);
m_animation->stop();
} else {
m_frame = 0; m_frame = 0;
m_animation = std::move(anim); m_animation = std::move(anim);
m_nextAnimation.reset(nullptr);
if(transition) {
m_transitionTime = 256/8;
m_fader->set_fadestep(8);
m_fader->fade_color(Fader::Color{0, 0, 0, 0});
} }
} }
void AnimationController::loop(void) void AnimationController::loop(void)
{ {
if(m_transitionTime > 0) { if(m_animation && !m_animation->finished()) {
m_transitionTime--;
} else if(m_animation) {
m_animation->loop(m_frame); m_animation->loop(m_frame);
} }
if(m_nextAnimation &&
(!m_animation || m_animation->finished())) {
// old animation has finished or is unset -> start the new one
m_frame = 0;
m_animation.swap(m_nextAnimation);
m_nextAnimation.reset(nullptr);
}
m_frame++; m_frame++;
} }
void AnimationController::restart(void)
{
m_animation->reset();
m_frame = 0;
}

View file

@ -3,24 +3,30 @@
#include "Animation/ConnectingAnimation.h" #include "Animation/ConnectingAnimation.h"
ConnectingAnimation::ConnectingAnimation(Fader *fader) ConnectingAnimation::ConnectingAnimation(Fader *fader)
: Animation(fader) : Animation(fader), m_stopping(false)
{} {}
void ConnectingAnimation::loop(uint64_t frame) void ConnectingAnimation::loop(uint64_t frame)
{ {
std::size_t nled = m_fader->modules_per_strip(); std::size_t nled = m_fader->modules_per_strip();
std::size_t nstrip = m_fader->strips(); std::size_t nstrip = m_fader->strips();
uint8_t intensity = 0;
if(frame == 0) { if(frame == 0) {
m_fader->fade_color(Fader::Color{0, 0, 0, 0}); m_fader->fade_color(Fader::Color{0, 0, 0, 0});
} }
for(std::size_t strip = 0; strip < nstrip; strip++) { for(std::size_t strip = 0; strip < nstrip; strip++) {
uint8_t intensity = (fasttrigon::fastsin(1 * frame * fasttrigon::LUT_SIZE / 60) + 127) / 4; intensity = (fasttrigon::fastsin(1 * frame * fasttrigon::LUT_SIZE / 60) + 127) / 4;
Fader::Color c; Fader::Color c;
c.b = intensity; c.b = intensity;
m_fader->set_color(strip, 0, c); m_fader->set_color(strip, 0, c);
} }
// stop the animation if everything is dark
if(m_stopping && intensity == 0) {
m_running = false;
}
} }

View file

@ -209,7 +209,8 @@ void setup()
Serial.println(); Serial.println();
Serial.println(); Serial.println();
animController.setAnimation(std::unique_ptr<Animation>(new ConnectingAnimation(&ledFader))); ledFader.set_color(Fader::Color{0, 1, 0, 0});
animController.changeAnimation(std::unique_ptr<Animation>(new ConnectingAnimation(&ledFader)));
xTaskCreate( xTaskCreate(
ledTask, /* Task function. */ ledTask, /* Task function. */