#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; | |||||
} |
#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 |
// | |||||
// 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) | |||||
*/ | |||||
} | |||||
// | |||||
// 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; | |||||
}; |
#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; | |||||
} | |||||
#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 |
settings.setGLVersion(3, 2); | settings.setGLVersion(3, 2); | ||||
settings.setSize(1280, 800); | settings.setSize(1280, 800); | ||||
ofCreateWindow(settings); | ofCreateWindow(settings); | ||||
ofRunApp(new ofApp()); | ofRunApp(new ofApp()); | ||||
ofRunApp( new ofApp()); | |||||
} | } |
}; | }; | ||||
// ----------------------------------- | |||||
// ----------------------------------- | // ----------------------------------- | ||||
//-------------------------------------------------------------- | //-------------------------------------------------------------- | ||||
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 *** | // *** 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 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) { | |||||
} | } | ||||
#pragma once | #pragma once | ||||
#include "ofxWarp.h" | |||||
#include "particle.h" | |||||
#include "drawableImage.h" | |||||
#include "imageParticleSystem.h" | |||||
#include "rainParticleSystem.h" | |||||
#include "ofMain.h" | #include "ofMain.h" | ||||
#include "particleSystem.h" | #include "particleSystem.h" | ||||
#include "greatWhole.h" | |||||
#include "avatar.h" | #include "avatar.h" | ||||
#include "ofxOsc.h" | #include "ofxOsc.h" | ||||
#include "visitor.h" | #include "visitor.h" | ||||
#include "objectPhysics.h" | #include "objectPhysics.h" | ||||
#include "particle.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; | |||||
#define PORT 12345 | #define PORT 12345 | ||||
#define HOST "xxx.xxx.xxx.xxx" | #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: | 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; | |||||
}; | }; | ||||
Particle::Particle() | Particle::Particle() | ||||
{ | { | ||||
} | |||||
} | |||||
// ----------------------------------- | // ----------------------------------- | ||||
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 | |||||
*/ | |||||
} | } | ||||
// | |||||
// particle.h | |||||
// | |||||
// Created by Sebastian Holzki on 16.04.19. | |||||
// | |||||
#ifndef particle_h | |||||
#define particle_h | |||||
#pragma once | #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 { | class Particle { | ||||
Particle(); | Particle(); | ||||
~Particle(); | ~Particle(); | ||||
void setup(ofVec2f position); | |||||
void update(float deltaT); | void update(float deltaT); | ||||
void draw(); | 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 getMaxLife(); | ||||
float getAge(); | float getAge(); | ||||
float getAgeNorm(); | float getAgeNorm(); | ||||
void mapParticle(); | |||||
bool borderCollission(); | 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: | private: | ||||
//if border 1/2/3/4 (<,>,v,^), then map particle | //if border 1/2/3/4 (<,>,v,^), then map particle | ||||
}; | }; | ||||
#endif |
vector<Particle*> particles; | 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 | //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: | //like following: |
#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(); | |||||
} | |||||
} | |||||
#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 | |||||