Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 38 additions & 15 deletions wled00/FX_fcn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,20 +287,36 @@ void Segment::startTransition(uint16_t dur, bool segmentCopy) {
return;
}
if (isInTransition()) {
const uint8_t visibleBri = currentBri();
if (segmentCopy && !_t->_oldSegment) {
// already in transition but segment copy requested and not yet created
_t->_oldSegment = new(std::nothrow) Segment(*this); // store/copy current segment settings
_t->_start = millis(); // restart countdown
if (blendingStyle != TRANSITION_FADE) {
// transition without a copy means we are in a segment brightness transition
// need to cancel the transition to not interfere with the new one (or global brightness change)
stopTransition();
} else {
// already in FADE transition but segment copy requested and not yet created (for example a SWIPE color change during brightness transition)
// create segment copy and restart timer so currentBri() can interpolate correctly
_t->_oldSegment = new(std::nothrow) Segment(*this); // store/copy current segment settings
_t->_start = millis(); // restart countdown
_t->_dur = dur;
_t->_bri = visibleBri;
_t->_prevPaletteBlends = 0;
if (_t->_oldSegment) {
_t->_oldSegment->palette = _t->_palette; // restore original palette and colors (from start of transition)
for (unsigned i = 0; i < NUM_COLORS; i++) _t->_oldSegment->colors[i] = _t->_colors[i];
DEBUGFX_PRINTF_P(PSTR("-- Updated transition with segment copy: S=%p T(%p) O[%p] OP[%p]\n"), this, _t, _t->_oldSegment, _t->_oldSegment->pixels);
if (!_t->_oldSegment->isActive()) stopTransition();
}
return;
}
} else {
// already in transition; restart from the currently visible brightness
_t->_start = millis();
_t->_dur = dur;
_t->_bri = visibleBri;
_t->_prevPaletteBlends = 0;
if (_t->_oldSegment) {
_t->_oldSegment->palette = _t->_palette; // restore original palette and colors (from start of transition)
for (unsigned i = 0; i < NUM_COLORS; i++) _t->_oldSegment->colors[i] = _t->_colors[i];
DEBUGFX_PRINTF_P(PSTR("-- Updated transition with segment copy: S=%p T(%p) O[%p] OP[%p]\n"), this, _t, _t->_oldSegment, _t->_oldSegment->pixels);
if (!_t->_oldSegment->isActive()) stopTransition();
}
return;
}
Comment thread
DedeHai marked this conversation as resolved.
return;
}

// no previous transition running, start by allocating memory for segment copy
Expand Down Expand Up @@ -355,8 +371,11 @@ uint8_t Segment::currentBri() const {
unsigned curBri = on ? opacity : 0;
if (prog < 0xFFFFU) {
// this will blend opacity in new mode if style is FADE (single effect call)
if (blendingStyle == TRANSITION_FADE) curBri = (prog * curBri + _t->_bri * (0xFFFFU - prog)) / 0xFFFFU;
else curBri = Segment::isPreviousMode() ? _t->_bri : curBri;
const bool onOffTransition = _t->_oldSegment && (_t->_oldSegment->on != on);
if (blendingStyle == TRANSITION_FADE || !_t->_oldSegment || !onOffTransition)
curBri = (prog * curBri + _t->_bri * (0xFFFFU - prog)) / 0xFFFFU;
else
curBri = std::max((unsigned)curBri, (unsigned)_t->_bri); // non-FADE on/off transition: use the higher of old and new brightness so it is correct for both turn-on and turn-off
}
return curBri;
}
Expand Down Expand Up @@ -530,7 +549,7 @@ Segment &Segment::setCCT(uint16_t k) {
Segment &Segment::setOpacity(uint8_t o) {
if (opacity != o) {
//DEBUG_PRINTF_P(PSTR("- Starting opacity transition: %d\n"), o);
startTransition(strip.getTransition(), blendingStyle != TRANSITION_FADE); // start transition prior to change
startTransition(strip.getTransition(), false); // opacity change always fades (no segment copy needed)
opacity = o;
stateChanged = true; // send UDP/WS broadcast
}
Expand Down Expand Up @@ -1588,10 +1607,12 @@ void WS2812FX::blendSegment(const Segment &topSegment) const {
c_a = color_blend16(c_a, segO->getPixelColorRaw(x + y*oCols), progInv);
} else if (blendingStyle != TRANSITION_FADE) {
// if we have global brightness change (not On/Off change) we will ignore transition style and just fade brightness (see led.cpp)
// workaround for On/Off transition
// workaround for global On/Off transition
// (bri != briT) && !bri => from On to Off
// (bri != briT) && bri => from Off to On
if ((briOld == 0 || bri == 0) && ((!clipped && (bri != briT) && !bri) || (clipped && (bri != briT) && bri))) c_a = BLACK;
// per-segment on/off: the area belonging to the off-state segment must be black
if (segO && !seg->on) c_a = BLACK;
}
// map it into frame buffer
x = c; // restore coordiates if we were PUSHing
Expand Down Expand Up @@ -1660,10 +1681,12 @@ void WS2812FX::blendSegment(const Segment &topSegment) const {
c_a = color_blend16(c_a, segO->getPixelColorRaw(i), progInv);
} else if (blendingStyle != TRANSITION_FADE) {
// if we have global brightness change (not On/Off change) we will ignore transition style and just fade brightness (see led.cpp)
// workaround for On/Off transition
// workaround for global On/Off transition
// (bri != briT) && !bri => from On to Off
// (bri != briT) && bri => from Off to On
if ((briOld == 0 || bri == 0) && ((!clipped && (bri != briT) && !bri) || (clipped && (bri != briT) && bri))) c_a = BLACK;
// per-segment on/off: the area belonging to the off-state segment must be black
if (segO && !seg->on) c_a = BLACK;
}
// map into frame buffer
i = k; // restore index if we were PUSHing
Expand Down
13 changes: 8 additions & 5 deletions wled00/led.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,15 @@ void stateUpdated(byte callMode) {
applyFinalBri();
strip.trigger();
} else {
if (transitionActive) {
briOld = briT;
} else if (bri != briOld || stateChanged)
if (bri != briOld) {
if (transitionActive) briOld = briT; // re-targeting mid-transition: start interpolation from current in-flight value
strip.setTransitionMode(true); // force all segments to transition mode
transitionActive = true;
transitionStartTime = now;
transitionActive = true;
transitionStartTime = now;
} else if (jsonTransitionOnce) {
strip.setTransition(transitionDelay);
jsonTransitionOnce = false;
}
}
stateChanged = false;
}
Expand Down
Loading