diff --git a/wled00/FX.cpp b/wled00/FX.cpp index a4e39d75cc..9308e8dc07 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -8033,7 +8033,7 @@ uint16_t mode_particlefireworks(void) uint16_t i = 0; uint16_t j = 0; - uint8_t numRockets = (SEGMENT.custom3+1) >> 2; //1 to 8 + uint8_t numRockets = 1+ ((SEGMENT.custom3) >> 2); //1 to 8 if (SEGMENT.call == 0) // initialization { @@ -8068,13 +8068,36 @@ uint16_t mode_particlefireworks(void) { // speed is zero, explode! emitparticles = random8(SEGMENT.intensity>>1) + 10; // defines the size of the explosion rockets[j].source.vy = -1; // set speed negative so it will emit no more particles after this explosion until relaunch + if (j == 0) // first rocket, do an angle emit + { + emitparticles>>1; //emit less particles for circle-explosion + rockets[j].maxLife = 150; + rockets[j].minLife = 120; + rockets[j].var = 0; // speed variation around vx,vy (+/- var/2) + } } + uint8_t speed = 5; + uint8_t angle = 0; + for (i; i < numParticles; i++) { if (particles[i].ttl == 0) { // particle is dead - if (emitparticles > 0) + + if (j == 0 && emitparticles > 2) // first rocket, do angle emit + { + Emitter_Angle_emit(&rockets[j], &particles[i],angle,speed); + emitparticles--; + //set angle for next particle + angle += 21; //about 30° + if(angle > 250) //full circle completed, increase speed and reset angle + { + angle = 0; + speed += 8; + } + } + else if (emitparticles > 0) { Emitter_Fountain_emit(&rockets[j], &particles[i]); emitparticles--; @@ -8114,7 +8137,7 @@ uint16_t mode_particlefireworks(void) rockets[i].source.ttl = random8((255 - SEGMENT.speed))+10; // standby time til next launch (in frames at 42fps, max of 265 is about 6 seconds rockets[i].vx = 0; // emitting speed rockets[i].vy = 0; // emitting speed - rockets[i].var = (SEGMENT.intensity >> 2) + 10; // speed variation around vx,vy (+/- var/2) + rockets[i].var = (SEGMENT.intensity >> 3) + 10; // speed variation around vx,vy (+/- var/2) } else if (rockets[i].source.vy < 0) // rocket is exploded and time is up (ttl=0 and negative speed), relaunch it { diff --git a/wled00/FXparticleSystem.cpp b/wled00/FXparticleSystem.cpp index f09c418296..29c8fe668d 100644 --- a/wled00/FXparticleSystem.cpp +++ b/wled00/FXparticleSystem.cpp @@ -45,14 +45,27 @@ void Emitter_Flame_emit(PSpointsource *emitter, PSparticle *part) // fountain style emitter void Emitter_Fountain_emit(PSpointsource *emitter, PSparticle *part) { - part->x = emitter->source.x + random8(emitter->var) - (emitter->var >> 1); - part->y = emitter->source.y + random8(emitter->var) - (emitter->var >> 1); + part->x = emitter->source.x; // + random8(emitter->var) - (emitter->var >> 1); //randomness uses cpu cycles and is almost invisible, removed for now. + part->y = emitter->source.y; // + random8(emitter->var) - (emitter->var >> 1); part->vx = emitter->vx + random8(emitter->var) - (emitter->var >> 1); part->vy = emitter->vy + random8(emitter->var) - (emitter->var >> 1); part->ttl = (rand() % (emitter->maxLife - emitter->minLife)) + emitter->minLife; part->hue = emitter->source.hue; } +// Emits a particle at given angle and speed, angle is from 0-255 (=0-360deg), speed is also affected by emitter->var +void Emitter_Angle_emit(PSpointsource *emitter, PSparticle *part, uint8_t angle, uint8_t speed) +{ + emitter->vx = (((int16_t)cos8(angle)-127) * speed) >> 7; //cos is signed 8bit, so 1 is 127, -1 is -127, shift by 7 + emitter->vy = (((int16_t)sin8(angle)-127) * speed) >> 7; + Serial.print(angle); + Serial.print(" "); + Serial.print(emitter->vx); + Serial.print(" "); + Serial.print(emitter->vy); + Serial.print(" "); + Emitter_Fountain_emit(emitter, part); +} // attracts a particle to an attractor particle using the inverse square-law void Particle_attractor(PSparticle *particle, PSparticle *attractor, uint8_t *counter, uint8_t strength, bool swallow) // todo: add a parameter 'swallow' so the attractor can 'suck up' particles that are very close, also could use hue of attractor particle for strength { diff --git a/wled00/FXparticleSystem.h b/wled00/FXparticleSystem.h index 82f0359244..0bcacd79ce 100644 --- a/wled00/FXparticleSystem.h +++ b/wled00/FXparticleSystem.h @@ -69,7 +69,8 @@ int8_t vortexpull; //if positive, vortex pushes, if negative it pulls void Emitter_Flame_emit(PSpointsource *emitter, PSparticle *part); void Emitter_Fountain_emit(PSpointsource *emitter, PSparticle *part); -void Particle_attractor(PSparticle *particle, PSparticle *attractor, uint8_t *counter, uint8_t strength, bool swallow); +void Emitter_Angle_emit(PSpointsource *emitter, PSparticle *part, uint8_t angle, uint8_t speed); +void Particle_attractor(PSparticle *particle, PSparticle *attractor, uint8_t *counter, uint8_t strength, bool swallow); void Particle_Move_update(PSparticle *part); void Particle_Bounce_update(PSparticle *part, const uint8_t hardness); void Particle_Gravity_update(PSparticle *part, bool wrapX, bool bounceX, bool bounceY, const uint8_t hardness);