Skip to content

Commit 46aef89

Browse files
committed
Bugfix in particle push, now piling is working again
particle pile-up did not work correctly, now fixed
1 parent dc5c58e commit 46aef89

File tree

2 files changed

+31
-24
lines changed

2 files changed

+31
-24
lines changed

wled00/FXparticleSystem.cpp

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,14 @@ void Particle_Gravity_update(PSparticle *part, bool wrapX, bool bounceX, bool bo
259259
part->ttl--;
260260

261261
// check if particle is out of bounds or died
262-
if ((part->y < -PS_P_RADIUS) || (part->y >= PS_MAX_Y << 1))
262+
if ((part->y < -PS_P_RADIUS) || (part->y >= PS_MAX_Y << 2))
263263
{ // if it moves more than 1 pixel below y=0, it will not come back. also remove particles that too far above
264264
part->ttl = 0;
265265
return; // particle died, we are done
266266
}
267267
if (wrapX == false)
268268
{
269-
if ((part->x < -PS_MAX_X) || (part->x >= PS_MAX_X << 1))
269+
if ((part->x < -PS_MAX_X) || (part->x >= PS_MAX_X << 2))
270270
{ // left and right: keep it alive as long as its not too far out (if adding more effects like wind, it may come back)
271271
part->ttl = 0;
272272
return; // particle died, we are done
@@ -733,7 +733,7 @@ void detectCollisions(PSparticle* particles, uint32_t numparticles, uint8_t hard
733733
{
734734
// go though all 'higher number' particles and see if any of those are in close proximity
735735
// if they are, make them collide
736-
if (particles[i].ttl > 0 && particles[i].collide) // if particle is alive and does collide
736+
if (particles[i].ttl > 0 && particles[i].collide && particles[i].outofbounds==0) // if particle is alive and does collide and is not out of view
737737
{
738738
int32_t dx, dy; // distance to other particles
739739
for (j = i + 1; j < numparticles; j++)
@@ -771,15 +771,15 @@ void handleCollision(PSparticle *particle1, PSparticle *particle2, const uint8_t
771771
{
772772
// Adjust positions based on relative velocity direction
773773

774-
if (relativeVx <= 0) { //if true, particle2 is on the right side
774+
if (relativeVx < 0) { //if true, particle2 is on the right side
775775
particle1->x--;
776776
particle2->x++;
777777
} else{
778778
particle1->x++;
779779
particle2->x--;
780780
}
781781

782-
if (relativeVy <= 0) {
782+
if (relativeVy < 0) {
783783
particle1->y--;
784784
particle2->y++;
785785
} else{
@@ -805,7 +805,7 @@ void handleCollision(PSparticle *particle1, PSparticle *particle2, const uint8_t
805805
particle2->vx -= ximpulse;
806806
particle2->vy -= yimpulse;
807807

808-
if (hardness < 50) // if particles are soft, they become 'sticky' i.e. no slow movements
808+
if (hardness < 50) // if particles are soft, they become 'sticky' i.e. slow movements are stopped
809809
{
810810
particle1->vx = (particle1->vx < 2 && particle1->vx > -2) ? 0 : particle1->vx;
811811
particle1->vy = (particle1->vy < 2 && particle1->vy > -2) ? 0 : particle1->vy;
@@ -814,38 +814,45 @@ void handleCollision(PSparticle *particle1, PSparticle *particle2, const uint8_t
814814
particle2->vy = (particle2->vy < 2 && particle2->vy > -2) ? 0 : particle2->vy;
815815
}
816816

817-
}
818-
817+
}
819818
// particles have volume, push particles apart if they are too close by moving each particle by a fixed amount away from the other particle
820819
// if pushing is made dependent on hardness, things start to oscillate much more, better to just add a fixed, small increment (tried lots of configurations, this one works best)
821820
// one problem remaining is, particles get squished if (external) force applied is higher than the pushback but this may also be desirable if particles are soft. also some oscillations cannot be avoided without addigng a counter
822-
if (distanceSquared < 2 * PS_P_HARDRADIUS * PS_P_HARDRADIUS)
821+
if (distanceSquared < (int32_t)2 * PS_P_HARDRADIUS * PS_P_HARDRADIUS)
823822
{
824-
uint8_t rndchoice = random8(2);
825-
const uint32_t HARDDIAMETER = 2*PS_P_HARDRADIUS;
823+
uint8_t choice = random8(2);//randomly choose one particle to push, avoids oscillations
824+
const int32_t HARDDIAMETER = (int32_t)2*PS_P_HARDRADIUS;
825+
826826

827827
if (dx < HARDDIAMETER && dx > -HARDDIAMETER)
828828
{ // distance is too small, push them apart
829-
int32_t push = 3;
830-
if (dx < 0) // dx is negative
831-
push =-push; // negative push direction
832829

833-
if (rndchoice) // randomly chose one of the particles to push, avoids oscillations
830+
int32_t push;
831+
if (dx <= 0)
832+
push = -1;//-(PS_P_HARDRADIUS + dx); // inverted push direction
833+
else
834+
push = 1;//PS_P_HARDRADIUS - dx;
835+
836+
if (choice) // chose one of the particles to push, avoids oscillations
834837
particle1->x -= push;
835838
else
836-
particle2->x += push; // only push one particle to avoid oscillations
839+
particle2->x += push;
837840
}
838-
841+
//Serial.print(" dy");
842+
//Serial.println(dy);
839843
if (dy < HARDDIAMETER && dy > -HARDDIAMETER)
840-
{ // distance is too small (or negative)
841-
int32_t push = 3;
842-
if (dy < 0) // dy is negative
843-
push = -push;//negative push direction
844+
{
845+
846+
int32_t push;
847+
if (dy <= 0)
848+
push = -1; //-(PS_P_HARDRADIUS + dy); // inverted push direction
849+
else
850+
push = 1; // PS_P_HARDRADIUS - dy;
844851

845-
if (rndchoice) // randomly chose one of the particles to push, avoids oscillations
852+
if (choice) // chose one of the particles to push, avoids oscillations
846853
particle1->y -= push;
847854
else
848-
particle2->y += push; // only push one particle to avoid oscillations
855+
particle2->y += push;
849856
}
850857
//note: pushing may push particles out of frame, if bounce is active, it will move it back as position will be limited to within frame
851858
}

wled00/FXparticleSystem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
//particle dimensions (subpixel division)
3333
#define PS_P_RADIUS 64 //subpixel size, each pixel is divided by this for particle movement
34-
#define PS_P_HARDRADIUS 100 //hard surface radius of a particle, used for collision detection proximity
34+
#define PS_P_HARDRADIUS 80 //hard surface radius of a particle, used for collision detection proximity
3535
#define PS_P_SURFACE 12 //shift: 2^PS_P_SURFACE = (PS_P_RADIUS)^2
3636

3737

0 commit comments

Comments
 (0)