Skip to content

Instantly share code, notes, and snippets.

@tado
Last active June 22, 2020 18:56
Show Gist options
  • Save tado/e7af7eda135a09062247 to your computer and use it in GitHub Desktop.
Save tado/e7af7eda135a09062247 to your computer and use it in GitHub Desktop.
3D Particle for openFrameworks
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){
ofSetFrameRate(60);
ofBackground(0);
mesh.setMode(OF_PRIMITIVE_POINTS);
pressed = false;
for (int i = 0; i < num; i++) {
particles[i].position = ofVec3f(ofRandom(ofGetWidth()), ofRandom(ofGetHeight()), ofRandom(-ofGetWidth(), ofGetWidth()));
particles[i].depth = ofGetWidth();
}
}
//--------------------------------------------------------------
void ofApp::update(){
mesh.clear();
for (int i = 0; i < num; i++) {
if (pressed) {
particles[i].addAttractionForce(mouseX, mouseY, 0, ofGetWidth() * 1.5, 1.0);
}
particles[i].update();
particles[i].throughOffWalls();
mesh.addVertex(ofVec3f(particles[i].position.x, particles[i].position.y, particles[i].position.z));
}
}
//--------------------------------------------------------------
void ofApp::draw(){
ofSetColor(210);
ofEnableBlendMode(OF_BLENDMODE_ADD);
static GLfloat distance[] = { 0.0, 0.0, 1.0 };
glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, distance);
glPointSize(4000);
mesh.draw();
ofDisableBlendMode();
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
}
//--------------------------------------------------------------
void ofApp::keyReleased(int key){
}
//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){
}
//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
}
//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){
pressed = true;
}
//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){
pressed = false;
}
//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){
}
//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){
}
//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){
}
#pragma once
#include "ofMain.h"
#include "ParticleVec3.h"
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
static const int num = 50000;
ParticleVec3 particles[num];
ofVboMesh mesh;
bool pressed;
};
#include "ParticleVec3.h"
ParticleVec3::ParticleVec3(){
radius = 5.0;
friction = 0.01;
mass = 1.0;
position.set(ofGetWidth()/2.0, ofGetHeight()/2.0, 0);
velocity.set(0, 0, 0);
acceleration.set(0, 0, 0);
minx = 0;
miny = 0;
minz = -ofGetHeight();
maxx = ofGetWidth();
maxy = ofGetHeight();
maxz = ofGetHeight();
}
void ParticleVec3::update(){
acceleration -= velocity * friction;
velocity += acceleration;
position += velocity;
acceleration.set(0, 0, 0);
}
void ParticleVec3::draw(){
ofCircle(position.x, position.y, radius);
}
void ParticleVec3::addForce(ofVec3f _force){
acceleration += _force / mass;
}
void ParticleVec3::addForce(float forceX, float forceY, float forceZ){
acceleration += ofVec3f(forceX, forceY, forceZ) / mass;
}
void ParticleVec3::bounceOffWalls(){
if (position.x > maxx){
position.x = maxx;
velocity.x *= -1;
}
if (position.x < minx){
position.x = minx;
velocity.x *= -1;
}
if (position.y > maxy){
position.y = maxy;
velocity.y *= -1;
}
if (position.y < miny){
position.y = miny;
velocity.y *= -1;
}
if (position.z > maxz){
position.z = maxz;
velocity.z *= -1;
}
if (position.z < minz){
position.z = minz;
velocity.z *= -1;
}
}
void ParticleVec3::throughOffWalls(){
if (position.x < minx) {
position.x = maxx;
}
if (position.y < miny) {
position.y = maxy;
}
if (position.z < minz) {
position.z = maxz;
}
if (position.x > maxx) {
position.x = minx;
}
if (position.y > maxy) {
position.y = miny;
}
if (position.z > maxz) {
position.z = minz;
}
}
void ParticleVec3::resetToRandomPos(){
float minx = 0;
float miny = 0;
float maxx = ofGetWidth();
float maxy = ofGetHeight();
float maxz = depth;
float minz = -depth;
if (position.x < minx || position.y < miny || position.z < minz || position.x > maxx || position.y > maxy || position.z > maxz) {
position.set(ofRandom(minx, maxx), ofRandom(miny, maxy), ofRandom(minz, maxz));
}
}
void ParticleVec3::addRepulsionForce(float x, float y, float z, float radius, float scale){
ofVec3f posOfForce;
posOfForce.set(x,y,z);
ofVec3f diff = position - posOfForce;
float length = diff.length();
bool bAmCloseEnough = true;
if (radius > 0){
if (length > radius){
bAmCloseEnough = false;
}
}
if (bAmCloseEnough == true){
float pct = 1 - (length / radius);
diff.normalize();
acceleration = acceleration + diff * scale * pct;
}
}
void ParticleVec3::addRepulsionForce(ParticleVec3 &p, float radius, float scale){
ofVec3f posOfForce;
posOfForce.set(p.position.x, p.position.y, p.position.z);
ofVec3f diff = position - posOfForce;
float length = diff.length();
bool bAmCloseEnough = true;
if (radius > 0){
if (length > radius){
bAmCloseEnough = false;
}
}
if (bAmCloseEnough == true){
float pct = 1 - (length / radius);
diff.normalize();
acceleration = acceleration + diff * scale * pct;
}
}
void ParticleVec3::addAttractionForce(float x, float y, float z, float radius, float scale){
ofVec3f posOfForce;
posOfForce.set(x,y,z);
ofVec3f diff = position - posOfForce;
float length = diff.length();
bool bAmCloseEnough = true;
if (radius > 0){
if (length > radius){
bAmCloseEnough = false;
}
}
if (bAmCloseEnough == true){
float pct = 1 - (length / radius);
diff.normalize();
acceleration = acceleration - diff * scale * pct;
}
}
void ParticleVec3::addAttractionForce(ParticleVec3 &p, float radius, float scale){
ofVec3f posOfForce;
posOfForce.set(p.position.x, p.position.y, p.position.z);
ofVec3f diff = position - posOfForce;
float length = diff.length();
bool bAmCloseEnough = true;
if (radius > 0){
if (length > radius){
bAmCloseEnough = false;
}
}
if (bAmCloseEnough == true){
float pct = 1 - (length / radius);
diff.normalize();
acceleration = acceleration - diff * scale * pct;
}
}
#pragma once
#include "ofMain.h"
class ParticleVec3 {
public:
ParticleVec3();
void addForce(ofVec3f force);
void addForce(float forceX, float forceY, float forceZ);
void update();
void draw();
void bounceOffWalls();
void throughOffWalls();
void resetToRandomPos();
void addRepulsionForce(float x, float y, float z, float radius, float scale);
void addRepulsionForce(ParticleVec3 &p, float radius, float scale);
void addAttractionForce(float x, float y, float z, float radius, float scale);
void addAttractionForce(ParticleVec3 &p, float radius, float scale);
ofVec3f position;
ofVec3f velocity;
ofVec3f acceleration;
float friction;
float radius;
bool bFixed;
float mass;
float depth;
float minx, miny, minz;
float maxx, maxy, maxz;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment