Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transition styles #3669

Open
wants to merge 39 commits into
base: 0_15
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
8804987
Initial support for transition styles.
tkadauke Dec 30, 2023
6ae30dd
Use transition styles when colors change
tkadauke Dec 30, 2023
9eb6b51
Persist transition style if it's not changed by the API call
tkadauke Dec 30, 2023
f8dd498
Fix crash when interrupting transition
tkadauke Jan 1, 2024
c129093
"Fairy Dust" transitional effect that transitions pixels in random order
tkadauke Jan 1, 2024
a37a9b1
Fix pixel indexes in transitions
tkadauke Jan 1, 2024
1bbb7ec
Use transition styles when changing segment brightness
tkadauke Jan 1, 2024
933ef59
Add LED buffer for transitions
tkadauke Jan 3, 2024
3babe23
Push transition effects that make use of the buffer
tkadauke Jan 3, 2024
4b0ec37
Fix progress calculation for transitions if segments use grouping or …
tkadauke Jan 3, 2024
613bdb3
Don't use floating point arithmetic for transition styles
tkadauke Jan 5, 2024
4abee2c
Get rid of buffer and calculate transition in setPixelColor
tkadauke Jan 6, 2024
0eed4c9
Support transition styles for 2D effects
tkadauke Jan 6, 2024
a9dac81
Double buffered transitions
tkadauke Jan 7, 2024
ed8ad4d
Fix bug that left artifacts behind
tkadauke Jan 7, 2024
63323ec
Make sure that the buffer grows as the segment virtual length changes
tkadauke Jan 7, 2024
4983e7f
Better random distribution for fairy dust transition style
tkadauke Jan 8, 2024
a9e4c55
Save pixels to both buffers at the beginning of a transition in order…
tkadauke Jan 8, 2024
f82c98d
Fix transition style progress calculation
tkadauke Jan 8, 2024
d49d772
Swipe/push up/down transition styles
tkadauke Jan 8, 2024
945bc56
Take palette changes into account when transitioning
tkadauke Jan 8, 2024
b683388
Guard everything behind compile flag
tkadauke Jan 8, 2024
18c2fc9
Add JSON path for transition styles
tkadauke Jan 8, 2024
aa7ca41
Dynamically load transition styles from the UI
tkadauke Jan 8, 2024
734f73b
Fix build when effect blending is disabled
tkadauke Jan 8, 2024
6674d8b
Make sure the build works with 2D disabled
tkadauke Jan 8, 2024
1f42862
Changes based on review feedback
tkadauke Jan 8, 2024
d9d8d60
Fix merge conflict issues
tkadauke Jan 10, 2024
401d7d2
Fix crash bug on 8266
tkadauke Jan 12, 2024
346869d
Disable effect transitions on ESP8266 by default
tkadauke Jan 14, 2024
2d22296
Merge remote-tracking branch 'aircoookie/0_15' into transition_styles
tkadauke Jan 14, 2024
ae9f1ca
Fix double application of brightness to pixel color when transitioning
tkadauke Jan 15, 2024
dfafb6e
Prevent triggering transitions when nothing changes
tkadauke Jan 16, 2024
7379589
Simply move transition style code into new cpp file
tkadauke Jan 31, 2024
49ab4fb
One function per transition style
tkadauke Jan 31, 2024
9b27d96
Decouple transition style conpile time flag from effect blending flag
tkadauke Jan 31, 2024
894500d
A few things that I missed in the last commit
tkadauke Jan 31, 2024
f3ff39b
Disable transition styles on ESP8266 for now
tkadauke Jan 31, 2024
8d4a5fa
Merge branch '0_15' into transition_styles
blazoncek Mar 12, 2024
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
2 changes: 1 addition & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 #-DWLED_DISABLE_2D
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -DWLEDISABLE_TRANSITION_STYLES #-DWLED_DISABLE_2D
lib_deps = ${esp8266.lib_deps}
monitor_filters = esp8266_exception_decoder

Expand Down
89 changes: 88 additions & 1 deletion wled00/FX.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,21 @@

#define MODE_COUNT 187

#define TRANSITION_STYLE_FADE 0
#define TRANSITION_STYLE_SWIPE_RIGHT 1
#define TRANSITION_STYLE_SWIPE_LEFT 2
#define TRANSITION_STYLE_SWIPE_UP 3
#define TRANSITION_STYLE_SWIPE_DOWN 4
#define TRANSITION_STYLE_PUSH_RIGHT 5
#define TRANSITION_STYLE_PUSH_LEFT 6
#define TRANSITION_STYLE_PUSH_UP 7
#define TRANSITION_STYLE_PUSH_DOWN 8
#define TRANSITION_STYLE_OUTSIDE_IN 9
#define TRANSITION_STYLE_INSIDE_OUT 10
#define TRANSITION_STYLE_FAIRY_DUST 11

#define TRANSITION_STYLE_COUNT 12

