@@ -0,0 +1,159 @@ | |||
#include "drawableImage.h" | |||
#include "images.h" | |||
//-------------------------------------------------------------- | |||
DrawableImage::DrawableImage(string imageName, float sceneSizeX, float sceneSizeY) { | |||
//Color for symbol | |||
redImageColor = 121; | |||
greenImageColor = 205; | |||
blueImageColor = 205; | |||
pastMiddle = true; | |||
fileImageHex.loadImage("Hexagon.png"); | |||
imageToDraw.loadImage(imageName); | |||
fileImageHex = changeImageColor(fileImageHex, redImageColor, greenImageColor, blueImageColor); | |||
imageToDraw = changeImageColor(imageToDraw, redImageColor, greenImageColor, blueImageColor); | |||
xToMoveInCloud = ofRandom(1, 4); | |||
yToMoveIntoCloud = 0; | |||
ticksToMovePictureToRight = 150; | |||
counterToMovePictureToRight = 0; | |||
newMaxHeight = sceneSizeY - imageToDraw.getHeight() - 3; | |||
imageHeight = imageToDraw.getHeight(); | |||
maxYpositionForPicture = setMaxHeightPosition(sceneSizeY); | |||
} | |||
//-------------------------------------------------------------- | |||
DrawableImage::~DrawableImage() { | |||
} | |||
//-------------------------------------------------------------- | |||
void DrawableImage::updateImage(float sceneSizeX, float sceneSizeY) { | |||
if (cloudAttractorIsSet) { | |||
doMovementOfImageAtCloud(maxYpositionForPicture, sceneSizeX, sceneSizeY); | |||
} | |||
else if (symbolAttractorIsSet) { | |||
drawImage(sceneSizeX, sceneSizeY); | |||
} | |||
} | |||
//-------------------------------------------------------------- | |||
void DrawableImage::drawImage(float sceneSizeX, float sceneSizeY) | |||
{ | |||
yToMoveIntoCloud = 0; | |||
xToMoveInCloud = 0; | |||
counterToMovePictureToRight = 0; | |||
imageToDraw.draw((sceneSizeX / 2 - imageToDraw.getWidth() / 2), (sceneSizeY - imageToDraw.getHeight() - 5)); //Symbol at bottom | |||
fileImageHex.draw((sceneSizeX / 2 - imageToDraw.getWidth() / 2), (sceneSizeY - imageToDraw.getHeight() - 5)); //Hexagon at bottom | |||
} | |||
//-------------------------------------------------------------- | |||
void DrawableImage::doMovementOfImageAtCloud(int maxYpositionForPicture, float sceneSizeX, float sceneSizeY) | |||
{ | |||
if (yToMoveIntoCloud <= maxYpositionForPicture) { //y-Movement into cloud | |||
yToMoveIntoCloud += 3; | |||
} | |||
else if (counterToMovePictureToRight < ticksToMovePictureToRight) { | |||
counterToMovePictureToRight++; | |||
} | |||
else { //x-Movement in cloud | |||
if (pastMiddle) { //from the middle to right: midpoint + x and x gets increased til its Scenesize | |||
xToMoveInCloud += 3; | |||
} | |||
else { //From left to the middle: midpoint - x decreased til x is 0 again | |||
xToMoveInCloud -= 3; | |||
} | |||
} | |||
if (pastMiddle && xToMoveInCloud >= sceneSizeX / 2 + imageToDraw.getWidth()) { //Left from middle | |||
pastMiddle = false; | |||
} | |||
if (!pastMiddle && xToMoveInCloud <= 0) { //Rigth from middle | |||
pastMiddle = true; | |||
} | |||
imageToDraw.draw(getImagePosX(sceneSizeX), getImagePosY(sceneSizeY)); | |||
fileImageHex.draw(getImagePosX(sceneSizeX), getImagePosY(sceneSizeY)); | |||
} | |||
int DrawableImage::setMaxHeightPosition(float sceneSizeY) // Array for max y-values (so that height of the hexagons fits together and can hook into one another in honeycomb structure) | |||
{ | |||
for (float i = 0; i <= 4; i++) { //alculate the max y-values | |||
newMaxHeight -= imageHeight / 2; | |||
maxHeightPositions.push_back(newMaxHeight); | |||
} | |||
int rgen = ofRandom(0, 4); | |||
return (int)maxHeightPositions.at(rgen); //random array position to choose random y-position | |||
} | |||
//-------------------------------------------------------------- | |||
bool DrawableImage::imageIsOnTop(float sceneSizeY) { //see if symbol and particles reached cloud | |||
return yToMoveIntoCloud >= maxYpositionForPicture; | |||
} | |||
//-------------------------------------------------------------- | |||
ofImage DrawableImage::changeImageColor(ofImage imageToDraw, int r, int g, int b) { //Processing the color information of the individual image pixels | |||
int threshold = 1; | |||
int picWidth = imageToDraw.getWidth(); | |||
int picHeight = imageToDraw.getHeight(); | |||
for (int x = 0; x < picWidth; x++) { //go through all pixel and set new rgb-values | |||
for (int y = 0; y < picHeight; y++) | |||
{ | |||
int index = (x + y * picWidth) * 4; | |||
if (imageToDraw.getPixelsRef()[index + 3] >= threshold) { | |||
imageToDraw.getPixelsRef()[index] = r; | |||
imageToDraw.getPixelsRef()[index + 1] = g; | |||
imageToDraw.getPixelsRef()[index + 2] = b; | |||
} | |||
} | |||
} | |||
ofSetColor(255, 255, 255); //set color to white again so the colors don't distort themself | |||
imageToDraw.update(); | |||
return imageToDraw; | |||
} | |||
//-------------------------------------------------------------- | |||
int DrawableImage::getHeight() { | |||
return imageToDraw.getHeight(); | |||
} | |||
//-------------------------------------------------------------- | |||
int DrawableImage::getWidth() { | |||
return imageToDraw.getWidth(); | |||
} | |||
//-------------------------------------------------------------- | |||
int DrawableImage::getMaxHeight() { | |||
return maxYpositionForPicture; | |||
} | |||
//-------------------------------------------------------------- | |||
float DrawableImage::getImagePosX(float sceneSizeX) { | |||
if (pastMiddle) | |||
return (sceneSizeX / 2 - imageToDraw.getWidth() / 2) + xToMoveInCloud; | |||
else | |||
return (sceneSizeX / 2 - imageToDraw.getWidth() / 2) - xToMoveInCloud; | |||
} | |||
//-------------------------------------------------------------- | |||
float DrawableImage::getImagePosY(float sceneSizeY) { | |||
return (sceneSizeY - imageToDraw.getHeight() - 5) - yToMoveIntoCloud; | |||
} |
@@ -0,0 +1,60 @@ | |||
#ifndef drawableImage_h | |||
#define drawableImage_h | |||
#pragma once | |||
#include "ofMain.h" | |||
#include "ofxCv.h" | |||
#include "ofxOpenCv.h" | |||
#include <stdio.h> | |||
class DrawableImage | |||
{ | |||
public: | |||
DrawableImage(string imageName, float sceneSizeX, float sceneSizeY); | |||
~DrawableImage(); | |||
ofColor color; | |||
ofImage fileImageHex; | |||
ofImage imageToDraw; | |||
float maxLife; | |||
float age; | |||
float size; | |||
float mass; | |||
int yToMoveIntoCloud; | |||
int xToMoveInCloud; | |||
int maxYpositionForPicture; | |||
int redImageColor; | |||
int greenImageColor; | |||
int blueImageColor; | |||
int ticksToMovePictureToRight; | |||
int counterToMovePictureToRight; | |||
int imageHeight; | |||
int newMaxHeight; | |||
int getHeight(); | |||
int getWidth(); | |||
int getMaxHeight(); | |||
bool pL; | |||
bool symbolAttractorIsSet; | |||
bool cloudAttractorIsSet; | |||
bool pastMiddle; | |||
void updateImage(float sceneSizeX, float sceneSizeY); | |||
void drawImage(float sceneSizeX, float sceneSizeY); | |||
void doMovementOfImageAtCloud(int maxYpositionForPicture, float sceneSizeX, float sceneSizeY); | |||
int setMaxHeightPosition(float sceneSizeY); | |||
bool imageIsOnTop(float sceneSizeY); | |||
float getImagePosX(float sceneSizeX); | |||
float getImagePosY(float sceneSizeY); | |||
vector<float>maxHeightPositions; | |||
ofImage changeImageColor(ofImage imageToDraw, int r, int g, int b); | |||
private: | |||
}; | |||
#endif | |||
#pragma once |
@@ -1,80 +0,0 @@ | |||
// | |||
// greatWhole.cpp | |||
// emptyExample | |||
// | |||
// Created by Sebastian Holzki on 17.04.19. | |||
// | |||
#include "greatWhole.h" | |||
#include "avatar.h" | |||
GreatWhole::GreatWhole() | |||
{ | |||
} | |||
// ----------------------------------- | |||
GreatWhole::~GreatWhole() | |||
{ | |||
} | |||
// ----------------------------------- | |||
void GreatWhole::setup(){ | |||
} | |||
// ----------------------------------------------- | |||
void GreatWhole::update(vector<Avatar*> avatars){ | |||
} | |||
// ----------------------------------------------- | |||
void GreatWhole::draw(){ | |||
/* | |||
draw the whole avatar vector | |||
*/ | |||
} | |||
// ----------------------------------------------- | |||
void GreatWhole::addAvatar(Avatar avatar){ | |||
// avatars.push_back(avatar); | |||
/* | |||
Set coordinates in abhängigkeit vom letzten also bei avatars at (max-1) | |||
clip avatar dann an den letzten, y und x angepasst an x und y von avatars.at(max-1) | |||
*/ | |||
} | |||
@@ -1,41 +0,0 @@ | |||
// | |||
// greatWhole.h | |||
// emptyExample | |||
// | |||
// Created by Sebastian Holzki on 17.04.19. | |||
// | |||
#include <stdio.h> | |||
#include "ofMain.h" | |||
#include "avatar.h" | |||
#pragma once | |||
/* Das Große Ganze beinhaltet eine unbestimmte Anzahl an bereits eingecheckten Personen, deren Infos in Avatare gespeichert werden. | |||
Es bedarf eine setup(), update() und draw()-Methode. Dabei soll Platz für den vector<Avatar> geschaffen werden. In update wird eine | |||
gewisse Bewegung der Avatar-"Bubbles" definiert. Draw zeichnet die Avatare auf die Stelen, also die entsprechenden Koordinaten. */ | |||
class GreatWhole { | |||
public: | |||
GreatWhole(); | |||
~GreatWhole(); | |||
void setup(); | |||
void update(vector<Avatar*> avatars); | |||
void draw(); | |||
void addAvatar(Avatar avatar); | |||
Avatar getAvatarAt(int i); | |||
private: | |||
vector<Avatar*> avatars; | |||
}; |
@@ -0,0 +1,236 @@ | |||
#include "imageParticleSystem.h" | |||
ImageParticleSystem::ImageParticleSystem(int sceneSizeX, int sceneSizeY, ofImage fileImageHex, string imageName) { | |||
this->imageToDraw = new DrawableImage(imageName, sceneSizeX, sceneSizeY); | |||
this->imageHeight = imageToDraw->getHeight(); | |||
this->imageWidth = imageToDraw->getWidth(); | |||
this->sceneSizeX = sceneSizeX; | |||
this->sceneSizeY = sceneSizeY; | |||
this->fileImageHex = fileImageHex; | |||
setAttractorsFromHexagonFromPicture(); | |||
maxParticle = 50; | |||
setSymbolAttractorIsSet(true); | |||
setCloudAttractorIsSet(false); | |||
ticksToMoveImageToTop = 200; | |||
counterToMoveImageToTop = 0; | |||
fileImageCloud.loadImage("Hexagon.png"); | |||
imageReachedTopAndAttractorIsChanged = false; | |||
} | |||
//---------------------------------------------------------- | |||
void ImageParticleSystem::updateParticleSystem() { | |||
double deltaT = ofGetLastFrameTime(); | |||
time += deltaT; | |||
if ((cloudAttractorIsSet == false) && (particles.size() < picPix / 7) && (this->imageToDraw->imageIsOnTop(sceneSizeY) == false)) { //Creating particles for symbol on bottom | |||
createParticlesForHexagonInSymbol(); | |||
} | |||
else if ((cloudAttractorIsSet == false) && (particles.size() < picPix / 7) && (this->imageToDraw->imageIsOnTop(sceneSizeY))) { //Creating particles for symbol in cloud | |||
createParticlesForHexagonInCloud(); | |||
} | |||
else if ((cloudAttractorIsSet == false) && (particles.size() > picPix / 7)) { //Deleting unused particles for hexagon on bottom | |||
deleteParticlesForHexagon(); | |||
} | |||
else if ((cloudAttractorIsSet == true) && (particles.size() > picPix / 7)) { //Deleting unused particles for rocketeffect | |||
//deleteParticlesForRocketEffect(); | |||
} | |||
//Movement | |||
for (int p = 0; p < particles.size(); p++) { | |||
if (p * 7 < attractors.size()) { | |||
if (cloudAttractorIsSet == true) { //Movement at rocketeffect | |||
particles.at(p)->updateParticle(deltaT, attractors[p * 7], | |||
cloudAttractorIsSet, this->imageToDraw->imageIsOnTop(sceneSizeY), true, imageHeight, imageWidth, sceneSizeX, sceneSizeY); | |||
} | |||
else if (symbolAttractorIsSet == true) //Movement at Symbol at the bottom | |||
{ | |||
particles.at(p)->updateParticle(deltaT, attractors[p * 7], | |||
cloudAttractorIsSet, this->imageToDraw->imageIsOnTop(sceneSizeY), true, imageHeight, imageWidth, sceneSizeX, sceneSizeY); | |||
if (this->imageToDraw->imageIsOnTop(sceneSizeY)) //Deleting the particle after they left scene at right | |||
{ | |||
deleteParticleAfterLeavingOntheRightAndCreateThemOnTheLeft(p); | |||
} | |||
} | |||
} | |||
} | |||
if (counterToMoveImageToTop < ticksToMoveImageToTop) { //Delay (every Frame) before the symbol and particle pass to the rocket effect | |||
counterToMoveImageToTop++; | |||
} | |||
else if (counterToMoveImageToTop == ticksToMoveImageToTop) { //Symbol and particles do over in rocketeffect | |||
changeAttractorImage(fileImageCloud); | |||
setCloudAttractorIsSet(true); | |||
} | |||
if (this->imageToDraw->imageIsOnTop(sceneSizeY)) { //Symbol and particles reached max. y-position and attractor gets changed from rocketeffect to hexagon | |||
setAttractorsFromHexagonFromPicture(); | |||
cloudAttractorIsSet = false; | |||
} | |||
} | |||
//---------------------------------------------------------- | |||
void ImageParticleSystem::createParticlesForHexagonInSymbol() | |||
{ | |||
int newPix = (picPix / 7) - particles.size(); | |||
for (int i = 1; i <= newPix; i++) { //Go through pixel i = 1 (there is no pixel 0) | |||
particles.push_back(new Particle); | |||
int x = sceneSizeX / 2; | |||
int y = sceneSizeY; | |||
particles.back()->setup(ofVec2f(x, y), 20); | |||
} | |||
} | |||
//---------------------------------------------------------- | |||
void ImageParticleSystem::createParticlesForHexagonInCloud() | |||
{ | |||
int newPix = (picPix / 7) - particles.size(); | |||
for (int i = 1; i <= newPix; i++) { //Go through pixel i = 1 (there is no pixel 0) | |||
particles.push_back(new Particle); | |||
int x = sceneSizeX / 2; | |||
int y = imageToDraw->getImagePosY(sceneSizeY) + imageHeight; | |||
particles.back()->setup(ofVec2f(x, y), 20); | |||
} | |||
} | |||
//---------------------------------------------------------- | |||
void ImageParticleSystem::deleteParticlesForRocketEffect() | |||
{ | |||
int newPix = (particles.size() - (picPix / 7)); | |||
for (int i = 0; i < newPix; i++) { | |||
delete particles.at(0); //Deleting particle object | |||
particles.erase(particles.begin()); //Deleting pointer to particle | |||
} | |||
} | |||
//---------------------------------------------------------- | |||
void ImageParticleSystem::deleteParticlesForHexagon() | |||
{ | |||
int newPix = (particles.size() - (picPix / 7)); | |||
for (int i = 0; i < newPix; i++) { | |||
delete particles.at(0); //Deleting particle object | |||
particles.erase(particles.begin()); //Deleting pointer to particle | |||
} | |||
} | |||
//---------------------------------------------------------- | |||
void ImageParticleSystem::deleteParticleAfterLeavingOntheRightAndCreateThemOnTheLeft(int p) | |||
{ | |||
bool particleToDelete = particles.at(p)->deleteAfterLeavingSceneX(); | |||
if (particleToDelete) { | |||
delete particles.at(0); //Deleting particle object | |||
particles.erase(particles.begin()); //Deleting pointer to particle | |||
//Durchgehen ab Partikel i = 1 da es kein Pixel 0 gibt | |||
particles.push_back(new Particle); | |||
int x = -50; | |||
int y = imageToDraw->getHeight(); | |||
particles.back()->setup(ofVec2f(x, y), 20); | |||
} | |||
} | |||
//---------------------------------------------------------- | |||
void ImageParticleSystem::changeAttractorImage(ofImage newAttractorImage) { //Attractor is changed between hexagon and cloud | |||
attractors = pixelInVector(newAttractorImage); | |||
} | |||
//---------------------------------------------------------- | |||
void ImageParticleSystem::setAttractorsFromHexagonFromPicture() { //Hexagon is attracot (pixel from hexagon get converted in attractors) | |||
int picWidth = fileImageHex.getWidth(); | |||
int picHeight = fileImageHex.getHeight(); | |||
ofPixels pix; | |||
pix = fileImageHex.getPixels(); | |||
vector<ofVec2f> pxPos; | |||
picPix = 0; | |||
for (int i = 3; i <= pix.size(); i += 4) { //i specifys that every fourth color information of the pixel is handled (rgba) | |||
if (pix[i] > 0) { | |||
int width = pix.getWidth(); | |||
int y = i / 4 / width; | |||
int x = i / 4 % width; | |||
ofVec2f vec; | |||
vec.set(x + imageToDraw->getImagePosX(sceneSizeX), y + imageToDraw->getImagePosY(sceneSizeY)); //Gets position of image and so that the attractor follows movement | |||
pxPos.push_back(vec); | |||
picPix++; | |||
} | |||
} | |||
attractors = pxPos; | |||
} | |||
//---------------------------------------------------------- | |||
vector<ofVec2f> ImageParticleSystem::pixelInVector(ofImage a) { //Read in all the coloured pixels of image and vonvert them in vectors | |||
int picWidth = a.getWidth(); | |||
int picHeight = a.getHeight(); | |||
ofPixels pix; | |||
pix = a.getPixels(); | |||
vector<ofVec2f> pxPos; | |||
picPix = 0; | |||
for (int i = 3; i <= pix.size(); i += 4) { //i specifys that every fourth color information of the pixel is handled (rgba) | |||
if (pix[i] > 0) { | |||
int width = pix.getWidth(); | |||
int y = i / 4 / width; | |||
int x = i / 4 % width; | |||
ofVec2f vec; | |||
vec.set(x + ((sceneSizeX / 2) - picWidth / 2), y - ((sceneSizeY)-picHeight - 7)); | |||
pxPos.push_back(vec); | |||
picPix++; | |||
} | |||
} | |||
return pxPos; | |||
} | |||
//---------------------------------------------------------- | |||
void ImageParticleSystem::drawImageParticleSystem() { //Drawing of symbols and particles | |||
imageToDraw->updateImage(sceneSizeX, sceneSizeY); | |||
for (int i = 0; i < particles.size(); i++) { | |||
particles.at(i)->draw(); | |||
} | |||
} | |||
//---------------------------------------------------------- | |||
void ImageParticleSystem::setSymbolAttractorIsSet(bool value) { | |||
imageToDraw->symbolAttractorIsSet = value; | |||
symbolAttractorIsSet = value; | |||
} | |||
//---------------------------------------------------------- | |||
void ImageParticleSystem::setCloudAttractorIsSet(bool value) { | |||
imageToDraw->cloudAttractorIsSet = value; | |||
cloudAttractorIsSet = value; | |||
} | |||
@@ -0,0 +1,64 @@ | |||
#ifndef imageParticleSystem_h | |||
#define imageParticleSystem_h | |||
#pragma once | |||
#include "ofMain.h" | |||
#include "ofxCv.h" | |||
#include "ofxOpenCv.h" | |||
#include "particle.h" | |||
#include "drawableImage.h" | |||
#include <stdio.h> | |||
class ImageParticleSystem | |||
{ | |||
public: | |||
ImageParticleSystem(int sceneSizeX, int sceneSizeY, ofImage fileImageHex, string imageName); | |||
~ImageParticleSystem(); | |||
vector<ofVec2f>attractors; | |||
vector<Particle*> particles; | |||
ofImage fileImageHex; | |||
ofImage fileImageCloud; | |||
int sceneSizeX; | |||
int sceneSizeY; | |||
int imageHeight; | |||
int imageWidth; | |||
int maxParticle; | |||
int picPix; | |||
int k; | |||
int ticksToMoveImageToTop; | |||
int counterToMoveImageToTop; | |||
int status; | |||
bool tornadoStarted; | |||
bool editingWarp; | |||
bool imageReachedTopAndAttractorIsChanged; | |||
float birthCnt; | |||
float maxLife; | |||
float parAmount; | |||
float height; | |||
double time; | |||
double tornadoStartTime; | |||
void updateParticleSystem(); | |||
void deleteParticlesForRocketEffect(); | |||
void deleteParticlesForHexagon(); | |||
void createParticlesForHexagonInSymbol(); | |||
void createParticlesForHexagonInCloud(); | |||
void deleteParticleAfterLeavingOntheRightAndCreateThemOnTheLeft(int p); | |||
void drawImageParticleSystem(); | |||
void setSymbolAttractorIsSet(bool value); | |||
void setCloudAttractorIsSet(bool value); | |||
void changeAttractorImage(ofImage newAttractorImage); | |||
private: | |||
DrawableImage* imageToDraw; | |||
vector<ofVec2f> pixelInVector(ofImage a); | |||
void setAttractorsFromHexagonFromPicture(); | |||
bool symbolAttractorIsSet; | |||
bool cloudAttractorIsSet; | |||
}; | |||
#endif | |||
#pragma once |
@@ -10,8 +10,8 @@ int main( ){ | |||
settings.setGLVersion(3, 2); | |||
settings.setSize(1280, 800); | |||
ofCreateWindow(settings); | |||
ofRunApp(new ofApp()); | |||
ofRunApp( new ofApp()); | |||
} |
@@ -34,17 +34,6 @@ Attraktor::Attraktor(){ | |||
}; | |||
// ----------------------------------- | |||
// ----------------------------------- | |||
@@ -6,220 +6,342 @@ | |||
//-------------------------------------------------------------- | |||
void ofApp::setup(){ | |||
VISITOR_COUNT = 0; | |||
VISITOR_COUNT_LASTFRAME = 0; | |||
PARTICLE_COUNT = 0; | |||
for (int i = 0; i < particleSystems.size(); i++){ | |||
void ofApp::setup() { | |||
currentImage = -1; | |||
ofDisableArbTex(); | |||
ofBackground(0); | |||
//test image | |||
img.setUseTexture(false); | |||
if (!img.load("testcard.png")) | |||
{ | |||
ofLogError("ofApp::setup") << "Could not load image!"; | |||
return; | |||
} | |||
} | |||
// *** OSC Setup *** OSC Setup *** OSC Setup *** | |||
receiver.setup(PORT); | |||
this->tex.enableMipmap(); | |||
this->tex.loadData(img.getPixels()); | |||
//scene properties | |||
sceneSize.set(1280, 800); | |||
area.set(0, 0, sceneSize.x, sceneSize.y); | |||
fbo.allocate(sceneSize.x, sceneSize.y, GL_RGBA); | |||
//clear fbo to make sure there's no scrap | |||
fbo.begin(); | |||
ofClear(0); | |||
fbo.end(); | |||
//load warp settings from file if present | |||
//this->warpController.loadSettings("settings.json"); | |||
//if there is no file, generate warp | |||
if (this->warpController.getWarps().empty()) | |||
{ | |||
std::shared_ptr<ofxWarpBase> warp; | |||
warp = this->warpController.buildWarp<ofxWarpPerspective>(); | |||
warp->setSize(sceneSize.x, sceneSize.y); | |||
warp->setEdges(glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); | |||
} | |||
editingWarp = false; | |||
//testing stuff | |||
ofSetCircleResolution(60); | |||
ofSetBackgroundColor(0, 0, 0); | |||
//ofSetFrameRate(60); | |||
fileImageHex.loadImage("Hexagon.png"); | |||
//rainIsActive = true; | |||
//int particleSystemsForStele = 7; //number of rainparticlesystems (one for single stele) | |||
//float sceneSizeForSingleParticleSystem = sceneSize.x / particleSystemsForStele; //calculate the widht for every single rainparticlesystem | |||
//for (int i = 0; i <= particleSystemsForStele - 1; i++) { //create all rainparticlesystem | |||
// rainParticleSyst.push_back(new RainParticleSystem(i * sceneSizeForSingleParticleSystem, sceneSizeForSingleParticleSystem, sceneSize.y)); | |||
//} | |||
VISITOR_COUNT = 0; | |||
VISITOR_COUNT_LASTFRAME = 0; | |||
PARTICLE_COUNT = 0; | |||
// *** OSC Setup *** OSC Setup *** OSC Setup *** | |||
receiver.setup(PORT); | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::update(){ | |||
// *** OSC RECEIVER *** OSC RECEIVER *** OSC RECEIVER *** | |||
/* | |||
Here the program will read and convert the information from the tracking, count them & put coordinates of people entering the ground. | |||
We have to define, how this information will affect the particleSystems! | |||
-Create message, put the stuff from the received OSC in it | |||
-duplicate the msg as string to enable onscreen supervision | |||
-There will be a global visitor count called VISITOR_COUNT | |||
-Use VISITOR_COUNT to correctly update the size of the visitors vector | |||
-Iterate trough Message-values and put information in the visitors vector | |||
*/ | |||
while(receiver.hasWaitingMessages()){ | |||
ofxOscMessage visitorInformations; | |||
receiver.getNextMessage(&visitorInformations); | |||
oscMsg = ofToString(visitorInformations); | |||
if(visitorInformations.getAddress() == "/centroidsOfBlob") { | |||
VISITOR_COUNT_LASTFRAME = VISITOR_COUNT; | |||
VISITOR_COUNT = visitorInformations.getArgAsInt(0); //update the number of Visitors from OSCs first Argument, which is the number of blobs (detected Contours) | |||
void ofApp::update() { | |||
// *** OSC RECEIVER *** OSC RECEIVER *** OSC RECEIVER *** | |||
/* | |||
Here the program will read and convert the information from the tracking, count them & put coordinates of people entering the ground. | |||
We have to define, how this information will affect the particleSystems! | |||
-Create message, put the stuff from the received OSC in it | |||
-duplicate the msg as string to enable onscreen supervision | |||
-There will be a global visitor count called VISITOR_COUNT | |||
-Use VISITOR_COUNT to correctly update the size of the visitors vector | |||
-Iterate trough Message-values and put information in the visitors vector | |||
*/ | |||
while (receiver.hasWaitingMessages()) { | |||
ofxOscMessage visitorInformations; | |||
receiver.getNextMessage(&visitorInformations); | |||
oscMsg = ofToString(visitorInformations); | |||
if (visitorInformations.getAddress() == "/centroidsOfBlob") { | |||
VISITOR_COUNT_LASTFRAME = VISITOR_COUNT; | |||
VISITOR_COUNT = visitorInformations.getArgAsInt(0); //update the number of Visitors from OSCs first Argument, which is the number of blobs (detected Contours) | |||
// *** CHECK FOR CHANGES IN THE NUMBER OF VISITORS *** CHECK FOR CHANGES IN THE NUMBER OF VISITORS *** CHECK FOR CHANGES IN THE NUMBER OF VISITORS *** | |||
// If there are MORE visitors now, add the difference to the visitors vector | |||
if(VISITOR_COUNT > VISITOR_COUNT_LASTFRAME){ | |||
for(int i = 0; i < (VISITOR_COUNT - VISITOR_COUNT_LASTFRAME); i++){ | |||
visitors.push_back(new Visitor); | |||
} | |||
} | |||
// If there are LESS visitors now, delete the difference from the visitors vector | |||
if(VISITOR_COUNT < VISITOR_COUNT_LASTFRAME){ | |||
for(int i = 0; i < (VISITOR_COUNT_LASTFRAME - VISITOR_COUNT); i++){ | |||
delete visitors.at(visitors.size()); //maybe nicht zulässig, weil fehleranfällig??? | |||
//erase ergänzen! | |||
} | |||
} | |||
// *** TRANSFER TRACKING-INFORMATION INTO VISITOR-CLASS *** TRANSFER TRACKING-INFORMATION INTO VISITOR-CLASS *** | |||
for(int i = 1; i <= VISITOR_COUNT; i++){ | |||
//put Information into visitors | |||
float xOfVisitor = visitorInformations.getArgAsFloat(i * 2 - 1) * ofGetWindowWidth(); | |||
float yOfVisitor = visitorInformations.getArgAsFloat(i * 2) * ofGetWindowHeight(); | |||
visitors.at( i - 1 )->setPosition(xOfVisitor, yOfVisitor); | |||
} | |||
} //end of .getAddress() == "/centroidsOfBlob") | |||
} //end of receiver.hasWaitingMessages | |||
// *** RFID Input *** RFID Input *** RFID Input *** RFID Input *** RFID Input *** | |||
/* | |||
Here we have to define, how the particleSystems react to RFID input. | |||
Read ID of a visitor and let the particlesystems react to it. | |||
!!! Here in ofApp.cpp there will only be the transfer of incoming information about IDs, playertypes, etc. into the update-methods of the particleSystems. !!! | |||
For example: | |||
- Tell all particleSystems about a new checkedIn-Visitor | |||
- Set the playerType of one particular particleSystem to the checked in. | |||
*/ | |||
// *** MAIN UPDATE PARTICLE SYSTEMS *** MAIN UPDATE PARTICLE SYSTEMS *** MAIN UPDATE PARTICLE SYSTEMS *** | |||
for (int p = 0; p < particleSystems.size();) | |||
{ | |||
// Update particle systems | |||
// particleSystems.at(p)->update("xxx , xxx , xxx , .... "); | |||
} | |||
} //end of update() | |||
//-------------------------------------------------------------- | |||
void ofApp::draw(){ | |||
//draw all ParticleSystems that are in the particleSystems vector | |||
for(int p = 0; p < particleSystems.size(); p++) | |||
{ | |||
particleSystems.at(p)->draw(); | |||
} | |||
if (VISITOR_COUNT > VISITOR_COUNT_LASTFRAME) { | |||
for (int i = 0; i < (VISITOR_COUNT - VISITOR_COUNT_LASTFRAME); i++) { | |||
visitors.push_back(new Visitor); | |||
} | |||
} | |||
// If there are LESS visitors now, delete the difference from the visitors vector | |||
if (VISITOR_COUNT < VISITOR_COUNT_LASTFRAME) { | |||
for (int i = 0; i < (VISITOR_COUNT_LASTFRAME - VISITOR_COUNT); i++) { | |||
delete visitors.at(visitors.size()); //maybe nicht zulässig, weil fehleranfällig??? | |||
//erase ergänzen! | |||
} | |||
} | |||
// *** TRANSFER TRACKING-INFORMATION INTO VISITOR-CLASS *** TRANSFER TRACKING-INFORMATION INTO VISITOR-CLASS *** | |||
for (int i = 1; i <= VISITOR_COUNT; i++) { | |||
//put Information into visitors | |||
float xOfVisitor = visitorInformations.getArgAsFloat(i * 2 - 1) * ofGetWindowWidth(); | |||
float yOfVisitor = visitorInformations.getArgAsFloat(i * 2) * ofGetWindowHeight(); | |||
visitors.at(i - 1)->setPosition(xOfVisitor, yOfVisitor); | |||
} | |||
} //end of .getAddress() == "/centroidsOfBlob") | |||
} //end of receiver.hasWaitingMessages | |||
// *** RFID Input *** RFID Input *** RFID Input *** RFID Input *** RFID Input *** | |||
/* | |||
Here we have to define, how the particleSystems react to RFID input. | |||
Read ID of a visitor and let the particlesystems react to it. | |||
!!! Here in ofApp.cpp there will only be the transfer of incoming information about IDs, playertypes, etc. into the update-methods of the particleSystems. !!! | |||
For example: | |||
- Tell all particleSystems about a new checkedIn-Visitor | |||
- Set the playerType of one particular particleSystem to the checked in. | |||
*/ | |||
// *** MAIN UPDATE PARTICLE SYSTEMS *** MAIN UPDATE PARTICLE SYSTEMS *** MAIN UPDATE PARTICLE SYSTEMS *** | |||
for (int p = 0; p < particleSystems.size();) | |||
{ | |||
// Update particle systems | |||
// particleSystems.at(p)->update("xxx , xxx , xxx , .... "); | |||
} | |||
if (rainIsActive) { //Movement of the particles of the rainparticlesystems | |||
for (int i = 0; i < rainParticleSyst.size(); i++) { | |||
rainParticleSyst.at(i)->updateParticleSystem(); | |||
} | |||
} | |||
else if (!rainIsActive){ //Movement of Imageparticlesystems and symbols when rain is false | |||
for (int i = 0; i < imageParticleSystems.size(); i++) { | |||
imageParticleSystems.at(i)->updateParticleSystem(); | |||
} | |||
} | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::exit() { | |||
//save warp settings on exit | |||
this->warpController.saveSettings("settings.json"); | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::keyPressed(int key){ | |||
void ofApp::draw() { | |||
fbo.begin(); | |||
ofClear(0, 0, 0); | |||
//draw stuff here | |||
//ofDrawRectangle(0, 0, 800, 800); | |||
//ofDrawCircle(sceneSize.x *.5, sceneSize.y * .5, 300); | |||
for (int p = 0; p < particleSystems.size(); p++) | |||
{ | |||
particleSystems.at(p)->draw(); | |||
} | |||
if (rainIsActive) { //drawing the rainparticlesystems | |||
for (int i = 0; i < rainParticleSyst.size(); i++) { | |||
rainParticleSyst.at(i)->drawRainParticleSystem(); | |||
} | |||
} | |||
else if (!rainIsActive) { //drawing the imageparticlesystems | |||
for (int i = 0; i < imageParticleSystems.size(); i++) { | |||
imageParticleSystems.at(i)->drawImageParticleSystem(); | |||
} | |||
} | |||
//draw all ParticleSystems that are in the particleSystems vector | |||
fbo.end(); | |||
//do not draw past this point | |||
//draw warp | |||
warpController.getWarp(0)->begin(); | |||
fbo.draw(0, 0); | |||
warpController.getWarp(0)->end(); | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::keyReleased(int key){ | |||
void ofApp::keyPressed(int key) { | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::mouseMoved(int x, int y){ | |||
void ofApp::keyReleased(int key) { | |||
if (key == 'f') //fullscreen | |||
{ | |||
ofToggleFullscreen(); | |||
} | |||
if (key == 'e') { //Mapping | |||
editingWarp = !editingWarp; | |||
warpController.getWarp(0)->setEditing(editingWarp); | |||
} | |||
//read in the single images and hand over all initial values | |||
switch (key) { | |||
case '1': | |||
imageParticleSystems.push_back(new ImageParticleSystem(sceneSize.x, sceneSize.y, fileImageHex, "PktUmweltTechnik.png")); | |||
rainIsActive = false; | |||
currentImage++; | |||
break; | |||
case '2': | |||
imageParticleSystems.push_back(new ImageParticleSystem(sceneSize.x, sceneSize.y, fileImageHex, "PktAlltagTechnikUmwelt.png")); | |||
rainIsActive = false; | |||
currentImage++; | |||
break; | |||
case '3': | |||
imageParticleSystems.push_back(new ImageParticleSystem(sceneSize.x, sceneSize.y, fileImageHex, "PktAlltagWissenschaftUmwelt.png")); | |||
rainIsActive = false; | |||
currentImage++; | |||
break; | |||
} | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::mouseMoved(int x, int y) { | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::mouseDragged(int x, int y, int button){ | |||
void ofApp::mouseDragged(int x, int y, int button) { | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::mousePressed(int x, int y, int button){ | |||
void ofApp::mousePressed(int x, int y, int button) { | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::mouseReleased(int x, int y, int button){ | |||
void ofApp::mouseReleased(int x, int y, int button) { | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::mouseEntered(int x, int y){ | |||
void ofApp::mouseEntered(int x, int y) { | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::mouseExited(int x, int y){ | |||
void ofApp::mouseExited(int x, int y) { | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::windowResized(int w, int h){ | |||
void ofApp::windowResized(int w, int h) { | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::gotMessage(ofMessage msg){ | |||
void ofApp::gotMessage(ofMessage msg) { | |||
} | |||
//-------------------------------------------------------------- | |||
void ofApp::dragEvent(ofDragInfo dragInfo){ | |||
void ofApp::dragEvent(ofDragInfo dragInfo) { | |||
} | |||
@@ -1,17 +1,25 @@ | |||
#pragma once | |||
#include "ofxWarp.h" | |||
#include "particle.h" | |||
#include "drawableImage.h" | |||
#include "imageParticleSystem.h" | |||
#include "rainParticleSystem.h" | |||
#include "ofMain.h" | |||
#include "particleSystem.h" | |||
#include "greatWhole.h" | |||
#include "avatar.h" | |||
#include "ofxOsc.h" | |||
#include "visitor.h" | |||
#include "objectPhysics.h" | |||
#include "particle.h" | |||
#include "ofxOpenCv.h" | |||
#include "ofTrueTypeFont.h" | |||
#include "ofxCv.h" | |||
//int WINDOWSIZE_WIDTH = 1000; | |||
//int WINDOWSIZE_HEIGHT = 1000; | |||
//int WINDOWSIZE_WIDTH = 1000; | |||
//int WINDOWSIZE_HEIGHT = 1000; | |||
@@ -21,62 +29,93 @@ | |||
#define PORT 12345 | |||
#define HOST "xxx.xxx.xxx.xxx" | |||
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 mouseEntered(int x, int y); | |||
void mouseExited(int x, int y); | |||
void windowResized(int w, int h); | |||
void dragEvent(ofDragInfo dragInfo); | |||
void gotMessage(ofMessage msg); | |||
int PARTICLE_COUNT; | |||
//+1 for every new Particle, -1 for every Particle that gets older than the defined maxLife | |||
int VISITOR_COUNT; | |||
//the visitor count will be fed with the nBlobs-value from incoming OSC messages | |||
int VISITOR_COUNT_LASTFRAME; | |||
class ofApp : public ofBaseApp { | |||
public: | |||
void setup(); | |||
void update(); | |||
void draw(); | |||
void exit(); | |||
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 mouseEntered(int x, int y); | |||
void mouseExited(int x, int y); | |||
void windowResized(int w, int h); | |||
void dragEvent(ofDragInfo dragInfo); | |||
void gotMessage(ofMessage msg); | |||
int PARTICLE_COUNT; | |||
//+1 for every new Particle, -1 for every Particle that gets older than the defined maxLife | |||
int VISITOR_COUNT; | |||
//the visitor count will be fed with the nBlobs-value from incoming OSC messages | |||
int VISITOR_COUNT_LASTFRAME; | |||
private: | |||
// *** OSC *** OSC *** OSC *** | |||
string oscMsg; | |||
ofxOscReceiver receiver; | |||
float timeSent, timeReceived; | |||
//Information about what is going on in the scene | |||
int nBlobs; //count of the tracked visitors | |||
vector<Visitor*> visitors; | |||
vector<ParticleSystem*> particleSystems; | |||
GreatWhole dasGrosseGanze; | |||
// *** OSC *** OSC *** OSC *** | |||
string oscMsg; | |||
ofxOscReceiver receiver; | |||
float timeSent, timeReceived; | |||
//Information about what is going on in the scene | |||
int nBlobs; //count of the tracked visitors | |||
// *** warp *** warp | |||
ofxWarpController warpController; | |||
ofTexture tex; | |||
ofRectangle area; | |||
ofVec2f sceneSize; | |||
ofVec2f force; | |||
ofImage img; | |||
ofImage fileImageHex; | |||
ofImage imageToDraw; | |||
ofImage drawImage; | |||
ofColor color; | |||
ofFbo fbo; | |||
vector<ofVec2f>attractors; | |||
vector<Particle*> system; | |||
vector<ImageParticleSystem*> imageParticleSystems; | |||
vector<RainParticleSystem*> rainParticleSyst; | |||
int currentImage; | |||
int maxParticle; | |||
int picPix; | |||
int k; | |||
int ticksToMoveParticlesToRight; | |||
int counterToMoveParticlesToRight; | |||
bool rainIsActive; | |||
bool editingWarp; | |||
vector<Visitor*> visitors; | |||
vector<ParticleSystem*> particleSystems; | |||
}; | |||
@@ -11,95 +11,259 @@ | |||
Particle::Particle() | |||
{ | |||
} | |||
} | |||
// ----------------------------------- | |||
Particle::~Particle() | |||
{ | |||
} | |||
// ----------------------------------- | |||
// ----------------------------------- | |||
void Particle::setup(ofVec2f pos, float maxAge) { | |||
this->position = pos; //Pointer to Position ofVec2f position | |||
velocity.set(0, 0); | |||
//vel.set(ofRandom(-20.0, 20.0), ofRandom(-90, -100)); //Movement direction | |||
age = 0.0; | |||
maxLife = 12.0; | |||
//maxLife = ofRandom(maxAge - 5, maxAge); //Max life of a particle | |||
color.set(5, 241, 219); | |||
//size = 2.0; | |||
//mass = 100; | |||
size = ofRandom(4.0, 0.01); | |||
mass = ofRandom(100, 250); //Changes the particle velocity | |||
valueToMoveToTop = 0; //Counter which causes the particle and the attractor to move to top | |||
valueToMoveToRight = 0; //Counter which causes the particle and the attractor to move to right | |||
ticksToMoveParticlesToRight = 70; //Framerate for movement velocity | |||
counterToMoveParticlesToRight = 0; //Counter for delay on top | |||
particleLeftScene = false; //Particle are out of ScenesizeX on the right side | |||
void Particle::setup(ofVec2f _position){ | |||
this->position = _position; | |||
velocity.set(0,0); | |||
age = 0.0; | |||
maxLife = 12.0; | |||
color.set(250,250,250); | |||
size = 2.0; | |||
mass = 100; | |||
} | |||
// ----------------------------------- | |||
void Particle::update(float deltaT){ | |||
void Particle::update(float deltaT) { | |||
} | |||
// -------------------------------------------------------------------------------- | |||
void Particle::updateParticle(double deltaT, ofVec2f attractor, bool cloudAttractorIsSet, bool imageIsOnTop, bool tornadoIsFinished, int imageHeight, int imageWidth, float sceneSizeX, float sceneSizeY) { | |||
//Movement of particle in the different settings | |||
doMovementOfParticlesAtRain(tornadoIsFinished, deltaT, sceneSizeX); | |||
if (cloudAttractorIsSet == true) { | |||
doMovementOfParticlesAtRocketEffect(sceneSizeY, imageHeight, imageWidth, sceneSizeX, attractor, deltaT); | |||
} | |||
if (tornadoIsFinished == true && cloudAttractorIsSet == false) { | |||
doMovementOfParticlesAtSymbols(deltaT, attractor); | |||
} | |||
if (imageIsOnTop == true) { | |||
doMovementOfHexagonOnTheTop(attractor, sceneSizeX, deltaT); | |||
} | |||
} | |||
//-------------------------------------------------------------- | |||
void Particle::doMovementOfParticlesAtSymbols(double deltaT, ofVec2f &attractor) | |||
{ | |||
valueToMoveToTop = 0; | |||
valueToMoveToRight = 0; | |||
counterToMoveParticlesToRight = 0; | |||
age += deltaT; | |||
vel *= 0.1; | |||
ofVec2f force = attractor - position; //Attraction | |||
if (50 < force.length() < 150) { //Movement of the particle which is located at a radius of 50 to 150 around the attractor | |||
force = 10 * force.getNormalized(); | |||
vel += force; //Movement to attractor | |||
vel = mass * vel.getNormalized(); | |||
} | |||
else if (150 < force.length() < 500) { //Movement of the particle which is located at a radius of 150 to 500 around the attractor | |||
force = 8 * force.getNormalized(); | |||
vel += force; | |||
vel = mass * vel.getNormalized(); | |||
} | |||
else { //Movement of the particle which is located at a radius more than 500 around the attractor | |||
force = 2 * force.getNormalized(); | |||
vel += force; | |||
vel = mass / 1.2* vel.getNormalized(); | |||
} | |||
position += (vel / 1.5 * deltaT); //Position = m/s * s [particle placed static] | |||
} | |||
//-------------------------------------------------------------- | |||
void Particle::doMovementOfParticlesAtRocketEffect(float sceneSizeY, int imageHeight, int imageWidth, float sceneSizeX, ofVec2f &attractor, double deltaT) | |||
{ | |||
int y = ((sceneSizeY / 2) + imageHeight); //Beginning height for attractor | |||
int x = ofRandom(sceneSizeX / 2 - imageWidth / 2, sceneSizeX / 2 + imageWidth / 2); //Width for attractor | |||
if (y - valueToMoveToTop - imageHeight > 200) { //Increase counter depending on velocity for movement to top | |||
valueToMoveToTop += 3; //Movement by 3 to top (pro Frame) | |||
} | |||
else if (y - valueToMoveToTop - imageHeight > 10) { //Increase counter depending on velocity for movement to top | |||
valueToMoveToTop += 2; //Movement by 3 to top (pro Frame) | |||
} | |||
else if (counterToMoveParticlesToRight < ticksToMoveParticlesToRight) { //Delay on top | |||
counterToMoveParticlesToRight++; | |||
} | |||
else if (y - valueToMoveToTop - imageHeight <= 10) { //Increase counter depending on velocity for movement to right( Movement by 3 to right (pro Frame)) | |||
valueToMoveToRight += 3; | |||
} | |||
attractor.set(x + valueToMoveToRight, y - valueToMoveToTop); | |||
age += deltaT; | |||
vel *= 0.1; | |||
ofVec2f force = (attractor - position); //Attraction | |||
if (30 < force.length() < 150) { //Movement of the particle which is located at a radius of 30 to 150 around the attractor | |||
force = 17 * force.getNormalized(); | |||
vel += force; //Movement to attractor | |||
vel = (mass / 1.2) * vel.getNormalized(); //Particle don't pass the symbol | |||
} | |||
else if (150 < force.length() < 250) { //Movement of the particle which is located at a radius of 150 to 250 around the attractor | |||
force = 14 * force.getNormalized(); | |||
vel += force; | |||
vel = mass * 10 * vel.getNormalized(); | |||
} | |||
else if (250 < force.length() < 500) { //Movement of the particle which is located at a radius of 250 to 500 around the attractor | |||
force = 14 * force.getNormalized(); | |||
vel += force; | |||
vel = mass * 4 * vel.getNormalized(); | |||
} | |||
else { //Movement of the particle which is located at a radius more than 500 around the attractor | |||
force = 20 * force.getNormalized(); | |||
vel += force; | |||
vel = mass * vel.getNormalized(); | |||
} | |||
position += (vel / 1.7 * deltaT); //Position = m/s * s [particle placed static] | |||
} | |||
//-------------------------------------------------------------- | |||
void Particle::doMovementOfHexagonOnTheTop(ofVec2f &attractor, float sceneSizeX, double deltaT) | |||
{ | |||
if (attractor.x + valueToMoveToRight >= sceneSizeX + 120) { | |||
particleLeftScene = true; | |||
} | |||
else { | |||
particleLeftScene = false; | |||
} | |||
age += deltaT; | |||
vel *= 0.1; | |||
ofVec2f force = attractor - position; //Attraction | |||
if (50 < force.length() < 150) { //Movement of the particle which is located at a radius of 50 to 150 around the attractor | |||
force = 60 * force.getNormalized(); //Anziehungskraft des Attraktors auf die Partikel | |||
vel += force; //Bewegung zum Attraktor | |||
vel = mass * vel.getNormalized(); | |||
} | |||
else { //Movement of the particle which is located at a radius of more than 150 around the attractor | |||
force = 100 * force.getNormalized(); | |||
vel += force; | |||
vel = mass / 2 * vel.getNormalized(); | |||
} | |||
position += (vel * deltaT); //Position = m/s * s [particle placed static] | |||
} | |||
// ----------------------------------- | |||
void Particle::draw(){ | |||
void Particle::draw() { | |||
if (position.x > 0 || position.x < 300) { | |||
ofSetColor(this->color); //To make particle turquoise | |||
color.set(getAgeNorm() * 241, 241 / getAgeNorm(), 219); //Color (Disco) | |||
} | |||
else { | |||
ofSetColor(255, 255, 255); | |||
} | |||
ofDrawCircle(position, size); | |||
} | |||
//-------------------------------------------------------------- | |||
float Particle::getAgeNorm() { | |||
return age / maxLife; | |||
} | |||
//-------------------------------------------------------------- | |||
float Particle::deleteAfterLeavingSceneY() { | |||
return position.y < 0 || position.y > ofGetHeight(); | |||
} | |||
//-------------------------------------------------------------- | |||
bool Particle::deleteAfterLeavingSceneX() { | |||
return particleLeftScene; | |||
} | |||
ofDrawCircle(position,size); | |||
//------------------------------------------------------------------ | |||
void Particle::setMode(particleMode newMode) { | |||
mode = newMode; | |||
} | |||
//----------------------------------- | |||
float Particle::getMaxLife(){ | |||
return maxLife; | |||
float Particle::getMaxLife() { | |||
return maxLife; | |||
} | |||
//----------------------------------- | |||
float Particle::getAge(){ | |||
return age; | |||
float Particle::getAge() { | |||
return age; | |||
} | |||
//----------------------------------- | |||
void Particle::mapParticle(){ | |||
/* | |||
Put an if Statement before it: | |||
if(borderCollission == true){mapParticle()} | |||
The particle will be mapped to a new position, using information about: | |||
- old position | |||
- velocity (direction) | |||
- defined borders in the projection --> globals like window size, angle between "stelen", width of stelen, etc. | |||
if the particle hits a border | |||
*/ | |||
void Particle::mapParticle() { | |||
/* | |||
Put an if Statement before it: | |||
if(borderCollission == true){mapParticle()} | |||
The particle will be mapped to a new position, using information about: | |||
- old position | |||
- velocity (direction) | |||
- defined borders in the projection --> globals like window size, angle between "stelen", width of stelen, etc. | |||
if the particle hits a border | |||
*/ | |||
} | |||
@@ -1,16 +1,17 @@ | |||
// | |||
// particle.h | |||
// | |||
// Created by Sebastian Holzki on 16.04.19. | |||
// | |||
#ifndef particle_h | |||
#define particle_h | |||
#pragma once | |||
#include <stdio.h> | |||
#include "ofMain.h" | |||
#include "ofMain.h" | |||
#include "ofxCv.h" | |||
#include "ofxXmlSettings.h" | |||
#include "ofxOpenCv.h" | |||
#include <stdio.h> | |||
enum particleMode { | |||
}; | |||
class Particle { | |||
@@ -19,19 +20,41 @@ public: | |||
Particle(); | |||
~Particle(); | |||
void setup(ofVec2f position); | |||
void update(float deltaT); | |||
void draw(); | |||
void mapParticle(); | |||
void setup(ofVec2f pos, float maxAge); | |||
void updateParticle(double deltaT, ofVec2f attractor, bool cloudAttractorIsSet, bool imageIsOnTop, bool tornadoIsFinished, int imageHeight, int imageWidth, float sceneSizeX, float sceneSizeY); | |||
void doMovementOfParticlesAtRain(bool tornadoIsFinished, double deltaT, float sceneSizeX); | |||
void doMovementOfParticlesAtSymbols(double deltaT, ofVec2f &attractor); | |||
void doMovementOfParticlesAtRocketEffect(float sceneSizeY, int imageHeight, int imageWidth, float sceneSizeX, ofVec2f &attractor, double deltaT); | |||
void doMovementOfHexagonOnTheTop(ofVec2f &attractor, float sceneSizeX, double deltaT); | |||
void setMode(particleMode newMode); | |||
float getMaxLife(); | |||
float getAge(); | |||
float getAgeNorm(); | |||
void mapParticle(); | |||
bool borderCollission(); | |||
ofVec2f vel; | |||
ofVec2f velocity2; | |||
ofVec2f force; | |||
particleMode mode; | |||
float deleteAfterLeavingSceneY(); | |||
bool deleteAfterLeavingSceneX(); | |||
bool pL; | |||
bool particleLeftScene; | |||
int valueToMoveToTop; | |||
int valueToMoveToRight; | |||
int ticksToMoveParticlesToRight; | |||
int counterToMoveParticlesToRight; | |||
private: | |||
@@ -52,3 +75,4 @@ private: | |||
//if border 1/2/3/4 (<,>,v,^), then map particle | |||
}; | |||
#endif |
@@ -41,9 +41,9 @@ private: | |||
vector<Particle*> particles; | |||
//adresses of the active emitters and attractors | |||
// vector<Attractor*> attractors; | |||
// vector<Emitter*> emitters; | |||
// adresses of the active emitters and attractors | |||
// vector<Attractor*> attractors; | |||
// vector<Emitter*> emitters; | |||
//Maybe the emitter does not have to be an own class, but is more like a Vector of Positions, so in the system.back it will setup particles for every position that is saved in this Vector | |||
//like following: |
@@ -0,0 +1,61 @@ | |||
#include "rainParticleSystem.h" | |||
RainParticleSystem::RainParticleSystem(float startSceneX, float sceneSizeX, float sceneSizeY) { | |||
this->startSceneX = startSceneX; | |||
this->sceneSizeX = sceneSizeX; | |||
this->sceneSizeY = sceneSizeY; | |||
maxParticle = 40; | |||
birthCnt = 0; | |||
parAmount = 2; | |||
tornadoStartTime = -1000; | |||
time = 0; | |||
status = -1; | |||
} | |||
//-------------------------------------------------------------- | |||
void RainParticleSystem::updateParticleSystem() { | |||
double deltaT = ofGetLastFrameTime(); | |||
time += deltaT; | |||
//---------------------------------------------------------- | |||
if ((birthCnt >= 0) && (status == -1)) { //Create the particle for the rainparticlesystems | |||
createParticlesForRain(); | |||
} | |||
//----------------------------------------------------------//Update particle (Movement) | |||
for (int p = 0; p < particles.size(); p++) { //Movement of particles from bottom to top | |||
particles.at(p)->updateParticle(deltaT, ofVec2f(ofRandom(startSceneX, startSceneX + sceneSizeX), 0), | |||
false, false, false, 0, 0, startSceneX + sceneSizeX, sceneSizeY); | |||
} | |||
} | |||
//-------------------------------------------------------------- | |||
void RainParticleSystem::createParticlesForRain() | |||
{ | |||
for (int i = 0; i < parAmount; i++) { | |||
particles.push_back(new Particle); | |||
int rgen = ofRandom(startSceneX, startSceneX + sceneSizeX); | |||
particles.back()->setup(ofVec2f(rgen, sceneSizeY), 20); | |||
} | |||
birthCnt = 0; | |||
} | |||
//-------------------------------------------------------------- | |||
void RainParticleSystem::drawRainParticleSystem() { | |||
for (int i = 0; i < particles.size(); i++) { | |||
particles.at(i)->draw(); | |||
} | |||
} | |||
@@ -0,0 +1,48 @@ | |||
#ifndef rainParticleSystem_h | |||
#define rainParticleSystem_h | |||
#pragma once | |||
#include "ofMain.h" | |||
#include "ofxCv.h" | |||
#include "ofxOpenCv.h" | |||
#include "particle.h" | |||
#include "drawableImage.h" | |||
#include <stdio.h> | |||
class RainParticleSystem | |||
{ | |||
public: | |||
RainParticleSystem(float startSceneX, float sceneSizeX, float sceneSizeY); | |||
~RainParticleSystem(); | |||
vector<ofVec2f>attractors; | |||
vector<Particle*> particles; | |||
int startSceneX; | |||
int sceneSizeX; | |||
int sceneSizeY; | |||
int maxParticle; | |||
int picPix; | |||
int k; | |||
int status; | |||
bool tornadoStarted; | |||
bool editingWarp; | |||
float birthCnt; | |||
float maxLife; | |||
float parAmount; | |||
float height; | |||
double time; | |||
double tornadoStartTime; | |||
void updateParticleSystem(); | |||
void createParticlesForRain(); | |||
void drawRainParticleSystem(); | |||
private: | |||
}; | |||
#endif | |||