Added new RgbwPsychedelicAnimation

It’s an extension to the previous RgbwSinusAnimation and tilts and
moves the sine waves differently for each color band. Additive color
mixing generates very interesting patterns.
This commit is contained in:
Thomas Kolb 2021-08-23 21:24:44 +02:00
parent 50fb58e494
commit 75c17f28f8
3 changed files with 134 additions and 0 deletions

View file

@ -8,5 +8,6 @@
#include "ImageScrollerAnimation.h"
#include "MatrixCodeAnimation.h"
#include "RgbwSinusAnimation.h"
#include "RgbwPsychedelicAnimation.h"
#include "SnowfallAnimation.h"
#include "StellarAnimation.h"

View file

@ -0,0 +1,46 @@
#pragma once
#include <array>
#include "Animation.h"
#include "fasttrigon.h"
class RgbwPsychedelicAnimation : public Animation
{
public:
typedef std::array<int32_t, 4> rgbw_val_array;
RgbwPsychedelicAnimation(Fader *fader,
const rgbw_val_array &move_speeds = {2273, 2281, 2287, 2293},
const rgbw_val_array &tilt_speeds = {2297, 2309, 2311, 2333},
int32_t tilt_maxperiods = 3,
uint32_t move_speed_divider = 1024,
uint32_t tilt_speed_divider = 8192,
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_move_speeds;
rgbw_val_array m_tilt_speeds;
uint32_t m_moveSpeedDivider;
uint32_t m_tiltSpeedDivider;
uint16_t m_brightnessScale;
int32_t m_tilt_maxperiods;
rgbw_val_array m_move_phi;
rgbw_val_array m_tilt_phi;
int32_t m_moveOverflowInterval;
int32_t m_tiltOverflowInterval;
};

View file

@ -0,0 +1,87 @@
#include <algorithm>
#include "Animation/RgbwPsychedelicAnimation.h"
RgbwPsychedelicAnimation::RgbwPsychedelicAnimation(Fader *fader,
const rgbw_val_array &move_speeds,
const rgbw_val_array &tilt_speeds,
int32_t tilt_maxperiods,
uint32_t move_speed_divider,
uint32_t tilt_speed_divider,
uint16_t brightness_scale)
: Animation(fader),
m_move_speeds(move_speeds),
m_tilt_speeds(move_speeds),
m_moveSpeedDivider(move_speed_divider),
m_tiltSpeedDivider(tilt_speed_divider),
m_brightnessScale(brightness_scale),
m_tilt_maxperiods(tilt_maxperiods),
m_move_phi{0,0,0,0},
m_tilt_phi{100,200,300,400},
m_moveOverflowInterval(fasttrigon::LUT_SIZE * move_speed_divider),
m_tiltOverflowInterval(fasttrigon::LUT_SIZE * tilt_speed_divider)
{
reset();
}
void RgbwPsychedelicAnimation::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_move_speeds.size(); i++) {
m_move_phi[i] += m_move_speeds[i];
if(m_move_phi[i] > m_moveOverflowInterval) {
m_move_phi[i] -= m_moveOverflowInterval;
}
}
rgbw_val_array tilt_nperiods;
for(unsigned i = 0; i < m_tilt_speeds.size(); i++) {
m_tilt_phi[i] += m_tilt_speeds[i];
if(m_tilt_phi[i] > m_tiltOverflowInterval) {
m_tilt_phi[i] -= m_tiltOverflowInterval;
}
tilt_nperiods[i] = m_tilt_maxperiods * fasttrigon::fastsin(m_tilt_phi[i] / m_tiltSpeedDivider);
}
for(std::size_t led = 0; led < nled; led++) {
for(std::size_t strip = 0; strip < nstrip; strip++) {
int32_t x = fasttrigon::LUT_SIZE * led / nled;
int32_t y = fasttrigon::LUT_SIZE * strip / nstrip;
rgbw_val_array rgbw {
(127 + fasttrigon::fastsin(m_move_phi[0] / m_moveSpeedDivider + ((x * tilt_nperiods[0]) >> 7) + y)),
(127 + fasttrigon::fastsin(m_move_phi[1] / m_moveSpeedDivider + ((x * tilt_nperiods[1]) >> 7) + y)),
(127 + fasttrigon::fastsin(m_move_phi[2] / m_moveSpeedDivider + ((x * tilt_nperiods[2]) >> 7) + y)),
(127 + fasttrigon::fastsin(m_move_phi[3] / m_moveSpeedDivider + ((x * tilt_nperiods[3]) >> 7) + y))
};
Fader::Color color{
static_cast<int16_t>(((rgbw[0] * rgbw[0] >> 7) * m_brightnessScale) >> 8),
static_cast<int16_t>(((rgbw[1] * rgbw[1] >> 7) * m_brightnessScale) >> 8),
static_cast<int16_t>(((rgbw[2] * rgbw[2] >> 7) * m_brightnessScale) >> 8),
static_cast<int16_t>(((rgbw[3] * rgbw[3] >> 7) * m_brightnessScale) >> 10)}; // 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 RgbwPsychedelicAnimation::reset(void)
{
m_stopping = false;
m_running = true;
}