#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 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) { }