Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
cdfeec2dbc | |||
1613d896e0 | |||
57dc25d39b | |||
5faa3e0025 | |||
c3c7178b18 | |||
14de0ec2f7 | |||
6b1179c77e | |||
|
247746be58 | ||
fd32d1984b | |||
75dd4f9bb3 |
@ -1,3 +1,4 @@
|
|||||||
ofxGui
|
ofxGui
|
||||||
ofxOsc
|
ofxOsc
|
||||||
ofxVectorGraphics
|
ofxVectorGraphics
|
||||||
|
ofxXmlSettings
|
||||||
|
42
attractor.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include "attractor.h"
|
||||||
|
|
||||||
|
Attractor::Attractor()
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Attractor::~Attractor()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float Attractor::getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float Attractor::getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Attractor::setX(float xNew) {
|
||||||
|
x = xNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Attractor::setY(float yNew) {
|
||||||
|
y = yNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Attractor::setup(float xSetup, float ySetup) {
|
||||||
|
x = xSetup;
|
||||||
|
y = ySetup;
|
||||||
|
}
|
||||||
|
|
34
attractor.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
//
|
||||||
|
// attractor.h
|
||||||
|
// particleSystem
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
class Attractor {
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Attractor();
|
||||||
|
~Attractor();
|
||||||
|
|
||||||
|
|
||||||
|
float getX();
|
||||||
|
float getY();
|
||||||
|
|
||||||
|
void setX(float x);
|
||||||
|
void setY(float y);
|
||||||
|
|
||||||
|
void setup(float x, float y);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//ofVec2f direction
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
|
||||||
|
float force;
|
||||||
|
};
|
BIN
bin/data/img/beer.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
bin/data/img/br.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
bin/data/img/tex.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
bin/data/img/tr.png
Normal file
After Width: | Height: | Size: 111 KiB |
10
bin/data/xml/attractor.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<default>
|
||||||
|
<sizeMin>0.05</sizeMin>
|
||||||
|
<sizeMax>4</sizeMax>
|
||||||
|
<mass>100</mass>
|
||||||
|
<drag>0</drag>
|
||||||
|
<maxLife>10</maxLife>
|
||||||
|
<velMin>-80</velMin>
|
||||||
|
<velMax>80</velMax>
|
||||||
|
<color></color>
|
||||||
|
</default>
|
10
bin/data/xml/default.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<default>
|
||||||
|
<sizeMin>0.05</sizeMin>
|
||||||
|
<sizeMax>4</sizeMax>
|
||||||
|
<mass>100</mass>
|
||||||
|
<drag>0</drag>
|
||||||
|
<maxLife>10</maxLife>
|
||||||
|
<velMin>-80</velMin>
|
||||||
|
<velMax>80</velMax>
|
||||||
|
<color></color>
|
||||||
|
</default>
|
10
bin/data/xml/detractor.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<default>
|
||||||
|
<sizeMin>0.05</sizeMin>
|
||||||
|
<sizeMax>4</sizeMax>
|
||||||
|
<mass>100</mass>
|
||||||
|
<drag>0</drag>
|
||||||
|
<maxLife>10</maxLife>
|
||||||
|
<velMin>-80</velMin>
|
||||||
|
<velMax>80</velMax>
|
||||||
|
<color></color>
|
||||||
|
</default>
|
10
bin/data/xml/radial.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<default>
|
||||||
|
<sizeMin>0.05</sizeMin>
|
||||||
|
<sizeMax>4</sizeMax>
|
||||||
|
<mass>100</mass>
|
||||||
|
<drag>0</drag>
|
||||||
|
<maxLife>10</maxLife>
|
||||||
|
<velMin>-80</velMin>
|
||||||
|
<velMax>80</velMax>
|
||||||
|
<color></color>
|
||||||
|
</default>
|
10
bin/data/xml/rain.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<default>
|
||||||
|
<sizeMin>0.05</sizeMin>
|
||||||
|
<sizeMax>4</sizeMax>
|
||||||
|
<mass>100</mass>
|
||||||
|
<drag>0</drag>
|
||||||
|
<maxLife>10</maxLife>
|
||||||
|
<velMin>-80</velMin>
|
||||||
|
<velMax>80</velMax>
|
||||||
|
<color></color>
|
||||||
|
</default>
|
9
main.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include "ofMain.h"
|
||||||
|
#include "ofApp.h"
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
int main() {
|
||||||
|
ofSetupOpenGL(2000, 2000, OF_WINDOW);
|
||||||
|
ofRunApp(new ofApp());
|
||||||
|
}
|
||||||
|
|
261
ofApp.cpp
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
#include "ofApp.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
void ofApp::setup() {
|
||||||
|
ofSetVerticalSync(true);
|
||||||
|
|
||||||
|
//Initialize 8 empty attractrs
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
attractors.push_back(new Attractor);
|
||||||
|
}
|
||||||
|
|
||||||
|
//OSC reciever port setup
|
||||||
|
receiver.setup(PORT);
|
||||||
|
|
||||||
|
varSystem = true;
|
||||||
|
trails = true;
|
||||||
|
history = 0.95;
|
||||||
|
num = 1000;
|
||||||
|
sys.assign(num, Particle());
|
||||||
|
|
||||||
|
currentMode = PARTICLE_MODE_DEFAULT;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_DEFAULT";
|
||||||
|
|
||||||
|
//Black background
|
||||||
|
ofSetBackgroundColor(0, 0, 0);
|
||||||
|
ofSetFrameRate(60);
|
||||||
|
birthCount = 0;
|
||||||
|
int w = ofGetWidth();
|
||||||
|
int h = ofGetHeight();
|
||||||
|
fbo.allocate(w, h, GL_RGB);
|
||||||
|
//attractors.at(0)->setup(600, 600);
|
||||||
|
|
||||||
|
attractors.at(1)->setup(200, 200);
|
||||||
|
attractors.at(2)->setup(400, 400);
|
||||||
|
attractors.at(3)->setup(500, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
void ofApp::update() {
|
||||||
|
// *** OSC RECEIVER ***
|
||||||
|
while (receiver.hasWaitingMessages()) {
|
||||||
|
|
||||||
|
ofxOscMessage contourCentroids;
|
||||||
|
receiver.getNextMessage(&contourCentroids);
|
||||||
|
oscMsg = ofToString(contourCentroids);
|
||||||
|
|
||||||
|
//Get active ammount of attractors (nBlobs) and their x & y coordinates
|
||||||
|
//Exp. OSC Message: " /centroidsOfBlob ammount xValue, yValue"
|
||||||
|
if (contourCentroids.getAddress() == "/centroidsOfBlob") {
|
||||||
|
nBlobs = contourCentroids.getArgAsInt(0);
|
||||||
|
for (int i = 1; i <= nBlobs; i++) {
|
||||||
|
xOfCentroid = contourCentroids.getArgAsFloat(i * 2 - 1) * ofGetWindowWidth();
|
||||||
|
yOfCentroid = contourCentroids.getArgAsFloat(i * 2) * ofGetWindowHeight();
|
||||||
|
|
||||||
|
attractors.at(i - 1)->setup(xOfCentroid, yOfCentroid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Delete all Attractors on command
|
||||||
|
if (contourCentroids.getAddress() == "/checkin") {
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
attractors.at(i)->setup(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// *** PARTICLE EMITTER ***
|
||||||
|
|
||||||
|
//Capture time based on FrameTime
|
||||||
|
double deltaT = ofGetLastFrameTime();
|
||||||
|
birthCount += deltaT;
|
||||||
|
|
||||||
|
if (varSystem == true) {
|
||||||
|
//Birth control for new particles
|
||||||
|
if (birthCount > 0.001) {
|
||||||
|
for (int i = 0;i < 4;i++) {
|
||||||
|
system.push_back(new Particle);
|
||||||
|
system.back()->setup(currentMode);
|
||||||
|
}
|
||||||
|
birthCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (int p = 0; p < system.size();)
|
||||||
|
{
|
||||||
|
//Upate particle system /w all active attractors
|
||||||
|
system.at(p)->update(deltaT, &attractors, system);
|
||||||
|
|
||||||
|
//Delete particles, that reached max Age
|
||||||
|
if (system.at(p)->getAgeNorm() > 4) {
|
||||||
|
delete system.at(p);
|
||||||
|
system.erase(system.begin() + p);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ofSeedRandom(39);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
void ofApp::reset() {
|
||||||
|
|
||||||
|
for (int p = 0; p < system.size();)
|
||||||
|
{
|
||||||
|
system.erase(system.begin() + p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
void ofApp::draw() {
|
||||||
|
if (varSystem == false) {
|
||||||
|
vector<ofVec2f> system;
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
ofVec2f particle(ofMap(ofNoise(ofRandom(100), ofGetFrameNum() * 0.0005), 0, 1, 0, ofGetWidth()), ofMap(ofNoise(ofRandom(100), ofGetFrameNum() * 0.0005), 0, 1, 0, ofGetHeight()));
|
||||||
|
system.push_back(particle);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int out = 0; out < system.size(); out++) {
|
||||||
|
for (int in = out + 1; in < system.size(); in++) {
|
||||||
|
if (system[out].distance(system[in]) < 60) {
|
||||||
|
ofDrawLine(system[out], system[in]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < system.size(); i++) {
|
||||||
|
|
||||||
|
ofDrawCircle(system[i], ofRandom(0.5, 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trails == true) {
|
||||||
|
fbo.begin();
|
||||||
|
ofEnableAlphaBlending(); //Enable transparency
|
||||||
|
|
||||||
|
float alpha = (1 - history) * 255;
|
||||||
|
ofSetColor(0, 0, 0, alpha);
|
||||||
|
ofFill();
|
||||||
|
ofRect(0, 0, ofGetWidth(), ofGetHeight());
|
||||||
|
|
||||||
|
ofDisableAlphaBlending(); //Disable transparency
|
||||||
|
//Draw particle system
|
||||||
|
for (int p = 0; p < system.size(); p++) {
|
||||||
|
system.at(p)->draw();
|
||||||
|
}
|
||||||
|
fbo.end();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//Draw particle system
|
||||||
|
for (int p = 0; p < system.size(); p++) {
|
||||||
|
system.at(p)->draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Capture time based on FrameTime
|
||||||
|
double deltaT = ofGetLastFrameTime();
|
||||||
|
time += deltaT;
|
||||||
|
|
||||||
|
// Delete inactive attractors after 4 seconds based on Frametime
|
||||||
|
if (time > 2) {
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
//attractors.at(i)->setup(0, 0);
|
||||||
|
time = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fbo.draw(0, 0);
|
||||||
|
// *** DEBUG INFO ***
|
||||||
|
ofSetColor(230);
|
||||||
|
//All 8 Attractors with x | y coordinates
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
|
||||||
|
string x = ofToString(attractors.at(i)->getX());
|
||||||
|
string y = ofToString(attractors.at(i)->getY());
|
||||||
|
|
||||||
|
ofDrawBitmapString("x: " + x + " y: " + y, 100, 100 + i * 20);
|
||||||
|
}
|
||||||
|
//Recieved OSC messages
|
||||||
|
ofDrawBitmapString("OSC: " + ofToString(oscMsg),100, 275);
|
||||||
|
//Elapsed time since last clear of attractors
|
||||||
|
ofDrawBitmapString("Time: " + ofToString(time),100, 300);
|
||||||
|
//Current FPS
|
||||||
|
ofDrawBitmapString("FPS: " + ofToString(ofGetFrameRate()), 100, 325);
|
||||||
|
//Current Mode
|
||||||
|
ofDrawBitmapString("Current Effect: " + currentModeDisp, 100, 350);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
void ofApp::keyPressed(int key) {
|
||||||
|
//Key press 1 to trigger default particle Mode
|
||||||
|
if (key == '1') {
|
||||||
|
currentMode = PARTICLE_MODE_DEFAULT;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_DEFAULT";
|
||||||
|
varSystem = true;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
//Key press 2 to trigger attractor particle Mode
|
||||||
|
if (key == '2') {
|
||||||
|
currentMode = PARTICLE_MODE_RADIAL;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_RADIAL";
|
||||||
|
varSystem = true;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
//Key press 2 to trigger rain particle Mode
|
||||||
|
if (key == '3') {
|
||||||
|
currentMode = PARTICLE_MODE_RAIN;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_RAIN";
|
||||||
|
varSystem = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
//Key press 2 to trigger attractor particle Mode
|
||||||
|
if (key == '4') {
|
||||||
|
currentMode = PARTICLE_MODE_ATTRACTOR;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_ATTRACTOR";
|
||||||
|
varSystem = true;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
//Key press 2 to trigger attractor particle Mode
|
||||||
|
if (key == '5') {
|
||||||
|
currentMode = PARTICLE_MODE_DETRACTOR;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_DETRACTOR";
|
||||||
|
varSystem = true;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
//Key press 2 to trigger attractor particle Mode
|
||||||
|
if (key == '6') {
|
||||||
|
currentMode = PARTICLE_MODE_POLY;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_POLY";
|
||||||
|
varSystem = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
if (key == '7') {
|
||||||
|
trails = true;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
void ofApp::keyReleased(int key) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
void ofApp::mouseMoved(int x, int y) {
|
||||||
|
attractors.at(0)->setup(ofGetMouseX(), ofGetMouseY());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
void ofApp::mousePressed(int x, int y, int button) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
void ofApp::mouseReleased(int x, int y, int button) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
60
ofApp.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ofMain.h"
|
||||||
|
#include "particle.h"
|
||||||
|
#include "ofxOsc.h"
|
||||||
|
#include "ofxGui.h"
|
||||||
|
|
||||||
|
//OSC Reciever PORT & HOST IP
|
||||||
|
#define PORT 12345
|
||||||
|
#define HOST "172.20.10.2"
|
||||||
|
|
||||||
|
class ofApp : public ofBaseApp {
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setup();
|
||||||
|
void update();
|
||||||
|
void draw();
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
void keyPressed(int key);
|
||||||
|
void keyReleased(int key);
|
||||||
|
void mouseMoved(int x, int y);
|
||||||
|
void mousePressed(int x, int y, int button);
|
||||||
|
void mouseReleased(int x, int y, int button);
|
||||||
|
|
||||||
|
ofxXmlSettings default;
|
||||||
|
ofxXmlSettings attractor;
|
||||||
|
ofxXmlSettings rain;
|
||||||
|
ofxXmlSettings brunig;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// OSC Receiver
|
||||||
|
|
||||||
|
particleMode currentMode;
|
||||||
|
string currentModeDisp;
|
||||||
|
|
||||||
|
string oscMsg;
|
||||||
|
ofxOscReceiver receiver;
|
||||||
|
float timeSent, timeReceived;
|
||||||
|
|
||||||
|
int nBlobs;
|
||||||
|
int blobCount;
|
||||||
|
int num;
|
||||||
|
float history;
|
||||||
|
ofFbo fbo;
|
||||||
|
|
||||||
|
float xOfCentroid;
|
||||||
|
float yOfCentroid;
|
||||||
|
|
||||||
|
vector<Particle*> system;
|
||||||
|
vector<Particle>sys;
|
||||||
|
vector<Attractor*> attractors;
|
||||||
|
|
||||||
|
float birthCount;
|
||||||
|
double time;
|
||||||
|
|
||||||
|
bool varSystem;
|
||||||
|
bool trails;
|
||||||
|
};
|
211
particle.cpp
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
|
||||||
|
// particle.cpp
|
||||||
|
// particleSystem
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "particle.h"
|
||||||
|
#include "ofApp.h"
|
||||||
|
|
||||||
|
Particle::Particle()
|
||||||
|
{
|
||||||
|
uniqueVal = ofRandom(-10000, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
void Particle::setup(particleMode newMode) {
|
||||||
|
mode = newMode;
|
||||||
|
age = 0.0;
|
||||||
|
//maxLife = 30.0;
|
||||||
|
frc = ofVec2f(0, 0);
|
||||||
|
//size = ofRandom(4.0, 0.01);
|
||||||
|
size = .5;
|
||||||
|
maxLife = 0.99;
|
||||||
|
mass = ofRandom(100, 250);
|
||||||
|
if (mode == PARTICLE_MODE_DEFAULT) {
|
||||||
|
effect.loadFile("xml/default.xml");
|
||||||
|
int velMin = effect.getValue("default:velMin", 0);
|
||||||
|
int velMax = effect.getValue("default:velMax", 0);
|
||||||
|
int lifeMax = effect.getValue("default:maxLife", 0);
|
||||||
|
setVel(velMin, velMax);
|
||||||
|
pos.x = ofRandomWidth();
|
||||||
|
pos.y = ofRandomHeight();
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_RADIAL) {
|
||||||
|
effect.loadFile("xml/radial.xml");
|
||||||
|
int velMin = effect.getValue("radial:velMin", 0);
|
||||||
|
int velMax = effect.getValue("radial:velMax", 0);
|
||||||
|
setVel(velMin, velMax);
|
||||||
|
pos.x = ofGetWidth()/2;
|
||||||
|
pos.y = ofGetHeight()/2;
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_RAIN) {
|
||||||
|
effect.loadFile("xml/rain.xml");
|
||||||
|
vel.x = ofRandom(-40, 40);
|
||||||
|
vel.y = ofRandom(-40, 40);
|
||||||
|
pos.x = ofRandomWidth();
|
||||||
|
pos.y = ofRandomHeight();
|
||||||
|
drag = ofRandom(0.97, 0.99);
|
||||||
|
vel.y = fabs(vel.y) * 6.0;
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_ATTRACTOR) {
|
||||||
|
effect.loadFile("xml/rain.xml");
|
||||||
|
vel.x = ofRandom(-40, 40);
|
||||||
|
vel.y = ofRandom(-40, 40);
|
||||||
|
pos.x = ofRandomWidth();
|
||||||
|
pos.y = ofRandomHeight();
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_DETRACTOR) {
|
||||||
|
effect.loadFile("xml/rain.xml");
|
||||||
|
vel.x = ofRandom(-40, 40);
|
||||||
|
vel.y = ofRandom(-40, 40);
|
||||||
|
pos.x = ofRandomWidth();
|
||||||
|
pos.y = ofRandomHeight();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
drag = ofRandom(0.95, 0.998);
|
||||||
|
}
|
||||||
|
|
||||||
|
tex.load("img/br.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Particle::update(float deltaT, vector<Attractor*>* attractors,vector<Particle*> system) {
|
||||||
|
if (mode == PARTICLE_MODE_DEFAULT) {
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_RAIN) {
|
||||||
|
float wind = ofSignedNoise(pos.x * 0.003, pos.y * 0.0006, ofGetElapsedTimef() * 0.6);
|
||||||
|
|
||||||
|
frc.x = wind * 0.25 + ofSignedNoise(uniqueVal, pos.y * 0.08) * 0.6;
|
||||||
|
frc.y = ofSignedNoise(uniqueVal, pos.x * 0.06, ofGetElapsedTimef()*0.2) * 0.09 + 0.18;
|
||||||
|
|
||||||
|
vel *= drag;
|
||||||
|
vel += frc * 0.2;
|
||||||
|
|
||||||
|
if (pos.y + vel.y > ofGetHeight()) {
|
||||||
|
pos.y -= ofGetHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_ATTRACTOR) {
|
||||||
|
|
||||||
|
ofVec2f force;
|
||||||
|
counterOfActiveAttractors = 0;
|
||||||
|
for (int i = 0; i < attractors->size(); i++) {
|
||||||
|
if (attractors->at(i)->getX() == 0 && attractors->at(i)->getY() == 0) {
|
||||||
|
vel += force;
|
||||||
|
vel = mass * vel.getNormalized();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
counterOfActiveAttractors++;
|
||||||
|
force.set(attractors->at(i)->getX() - pos.x, attractors->at(i)->getY() - pos.y);
|
||||||
|
|
||||||
|
if (force.length() < 250) {
|
||||||
|
force = 40 * force.getNormalized();
|
||||||
|
size = size + ofRandom(.03, 0.01);
|
||||||
|
vel += force;
|
||||||
|
vel = mass * vel.getNormalized();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
force = 0 * force.getNormalized();
|
||||||
|
vel += force;
|
||||||
|
vel = mass * vel.getNormalized();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_DETRACTOR) {
|
||||||
|
ofVec2f force;
|
||||||
|
counterOfActiveAttractors = 0;
|
||||||
|
for (int i = 0; i < attractors->size(); i++) {
|
||||||
|
if (attractors->at(i)->getX() == 0 && attractors->at(i)->getY() == 0) {
|
||||||
|
//force = 0 * force.getNormalized();
|
||||||
|
vel += force;
|
||||||
|
vel = mass * vel.getNormalized();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
counterOfActiveAttractors++;
|
||||||
|
force.set(attractors->at(i)->getX() - pos.x, attractors->at(i)->getY() - pos.y);
|
||||||
|
|
||||||
|
if (force.length() < 600) {
|
||||||
|
force.normalize();
|
||||||
|
size = size + ofRandom(.01, 0.01);
|
||||||
|
|
||||||
|
vel += -force*2000;
|
||||||
|
vel = mass * vel.getNormalized();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
force = 0 * force.getNormalized();
|
||||||
|
vel += force;
|
||||||
|
vel = mass * vel.getNormalized();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Update particle pos
|
||||||
|
age += deltaT* .5;
|
||||||
|
pos += (vel * deltaT);
|
||||||
|
|
||||||
|
// *** COLLISION *** COLLISION *** COLLISION *** COLLISION *** COLLISION *** COLLISION
|
||||||
|
|
||||||
|
//if (position.x <= 0 || position.x >= ofGetWidth()) {
|
||||||
|
//vel.x = -vel.x;
|
||||||
|
//position += (vel * deltaT);
|
||||||
|
//}
|
||||||
|
//else if (position.y <= 0 || position.y >= ofGetHeight()) {
|
||||||
|
//vel.y = -vel.y;
|
||||||
|
//position += (vel * deltaT);
|
||||||
|
//}
|
||||||
|
//else {
|
||||||
|
//position += (vel * deltaT);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
void Particle::draw() {
|
||||||
|
|
||||||
|
color.set(getAgeNorm() * 241,241/ getAgeNorm() ,219);
|
||||||
|
|
||||||
|
ofSetColor(color, (1 - getAgeNorm()) * 255);
|
||||||
|
if (mode == PARTICLE_MODE_BRUNIG) {
|
||||||
|
tex.setColor(color);
|
||||||
|
tex.draw(pos.x, pos.y, size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ofDrawCircle(pos.x, pos.y, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
void Particle::setMode(particleMode newMode) {
|
||||||
|
mode = newMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
float Particle::getAgeNorm() {
|
||||||
|
return age / maxLife;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
void Particle::setVel(float min, float max) {
|
||||||
|
vel.x = ofRandom(min,max);
|
||||||
|
vel.y = ofRandom(min,max);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Particle::getMaxLife() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Particle::getY() {
|
||||||
|
return pos.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float Particle::getX() {
|
||||||
|
return pos.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
63
particle.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ofMain.h"
|
||||||
|
#include "ofxXmlSettings.h"
|
||||||
|
#include "attractor.h"
|
||||||
|
|
||||||
|
enum particleMode{
|
||||||
|
PARTICLE_MODE_DEFAULT,
|
||||||
|
PARTICLE_MODE_ATTRACTOR,
|
||||||
|
PARTICLE_MODE_RAIN,
|
||||||
|
PARTICLE_MODE_RADIAL,
|
||||||
|
PARTICLE_MODE_DETRACTOR,
|
||||||
|
PARTICLE_MODE_POLY,
|
||||||
|
PARTICLE_MODE_BRUNIG
|
||||||
|
};
|
||||||
|
|
||||||
|
class Particle{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Particle();
|
||||||
|
|
||||||
|
void setup(particleMode newMode);
|
||||||
|
|
||||||
|
void update(float deltaT, vector<Attractor*>* attractors, vector<Particle*> system);
|
||||||
|
void setMode(particleMode newMode);
|
||||||
|
particleMode mode;
|
||||||
|
|
||||||
|
void draw();
|
||||||
|
void reset(ofVec2f _pos);
|
||||||
|
|
||||||
|
float getX();
|
||||||
|
float getY();
|
||||||
|
|
||||||
|
void setVel(float min, float max);
|
||||||
|
|
||||||
|
float getAgeNorm();
|
||||||
|
float getMaxLife();
|
||||||
|
|
||||||
|
|
||||||
|
ofxXmlSettings effect;
|
||||||
|
|
||||||
|
int counterOfActiveAttractors;
|
||||||
|
|
||||||
|
ofVec2f vel;
|
||||||
|
ofVec2f pos;
|
||||||
|
ofVec2f frc;
|
||||||
|
|
||||||
|
float scale;
|
||||||
|
float drag;
|
||||||
|
float uniqueVal;
|
||||||
|
|
||||||
|
float maxLife;
|
||||||
|
float age;
|
||||||
|
|
||||||
|
float size;
|
||||||
|
float mass;
|
||||||
|
|
||||||
|
int blobCounterInParticle;
|
||||||
|
|
||||||
|
ofColor color;
|
||||||
|
ofImage tex;
|
||||||
|
};
|
10
src/bin/data/xml/attractor.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<default>
|
||||||
|
<sizeMin>0.05</sizeMin>
|
||||||
|
<sizeMax>4</sizeMax>
|
||||||
|
<mass>100</mass>
|
||||||
|
<drag>0</drag>
|
||||||
|
<maxLife>10</maxLife>
|
||||||
|
<velMin>-80</velMin>
|
||||||
|
<velMax>80</velMax>
|
||||||
|
<color></color>
|
||||||
|
</default>
|
10
src/bin/data/xml/default.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<default>
|
||||||
|
<sizeMin>0.05</sizeMin>
|
||||||
|
<sizeMax>4</sizeMax>
|
||||||
|
<mass>100</mass>
|
||||||
|
<drag>0</drag>
|
||||||
|
<maxLife>10</maxLife>
|
||||||
|
<velMin>-80</velMin>
|
||||||
|
<velMax>80</velMax>
|
||||||
|
<color></color>
|
||||||
|
</default>
|
10
src/bin/data/xml/detraktor.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<default>
|
||||||
|
<sizeMin>0.05</sizeMin>
|
||||||
|
<sizeMax>4</sizeMax>
|
||||||
|
<mass>100</mass>
|
||||||
|
<drag>0</drag>
|
||||||
|
<maxLife>10</maxLife>
|
||||||
|
<velMin>-80</velMin>
|
||||||
|
<velMax>80</velMax>
|
||||||
|
<color></color>
|
||||||
|
</default>
|
10
src/bin/data/xml/radial.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<default>
|
||||||
|
<sizeMin>0.05</sizeMin>
|
||||||
|
<sizeMax>4</sizeMax>
|
||||||
|
<mass>100</mass>
|
||||||
|
<drag>0</drag>
|
||||||
|
<maxLife>10</maxLife>
|
||||||
|
<velMin>-80</velMin>
|
||||||
|
<velMax>80</velMax>
|
||||||
|
<color></color>
|
||||||
|
</default>
|
10
src/bin/data/xml/rain.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<default>
|
||||||
|
<sizeMin>0.05</sizeMin>
|
||||||
|
<sizeMax>4</sizeMax>
|
||||||
|
<mass>100</mass>
|
||||||
|
<drag>0</drag>
|
||||||
|
<maxLife>10</maxLife>
|
||||||
|
<velMin>-80</velMin>
|
||||||
|
<velMax>80</velMax>
|
||||||
|
<color></color>
|
||||||
|
</default>
|
BIN
src/bin/img/beer.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
src/bin/img/br.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
src/bin/img/tex.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
src/bin/img/tr.png
Normal file
After Width: | Height: | Size: 111 KiB |
@ -3,8 +3,7 @@
|
|||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
int main() {
|
int main() {
|
||||||
ofSetupOpenGL(1000, 1000, OF_WINDOW); // <-------- setup the GL context
|
ofSetupOpenGL(2000, 2000, OF_WINDOW);
|
||||||
ofRunApp(new ofApp());
|
ofRunApp(new ofApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
//hahahahahahahahha
|
|
||||||
|
162
src/ofApp.cpp
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
void ofApp::setup() {
|
void ofApp::setup() {
|
||||||
|
ofSetVerticalSync(true);
|
||||||
|
|
||||||
//Initialize 8 empty attractrs
|
//Initialize 8 empty attractrs
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
@ -12,19 +13,27 @@ void ofApp::setup() {
|
|||||||
//OSC reciever port setup
|
//OSC reciever port setup
|
||||||
receiver.setup(PORT);
|
receiver.setup(PORT);
|
||||||
|
|
||||||
|
varSystem = true;
|
||||||
|
trails = true;
|
||||||
|
history = 0.95;
|
||||||
|
//num = 1000;
|
||||||
|
//sys.assign(num, Particle());
|
||||||
|
|
||||||
|
currentMode = PARTICLE_MODE_DEFAULT;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_DEFAULT";
|
||||||
|
|
||||||
//Black background
|
//Black background
|
||||||
ofSetBackgroundColor(0, 0, 0);
|
ofSetBackgroundColor(0, 0, 0);
|
||||||
|
|
||||||
ofSetFrameRate(60);
|
ofSetFrameRate(60);
|
||||||
|
birthCount = 100;
|
||||||
birthCount = 0;
|
w = ofGetWidth();
|
||||||
|
h = ofGetHeight();
|
||||||
//attractors.at(0)->setup(200, 200);
|
fbo.allocate(w, h, GL_RGB);
|
||||||
|
//attractors.at(0)->setup(600, 600);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
void ofApp::update() {
|
void ofApp::update() {
|
||||||
|
|
||||||
// *** OSC RECEIVER ***
|
// *** OSC RECEIVER ***
|
||||||
while (receiver.hasWaitingMessages()) {
|
while (receiver.hasWaitingMessages()) {
|
||||||
|
|
||||||
@ -57,11 +66,12 @@ void ofApp::update() {
|
|||||||
double deltaT = ofGetLastFrameTime();
|
double deltaT = ofGetLastFrameTime();
|
||||||
birthCount += deltaT;
|
birthCount += deltaT;
|
||||||
|
|
||||||
|
if (varSystem == true) {
|
||||||
//Birth control for new particles
|
//Birth control for new particles
|
||||||
if (birthCount > 0.001) {
|
if (birthCount > 0.001) {
|
||||||
for (int i = 0;i < 4;i++) {
|
for (int i = 0;i < 4;i++) {
|
||||||
system.push_back(new thParticle);
|
system.push_back(new Particle);
|
||||||
system.back()->setup(ofVec2f(ofGetWidth()*.5, ofGetHeight()*.5));
|
system.back()->setup(currentMode);
|
||||||
}
|
}
|
||||||
birthCount = 0;
|
birthCount = 0;
|
||||||
}
|
}
|
||||||
@ -70,7 +80,7 @@ void ofApp::update() {
|
|||||||
for (int p = 0; p < system.size();)
|
for (int p = 0; p < system.size();)
|
||||||
{
|
{
|
||||||
//Upate particle system /w all active attractors
|
//Upate particle system /w all active attractors
|
||||||
system.at(p)->update(deltaT, &attractors);
|
system.at(p)->update(deltaT, &attractors, system);
|
||||||
|
|
||||||
//Delete particles, that reached max Age
|
//Delete particles, that reached max Age
|
||||||
if (system.at(p)->getAgeNorm() > 4) {
|
if (system.at(p)->getAgeNorm() > 4) {
|
||||||
@ -81,19 +91,67 @@ void ofApp::update() {
|
|||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ofSeedRandom(39);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
void ofApp::reset() {
|
||||||
|
|
||||||
|
for (int p = 0; p < system.size();)
|
||||||
|
{
|
||||||
|
system.erase(system.begin() + p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
void ofApp::draw() {
|
void ofApp::draw() {
|
||||||
|
if (varSystem == false) {
|
||||||
|
vector<ofVec2f> system;
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
ofVec2f particle(ofMap(ofNoise(ofRandom(100), ofGetFrameNum() * 0.0005), 0, 1, 0, ofGetWidth()), ofMap(ofNoise(ofRandom(100), ofGetFrameNum() * 0.0005), 0, 1, 0, ofGetHeight()));
|
||||||
|
system.push_back(particle);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int out = 0; out < system.size(); out++) {
|
||||||
|
for (int in = out + 1; in < system.size(); in++) {
|
||||||
|
if (system[out].distance(system[in]) < 60) {
|
||||||
|
ofDrawLine(system[out], system[in]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < system.size(); i++) {
|
||||||
|
|
||||||
|
ofDrawCircle(system[i], ofRandom(0.5, 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trails == true) {
|
||||||
|
fbo.begin();
|
||||||
|
ofEnableAlphaBlending(); //Enable transparency
|
||||||
|
|
||||||
|
float alpha = (1 - history) * 255;
|
||||||
|
ofSetColor(0, 0, 0, alpha);
|
||||||
|
ofFill();
|
||||||
|
ofRect(0, 0, ofGetWidth(), ofGetHeight());
|
||||||
|
|
||||||
|
ofDisableAlphaBlending(); //Disable transparency
|
||||||
//Draw particle system
|
//Draw particle system
|
||||||
for (int p = 0; p < system.size(); p++) {
|
for (int p = 0; p < system.size(); p++) {
|
||||||
system.at(p)->draw();
|
system.at(p)->draw();
|
||||||
}
|
}
|
||||||
|
fbo.end();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//Draw particle system
|
||||||
|
for (int p = 0; p < system.size(); p++) {
|
||||||
|
system.at(p)->draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
//Capture time based on FrameTime
|
//Capture time based on FrameTime
|
||||||
double deltaT = ofGetLastFrameTime();
|
double deltaT = ofGetLastFrameTime();
|
||||||
time += deltaT;
|
time += deltaT;
|
||||||
@ -105,28 +163,91 @@ void ofApp::draw() {
|
|||||||
time = 0;
|
time = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fbo.draw(0, 0);
|
||||||
// *** DEBUG INFO ***
|
// *** DEBUG INFO ***
|
||||||
|
ofSetColor(230);
|
||||||
//All 8 Attractors with x | y coordinates
|
//All 8 Attractors with x | y coordinates
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
|
|
||||||
//string x = ofToString(attractors.at(i)->getX());
|
string x = ofToString(attractors.at(i)->getX());
|
||||||
//string y = ofToString(attractors.at(i)->getY());
|
string y = ofToString(attractors.at(i)->getY());
|
||||||
|
|
||||||
//ofDrawBitmapString("x: " + x + " y: " + y, 100, 100 + i * 20);
|
ofDrawBitmapString("x: " + x + " y: " + y, 100, 100 + i * 20);
|
||||||
}
|
}
|
||||||
//Recieved OSC messages
|
//Recieved OSC messages
|
||||||
//ofDrawBitmapString("OSC: " + ofToString(oscMsg),100, 275);
|
ofDrawBitmapString("OSC: " + ofToString(oscMsg),100, 275);
|
||||||
//Elapsed time since last clear of attractors
|
//Elapsed time since last clear of attractors
|
||||||
//ofDrawBitmapString("Time: " + ofToString(time),100, 300);
|
ofDrawBitmapString("Time: " + ofToString(time),100, 300);
|
||||||
//Current FPS
|
//Current FPS
|
||||||
//ofDrawBitmapString("FPS: " + ofToString(ofGetFrameRate()), 100, 325);
|
ofDrawBitmapString("FPS: " + ofToString(ofGetFrameRate()), 100, 325);
|
||||||
|
//Current Mode
|
||||||
|
ofDrawBitmapString("Current Effect: " + currentModeDisp, 100, 350);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
void ofApp::keyPressed(int key) {
|
void ofApp::keyPressed(int key) {
|
||||||
|
//Key press 1 to trigger default particle Mode
|
||||||
|
if (key == '1') {
|
||||||
|
currentMode = PARTICLE_MODE_DEFAULT;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_DEFAULT";
|
||||||
|
varSystem = true;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
//Key press 2 to trigger attractor particle Mode
|
||||||
|
if (key == '2') {
|
||||||
|
currentMode = PARTICLE_MODE_RADIAL;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_RADIAL";
|
||||||
|
varSystem = true;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
//Key press 2 to trigger rain particle Mode
|
||||||
|
if (key == '3') {
|
||||||
|
currentMode = PARTICLE_MODE_RAIN;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_RAIN";
|
||||||
|
varSystem = true;
|
||||||
|
trails = false;
|
||||||
|
fbo.clear();
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
//Key press 2 to trigger attractor particle Mode
|
||||||
|
if (key == '4') {
|
||||||
|
currentMode = PARTICLE_MODE_ATTRACTOR;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_ATTRACTOR";
|
||||||
|
varSystem = true;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
//Key press 2 to trigger attractor particle Mode
|
||||||
|
if (key == '5') {
|
||||||
|
currentMode = PARTICLE_MODE_DETRACTOR;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_DETRACTOR";
|
||||||
|
varSystem = true;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
//Key press 2 to trigger attractor particle Mode
|
||||||
|
if (key == '6') {
|
||||||
|
currentMode = PARTICLE_MODE_POLY;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_POLY";
|
||||||
|
varSystem = false;
|
||||||
|
trails = false;
|
||||||
|
fbo.clear();
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
if (key == '7') {
|
||||||
|
trails = true;
|
||||||
|
fbo.allocate(w, h, GL_RGB);
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
if (key == '8') {
|
||||||
|
trails = false;
|
||||||
|
fbo.clear();
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
if (key == '9') {
|
||||||
|
currentMode = PARTICLE_MODE_POLY;
|
||||||
|
currentModeDisp = "PARTICLE_MODE_BRUNIG";
|
||||||
|
varSystem = true;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
@ -136,6 +257,7 @@ void ofApp::keyReleased(int key) {
|
|||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
void ofApp::mouseMoved(int x, int y) {
|
void ofApp::mouseMoved(int x, int y) {
|
||||||
|
attractors.at(0)->setup(ofGetMouseX(), ofGetMouseY());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
21
src/ofApp.h
@ -15,6 +15,7 @@ public:
|
|||||||
void setup();
|
void setup();
|
||||||
void update();
|
void update();
|
||||||
void draw();
|
void draw();
|
||||||
|
void reset();
|
||||||
|
|
||||||
void keyPressed(int key);
|
void keyPressed(int key);
|
||||||
void keyReleased(int key);
|
void keyReleased(int key);
|
||||||
@ -22,23 +23,41 @@ public:
|
|||||||
void mousePressed(int x, int y, int button);
|
void mousePressed(int x, int y, int button);
|
||||||
void mouseReleased(int x, int y, int button);
|
void mouseReleased(int x, int y, int button);
|
||||||
|
|
||||||
|
ofxXmlSettings default;
|
||||||
|
ofxXmlSettings attractor;
|
||||||
|
ofxXmlSettings rain;
|
||||||
|
ofxXmlSettings brunig;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// OSC Receiver
|
// OSC Receiver
|
||||||
|
|
||||||
|
particleMode currentMode;
|
||||||
|
string currentModeDisp;
|
||||||
|
|
||||||
string oscMsg;
|
string oscMsg;
|
||||||
ofxOscReceiver receiver;
|
ofxOscReceiver receiver;
|
||||||
float timeSent, timeReceived;
|
float timeSent, timeReceived;
|
||||||
|
|
||||||
int nBlobs;
|
int nBlobs;
|
||||||
int blobCount;
|
int blobCount;
|
||||||
|
int num;
|
||||||
|
float history;
|
||||||
|
ofFbo fbo;
|
||||||
|
|
||||||
float xOfCentroid;
|
float xOfCentroid;
|
||||||
float yOfCentroid;
|
float yOfCentroid;
|
||||||
|
|
||||||
vector<thParticle*> system;
|
vector<Particle*> system;
|
||||||
|
vector<Particle>sys;
|
||||||
vector<Attractor*> attractors;
|
vector<Attractor*> attractors;
|
||||||
|
|
||||||
float birthCount;
|
float birthCount;
|
||||||
double time;
|
double time;
|
||||||
|
|
||||||
|
bool varSystem;
|
||||||
|
bool trails;
|
||||||
|
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
};
|
};
|
||||||
|
220
src/particle.cpp
@ -8,61 +8,132 @@
|
|||||||
|
|
||||||
Particle::Particle()
|
Particle::Particle()
|
||||||
{
|
{
|
||||||
|
uniqueVal = ofRandom(-10000, 10000);
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Particle::~Particle()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
void Particle::setup(ofVec2f _position) {
|
void Particle::setup(particleMode newMode) {
|
||||||
|
mode = newMode;
|
||||||
this->position = _position;
|
|
||||||
|
|
||||||
vel.set(ofRandom(-3.0, 3.0), ofRandom(-3.0, 3.0));
|
|
||||||
|
|
||||||
age = 0.0;
|
age = 0.0;
|
||||||
maxLife = 12.0;
|
maxLife = 10.0;
|
||||||
|
frc = ofVec2f(0, 0);
|
||||||
color.set(250, 250, 250);
|
size = ofRandom(1, 1);
|
||||||
|
size = .5;
|
||||||
size = ofRandom(4.0, 0.01);
|
|
||||||
|
|
||||||
mass = ofRandom(100, 250);
|
mass = ofRandom(100, 250);
|
||||||
|
//setVel(-40, 40);
|
||||||
|
if (mode == PARTICLE_MODE_DEFAULT) {
|
||||||
|
effect.loadFile("xml/default.xml");
|
||||||
|
int velMin = effect.getValue("default:velMin", 0);
|
||||||
|
int velMax = effect.getValue("default:velMax", 0);
|
||||||
|
setVel(velMin, velMax);
|
||||||
|
int lifeMax = effect.getValue("default:maxLife", 0);
|
||||||
|
maxLife = lifeMax;
|
||||||
|
int sizeMin = effect.getValue("default:sizeMin", 0);
|
||||||
|
int sizeMax = effect.getValue("default:sizeMax", 0);
|
||||||
|
size = ofRandom(sizeMin, sizeMax);
|
||||||
|
pos.x = ofRandomWidth();
|
||||||
|
pos.y = ofRandomHeight();
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_RADIAL) {
|
||||||
|
effect.loadFile("xml/radial.xml");
|
||||||
|
int velMin = effect.getValue("default:velMin", 0);
|
||||||
|
int velMax = effect.getValue("default:velMax", 0);
|
||||||
|
setVel(velMin, velMax);
|
||||||
|
int lifeMax = effect.getValue("default:maxLife", 0);
|
||||||
|
maxLife = lifeMax;
|
||||||
|
int sizeMin = effect.getValue("default:sizeMin", 0);
|
||||||
|
int sizeMax = effect.getValue("default:sizeMax", 0);
|
||||||
|
size = ofRandom(sizeMin, sizeMax);
|
||||||
|
pos.x = ofGetWidth()/2;
|
||||||
|
pos.y = ofGetHeight()/2;
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_RAIN) {
|
||||||
|
effect.loadFile("xml/rain.xml");
|
||||||
|
int velMin = effect.getValue("default:velMin", 0);
|
||||||
|
int velMax = effect.getValue("default:velMax", 0);
|
||||||
|
setVel(velMin, velMax);
|
||||||
|
int lifeMax = effect.getValue("default:maxLife", 0);
|
||||||
|
maxLife = lifeMax;
|
||||||
|
int sizeMin = effect.getValue("default:sizeMin", 0);
|
||||||
|
int sizeMax = effect.getValue("default:sizeMax", 0);
|
||||||
|
size = ofRandom(sizeMin, sizeMax);
|
||||||
|
pos.x = ofRandomWidth();
|
||||||
|
pos.y = ofRandomHeight();
|
||||||
|
drag = ofRandom(0.97, 0.99);
|
||||||
|
vel.y = fabs(vel.y) * 6.0;
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_ATTRACTOR) {
|
||||||
|
effect.loadFile("xml/attractor.xml");
|
||||||
|
int velMin = effect.getValue("default:velMin", 0);
|
||||||
|
int velMax = effect.getValue("default:velMax", 0);
|
||||||
|
setVel(velMin, velMax);
|
||||||
|
int lifeMax = effect.getValue("default:maxLife", 0);
|
||||||
|
maxLife = lifeMax;
|
||||||
|
int sizeMin = effect.getValue("default:sizeMin", 0);
|
||||||
|
int sizeMax = effect.getValue("default:sizeMax", 0);
|
||||||
|
size = ofRandom(sizeMin, sizeMax);
|
||||||
|
pos.x = ofRandomWidth();
|
||||||
|
pos.y = ofRandomHeight();
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_DETRACTOR) {
|
||||||
|
effect.loadFile("xml/detractor.xml");
|
||||||
|
int velMin = effect.getValue("default:velMin", 0);
|
||||||
|
int velMax = effect.getValue("default:velMax", 0);
|
||||||
|
setVel(velMin, velMax);
|
||||||
|
int lifeMax = effect.getValue("default:maxLife", 0);
|
||||||
|
maxLife = lifeMax;
|
||||||
|
int sizeMin = effect.getValue("default:sizeMin", 0);
|
||||||
|
int sizeMax = effect.getValue("default:sizeMax", 0);
|
||||||
|
size = ofRandom(sizeMin, sizeMax);
|
||||||
|
pos.x = ofRandomWidth();
|
||||||
|
pos.y = ofRandomHeight();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
tex.load("img/overlay.png");
|
drag = ofRandom(0.95, 0.998);
|
||||||
|
}
|
||||||
|
|
||||||
|
tex.load("img/br.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
void Particle::update(float deltaT, vector<Attractor*>* attractors) {
|
void Particle::update(float deltaT, vector<Attractor*>* attractors,vector<Particle*> system) {
|
||||||
|
if (mode == PARTICLE_MODE_DEFAULT) {
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_RAIN) {
|
||||||
|
float wind = ofSignedNoise(pos.x * 0.003, pos.y * 0.006, ofGetElapsedTimef() * 0.6);
|
||||||
|
|
||||||
|
frc.x = wind * 0.25 + ofSignedNoise(uniqueVal, pos.y * 0.08) * 0.6;
|
||||||
|
frc.y = ofSignedNoise(uniqueVal, pos.x * 0.06, ofGetElapsedTimef()*0.2) * 0.09 + 0.18;
|
||||||
|
|
||||||
|
vel *= drag;
|
||||||
|
vel += frc * 0.2;
|
||||||
|
|
||||||
|
if (pos.y + vel.y > ofGetHeight()) {
|
||||||
|
pos.y -= ofGetHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_ATTRACTOR) {
|
||||||
|
|
||||||
ofVec2f force;
|
ofVec2f force;
|
||||||
counterOfActiveAttractors = 0;
|
counterOfActiveAttractors = 0;
|
||||||
for (int i = 0; i < attractors->size(); i++) {
|
for (int i = 0; i < attractors->size(); i++) {
|
||||||
if (attractors->at(i)->getX() == 0 && attractors->at(i)->getY() == 0) {
|
if (attractors->at(i)->getX() == 0 && attractors->at(i)->getY() == 0) {
|
||||||
force = 0 * force.getNormalized();
|
|
||||||
vel += force;
|
vel += force;
|
||||||
vel = mass * vel.getNormalized();
|
vel = mass * vel.getNormalized();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
counterOfActiveAttractors++;
|
counterOfActiveAttractors++;
|
||||||
force.set(attractors->at(i)->getX() - position.x, attractors->at(i)->getY() - position.y);
|
force.set(attractors->at(i)->getX() - pos.x, attractors->at(i)->getY() - pos.y);
|
||||||
|
|
||||||
if (force.length() < 150) {
|
|
||||||
force = 60 * force.getNormalized();
|
|
||||||
size = size + ofRandom(.01, 0.01);
|
|
||||||
|
|
||||||
|
if (force.length() < 250) {
|
||||||
|
force = 40 * force.getNormalized();
|
||||||
|
size = size + ofRandom(.03, 0.01);
|
||||||
vel += force;
|
vel += force;
|
||||||
vel = mass * vel.getNormalized();
|
vel = mass * vel.getNormalized();
|
||||||
}
|
}
|
||||||
@ -72,9 +143,38 @@ void Particle::update(float deltaT, vector<Attractor*>* attractors) {
|
|||||||
vel = mass * vel.getNormalized();
|
vel = mass * vel.getNormalized();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (mode == PARTICLE_MODE_DETRACTOR) {
|
||||||
|
ofVec2f force;
|
||||||
|
counterOfActiveAttractors = 0;
|
||||||
|
for (int i = 0; i < attractors->size(); i++) {
|
||||||
|
if (attractors->at(i)->getX() == 0 && attractors->at(i)->getY() == 0) {
|
||||||
|
//force = 0 * force.getNormalized();
|
||||||
|
vel += force;
|
||||||
|
vel = mass * vel.getNormalized();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
counterOfActiveAttractors++;
|
||||||
|
force.set(attractors->at(i)->getX() - pos.x, attractors->at(i)->getY() - pos.y);
|
||||||
|
|
||||||
|
if (force.length() < 600) {
|
||||||
|
force.normalize();
|
||||||
|
size = size + ofRandom(.01, 0.01);
|
||||||
|
|
||||||
|
vel += -force*2000;
|
||||||
|
vel = mass * vel.getNormalized();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
force = 0 * force.getNormalized();
|
||||||
|
vel += force;
|
||||||
|
vel = mass * vel.getNormalized();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Update particle pos
|
||||||
age += deltaT * .5;
|
age += deltaT * .5;
|
||||||
position += (vel * deltaT);
|
pos += (vel * deltaT);
|
||||||
|
|
||||||
// *** COLLISION *** COLLISION *** COLLISION *** COLLISION *** COLLISION *** COLLISION
|
// *** COLLISION *** COLLISION *** COLLISION *** COLLISION *** COLLISION *** COLLISION
|
||||||
|
|
||||||
@ -89,60 +189,50 @@ void Particle::update(float deltaT, vector<Attractor*>* attractors) {
|
|||||||
//else {
|
//else {
|
||||||
//position += (vel * deltaT);
|
//position += (vel * deltaT);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
//void thParticle::update(float deltaT, ofVec2f attractor){
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// age += deltaT;
|
|
||||||
//
|
|
||||||
// ofVec2f force = attractor - position;
|
|
||||||
// color.set(250,250, 250, (1 - age / maxLife) * 255);
|
|
||||||
//
|
|
||||||
// if( force.length() < 40 && force.length() > 11 ){
|
|
||||||
// velocity = velocity.getNormalized() * mass;
|
|
||||||
// velocity += 0.01 * force ;
|
|
||||||
//
|
|
||||||
// }else if(force.length() < 12){
|
|
||||||
// velocity = velocity.getNormalized() * mass;
|
|
||||||
// velocity += 5 * force ;
|
|
||||||
//
|
|
||||||
// }else{
|
|
||||||
//
|
|
||||||
// velocity = velocity.getNormalized() * mass;
|
|
||||||
// velocity += 0.12 * force ;
|
|
||||||
// }
|
|
||||||
// position += velocity * deltaT;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
void Particle::draw() {
|
void Particle::draw() {
|
||||||
|
|
||||||
color.set(getAgeNorm() * 241,241/ getAgeNorm() ,219);
|
color.set(getAgeNorm() * 241,241/ getAgeNorm() ,219);
|
||||||
|
|
||||||
ofSetColor(color, (1 - getAgeNorm()) * 255);
|
ofSetColor(color, (1 - getAgeNorm()) * 255);
|
||||||
//tex.setColor(color);
|
if (mode == PARTICLE_MODE_BRUNIG) {
|
||||||
//tex.draw(position, size, size);
|
tex.setColor(color);
|
||||||
|
tex.draw(pos.x, pos.y, size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ofDrawCircle(pos.x, pos.y, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ofDrawCircle(position, size);
|
//------------------------------------------------------------------
|
||||||
|
void Particle::setMode(particleMode newMode) {
|
||||||
|
mode = newMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
float Particle::getAgeNorm() {
|
float Particle::getAgeNorm() {
|
||||||
return age / maxLife;
|
return age / maxLife;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
void Particle::setVel(float min, float max) {
|
||||||
|
vel.x = ofRandom(min,max);
|
||||||
|
vel.y = ofRandom(min,max);
|
||||||
|
}
|
||||||
|
|
||||||
float Particle::getMaxLife() {
|
float Particle::getMaxLife() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Particle::getY() {
|
||||||
|
return pos.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float Particle::getX() {
|
||||||
|
return pos.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
|
@ -1,33 +1,54 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ofMain.h"
|
#include "ofMain.h"
|
||||||
|
#include "ofxXmlSettings.h"
|
||||||
#include "attractor.h"
|
#include "attractor.h"
|
||||||
#include "line.h"
|
|
||||||
|
|
||||||
class Particle
|
enum particleMode{
|
||||||
{
|
PARTICLE_MODE_DEFAULT,
|
||||||
|
PARTICLE_MODE_ATTRACTOR,
|
||||||
|
PARTICLE_MODE_RAIN,
|
||||||
|
PARTICLE_MODE_RADIAL,
|
||||||
|
PARTICLE_MODE_DETRACTOR,
|
||||||
|
PARTICLE_MODE_POLY,
|
||||||
|
PARTICLE_MODE_BRUNIG
|
||||||
|
};
|
||||||
|
|
||||||
|
class Particle{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Particle();
|
Particle();
|
||||||
~Particle();
|
|
||||||
|
|
||||||
void setup(ofVec2f position);
|
void setup(particleMode newMode);
|
||||||
|
|
||||||
void update(float deltaT, vector<Attractor*>* attractors);
|
void update(float deltaT, vector<Attractor*>* attractors, vector<Particle*> system);
|
||||||
|
void setMode(particleMode newMode);
|
||||||
|
particleMode mode;
|
||||||
|
|
||||||
void draw();
|
void draw();
|
||||||
|
void reset(ofVec2f _pos);
|
||||||
|
|
||||||
|
float getX();
|
||||||
|
float getY();
|
||||||
|
|
||||||
|
void setVel(float min, float max);
|
||||||
|
|
||||||
float getAgeNorm();
|
float getAgeNorm();
|
||||||
float getMaxLife();
|
float getMaxLife();
|
||||||
|
|
||||||
|
|
||||||
private:
|
ofxXmlSettings effect;
|
||||||
|
|
||||||
int counterOfActiveAttractors;
|
int counterOfActiveAttractors;
|
||||||
|
|
||||||
ofVec2f vel;
|
ofVec2f vel;
|
||||||
ofVec2f position;
|
ofVec2f pos;
|
||||||
|
ofVec2f frc;
|
||||||
|
|
||||||
|
float scale;
|
||||||
|
float drag;
|
||||||
|
float uniqueVal;
|
||||||
|
|
||||||
float maxLife;
|
float maxLife;
|
||||||
float age;
|
float age;
|
||||||
|