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:
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;
/*!
* 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:
Fader *m_fader;
bool m_running;
};

View file

@ -9,13 +9,15 @@ class AnimationController
public:
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 restart(void);
private:
Fader *m_fader;
std::unique_ptr<Animation> m_animation;
std::unique_ptr<Animation> m_nextAnimation;
uint32_t m_transitionTime;
uint64_t m_frame;
};

View file

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

View file

@ -1,30 +1,43 @@
#include <Arduino.h>
#include "Animation/AnimationController.h"
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)
{
m_frame = 0;
if(transition && m_animation) {
m_nextAnimation = std::move(anim);
m_animation->stop();
} else {
m_frame = 0;
m_animation = std::move(anim);
if(transition) {
m_transitionTime = 256/8;
m_fader->set_fadestep(8);
m_fader->fade_color(Fader::Color{0, 0, 0, 0});
m_animation = std::move(anim);
m_nextAnimation.reset(nullptr);
}
}
void AnimationController::loop(void)
{
if(m_transitionTime > 0) {
m_transitionTime--;
} else if(m_animation) {
if(m_animation && !m_animation->finished()) {
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++;
}
void AnimationController::restart(void)
{
m_animation->reset();
m_frame = 0;
}

View file

@ -3,24 +3,30 @@
#include "Animation/ConnectingAnimation.h"
ConnectingAnimation::ConnectingAnimation(Fader *fader)
: Animation(fader)
: Animation(fader), m_stopping(false)
{}
void ConnectingAnimation::loop(uint64_t frame)
{
std::size_t nled = m_fader->modules_per_strip();
std::size_t nstrip = m_fader->strips();
uint8_t intensity = 0;
if(frame == 0) {
m_fader->fade_color(Fader::Color{0, 0, 0, 0});
}
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;
c.b = intensity;
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();
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(
ledTask, /* Task function. */