typedef enum mapping1D2D {
M12_Pixels = 0,
M12_pBar = 1,
Expand Down Expand Up @@ -378,6 +393,10 @@ typedef struct Segment {
uint16_t aux1; // custom var
byte *data; // effect data pointer
static uint16_t maxWidth, maxHeight; // these define matrix width & height (max. segment dimensions)
#ifndef WLED_DISABLE_TRANSITION_STYLES
uint32_t *buffer1;
uint32_t *buffer2;
#endif

typedef struct TemporarySegmentData {
uint16_t _optionsT;
Expand Down Expand Up @@ -424,6 +443,10 @@ typedef struct Segment {
static uint16_t _lastPaletteBlend; // blend palette according to set Transition Delay in millis()%0xFFFF
#ifndef WLED_DISABLE_MODE_BLEND
static bool _modeBlend; // mode/effect blending semaphore
#ifndef WLED_DISABLE_TRANSITION_STYLES
static uint32_t* _activeBuffer; // pointer to the buffer where the mode should be rendered to
uint16_t _bufferSize;
#endif
#endif

// transition data, valid only if transitional==true, holds values during transition (72 bytes)
Expand All @@ -449,7 +472,6 @@ typedef struct Segment {
} *_t;

public:

Segment(uint16_t sStart=0, uint16_t sStop=30) :
start(sStart),
stop(sStop),
Expand Down Expand Up @@ -479,8 +501,15 @@ typedef struct Segment {
aux0(0),
aux1(0),
data(nullptr),
#ifndef WLED_DISABLE_TRANSITION_STYLES
buffer1(nullptr),
buffer2(nullptr),
#endif
_capabilities(0),
_dataLen(0),
#ifndef WLED_DISABLE_TRANSITION_STYLES
_bufferSize(0),
#endif
_t(nullptr)
{
#ifdef WLED_DEBUG
Expand All @@ -504,13 +533,22 @@ typedef struct Segment {
//Serial.println();
#endif
if (name) { delete[] name; name = nullptr; }
#ifndef WLED_DISABLE_TRANSITION_STYLES
if (buffer1) { delete[] buffer1; buffer1 = nullptr; }
if (buffer2) { delete[] buffer2; buffer2 = nullptr; }
#endif
stopTransition();
deallocateData();
}

Segment& operator= (const Segment &orig); // copy assignment
Segment& operator= (Segment &&orig) noexcept; // move assignment

#ifndef WLED_DISABLE_TRANSITION_STYLES
void allocateBuffers();
void savePixelsToBuffer(uint32_t* buffer);
#endif

#ifdef WLED_DEBUG
size_t getSize() const { return sizeof(Segment) + (data?_dataLen:0) + (name?strlen(name):0) + (_t?sizeof(Transition):0); }
#endif
Expand All @@ -533,6 +571,9 @@ typedef struct Segment {
static void addUsedSegmentData(int len) { _usedSegmentData += len; }
#ifndef WLED_DISABLE_MODE_BLEND
static void modeBlend(bool blend) { _modeBlend = blend; }
#ifndef WLED_DISABLE_TRANSITION_STYLES
static void renderToBuffer(uint32_t* buffer) { _activeBuffer = buffer; }
#endif
#endif
static void handleRandomPalette();

Expand Down Expand Up @@ -584,6 +625,7 @@ typedef struct Segment {
inline void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); }
inline void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, RGBW32(c.r,c.g,c.b,0), aa); }
uint32_t getPixelColor(int i);
int getPixelIndex(int i);
// 1D support functions (some implement 2D as well)
void blur(uint8_t);
void fill(uint32_t c);
Expand Down Expand Up @@ -680,6 +722,10 @@ class WS2812FX { // 96 bytes
ModeData(uint8_t id, uint16_t (*fcn)(void), const char *data) : _id(id), _fcn(fcn), _data(data) {}
} mode_data_t;

#ifndef WLED_DISABLE_TRANSITION_STYLES
typedef void (*transition_ptr)(void); // pointer to transition function
#endif

static WS2812FX* instance;

public:
Expand Down Expand Up @@ -711,6 +757,9 @@ class WS2812FX { // 96 bytes
_hasWhiteChannel(false),
_triggered(false),
_modeCount(MODE_COUNT),
#ifndef WLED_DISABLE_TRANSITION_STYLES
_transitionStyleCount(TRANSITION_STYLE_COUNT),
#endif
_callback(nullptr),
customMappingTable(nullptr),
customMappingSize(0),
Expand All @@ -731,12 +780,21 @@ class WS2812FX { // 96 bytes
_modeData.reserve(_modeCount); // allocate memory to prevent initial fragmentation (does not increase size())
if (_mode.capacity() <= 1 || _modeData.capacity() <= 1) _modeCount = 1; // memory allocation failed only show Solid
else setupEffectData();

#ifndef WLED_DISABLE_TRANSITION_STYLES
_transitionStyles.reserve(_transitionStyleCount); // allocate memory to prevent initial fragmentation (does not increase size())
if (_mode.capacity() <= 1 || _modeData.capacity() <= 1) _transitionStyleCount = 0; // memory allocation failed, disable transition styles
else setupTransitionStyleData();
#endif
}

~WS2812FX() {
if (customMappingTable) delete[] customMappingTable;
_mode.clear();
_modeData.clear();
#ifndef WLED_DISABLE_TRANSITION_STYLES
_transitionStyles.clear();
#endif
_segments.clear();
#ifndef WLED_DISABLE_2D
panel.clear();
Expand Down Expand Up @@ -769,6 +827,11 @@ class WS2812FX { // 96 bytes
addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name), // add effect to the list; defined in FX.cpp
setupEffectData(void); // add default effects to the list; defined in FX.cpp

#ifndef WLED_DISABLE_TRANSITION_STYLES
void setupTransitionStyleData();
void addTransitionStyle(uint8_t id, transition_ptr func, const char *name, bool only2D); // add transition style to the list
#endif

inline void restartRuntime() { for (Segment &seg : _segments) seg.markForReset(); }
inline void setTransitionMode(bool t) { for (Segment &seg : _segments) seg.startTransition(t ? _transitionDur : 0); }
inline void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); }
Expand Down Expand Up @@ -813,6 +876,9 @@ class WS2812FX { // 96 bytes
inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } // will only return built-in palette count
inline uint8_t getTargetFps() { return _targetFps; } // returns rough FPS value for las 2s interval
inline uint8_t getModeCount() { return _modeCount; } // returns number of registered modes/effects
#ifndef WLED_DISABLE_TRANSITION_STYLES
inline uint8_t getTransitionStyleCount() { return _transitionStyleCount; }
#endif

uint16_t
getLengthPhysical(void),
Expand All @@ -838,6 +904,11 @@ class WS2812FX { // 96 bytes

const char **
getModeDataSrc(void) { return &(_modeData[0]); } // vectors use arrays for underlying data

#ifndef WLED_DISABLE_TRANSITION_STYLES
const char* getTransitionStyleName(uint8_t id) { return (id && id<_transitionStyleCount) ? _transitionStyles[id]._name : PSTR("Fade"); }
bool isTransitionStyle2DOnly(uint8_t id) { return (id && id<_transitionStyleCount) ? _transitionStyles[id]._only2D : false; }
#endif

Segment& getSegment(uint8_t id);
inline Segment& getFirstSelectedSeg(void) { return _segments[getFirstSelectedSegId()]; } // returns reference to first segment that is "selected"
Expand Down Expand Up @@ -923,6 +994,22 @@ class WS2812FX { // 96 bytes
uint8_t _modeCount;
std::vector<mode_ptr> _mode; // SRAM footprint: 4 bytes per element
std::vector<const char*> _modeData; // mode (effect) name and its slider control data array
#ifndef WLED_DISABLE_TRANSITION_STYLES
uint8_t _transitionStyleCount;

struct TransitionStyleData {
TransitionStyleData() : _name("RSVD"), _only2D(false) {}
TransitionStyleData(transition_ptr func, const char* name, bool only2D)
: _func(func),
_name(name),
_only2D(only2D) {}

transition_ptr _func;
const char* _name;
bool _only2D;
};
std::vector<TransitionStyleData> _transitionStyles; // transition style names
#endif

show_callback _callback;

Expand Down
15 changes: 14 additions & 1 deletion wled00/FX_2Dfcn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,13 @@ void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col)
col = RGBW32(r, g, b, w);
}

#ifndef WLED_DISABLE_TRANSITION_STYLES
if (_activeBuffer) {
_activeBuffer[y * virtualWidth() + x] = col;
return;
}
#endif

if (reverse ) x = virtualWidth() - x - 1;
if (reverse_y) y = virtualHeight() - y - 1;
if (transpose) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
Expand All @@ -195,7 +202,7 @@ void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col)
uint16_t xX = (x+g), yY = (y+j);
if (xX >= width() || yY >= height()) continue; // we have reached one dimension's end

#ifndef WLED_DISABLE_MODE_BLEND
#if ! defined(WLED_DISABLE_MODE_BLEND) && defined(WLED_DISABLE_TRANSITION_STYLES)
// if blending modes, blend with underlying pixel
if (_modeBlend) tmpCol = color_blend(strip.getPixelColorXY(start + xX, startY + yY), col, 0xFFFFU - progress(), true);
#endif
Expand Down Expand Up @@ -265,6 +272,12 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
uint32_t IRAM_ATTR Segment::getPixelColorXY(uint16_t x, uint16_t y) {
if (!isActive()) return 0; // not active
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit
#ifndef WLED_DISABLE_TRANSITION_STYLES
if (_activeBuffer) {
return _activeBuffer[y * virtualWidth() + x];
}
#endif

if (reverse ) x = virtualWidth() - x - 1;
if (reverse_y) y = virtualHeight() - y - 1;
if (transpose) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
Expand Down
Loading