48 (
mLastMs == 0) ? 0.016f :
static_cast<float>(nowMs -
mLastMs) * 0.001f;
66 mBreath.render(s, pal, dtSec, breath);
67 mFlow.render(s, pal, dtSec, flow);
68 mGroove.render(s, pal, dtSec, groove);
73 float keep =
tuning.trailOverride;
75 keep = kKeepCalm * s.
calm + kKeepFlow * s.
flow +
81 for (fl::size i = 0; i <
mTrail.size(); ++i)
97 for (fl::size i = 0; i < out.
size(); ++i)
105 const fl::size n =
mMix.size();
106 for (fl::size i = 0; i < n; ++i) {
111 m.
r = b.
r * wb + f.
r * wf + g.r * wg;
112 m.
g = b.
g * wb + f.
g * wf + g.g * wg;
113 m.
b = b.
b * wb + f.
b * wf + g.b * wg;
122 keep =
clampf(keep, 0.0f, 0.98f);
123 const fl::size n =
mMix.size();
124 for (fl::size i = 0; i < n; ++i) {
130 if (
t.r < kTrailFloor)
132 if (
t.g < kTrailFloor)
134 if (
t.b < kTrailFloor)
147 if (strength <= 0.02f)
166 mPulses[slot].strength = strength;
167 mPulses[slot].downbeat = downbeat;
178 const fl::u32 elapsed = nowMs - p.
startMs;
179 if (elapsed >= kPulseLifetimeMs) {
184 static_cast<float>(elapsed) /
static_cast<float>(kPulseLifetimeMs);
185 const float radius = life * 0.5f;
186 const float sigma = p.
downbeat ? kPulseSigmaDownbeat : kPulseSigmaBeat;
194 c.
ring(origin, radius, sigma, tint, amp);
constexpr bool empty() const FL_NO_EXCEPT
constexpr fl::size size() const FL_NO_EXCEPT
fl::vector< RGBf > mBufGroove
fl::vector< RGBf > mTrail
persistence shadow
fl::vector< RGBf > mBufFlow
void drawPulses(const MoodPalette &pal, fl::u32 nowMs)
void mixLayers(const RoomSense &s)
void applyTrails(float keep)
Pulse mPulses[kMaxPulses]
void ensureBuffers(fl::size n)
float mHueDrift
slow hue travel, turns of the wheel
fl::vector< RGBf > mBufBreath
static const int kMaxPulses
void emitPulse(float strength, bool downbeat, fl::u32 nowMs)
void draw(const RoomSense &s, fl::u32 nowMs, fl::span< CRGB > out)
Render one frame into out.
int activePulseCount() const
fl::vector< RGBf > mMix
this frame, summed
void ring(float origin, float radius, float sigma, const RGBf &color, float gain)
Add a band at distance radius (turns, 0..0.5) from origin, on both sides of it at once: an expanding ...
Additive drawing helpers over a span of float pixels.
constexpr fl::u32 kPulseLifetimeMs
constexpr float kHueDriftTurnsPerSecCalm
constexpr float kPulseSigmaDownbeat
constexpr float kKeepGroove
constexpr float kPulseFadeIn
constexpr float kKeepFlow
constexpr float kTrailFloor
constexpr float kPulseSigmaBeat
constexpr float kKeepCalm
float smoothstepf(float e0, float e1, float x)
0 below e0, 1 above e1, smooth in between.
CRGB toCRGB(const RGBf &p)
MoodPalette paletteFor(const RoomSense &s, float hueDrift)
Derive the family for this frame. Cheap; call every frame.
float clampf(float v, float lo, float hi)
RGBf paletteColor(const MoodPalette &p, float t)
Colour at position t in [0, 1] along the family, at value v.
float wrapTurns(float t)
Wrap into [0, 1).
Everything a visual is allowed to react to.
Linear-light float pixel, nominal range [0, 1], may exceed 1 before clip.