Skip to content

Instantly share code, notes, and snippets.

@roxlu
Created February 7, 2012 22:47
Show Gist options
  • Save roxlu/1762657 to your computer and use it in GitHub Desktop.
Save roxlu/1762657 to your computer and use it in GitHub Desktop.
Supersimp water simulation
#include "testApp.h"
#define IX(i, j) (((j)*(sim_w))+(i))
//--------------------------------------------------------------
void testApp::setup(){
ofBackground(33);
ofSetFrameRate(60);
sim_w = 128;
sim_h = 128;
num_sim = sim_w * sim_h;
sim1 = new float[num_sim];
sim2 = new float[num_sim];
memset(sim1, 0, num_sim*sizeof(float));
memset(sim2, 0, num_sim*sizeof(float));
scale = 0.3;
half_size = sim_w * scale * 0.5;
cam.setup(ofGetWidth(), ofGetHeight());
cam.translate(0,0,20);
ax.setup(10);
screenshot = false;
// create quad indices
for(int j = 0; j < sim_h-1; ++j) {
for(int i = 0; i < sim_w-1; ++i) {
point a = {i,j};
indices.push_back(a);
point b = {i+1,j};
indices.push_back(b);
point c = {i+1,j+1};
indices.push_back(c);
point d = {i,j+1};
indices.push_back(d);
}
}
mode = 0;
}
void testApp::addForce(float* data, int i, int j, float f) {
data[IX(i,j)] += f;
}
void testApp::print(){
}
//--------------------------------------------------------------
void testApp::update(){
for(int i = 1; i < sim_w-1; ++i) {
for(int j = 1; j < sim_h-1; ++j) {
float sum = sim2[IX(i-1, j)] + sim2[IX(i+1, j)] +sim2[IX(i, j-1)] + sim2[IX(i,j+1)];
sim1[IX(i,j)] = (sum * 0.5) - (sim1[IX(i,j)] * 0.97);
sim1[IX(i,j)] -= sim1[IX(i,j)] * 0.04;
}
}
// swap
float* tmp = sim1;
sim1 = sim2;
sim2 = tmp;
sim = sim1;
}
//--------------------------------------------------------------
void testApp::draw(){
glEnable(GL_CULL_FACE);
ofEnableAlphaBlending();
cam.place();
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUADS);
for(int i = 0; i < indices.size(); i++) {
point& p = indices[i];
float x = p.i * scale;
float z = p.j * scale;
float y = sim[IX(p.i, p.j)];
glColor4f(0.4+y/1.3f,y/1.1,0,0.3+z/sim_w);
x -= half_size;
z -= half_size;
glVertex3f(x,y,-z);
}
glEnd();
glColor4f(1,1,1,0.5);
glBegin(GL_POINTS);
for(int j = 0; j < sim_h; ++j) {
for(int i = 0; i < sim_w; ++i) {
float x = i * scale;
float z = j * scale;
float y = sim[IX(i,j)];
x -= half_size;
z -= half_size;
// glVertex3f(x,y,-z);
}
}
glEnd();
static int shot = 0;
if(screenshot) {
++shot;
char buf[512];
sprintf(buf, "movie_%05d.png", shot);
ofSaveScreen(buf);
screenshot = false;
}
}
//--------------------------------------------------------------
void testApp::keyPressed(int key){
if(key == '1') {
addForce(sim1, sim_w*0.5,sim_h * 0.5,-30.4);
}
else if(key == '2') {
addForce(sim1, sim_w*0.2,sim_h * 0.2,-17.4);
}
else if(key == '3') {
addForce(sim1, sim_w*0.6,sim_h * 0.2,-19.4);
}
else if(key == ' ') {
screenshot = !screenshot;
}
else if(key == 'a') {
mode = 'a';
}
else if(key == 'b') {
mode = 'b';
}
}
#pragma once
#include "ofMain.h"
#include "Roxlu.h"
struct point {
int i;
int j;
};
class testApp : 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 windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
Axis ax;
EasyCam cam;
void addForce(float* data, int i, int j, float f);
void print();
float half_size;
float scale;
int sim_w;
int sim_h;
int num_sim;
float* sim1;
float* sim2;
float* sim;
bool screenshot;
int mode;
vector<point> indices;
};
@roxlu
Copy link
Author

roxlu commented Feb 7, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment