It's the 4th of July today and we're celebrating at ArrayFire! The 4th of July implies fireworks, and fireworks obviously imply particle systems. Particle systems are a collection of many small images or points that can be rendered to represent some complex behaving object. So before we can launch our fireworks, we will need to create a particle system. The large number of particles in a system lends well to GPU computation. Thankfully, ArrayFire's easy to use interface will allow us to do this simply and efficiently. First, let's examine the structure of a typical particle system.

[feature_headline type="left" level="h4" looks_like="h4"]Particle System Structure and Hierarchy
[/feature_headline]
Individual particles in a system typically have a variety of properties that govern their individual behavior. A non-comprehensive list below summarizes some of these:
<ul>
 	<li>position</li>
 	<li>velocity</li>
 	<li>acceleration</li>
 	<li>lifespan</li>
 	<li>color</li>
 	<li>size</li>
 	<li>rotation</li>
</ul>
The properties are used to simulate the particles motion and appearance. Together, a collection of particles forms a particle system. The particle system holds additional information about the system as a whole. For example, these properties can include:
<ul>
 	<li>position of the particle system center of mass</li>
 	<li>total # of particles</li>
 	<li>type of particle system</li>
 	<li>image to draw</li>
 	<li># of active particles</li>
 	<li>particle system bounding box</li>
</ul>
The particle system is responsible for keeping track of all of its particles. It simulates and updates their positions. It draws the particles to the screen. It also keeps track of which particles are alive or need to be respawned.
A single scene might have multiple particle systems at once. Fireworks wouldn't be as exciting if there could only be one explosion at a time, so we'll also need a particle system manager. The manager will keep track of active particle systems and make sure each one of them is updated at the appropriate time. Particle systems can be added and removed from the manager and the manager will keep track of the systems in memory. These functional requirements create a straightforward blueprint for a small collection of classes and functions required to make a particle system.

[feature_headline type="left" level="h4" looks_like="h4"]Basic classes and data structures
[/feature_headline]
Starting from the top down, let's create a particle manager:
<pre class="lang:default decode:true ">/*
 * Particle Manager Class
 * keeps track of all living particle systems
 */

class particle_manager
{
public:
    //a vector containing pointers to our active systems
    std::vector systems;

    particle_manager() {}
    
    //function to add a system
    void addSystem(particle_system *sys) {
        systems.push_back(sys);
    }

    //used to update all systems
    //will free particle systems which are inactive
    void update() {
        systems.erase(std::remove_if(systems.begin(), systems.end(),
                    [](particle_system* ps)
                    bool alive = ps-&gt;update(); if(!alive) delete ps; return !alive;}), 
                    systems.end());
    }

    //used to render all systems
    void render(af::array &amp;image) {
        for(auto sys : systems)
            sys-&gt;render(image);
    }
};</pre>
As we planned, the particle manager supports:
<ul>
 	<li>adding particle systems</li>
 	<li>(automatically) removing particle systems</li>
 	<li>updating particle systems</li>
 	<li>rendering particle systems</li>
</ul>
Our actual particle system is still undefined. We want the particle system to implement the updating and rendering functions required by the manager while holding data to keep track of the particle system as a whole. We also want our basic particle system class to be generic so we can extend its functionality to match the complexity of any imaginable particle system.
<pre class="lang:default decode:true ">class particle_system
{
public:
    //particle system data
    af::array texture;
    int num_particles;
    int particle_size;
    int system_type;
    float system_pos[2];

    particle_system(int num_particles_) {
        num_particles = num_particles_;
        system_pos[0] = 0; system_pos[1] = 0;
    }

    virtual ~particle_system() {}

    // updates positions, velocities, and lifetime of particles in system
    virtual bool update() {
        return true;
    }
    //renders specific particle system
    virtual void render(af::array &amp;image) = 0;
};
</pre>
So far, our particle system is actually missing our particles! In a more traditional approach, we would need to dynamically allocate space for our particles as they come alive and free space as they disappear. The frequent allocations would not work well with a GPU approach or with ArrayFire. Instead, we will be managing a data-structure that is known as a pool. Instead of frequently re-allocating space as each particle appears/disappears, we will instead allocate one large array with the maximum number of particles and keep track of what particles need to be updated. The pool approach maps directly to an af:array. This frees up our need to manage memory and puts all of the heavy lifting on ArrayFire. We will add several pools to our particle system to keep track of the particles' properties:
<pre class="lang:default decode:true">//particle data
    static const int dims = 2;
    std::vector pos;
    std::vector vel;
    std::vector accel;
    af::array lifetime;
    af::array is_active;
</pre>
The key array that lets us use a pool approach is the <span class="lang:default decode:true crayon-inline ">is_active</span>  array. It will be used as a mask array to update only the particles which are active. Now, we can make our generic functions slightly more useful by addressing the newly added particles.
<pre class="lang:default decode:true">particle_system(int num_particles_) {
    num_particles = num_particles_;
    system_pos[0] = 0; system_pos[1] = 0; system_pos[2] = 0;

    for(int dim=0; dim&lt;dims; ++dim) {
        pos.push_back(af::constant(0, num_particles));
        vel.push_back(af::constant(0, num_particles));
        accel.push_back(af::constant(0, num_particles));
    }
    lifetime = af::constant(0, num_particles);
    is_active = af::constant(0, num_particles);
}
 //offsets the whole particle system
void move_system(float x, float y) {
    system_pos[0] += x;
    system_pos[1] += y;
    pos[0] += x;
    pos[1] += y;
}
// updates positions, velocities, and lifetime of particles in system
virtual bool update() {
    if(af::where(is_active &gt; 0).elements() &gt; 0 ) {
        for(int i=0; i&lt;pos.size(); ++i) {
            pos[i](is_active&gt;0) += vel[i](is_active&gt;0);
            vel[i](is_active&gt;0) += accel[i](is_active&gt;0);
            lifetime += 1;
        }
        return true;
    }
    return false;
}
</pre>
First, we initialize <span class="lang:default decode:true crayon-inline ">af::arrays</span> which represent the particles in the constructor. Then we add a method to move the particle system as a whole. The update function shows the key use of the <span class="lang:default decode:true crayon-inline ">is_active</span>  array where the <span class="lang:default decode:true crayon-inline ">is_active</span> array is used to index into the positions of the active particles and update only those particles.
[feature_headline type="left" level="h4" looks_like="h4"]Constructing a specific particle system
[/feature_headline]
Now that we have these generic classes we can attempt to make something more concrete, like an explosion! To do this, we will inherit from our basic particle system and mainly implement the rendering function specific to our firework explosion.
<pre class="lang:default decode:true">class explosion_system : public particle_system
{
public:
    float expl_speed;
    explosion_system(int num_particles_, float expl_speed_) 
    : particle_system::particle_system(num_particles_)
    {
        particle_size = 5;
        expl_speed = expl_speed_;

        is_active = af::constant(1, num_particles);

        pos[0]   = af::constant(system_pos[0], num_particles);
        pos[1]   = af::constant(system_pos[1], num_particles);
        vel[0]   = af::randn(num_particles) * expl_speed;
        vel[1]   = af::randn(num_particles) * expl_speed;
        accel[0] = af::constant(0.f, num_particles);
        accel[1] = af::constant(0.09f, num_particles);

        system_type = EXPLOSION_SYSTEM;
    }

    bool update() {
        //kill particles after 250 iterations
        if(af::where(lifetime &gt; 250).elements() &gt; 0 ) {
            is_active(lifetime &gt; 250) = 0;
        }
        //limit the top speed of our particles
        if(af::where(vel[1] &gt; 3.f).elements() &gt; 0) {
            vel[0](vel[1] &gt; 3.f) *= 0.9f;
            vel[1](vel[1] &gt; 3.f) *= 0.9f;
        }
        return particle_system::update();
    }

    void render(af::array &amp;image) {
        int image_width = image.dims(0);
        int image_height = image.dims(1);
        static const af::array particle = af::constant(1, particle_size, particle_size);
        af::array ids = ids_from_pos(image_width, image_height, pos);
        if(af::where(is_active &gt; 0).elements() &gt; 0 ) {
            ids = ids(is_active&gt;0);
            af::array temp = af::constant(0, image.dims());
            temp(ids) = 5/lifetime(is_active&gt;0);
            image += af::convolve(temp, particle);
        }
    }
};
</pre>
In this class, we start by setting up the initial conditions of our explosion particle system. This uses the <span class="lang:default decode:true crayon-inline ">af::constant</span> and <span class="lang:default decode:true crayon-inline ">af::randn</span> functions to set the particles' positions and speeds. We set all of the pooled particles to be active from the very beginning and specify the type of our system in case we need to modify it from the manager.
Our update function keeps track of the lifetime of our particles and also limits their maximum speed.
The render function is fairly similar to the update function with regards to the use of the <span class="lang:default decode:true crayon-inline ">is_active</span> array. Once again, this allows drawing only the active particles. To make our fireworks fade away, we vary the intensity of each particle with respect to its lifetime.

Now that we have a decent particle system and manager, let's set up the framework code and use our shiny new classes.
<pre class="lang:default decode:true ">#include "arrayfire.h"
#include "particle_system.h"

using namespace af;
using namespace std;

static const int width = 768, height = 768;
const float explosion_speed = 1.1f;
const int num_explosion_particles = 400;

int main(int argc, char *argv[])
{
    try {
        //set up an arrayfire window with a color map
        af::Window myWindow(width, height, "Particle Engine using ArrayFire");
        myWindow.setColorMap(AF_COLORMAP_HEAT);

        int frame_count = 0;
        af::array image = af::constant(0, width, height);

        //create our particle manager
        particle_manager particles;

        while(!myWindow.close()) {
            //launch new firework every 200 frames
            if(frame_count % 200 == 0) {
                explosion_system *explosion = new 
                                  explosion_system(num_explosion_particles, explosion_speed);
                explosion -&gt; move_system(width/2, height/2);
                particles.addSystem(explosion);
            }

            //render image with the particle manager
            particles.render(image);
            //and display it to the window then clear the image
            myWindow.image(image);
            image = af::constant(0, image.dims());

            //simulate all particle systems
            particles.update();
            frame_count++;
        }
    } catch (af::exception&amp; e) {
        fprintf(stderr, "%s\n", e.what());
        throw;
    }
    return 0;
}
</pre>
And Boom! You should have a working particle system.
<a href="http://sandbox.arrayfire.com/wp-content/uploads/2016/07/optimized.gif"><img class="aligncenter size-full wp-image-8993" src="http://sandbox.arrayfire.com/wp-content/uploads/2016/07/optimized.gif" alt="optimized" width="640" height="678" /></a>
In our full code, we added one more particle system which shows additional ways the particle manager can be used to manage particle systems. Check it out at this <a href="https://github.com/syurkevi/arrayfire_particle_system_example">github repository.</a>