Particles (Seg Line) - AlbertGBarber/PixelSpork GitHub Wiki
See the Documentation Guide for help understanding each page section.
Effect Sample (see here for sample info) (Trails look much better IRL) | ||
Single Trails (in 1D)
|
No Trails (in 2D)
|
No and Infinite Trails (in 2D)
|
An effect for driving a set of particles. A particle is a moving pixel. A particle has a direction, speed, and can leave a trail that blends cleanly into the background color over the trail length (like waving a flame around, or a comet trail). Particles are grouped into particle sets. Each particle in a set has its own properties, so you can have multiple particles with different sizes, speeds, trails, etc. This effect animates a set of particles. For this effect, you have the option of using your own particle set, or have the effect create one for you.
You have a lot of options when creating a particle set, so you can use this effect to build some really great looks! Please take a look at the Particles page, and the Particle Utils page for the full details on particles. Of particular interest are the buildParticleSet()
and setAllTrailRand()
util functions.
The effect is adapted to work on segment lines for 2D use. For 2D segments particles move along segment lines, with the particle being replicated across all the segment, like a wave.
Supports color modes for both the main and background colors.
Note that unlike other effects, the update rate is not externally controllable, and depends on the update rates of the particles.
Also note that, if you choose to have the effect create a particle set, it will be allocated dynamically. To avoid memory fragmentation, when you create the effect, you should set numParticles
to the maximum value you expect to use. See Memory Management for more details.
Particles can have a number of different trails. The type of trail is set by the particle's trailType
. Unless otherwise noted, any effects that use particles should have the trail options below.
trailType
(uint8_t):
- 0 -- no trails.
- 1 -- One trail facing away from the direction of motion (like a comet).
- 2 -- two trails, coming from both sides of the particle.
- 3 -- One trail facing towards the direction of motion.
- 4 -- Infinite trails that persist after the particle, and are not faded.
For example, with a trail length of 4, and a body size of 1, the modes will produce: (The trail head is *, - are the trail, particle is moving to the right ->)
- 0:
*
- 1:
----*
- 2:
----*----
- 3:
*----
- 4:
*****
During effect creation you can only have one type of trail for your particles. However, after creation, you can use the Particle Utils setAllTrailRand( *yourParticlesInstance.particleSet, options... )
to add multiple trail types. You can also directly edit a particle's trail type within the particle set.
By default, the trails dim quickly in a non-linear fashion. This makes the particle "heads" brighter and standout more, which, in my opinion, looks better then just using a linear fade. You can control the linearity of the trail fades using the dimPow
setting. A default of 80 is used in this effect. You can read the dimPow
notes in Particle Utils) for more.
Due to the way the effect is programmed, particles at the end in the particle set will run "in front" of those earlier in the set. This means that when two particles pass each other, the later one will be drawn over the earlier one.
You can adjust this behavior by turning on blend
, which will add particle colors together as they pass by each other. However this does have a few draw backs:
-
Due to the way particle trails are drawn, this forces the background to be re-drawn each update cycle, which may have a performance impact depending on your strip length, update rate, etc.
-
For colored backgrounds, the particles colors are added to the background colors. This will in most cases significantly change the particle colors. For example, blue particles running on a red background will appear purple (blue + red = purple). While this can be used to create some nice effects, (like ocean-ish of lava-ish looking things), overall I do not recommend using blend for colored backgrounds.
-
Using
blend
on segment sets with lines of unequal length may look weird, because pixels may be added to many times where multiple lines converge/overlap.
For a particle to bounce, it must reverse its direction once it hits either end of the segment set. However, how/when it bounces is a matter of opinion.
I have opted for the following:
-
The particle only bounces when its main body (not trail) reaches an end point.
-
Both the front and rear trails wrap back on themselves as the particle bounces. Ie the head of the trail moves back down the strip, opposite the direction of the particle.
-
The rear trail is always drawn last. In practice this means that particles with two trails mimic the classic "Cylon" scanner look, where the front of the trail disappears off the strip (it is actually wrapping back, but is over written by the rear trail, which is drawn after). While for particles with only a rear trail, it naturally fades as like it would for a physical streamer/flame/etc.
-
For particles with only a front trail the trail also wraps back, but under the particle. This does look a little weird, but there's not a good real world approximation to this kind of particle, so w/e.
-
For particles where the body size is larger than one, when a bounce happens, the entire body reverses direction at once. This is not visually noticeable, and makes coding easier. However, it does mean there's no "center" of a particle.
Note that unlike other effects, the update rate is preset for you at 5ms, which helps catch each of the particles updates on time (hopefully!). You see, each particle has its own speed (update rate), but we still want be able to update the effect with a single update()
call. I could have ignored the "rate" setting, and just updated all the particles whenever you call update()
. However, the particles are re-drawn every update()
, even if they haven't moved, so this becomes problematic, especially when working with multiple effects or segment sets, where you want more control over when you update. Instead I opted to treat the effect as normal, and keep the overall update rate, but default it to a very fast 5ms.
Usually I set my speeds to multiples of 10, so hopefully the default will catch most particles on time. You are free to change the update rate as needed by setting rateOrig
(Note, just setting the update rate to the speed of the fastest particle doesn't work, just think of two particles with speeds 40 and 50. The 50 speed particle ends up moving at more like 80 due to the 40ms update rate).
ParticlesSL particles(mainSegments, cybPnkPal_PS, 0, 3, 2, 60, 50, 1, 3, 2, 3, 0, 2, cybPnkPal_PS.length, true);
/* Creates a set of three particles that will run on a blank background with the following properties:
The particle directions will be chosen at random (direction is 2 for random)
They will have a maximum speed of 60ms, and a speed range of 50, for a speed up to 110ms (60 + 50)
The will have a minimum size of 1, and a size range of 3 for up to 4 (1 + 3)
They will have type 2 trails of length 3 and no variations in length (trail range is 0)
Their bounce properties will be chosen at random (bounce is 2)
Their colors will be chosen at random from the cybPnkPal_PS palette.*/
//Using a predefined particle set:
ParticlesSL particles(mainSegments, particleSet, cybPnkPal_PS, CRGB::Red);
//Will animate the particle set, placing it on a red background.
/* Tip: you can use particleUtilsPS::setAllTrailRand( *particles.particleSet, options... );
to add multiple trail types to your particle set after creation.
See the Particle Utils page for more! */
//Constructor for having the effect generate a set of particles
ParticlesSL(SegmentSetPS &SegSet, palettePS &Palette, CRGB BgColor, uint16_t numParticles, uint8_t direction, //
uint16_t baseSpeed, uint16_t speedRange, uint16_t size, uint16_t sizeRange, uint8_t trailType, //
uint8_t trailSize, uint8_t trailRange, uint8_t bounce, uint8_t colorIndex, bool randColor);
//Constructor for using a predefined set of particles
ParticlesSL(SegmentSetPS &SegSet, particleSetPS &ParticleSet, palettePS &Palette, CRGB BgColor);
Note, I'm only going over the inputs for the constructor that builds a particle set. The second constructor using a predefined set should be self explanatory. The effect-built set will be stored in the effect's particle set, particleSetTemp
.
-
SegmentSetPS* segSet -- The Segment Set the effect will draw on. See common vars
segSet
entry for more details. -
palettePS* palette (optional, see constructors) -- The set of colors the effect will use. See palettes. It is a pointer. See common vars
palette
entry for more details. -
CRGB* bgColor -- The color used for background pixels. Is a pointer, allowing you to bind it to an external color. By default it's bound the effect's local,
bgColorOrig
color. See common varsbgColor
entry for more details. -
uint16_t numParticles -- How many particles the effect will have. Note that the particles will be given random start points.
-
uint8_t direction -- The particle's direction of motion. Passing "2" will choose a random direction for each particle.
-
uint16_t baseSpeed -- The base speed of the particles.
-
uint16_t speedRange -- A random factor added to each particle's base speed, ie
speed = baseSpeed + random(speedRange)
. -
uint16_t size -- The size of the particle's bodies (not trails), min of 1.
-
uint16_t sizeRange -- A random factor added to each particle's base size, ie
size = size + random(sizeRange)
. -
uint8_t trailType -- The trail type for the particles, a value > 4 (the highest trail type) the trails will be chosen randomly from the first three trail types (0, 1, 2). (see setTrailRand() for configuring a custom set or random trails).
-
uint8_t trailSize -- The length of the particle trails, min of 1.
-
uint8_t trailRange -- A random factor added to each particle's trail size, ie
trailSize = trailSize + random(trailSize)
. -
uint8_t bounce -- The "bounce" setting for the particles. Passing "2" will choose a random "bounce" for each particle.
-
uint8_t colorIndex -- The color index for the particles (from the palette).
-
uint8_t randColor -- If true, each particle will be set to a index, randomized up to the
colorIndex
setting value. In other words, if you want to randomize the particle colors, pass your palette's length as thecolorIndex
.
-
uint8_t colorMode (default 0) -- The colorMode use for the effect, also see common vars
colorMode
entry for more details. -
uint8_t bgColorMode (default 0) -- The colorMode used for the background pixels, also see common vars
colorMode
entry for more details. -
int8_t dimPow (default 80, min -127, max 127) -- Adjusts the rate of dimming for the trails (see Fading notes in Intro).
-
bool blend (default false) -- Causes particles to add their colors to the strip's pixels, rather than set them (see blend notes in intro).
-
bool fillBg (default false) -- If true, then all pixels will be re-colored with each update(), rather than just drawing those that have changed. See common vars
fillBg
entry for more details. -
particleSetPS* particleSet -- The effect's particle set. Is a pointer, so you can bind it to an external set. If the effect builds a particle set for you,
particleSet
, will be bound to the effect's local set,particleSetTemp
. -
uint16_t* rate -- Update rate (ms). Defaulted to 5ms (see Update note in Inputs Guide). Is a pointer, allowing you to bind it to an external variable. By default it's bound the effect's local variable,
rateOrig
. See common varsrate
entry for more. -
bool showNow (default true) -- Controls if the effect "draws" during each update cycle by calling
FastLED.show()
. Common to all effects. See common varsshowNow
entry for more details.
-
void setParticleSet( particleSetPS *newParticleSet );
Sets the effect to use a new particle set.
-
void reset();
Resets all particles to the starting locations.
-
void update();
Updates the effect.
-
More functions for controlling particle sets can be found on the Particle Utils page.