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

97 lines
2.3 KiB
C++

#pragma once
#include "effects/Common.h"
#include "helpers/ColorRGBW.h"
#include "helpers/ColorConversions.h"
#pragma pack(push, 1)
struct EffectStaticDetailedConfig
{
EffectStaticDetailedConfig(const ColorRGBW &c = ColorRGBW{0, 0, 0, 0}, uint16_t beg = 0, uint16_t en = 0)
: color(c), begin(beg), end(en) {}
ColorRGBW color;
uint16_t increment = 1;
float begin = 0.0f;
float end = 0.0f;
float transition_time_in_ms = 0.0f;
};
#pragma pack(pop)
template <typename TLedStrip>
class EffectStaticDetailed
{
public:
static constexpr auto NUM_LEDS = numLeds<TLedStrip>();
static constexpr int DELAY_MS = 10;
using ConfigType = EffectStaticDetailedConfig;
EffectStaticDetailed(const EffectStaticDetailedConfig &cfg, TLedStrip &ledStrip)
: config_(cfg),
ledStrip_(ledStrip)
{
for (int i = 0; i < NUM_LEDS; ++i)
state_[i] = getLedRGBW(ledStrip_, i);
beginIdx_ = constrain(static_cast<int>(cfg.begin * NUM_LEDS + 0.5f), 0, NUM_LEDS - 1);
endIdx_ = constrain(static_cast<int>(cfg.end * NUM_LEDS + 0.5f), 0, NUM_LEDS - 1);
}
bool finished() const { return finished_; }
int operator()()
{
if (finished_)
return 1000000;
const float progress = static_cast<float>(DELAY_MS * calls_) / config_.transition_time_in_ms;
// Finished case
if(progress > 1.0) {
finished_ = true;
return 10000000;
}
// In-progress case
clear(ledStrip_);
for(int i = beginIdx_; i != endIdx_; i += config_.increment) {
ColorRGBW newColor = hsv2rgb(interpolate(rgb2hsv(state_[i]), rgb2hsv(config_.color), progress));
newColor.w = config_.color.w * progress + state_[i].w * (1 - progress);
setLedRGBW(ledStrip_, i, newColor);
if(i >= NUM_LEDS)
i = 0;
}
++calls_;
return DELAY_MS;
}
private:
EffectStaticDetailedConfig config_;
TLedStrip &ledStrip_;
ColorRGBW state_[NUM_LEDS];
int beginIdx_;
int endIdx_;
int calls_ = 0;
bool finished_ = false;
};
// Traits
template <>
struct EffectIdToConfig<EffectId::STATIC_DETAILED>
{
using type = EffectStaticDetailedConfig;
};
template <>
struct EffectConfigToId<EffectStaticDetailedConfig>
{
static constexpr auto id = EffectId::STATIC_DETAILED;
};
template <typename TLedStrip>
struct EffectIdToClass<EffectId::STATIC_DETAILED, TLedStrip>
{
using type = EffectStaticDetailed<TLedStrip>;
};