112 lines
2.7 KiB
C
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>;
|
||
|
};
|