-
Notifications
You must be signed in to change notification settings - Fork 2
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
Fxparticle system pr #5
Conversation
touch is implemented differently on S2 and S3, these changes make touch buttons work on S2 and S3
now better fits the default threshold value of 32
This reverts commit d21ad8e.
This reverts commit 0904155.
update gif with new changes
-removed particle box 'rocking boat' (buggy) and replaced with random sloshing. -removed comments -changed some variables into 32bit for speed boost on ESP32 -added link to KB at the top of FX.cpp
-animation works but sliders are too sensitive. need to adjust the ranges
-added particle reductions for ESP8266 for all FX -Removed collisions from Particle Perlin Noise FX, slows things down and does not contribute to a better effect experience -lots of optimizations for ESP8266, all FX now work (at least on 160MHz but still slow) -Some bugfixes -removed unused variables to make compiler happy
-Now shorter names, 'PS' in front to filter the list -Tuned default parameters to make them look better by default -Bugfix in particle system (removed duplicate application of velocity) -reduced PS fire RAM usage (less particles, less base flames, no noticeable difference) -some variable renaming
-fixed fire burning more on the left side -fixed crash in particle attractor -added many improvements for ESP8266 -improved particle rendering efficiency -efficiency improvements in general -changed the way fire is rendered, now more than 2x faster -re-tuned fire to new rendering, also seperately tuned it for ESP8266 -changed all random8() to random16() as it runs faster on ESPs -some reformating -some renaming of effect stuff -fine tuning on falling particle effect -improvements to collision handling (faster and better) -added a (temporary) function for speed tests, will be removed again
Includes update to use matching newer AsyncTCP on ESP32
Enable the new concurrent request and queue size limit features of AsyncWebServer. This should improve the handling of burst traffic or many clients, and significantly reduce the likelihood of OOM crashes due to HTTP requests.
This can be helpful for debugging web handler related issues.
Use the web server's queuing mechanism to call us back later.
No locking contention, but a much larger target
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThe pull request introduces a comprehensive particle system implementation for LED effects in the WLED project. The changes include adding new build flags to disable particle systems for specific environments, expanding the range of effect modes with numerous particle-based effects, and implementing both 1D and 2D particle system classes. The modifications enhance the visual effect capabilities by providing advanced particle rendering, movement, and interaction methods across different hardware configurations. Changes
Sequence DiagramsequenceDiagram
participant PS as Particle System
participant Seg as Segment
participant FX as WS2812FX
PS->>PS: Initialize Particle System
PS->>Seg: Load Old Palette
Seg-->>PS: Palette Loaded
FX->>PS: Service Particle Memory
PS->>PS: Update Particles
PS->>PS: Render Particles
Poem
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (8)
wled00/FXparticleSystem.h (5)
15-22
: Consider clarifying conditional compilation.You wrap certain particle system functionality with
WLED_DISABLE_PARTICLESYSTEM2D
andWLED_DISABLE_PARTICLESYSTEM1D
. Consider grouping these#ifdef
directives in a single, self-contained block or adding documentation explaining their intended usages and interactions to prevent confusion when toggling them.
46-54
: Strengthen error handling strategies.These function prototypes—particularly
particleMemoryManager
,particleHandover
, andservicePSmem
—are critical for memory allocation and deallocation. It would be wise to document expected return values, possible error states, and the calling conventions (e.g., who is responsible for cleaning up memory) to improve maintainability.
56-59
: Validate speed-limiting segments.Your
limitSpeed
inline function enforces a hard-coded maximum speed (PS_P_MAXSPEED
). Consider either exposing this threshold for advanced configuration (allowing the user to tune the limit) or documenting where it originates and why it’s immutable. This ensures the constant remains meaningful and maintainable.
104-117
: Document particle flags usage.
PSparticleFlags
includes several custom bits (custom1
throughcustom5
). Document how these bits are intended to be used, or provide helper methods to set and clear them. Doing so helps new contributors avoid collisions in meaning or misuse of these seemingly “free” bits.
256-416
: Replicate 2D improvements in 1D code.
ParticleSystem1D
repeats much of the 2D logic with a narrower scope. If possible, consider extracting shared logic—like memory management, friction, force updates—into a base class or utility functions. This helps avoid duplication and simplifies maintenance when introducing future enhancements.wled00/FX.h (1)
510-510
: Handle new struct padding carefully.Line 510 references “one byte of padding.” If you intend or need comfortable usage across compiler versions or architectures, explicitly documenting why this padding is necessary (e.g., alignment with a union or backward-compatibility concerns) can prevent accidental breakage.
wled00/FX_fcn.cpp (1)
14-14
: Resolve TODO regarding dependencies.The comment “// TODO: better define the required function (mem service) in FX.h?” indicates uncertainty about where
servicePSmem()
belongs. Decide if this belongs inFX.h
or ifFX_fcn.cpp
is the right place to reduce cross-file dependencies and keep particle core logic together.platformio.ini (1)
361-361
: Memory optimization strategy looks good!The selective disabling of particle systems based on board capabilities is well thought out:
- More capable boards (nodemcuv2) only disable 2D particles
- Memory-constrained boards (esp8266_2m, esp01_1m) disable both 1D and 2D particles
- ESP32 variants retain full particle system support
Consider documenting the memory requirements that led to these decisions, such as:
- Minimum RAM/flash needed for 1D particle system
- Additional memory overhead for 2D particle system
- Impact on other features when particle systems are enabled
Also applies to: 371-371, 379-379, 388-389, 398-399, 406-407, 417-418, 427-428, 436-437
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
platformio.ini
(6 hunks)wled00/FX.h
(5 hunks)wled00/FX_fcn.cpp
(4 hunks)wled00/FXparticleSystem.h
(1 hunks)wled00/cfg.cpp
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- wled00/cfg.cpp
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: wled_build / Build Enviornments (esp01_1m_full_compat)
- GitHub Check: wled_build / Build Enviornments (esp01_1m_full_160)
🔇 Additional comments (5)
wled00/FXparticleSystem.h (2)
33-45
: Ensure consistent memory lifecycle.
partMem
is pivotal for tracking particle memory usage. Verify that the code systematically resets or updates fields likewatchdog
,inTransition
, andtransferParticles
at the appropriate points to avoid stale flags. Also, ensure that the transitions between FX modes properly manage the states in this structure without risking data races or invalid pointers.
79-92
: Avoid potential bitfield pitfalls.
PSsettings2D
packs multiple booleans into a single byte. If the code evolves, ensure that reading/writing these bitfields remains consistent across compilers and architectures. In particular, watch for alignment or endianness issues if cross-platform usage is intended.wled00/FX.h (1)
607-607
: Expose usage of_modeBlend
.
getmodeBlend()
seems to be used internally during effect transitions. Consider clarifying in code comments how and when_modeBlend
is modified. Doing so reduces confusion for maintainers and helps them understand transitions or layering logic in WLED.wled00/FX_fcn.cpp (2)
471-476
: Ensure safe transitions inloadOldPalette()
.When loading the old palette during transitions, confirm that the function won't be called after the transitional data becomes invalid, potentially leading to memory corruption or unexpected fallback behaviors. Audits or additional checks can strengthen resilience.
1553-1555
: Tie memory servicing to compile-time flags.The call to
servicePSmem()
depends on whether bothWLED_DISABLE_PARTICLESYSTEM2D
andWLED_DISABLE_PARTICLESYSTEM1D
are undefined. This conditional block could benefit from a brief comment explaining its presence so future developers know why it’s needed only when those particle systems are active.
wled00/FXparticleSystem.h
Outdated
class ParticleSystem2D { | ||
public: | ||
ParticleSystem2D(const uint32_t width, const uint32_t height, const uint32_t numberofparticles, const uint32_t numberofsources, const bool isadvanced = false, const bool sizecontrol = false); // constructor | ||
// note: memory is allcated in the FX function, no deconstructor needed | ||
void update(void); //update the particles according to set options and render to the matrix | ||
void updateFire(const uint8_t intensity, const bool renderonly); // update function for fire, if renderonly is set, particles are not updated (required to fix transitions with frameskips) | ||
void updateSystem(void); // call at the beginning of every FX, updates pointers and dimensions | ||
void particleMoveUpdate(PSparticle &part, PSparticleFlags &partFlags, PSsettings2D *options = NULL, PSadvancedParticle *advancedproperties = NULL); // move function | ||
// particle emitters | ||
int32_t sprayEmit(const PSsource &emitter); | ||
void flameEmit(const PSsource &emitter); | ||
int32_t angleEmit(PSsource& emitter, const uint16_t angle, const int32_t speed); | ||
//particle physics | ||
void applyGravity(PSparticle &part); // applies gravity to single particle (use this for sources) | ||
[[gnu::hot]] void applyForce(PSparticle &part, const int8_t xforce, const int8_t yforce, uint8_t &counter); | ||
[[gnu::hot]] void applyForce(const uint32_t particleindex, const int8_t xforce, const int8_t yforce); // use this for advanced property particles | ||
void applyForce(const int8_t xforce, const int8_t yforce); // apply a force to all particles | ||
void applyAngleForce(PSparticle &part, const int8_t force, const uint16_t angle, uint8_t &counter); | ||
void applyAngleForce(const uint32_t particleindex, const int8_t force, const uint16_t angle); // use this for advanced property particles | ||
void applyAngleForce(const int8_t force, const uint16_t angle); // apply angular force to all particles | ||
void applyFriction(PSparticle &part, const int32_t coefficient); // apply friction to specific particle | ||
void applyFriction(const int32_t coefficient); // apply friction to all used particles | ||
void pointAttractor(const uint32_t particleindex, PSparticle &attractor, const uint8_t strength, const bool swallow); | ||
// set options note: inlining the set function uses more flash so dont optimize | ||
void setUsedParticles(const uint8_t percentage); // set the percentage of particles used in the system, 255=100% | ||
inline uint32_t getAvailableParticles(void) { return availableParticles; } // available particles in the buffer, use this to check if buffer changed during FX init | ||
void setCollisionHardness(const uint8_t hardness); // hardness for particle collisions (255 means full hard) | ||
void setWallHardness(const uint8_t hardness); // hardness for bouncing on the wall if bounceXY is set | ||
void setWallRoughness(const uint8_t roughness); // wall roughness randomizes wall collisions | ||
void setMatrixSize(const uint32_t x, const uint32_t y); | ||
void setWrapX(const bool enable); | ||
void setWrapY(const bool enable); | ||
void setBounceX(const bool enable); | ||
void setBounceY(const bool enable); | ||
void setKillOutOfBounds(const bool enable); // if enabled, particles outside of matrix instantly die | ||
void setSaturation(const uint8_t sat); // set global color saturation | ||
void setColorByAge(const bool enable); | ||
void setMotionBlur(const uint8_t bluramount); // note: motion blur can only be used if 'particlesize' is set to zero | ||
void setSmearBlur(const uint8_t bluramount); // enable 2D smeared blurring of full frame | ||
void setParticleSize(const uint8_t size); | ||
void setGravity(const int8_t force = 8); | ||
void enableParticleCollisions(const bool enable, const uint8_t hardness = 255); | ||
|
||
PSparticle *particles; // pointer to particle array | ||
PSparticleFlags *particleFlags; // pointer to particle flags array | ||
PSsource *sources; // pointer to sources | ||
PSadvancedParticle *advPartProps; // pointer to advanced particle properties (can be NULL) | ||
PSsizeControl *advPartSize; // pointer to advanced particle size control (can be NULL) | ||
uint8_t* PSdataEnd; // points to first available byte after the PSmemory, is set in setPointers(). use this for FX custom data | ||
int32_t maxX, maxY; // particle system size i.e. width-1 / height-1 in subpixels, Note: all "max" variables must be signed to compare to coordinates (which are signed) | ||
int32_t maxXpixel, maxYpixel; // last physical pixel that can be drawn to (FX can read this to read segment size if required), equal to width-1 / height-1 | ||
uint32_t numSources; // number of sources | ||
uint32_t usedParticles; // number of particles used in animation, is relative to 'numParticles' | ||
//note: some variables are 32bit for speed and code size at the cost of ram | ||
|
||
private: | ||
//rendering functions | ||
void ParticleSys_render(); | ||
[[gnu::hot]] void renderParticle(const uint32_t particleindex, const uint32_t brightness, const CRGB& color, const bool wrapX, const bool wrapY); | ||
//paricle physics applied by system if flags are set | ||
void applyGravity(); // applies gravity to all particles | ||
void handleCollisions(); | ||
[[gnu::hot]] void collideParticles(PSparticle &particle1, PSparticle &particle2, const int32_t dx, const int32_t dy); | ||
void fireParticleupdate(); | ||
//utility functions | ||
void updatePSpointers(const bool isadvanced, const bool sizecontrol); // update the data pointers to current segment data space | ||
bool updateSize(PSadvancedParticle *advprops, PSsizeControl *advsize); // advanced size control | ||
void getParticleXYsize(PSadvancedParticle *advprops, PSsizeControl *advsize, uint32_t &xsize, uint32_t &ysize); | ||
[[gnu::hot]] void bounce(int8_t &incomingspeed, int8_t ¶llelspeed, int32_t &position, const uint32_t maxposition); // bounce on a wall | ||
// note: variables that are accessed often are 32bit for speed | ||
PSsettings2D particlesettings; // settings used when updating particles (can also used by FX to move sources), do not edit properties directly, use functions above | ||
uint32_t numParticles; // total number of particles allocated by this system note: during transitions, less are available, use availableParticles | ||
uint32_t availableParticles; // number of particles available for use (can be more or less than numParticles, assigned by memory manager) | ||
uint32_t emitIndex; // index to count through particles to emit so searching for dead pixels is faster | ||
int32_t collisionHardness; | ||
uint32_t wallHardness; | ||
uint32_t wallRoughness; // randomizes wall collisions | ||
uint32_t particleHardRadius; // hard surface radius of a particle, used for collision detection (32bit for speed) | ||
uint16_t collisionStartIdx; // particle array start index for collision detection | ||
uint8_t fireIntesity = 0; // fire intensity, used for fire mode (flash use optimization, better than passing an argument to render function) | ||
uint8_t fractionOfParticlesUsed; // percentage of particles used in the system (255=100%), used during transition updates | ||
uint8_t forcecounter; // counter for globally applied forces | ||
uint8_t gforcecounter; // counter for global gravity | ||
int8_t gforce; // gravity strength, default is 8 (negative is allowed, positive is downwards) | ||
// global particle properties for basic particles | ||
uint8_t particlesize; // global particle size, 0 = 2 pixels, 255 = 10 pixels (note: this is also added to individual sized particles) | ||
uint8_t motionBlur; // motion blur, values > 100 gives smoother animations. Note: motion blurring does not work if particlesize is > 0 | ||
uint8_t smearBlur; // 2D smeared blurring of full frame | ||
uint8_t effectID; // ID of the effect that is using this particle system, used for transitions | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider splitting large class.
ParticleSystem2D
is quite extensive, handling initialization, movement updates, rendering, collisions, and more. While the functionality is closely related, the class might be pushing the Single Responsibility Principle. Evaluate a split into smaller classes or modules (e.g., a dedicated collision handler) to improve clarity and reduce potential coupling.
#define FX_MODE_PARTICLEVOLCANO 187 | ||
#define FX_MODE_PARTICLEFIRE 188 | ||
#define FX_MODE_PARTICLEFIREWORKS 189 | ||
#define FX_MODE_PARTICLEVORTEX 190 | ||
#define FX_MODE_PARTICLEPERLIN 191 | ||
#define FX_MODE_PARTICLEPIT 192 | ||
#define FX_MODE_PARTICLEBOX 193 | ||
#define FX_MODE_PARTICLEATTRACTOR 194 | ||
#define FX_MODE_PARTICLEIMPACT 195 | ||
#define FX_MODE_PARTICLEWATERFALL 196 | ||
#define FX_MODE_PARTICLESPRAY 197 | ||
#define FX_MODE_PARTICLESGEQ 198 | ||
#define FX_MODE_PARTICLECENTERGEQ 199 | ||
#define FX_MODE_PARTICLEGHOSTRIDER 200 | ||
#define FX_MODE_PARTICLEBLOBS 201 | ||
#define FX_MODE_PSDRIP 202 | ||
#define FX_MODE_PSPINBALL 203 | ||
#define FX_MODE_PSDANCINGSHADOWS 204 | ||
#define FX_MODE_PSFIREWORKS1D 205 | ||
#define FX_MODE_PSSPARKLER 206 | ||
#define FX_MODE_PSHOURGLASS 207 | ||
#define FX_MODE_PS1DSPRAY 208 | ||
#define FX_MODE_PSBALANCE 209 | ||
#define FX_MODE_PSCHASE 210 | ||
#define FX_MODE_PSSTARBURST 211 | ||
#define FX_MODE_PS1DGEQ 212 | ||
#define FX_MODE_PSFIRE1D 213 | ||
#define FX_MODE_PS1DSONICSTREAM 214 | ||
#define MODE_COUNT 215 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validate large effect enumeration.
A considerable block of new particle effect modes (187 to 215) has been introduced. Verify that:
- The definitions don’t overlap with existing modes.
- Each effect has a matching handler in your FX function table.
MODE_COUNT
properly reflects this extended set, ensuring array bounds are respected.
Image effect (GIF support)
Update AsyncWebServer and enable response queue
Support PWM phase shifts on ESP8266
…, minor tweaks - collisions are now also velocity based in 1D, there was a bug that prevented that from working well (wrong collision distance calculation) - improvement and bugfix in 2D collision distance calculation - added distance based pushing in 2D (instead of only using the dotproduct) the combination of improved distance calculation and proper pushing make collisions a lot better in all tested FX
Was just for testing CodeRabbit |
Summary by CodeRabbit
New Features
Improvements
Technical Updates