From ca54d819650509b000037042e737b579f118e7be Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Fri, 10 Jan 2025 21:04:22 +0100 Subject: [PATCH] removed todos after some checks, minor improvements --- wled00/FXparticleSystem.cpp | 17 ++++++++++------- wled00/FXparticleSystem.h | 15 ++++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/wled00/FXparticleSystem.cpp b/wled00/FXparticleSystem.cpp index a5fbd41650..b3ffd66152 100644 --- a/wled00/FXparticleSystem.cpp +++ b/wled00/FXparticleSystem.cpp @@ -22,7 +22,6 @@ // local shared functions (used both in 1D and 2D system) static int32_t calcForce_dv(const int8_t force, uint8_t &counter); -static int32_t limitSpeed(int32_t speed); static bool checkBoundsAndWrap(int32_t &position, const int32_t max, const int32_t particleradius, const bool wrap); // returns false if out of bounds by more than particleradius static void fast_color_add(CRGB &c1, const CRGB &c2, uint32_t scale = 255); // fast and accurate color adding with scaling (scales c2 before adding) static void fast_color_scale(CRGB &c, const uint32_t scale); // fast scaling function using 32bit variable and pointer. note: keep 'scale' within 0-255 @@ -252,7 +251,7 @@ void ParticleSystem2D::particleMoveUpdate(PSparticle &part, PSparticleFlags &par int32_t renderradius = PS_P_HALFRADIUS; // used to check out of bounds int32_t newX = part.x + (int32_t)part.vx; int32_t newY = part.y + (int32_t)part.vy; - partFlags.outofbounds = false; // reset out of bounds (in case particle was created outside the matrix and is now moving into view) TODO: move this below, setting a flag is slow, only set if actually in bounds + partFlags.outofbounds = false; // reset out of bounds (in case particle was created outside the matrix and is now moving into view) note: moving this to checks below adds code and is not faster if (advancedproperties) { //using individual particle size? if (advancedproperties->size > 0) { @@ -302,7 +301,7 @@ void ParticleSystem2D::fireParticleupdate() { particles[i].ttl--; // age int32_t newY = particles[i].y + (int32_t)particles[i].vy + (particles[i].ttl >> 2); // younger particles move faster upward as they are hotter int32_t newX = particles[i].x + (int32_t)particles[i].vx; - particleFlags[i].outofbounds = 0; // reset out of bounds flag //TODO: can this be moved to else statements below? + particleFlags[i].outofbounds = 0; // reset out of bounds flag note: moving this to checks below is not faster but adds code // check if particle is out of bounds, wrap x around to other side if wrapping is enabled // as fire particles start below the frame, lots of particles are out of bounds in y direction. to improve speed, only check x direction if y is not out of bounds if (newY < -PS_P_HALFRADIUS) @@ -1063,7 +1062,8 @@ void blur2D(CRGB *colorbuffer, uint32_t xsize, uint32_t ysize, uint32_t xblur, u fast_color_scale(seeppart, seep); // scale it and seep to neighbours if (x > 0) { fast_color_add(colorbuffer[indexXY - 1], seeppart); - fast_color_add(colorbuffer[indexXY], carryover); // TODO: could check if carryover is > 0, takes 7 instructions, add takes ~35, with lots of same color pixels (like background), it would be faster + if(carryover) // note: check adds overhead but is faster on average + fast_color_add(colorbuffer[indexXY], carryover); } carryover = seeppart; indexXY++; // next pixel in x direction @@ -1084,7 +1084,8 @@ void blur2D(CRGB *colorbuffer, uint32_t xsize, uint32_t ysize, uint32_t xblur, u fast_color_scale(seeppart, seep); // scale it and seep to neighbours if (y > 0) { fast_color_add(colorbuffer[indexXY - width], seeppart); - fast_color_add(colorbuffer[indexXY], carryover); // todo: could check if carryover is > 0, takes 7 instructions, add takes ~35, with lots of same color pixels (like background), it would be faster + if(carryover) // note: check adds overhead but is faster on average + fast_color_add(colorbuffer[indexXY], carryover); } carryover = seeppart; indexXY += width; // next pixel in y direction @@ -1891,7 +1892,8 @@ void blur1D(CRGB *colorbuffer, uint32_t size, uint32_t blur, uint32_t start) fast_color_scale(seeppart, seep); // scale it and seep to neighbours if (x > 0) { fast_color_add(colorbuffer[x-1], seeppart); - fast_color_add(colorbuffer[x], carryover); // is black on first pass + if(carryover) // note: check adds overhead but is faster on average + fast_color_add(colorbuffer[x], carryover); // is black on first pass } carryover = seeppart; } @@ -1928,10 +1930,11 @@ static int32_t calcForce_dv(const int8_t force, uint8_t &counter) { // limit speed to prevent overflows //TODO: inline this function? check if that uses a lot more flash. +/* static int32_t limitSpeed(int32_t speed) { return min((int32_t)PS_P_MAXSPEED, max((int32_t)-PS_P_MAXSPEED, speed)); //return speed > PS_P_MAXSPEED ? PS_P_MAXSPEED : (speed < -PS_P_MAXSPEED ? -PS_P_MAXSPEED : speed); // note: this uses more code, not sure due to speed or inlining -} +}*/ // check if particle is out of bounds and wrap it around if required, returns false if out of bounds static bool checkBoundsAndWrap(int32_t &position, const int32_t max, const int32_t particleradius, const bool wrap) { diff --git a/wled00/FXparticleSystem.h b/wled00/FXparticleSystem.h index acf48504b5..f9c44ccac1 100644 --- a/wled00/FXparticleSystem.h +++ b/wled00/FXparticleSystem.h @@ -16,7 +16,7 @@ #define PS_P_MAXSPEED 120 // maximum speed a particle can have (vx/vy is int8) #define MAX_MEMIDLE 10 // max idle time (in frames) before memory is deallocated (if deallocated during an effect, it will crash!) -#define WLED_DEBUG_PS +//#define WLED_DEBUG_PS // note: enabling debug uses ~3k of flash #ifdef WLED_DEBUG_PS #define PSPRINT(x) Serial.print(x) @@ -44,9 +44,13 @@ partMem* getPartMem(void); // returns pointer to memory struct for current segme void updateRenderingBuffer(uint32_t requiredpixels, bool isFramebuffer, bool initialize); // allocate CRGB rendering buffer, update size if needed void transferBuffer(uint32_t width, uint32_t height, bool useAdditiveTransfer = false); // transfer the buffer to the segment (supports 1D and 2D) void servicePSmem(); // increments watchdog, frees memory if idle too long + +// limit speed of particles (used in 1D and 2D) +static inline int32_t limitSpeed(int32_t speed) { + return speed > PS_P_MAXSPEED ? PS_P_MAXSPEED : (speed < -PS_P_MAXSPEED ? -PS_P_MAXSPEED : speed); // note: this is slightly faster than using min/max at the cost of 50bytes of flash +} #endif -//TODO: maybe update PS_P_MINSURFACEHARDNESS for 2D? its a bit too sticky already at hardness 100 #ifndef WLED_DISABLE_PARTICLESYSTEM2D // memory allocation #define ESP8266_MAXPARTICLES 300 // enough up to 20x20 pixels @@ -165,7 +169,7 @@ class ParticleSystem2D { 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 + // 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) @@ -319,9 +323,6 @@ typedef struct { uint8_t size; // particle size (advanced property) } PSsource1D; -//TODO: 1D function cleanup: add const where possible, replace pointers with reference where possible -//TODO: match all functions with declarations in header file for consistency -// TODO: make all 1-line function inline (check first if this makes code larger or smaller with one) class ParticleSystem1D { public: @@ -393,7 +394,7 @@ class ParticleSystem1D uint8_t forcecounter; // counter for globally applied forces uint16_t collisionStartIdx; // particle array start index for collision detection //global particle properties for basic particles - uint8_t particlesize; // global particle size, 0 = 1 pixel, 1 = 2 pixels, larger sizez TBD (TODO: need larger sizes?) + uint8_t particlesize; // global particle size, 0 = 1 pixel, 1 = 2 pixels uint8_t motionBlur; // enable motion blur, values > 100 gives smoother animations uint8_t smearBlur; // smeared blurring of full frame uint8_t effectID; // ID of the effect that is using this particle system, used for transitions