diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 8c5ee32644..70e4747167 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -8770,7 +8770,7 @@ uint16_t mode_particlebox(void) for (i = 0; i < maxnumParticles; i++) { PartSys->particles[i].ttl = 500; //set all particles alive (not all are rendered though) - PartSys->particles[i].hue = i * 5; // color range + PartSys->particles[i].hue = i * 5; // color range PartSys->particles[i].x = map(i, 0, maxnumParticles, 1, PartSys->maxX); // distribute along x according to color PartSys->particles[i].y = random16(PartSys->maxY); // randomly in y direction PartSys->particles[i].collide = true; // all particles collide @@ -8975,7 +8975,7 @@ uint16_t mode_particleimpact(void) #ifdef ESP8266 emitparticles = random16(SEGMENT.intensity >> 3) + 5; // defines the size of the explosion #else - emitparticles = map(SEGMENT.intensity, 0, 255, 10, random16(PartSys->numParticles>>2)); // defines the size of the explosion !!!TODO: check if this works, drop esp8266 def if it does + emitparticles = map(SEGMENT.intensity, 0, 255, 10, random16(PartSys->numParticles>>2)); // defines the size of the explosion !!!TODO: check if this works on ESP8266, drop esp8266 def if it does #endif } for (int e = emitparticles; e > 0; e--) @@ -9429,7 +9429,7 @@ static const char _data_FX_MODE_PARTICLEGEQ[] PROGMEM = "PS Equalizer@Speed,Inte /* Particle replacement of Ghost Rider by DedeHai (Damian Schneider), original by stepko adapted by Blaz Kristan (AKA blazoncek) */ -#define MAXANGLESTEP 2000 //32767 means 180° +#define MAXANGLESTEP 2200 //32767 means 180° uint16_t mode_particlghostrider(void) { if (SEGLEN == 1) @@ -9487,10 +9487,16 @@ uint16_t mode_particlghostrider(void) PartSys->particles[i].hue = PartSys->sources[0].source.hue + (PartSys->particles[i].ttl<<2); } } - SEGMENT.aux0 += (int32_t)SEGMENT.step; //step is angle increment + //enable/disable walls + ghostsettings.bounceX = SEGMENT.check2; + ghostsettings.bounceY = SEGMENT.check2; + + SEGMENT.aux0 += (int32_t)SEGMENT.step; //step is angle increment uint16_t emitangle = SEGMENT.aux0 + 32767; //+180° int32_t speed = map(SEGMENT.speed, 0, 255, 12, 64); + int8_t newvx = ((int32_t)cos16(SEGMENT.aux0) * speed) / (int32_t)32767; + int8_t newvy = ((int32_t)sin16(SEGMENT.aux0) * speed) / (int32_t)32767; PartSys->sources[0].source.vx = ((int32_t)cos16(SEGMENT.aux0) * speed) / (int32_t)32767; PartSys->sources[0].source.vy = ((int32_t)sin16(SEGMENT.aux0) * speed) / (int32_t)32767; PartSys->sources[0].source.ttl = 500; //source never dies @@ -9508,7 +9514,7 @@ uint16_t mode_particlghostrider(void) PartSys->update(); // update and render return FRAMETIME; } -static const char _data_FX_MODE_PARTICLEGHOSTRIDER[] PROGMEM = "PS Ghost Rider@Speed,Spiral,Blur,Color Cycle,Spread,Color by age;;!;2;pal=1,sx=70,ix=0,c1=220,c2=30,c3=21,o1=1,o2=0,o3=0"; +static const char _data_FX_MODE_PARTICLEGHOSTRIDER[] PROGMEM = "PS Ghost Rider@Speed,Spiral,Blur,Color Cycle,Spread,Color by age,Walls;;!;2;pal=1,sx=70,ix=0,c1=220,c2=30,c3=21,o1=1,o2=0,o3=0"; /* * Particle rotating GEQ diff --git a/wled00/FXparticleSystem.cpp b/wled00/FXparticleSystem.cpp index 12fbf14944..64fee78ccc 100644 --- a/wled00/FXparticleSystem.cpp +++ b/wled00/FXparticleSystem.cpp @@ -36,9 +36,6 @@ -add function to 'update sources' so FX does not have to take care of that. FX can still implement its own version if so desired. config should be optional, if not set, use default config. -add possiblity to emit more than one particle, just pass a source and the amount to emit or even add several sources and the amount, function decides if it should do it fair or not -add an x/y struct, do particle rendering using that, much easier to read - -extend rendering to more than 2x2, 3x2 (fire) should be easy, 3x3 maybe also doable without using much math (need to see if it looks good) - - */ // sources need to be updatable by the FX, so functions are needed to apply it to a single particle that are public #include "FXparticleSystem.h" @@ -56,7 +53,7 @@ ParticleSystem::ParticleSystem(uint16_t width, uint16_t height, uint16_t numbero updatePSpointers(isadvanced); // set the particle and sources pointer (call this before accessing sprays or particles) setMatrixSize(width, height); setWallHardness(255); // set default wall hardness to max - setWallRoughness(0); // smooth walls by default !!! testing this + setWallRoughness(0); // smooth walls by default setGravity(0); //gravity disabled by default setParticleSize(0); // minimum size by default motionBlur = 0; //no fading by default @@ -67,6 +64,10 @@ ParticleSystem::ParticleSystem(uint16_t width, uint16_t height, uint16_t numbero { sources[i].source.sat = 255; //set saturation to max by default } + for (int i = 0; i < numParticles; i++) + { + particles[i].sat = 255; // full saturation + } /* Serial.println("alive particles: "); uint32_t aliveparticles = 0; @@ -110,16 +111,16 @@ void ParticleSystem::update(void) } particleMoveUpdate(particles[i], particlesettings, advprop); } - //!!! remove this - //Serial.print("alive particles: "); + /*!!! remove this + Serial.print("alive particles: "); uint32_t aliveparticles = 0; for (int i = 0; i < numParticles; i++) { if(particles[i].ttl) aliveparticles++; } - - //Serial.println(aliveparticles); + Serial.println(aliveparticles); + */ ParticleSys_render(); } @@ -550,7 +551,7 @@ void ParticleSystem::applyFriction(uint8_t coefficient) } // attracts a particle to an attractor particle using the inverse square-law -void ParticleSystem::pointAttractor(uint16_t particleindex, PSparticle *attractor, uint8_t strength, bool swallow) // TODO: need to check if this is ok with new advancedprops !!! +void ParticleSystem::pointAttractor(uint16_t particleindex, PSparticle *attractor, uint8_t strength, bool swallow) { if (advPartProps == NULL) return; // no advanced properties available @@ -682,19 +683,18 @@ void ParticleSystem::ParticleSys_render(bool firemode, uint32_t fireintensity) if(!useLocalBuffer) //disabled or allocation above failed { + Serial.println("NOT using local buffer!"); if (motionBlur > 0) - SEGMENT.fadeToBlackBy(256 - motionBlur); + SEGMENT.fadeToBlackBy(255 - motionBlur); else SEGMENT.fill(BLACK); //clear the buffer before rendering to it } - uint32_t debug = 0; // go over particles and render them to the buffer for (i = 0; i < usedParticles; i++) { if (particles[i].outofbounds || particles[i].ttl == 0) continue; - debug++; // generate RGB values for particle if(firemode) { @@ -768,7 +768,6 @@ void ParticleSystem::ParticleSys_render(bool firemode, uint32_t fireintensity) } if(renderbuffer) free(renderbuffer); // free buffer memory - Serial.println(debug); } // calculate pixel positions and brightness distribution and render the particle to local buffer or global buffer @@ -1091,7 +1090,7 @@ void ParticleSystem::handleCollisions() } collisioncounter++; - //startparticle = 0;//!!! test: do all collisions every frame, FPS goes from about 52 to + //startparticle = 0;//!!!TODO test: do all collisions every frame //endparticle = usedParticles; for (i = startparticle; i < endparticle; i++) @@ -1363,9 +1362,7 @@ int32_t ParticleSystem::limitSpeed(int32_t speed) // allocate memory for the 2D array in one contiguous block and set values to zero CRGB **ParticleSystem::allocate2Dbuffer(uint32_t cols, uint32_t rows) { - //cli();//!!! test to see if anything messes with the allocation (flicker issues) CRGB ** array2D = (CRGB **)malloc(cols * sizeof(CRGB *) + cols * rows * sizeof(CRGB)); - //sei(); if (array2D == NULL) DEBUG_PRINT(F("PS buffer alloc failed")); else diff --git a/wled00/FXparticleSystem.h b/wled00/FXparticleSystem.h index d976fa8b46..dacf6ab5b1 100644 --- a/wled00/FXparticleSystem.h +++ b/wled00/FXparticleSystem.h @@ -30,7 +30,7 @@ #include "FastLED.h" //memory allocation -#define ESP8266_MAXPARTICLES 200// // enough for one 16x16 segment with transitions +#define ESP8266_MAXPARTICLES 180// // enough for one 16x16 segment with transitions #define ESP8266_MAXSOURCES 16 #define ESP32S2_MAXPARTICLES 840 // enough for four 16x16 segments #define ESP32S2_MAXSOURCES 48