Skip to content

Instantly share code, notes, and snippets.

@micromeeeter
Last active July 23, 2017 15:09
Show Gist options
  • Save micromeeeter/3367eebce42888ef5b00aa50a9861ced to your computer and use it in GitHub Desktop.
Save micromeeeter/3367eebce42888ef5b00aa50a9861ced to your computer and use it in GitHub Desktop.
floating flock
#include "ofMain.h"
#include "ofApp.h"
//========================================================================
int main( ){
ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context
// this kicks off the running of my app
// can be OF_WINDOW or OF_FULLSCREEN
// pass in width and height too:
ofRunApp(new ofApp());
}
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){
ofBackground(0, 0, 0);
ofSetFrameRate(60);
ofEnableSmoothing();
ofEnableAlphaBlending();
// ofToggleFullscreen();
for(int i = 0; i < 200; i++){
Particle p = Particle();
particles.push_back(p);
}
//set light
dir.setDirectional();
dir.setSpecularColor(ofFloatColor(1.0, 1.0, 1.0));
dir.setAmbientColor(ofFloatColor(1.0, 1.0, 1.0));
//set gui
gui.setup();
gui.add(w1.setup("w1", 0.5, 0.0, 1.0));
gui.add(w2.setup("w2", 0.2, 0.0, 1.0));
gui.add(w3.setup("w3", 0.1, 0.0, 1.0));
gui.add(col.setup("color", ofColor(144, 182, 232), ofColor(0, 0, 0), ofColor(255, 255, 255)));
//set esa
esaInside.setResolution(4);
esaOutside.setResolution(4);
state_esa = false;
frameCount = 0;
rotate_x = 0.0;
rotate_y = 0.0;
rotate_z = 0.0;
cam.setDistance(2200);
state_log = false;
state_gui = false;
}
//--------------------------------------------------------------
void ofApp::update(){
for(int i = 0; i < particles.size(); i++){
particles[i].w1 = w1;
particles[i].w2 = w2;
particles[i].w3 = w3;
}
for(int i = 0; i < particles.size(); i++){
for(int j = 0; j < particles.size(); j++){
if ( i != j) particles[i].getOtherBoids(particles[j]);
}
particles[i].addBoidsVel();
particles[i].update();
}
//esa
if(state_esa == true){
frameCount--;
if(frameCount < 0) state_esa = false;
}
for(int i = 0; i < particles.size(); i++){
particles[i].esa = state_esa;
}
rotate_x += 0.05;
rotate_y += 0.07;
rotate_z += 0.09;
}
//--------------------------------------------------------------
void ofApp::draw(){
ofBackground(col);
ofEnableDepthTest();
ofEnableLighting();
ofEnableAlphaBlending();
dir.enable();
cam.begin();
ofRotateX(rotate_x);
ofRotateY(rotate_y);
ofRotateZ(rotate_z);
//draw all object
ofPushMatrix();
ofSetColor(255, 255, 255);
for(int i = 0; i < particles.size(); i++){
if(i == 0){
ofSetColor(40, 40, 40); //スイミー
}else{
ofSetColor(255, 98, 98); //その他の魚
}
particles[i].draw();
}
if(state_esa == true){
theta0 += 0.01;
theta1 += 0.02;
pos_esa.x = 200 * cos(theta0) * cos(theta1);
pos_esa.y = 200 * sin(theta0) * cos(theta1);
pos_esa.z = 200 * sin(theta0) * sin(theta1);
ofPushMatrix();
ofTranslate(pos_esa);
esaInside.setRadius(frameCount/4);
esaOutside.setRadius(frameCount/4+5);
ofSetColor(255, 150, 100);
esaInside.draw();
ofSetColor(255, 255, 255);
esaOutside.drawWireframe();
ofPopMatrix();
}
//水槽
ofSetColor(255, 255, 255);
ofDrawLine(550, 550, 550, -550, 550, 550);
ofDrawLine(550, 550, 550, 550, -550, 550);
ofDrawLine(550, 550, 550, 550, 550, -550);
ofDrawLine(-550, 550, 550, -550, -550, 550);
ofDrawLine(-550, 550, 550, -550, 550, -550);
ofDrawLine(550, -550, 550, -550, -550, 550);
ofDrawLine(550, -550, 550, 550, -550, -550);
ofDrawLine(550, 550, -550, -550, 550, -550);
ofDrawLine(550, 550, -550, 550, -550, -550);
ofDrawLine(-550, -550, 550, -550, -550, -550);
ofDrawLine(-550, 550, -550, -550, -550, -550);
ofDrawLine(550, -550, -550, -550, -550, -550);
//水
ofSetColor(120, 220, 255, 100);
ofDrawBox(0, 0, 0, 1050, 1050, 1050);
ofPopMatrix();
cam.end();
dir.disable();
ofDisableAlphaBlending();
ofDisableLighting();
ofDisableDepthTest();
////
if(state_gui == true){
gui.draw();
}
if(state_log == true){
ofSetColor(255, 255, 255);
ofDrawBitmapString("num: " + ofToString(particles.size()), 15, 25);
ofDrawBitmapString("frameRate: " + ofToString(ofGetFrameRate()), 15, 40);
}
//ofSaveFrame();
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
if(key == ' '){ //add fish
Particle p = Particle();
particles.push_back(p);
}
if(key == 'z'){ //delete fish
particles.pop_back();
}
if(key == 'e'){ //switch esa on
state_esa = true;
frameCount = 300;
theta0 = 0;
theta1 = 0;
}
if(key == 'f'){ //change fullscrean or not
ofToggleFullscreen();
}
if(key == 'g'){
state_gui = !state_gui;
}
if(key == 'l'){
state_log = !state_log;
}
}
#pragma once
#include "ofMain.h"
#include "Particle.hpp"
#include "ofxGui.h" //import the addon(ofxGui)
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed(int key);
vector<Particle> particles; //fish
//fish food (ja: esa)
ofSpherePrimitive esaInside, esaOutside;
ofVec3f pos_esa; //position of fish food
float theta0, theta1; //for pos_esa
bool state_esa;
int frameCount;
ofLight dir;
float rotate_x, rotate_y, rotate_z; //rotate all object
ofEasyCam cam;
bool state_log;
bool state_gui;
ofxPanel gui;
ofxFloatSlider w1, w2, w3;
ofxColorSlider col; //change background color by gui
};
//SFC17春学期「グラフィックスプログラミング」で提出した最終作品
//openFrameworksで三次元boidsを実装、魚の群れを表現
//参考: http://www.red3d.com/cwr/boids/
//import ofxGui
#include "Particle.hpp"
Particle::Particle(){
pos.x = ofRandom(-500, 500);
pos.y = ofRandom(-500, 500);
pos.z = ofRandom(-500, 500);
size = 13;
vel.x = ofRandom(-5, 5);
vel.y = ofRandom(-5, 5);
vel.z = ofRandom(-5, 5);
clear();
w1 = 1.0;
w2 = 1.0;
w3 = 1.0;
maxSpeed = 2.0;
}
void Particle::update(){
if(esa == true){
vel += (pos_esa - pos) / 31000.0;
}
if(vel.length() > maxSpeed) vel = vel.getNormalized() * maxSpeed;
pos += vel;
if(abs(pos.x) > 500) vel.x *= -1;
if(abs(pos.y) > 500) vel.y *= -1;
if(abs(pos.z) > 500) vel.z *= -1;
}
void Particle::draw(){
ofDrawSphere(pos, size);
clear();
}
void Particle::clear(){
v1.set(0, 0, 0);
v2.set(0, 0, 0);
v3.set(0, 0, 0);
count1 = 0;
count2 = 0;
count3 = 0;
}
void Particle::getOtherBoids(Particle tmp){
ofVec3f diff = tmp.pos - pos;
float dist = diff.length();
if(dist < 30){ //separation(分離)
v1 += tmp.vel;
count1++;
}
if(dist < 80){ //alignment(整列)
v2 += tmp.vel;
count2++;
}
if(dist < 40){ //cohension(結合)
v3 += tmp.vel;
count3++;
}
}
void Particle::addBoidsVel(){
if(count1 > 0){
v1 /= count1;
vel -= v1.getNormalized() * w1;
}
if(count2 > 0){
v2 /= count2;
vel += v2.getNormalized() * w2;
}if(count3 > 0){
v3 /= count3;
vel -= v3.getNormalized() * w3;
}
}
void Particle::setSize(float sz){
size = sz;
}
void Particle::setWeight(){
float sum = w1 + w2 + w3;
w1 /= sum;
w2 /= sum;
w3 /= sum;
}
#ifndef Particle_hpp
#define Particle_hpp
#include <stdio.h>
#include "ofMain.h"
class Particle {
public:
void update();
void draw();
void clear();
void getOtherBoids(Particle tmp);
void addBoidsVel();
void setSize(float sz);
Particle();
ofVec3f pos, vel;
float w1, w2, w3; //boidsの各要素の重み
bool esa;
ofVec3f pos_esa;
float size; //魚の球の半径
private:
ofVec3f v1, v2, v3;
int count1, count2, count3;
void setWeight();
float maxSpeed;
};
#endif /* Particle_hpp */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment