Skip to content

Instantly share code, notes, and snippets.

@satoruhiga
Created September 29, 2011 14:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save satoruhiga/1250787 to your computer and use it in GitHub Desktop.
Save satoruhiga/1250787 to your computer and use it in GitHub Desktop.
ofxSimpleParticleSystem
#pragma once
#include "ofMain.h"
#include <tr1/array>
/*
// EXAMPLE
#include "testApp.h"
#include "ofxSimpleParticleSystem.h"
class Particle : public ofxSimpleParticleSystemBase
{
public:
deque<ofVec3f> lines;
void update()
{
lines.push_front(pos);
if (lines.size() > 100)
lines.pop_back();
force += vec.rotated(0, 0, 90).normalized() * 3 * sin((1 - delta()) * PI);
}
void draw()
{
glBegin(GL_LINE_STRIP);
for (int i = 0; i < lines.size(); i++)
{
float a = sin(ofMap(i, 0, lines.size(), 0, 1, true) * PI);
glColor4f(1, 1, 1, a * delta());
glVertex3fv(lines[i].getPtr());
}
glEnd();
}
void reset()
{
vec.x = ofRandom(-1, 1);
vec.y = ofRandom(-1, 1);
lines.clear();
}
};
ofxSimpleParticleSystem<Particle, 100> particles;
void testApp::setup()
{
ofSetFrameRate(60);
ofSetVerticalSync(true);
ofBackground(0);
ofSetColor(255);
particles.setup();
}
void testApp::update()
{
particles.update();
}
void testApp::draw()
{
ofEnableAlphaBlending();
particles.draw();
}
void testApp::mouseMoved(int x, int y)
{
Particle &p = particles.emit();
p.pos.set(x, y);
}
*/
struct ofxSimpleParticleSystemBase
{
ofVec3f force, vec, pos;
float life, lifetime;
float mass;
float _delta;
ofxSimpleParticleSystemBase() : mass(1), life(0) {}
float delta() { return _delta; }
};
template <class T, int NUM = 100000>
class ofxSimpleParticleSystem
{
typedef std::tr1::array<T, NUM> ParticleArray;
ParticleArray particles;
int currentIndex;
float speed;
float lifetime;
public:
ofxSimpleParticleSystem()
{
lifetime = 5;
speed = 1;
currentIndex = 0;
}
void setup()
{
for (int i = 0; i < particles.size(); i++)
{
T &t = particles[i];
t.life = 0;
t._delta = 0;
}
}
void update()
{
const float last_frame_time = ofGetLastFrameTime();
for (int i = 0; i < particles.size(); i++)
{
T &t = particles[i];
if (t.life <= 0) continue;
t.force.set(0, 0, 0);
t.update();
t.force /= t.mass;
t.vec += t.force * speed;
t.pos += t.vec * speed;
t.life -= last_frame_time;
t._delta = t.life / t.lifetime;
}
}
void draw()
{
for (int i = 0; i < particles.size(); i++)
{
T &t = particles[i];
if (t.life <= 0) continue;
t.draw();
}
}
T& emit()
{
T &t = particles[currentIndex];
reset(t);
currentIndex++;
currentIndex = currentIndex % NUM;
return t;
}
void reset(T &t)
{
t.lifetime = lifetime;
t.life = lifetime;
t.reset();
}
float getSpeed() const { return speed; }
void setSpeed(float v) { speed = v; }
float getLifetime() const { return lifetime; }
void setLifetime(float v) { lifetime = v; }
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment