musicmouse/espmusicmouse/lib/ledtl/effects/ReverseSwipe.h

112 lines
2.7 KiB
C++

#pragma once
#include "effects/Common.h"
#include "helpers/BellCurve.h"
#pragma pack(push, 1)
struct EffectReverseSwipeConfig
{
float swipeSpeed; // in degrees per second
float bellCurveWidthInLeds;
float startPosition;
};
#pragma pack(pop)
template <typename TLedStrip>
class EffectReverseSwipe
{
public:
static constexpr auto NUM_LEDS = numLeds<TLedStrip>();
static constexpr int DELAY_MS = 10;
using ConfigType = EffectReverseSwipeConfig;
EffectReverseSwipe(const EffectReverseSwipeConfig &cfg, TLedStrip &ledStrip)
: ledStrip_(ledStrip),
currentPosition_(float(NUM_LEDS) / 2 + cfg.bellCurveWidthInLeds),
bellCurveWidth_(cfg.bellCurveWidthInLeds),
invBellCurveWidth_(1.0f / cfg.bellCurveWidthInLeds),
speed_(cfg.swipeSpeed / 360 / 1000 * NUM_LEDS * DELAY_MS),
startPosition_(cfg.startPosition / 360.0f * NUM_LEDS),
finished_(false)
{
for (int i = 0; i < NUM_LEDS; ++i)
state_[i] = getLedRGBW(ledStrip_, i);
}
bool finished() const { return finished_; }
int operator()()
{
if (finished_)
return 60000;
const auto width = std::min(int(currentPosition_ + 1), int(NUM_LEDS / 2) + 1);
{
float brightness = stepFunction(currentPosition_, bellCurveWidth_, invBellCurveWidth_);
ColorRGBW &prevC = state_[ledStrip_.normalizeIdx(startPosition_)];
setLedRGBW(ledStrip_, startPosition_, prevC * brightness);
}
for (int i = 1; i < width; ++i)
{
const float x = currentPosition_ - float(i);
if (x > 0.0f)
{
const int led1 = startPosition_ + i;
const int led2 = startPosition_ - i;
float brightness = stepFunction(x, bellCurveWidth_, invBellCurveWidth_);
ColorRGBW &prevC1 = state_[ledStrip_.normalizeIdx(led1)];
ColorRGBW &prevC2 = state_[ledStrip_.normalizeIdx(led2)];
setLedRGBW(ledStrip_, led1, prevC1 * brightness);
setLedRGBW(ledStrip_, led2, prevC2 * brightness);
}
}
currentPosition_ -= speed_;
if (currentPosition_ < 0)
{
finished_ = true;
clear(ledStrip_);
}
return DELAY_MS;
}
private:
TLedStrip &ledStrip_;
float currentPosition_;
float bellCurveWidth_;
float invBellCurveWidth_;
float speed_;
int startPosition_;
bool finished_;
ColorRGBW state_[NUM_LEDS];
};
// Traits
template <>
struct EffectIdToConfig<EffectId::REVERSE_SWIPE>
{
using type = EffectReverseSwipeConfig;
};
template <>
struct EffectConfigToId<EffectReverseSwipeConfig>
{
static constexpr auto id = EffectId::REVERSE_SWIPE;
};
template <typename TLedStrip>
struct EffectIdToClass<EffectId::REVERSE_SWIPE, TLedStrip>
{
using type = EffectReverseSwipe<TLedStrip>;
};