andrewowaun 
		
		Full Member
		 
		Offline 
		
		
		Posts: 202
		Barbados
		
		
		
 
	 
	
		
			
				Re: 2d water simulation with refraction  
				Reply #6 -  Dec 13th , 2009, 7:35pm 
			 
			
				
	  
			 
		
		
			This is an awesome piece of code. I applied an algorithmic background. float[] temp; int tankX = 401; int tankY = 401; int tankSize = tankX*tankY; float tankScale = 1; float damping = 0.99; int dropSize=20;//10 float lightIntensity=0.6;//0.2 PImage water; public boolean rise = false; float[] waveBuffer1 = new float[tankSize]; float[] waveBuffer2 = new float[tankSize]; int[] wallMap = new int[tankSize]; PImage bbg; import processing.opengl.*; void setup() {  frameRate(100);  size(round(tankScale*tankX),round(tankScale*tankY),OPENGL);   makebg(false,false);  background(1);  noStroke();  smooth();  colorMode(HSB,1,1,1,1);  water=createImage(width,height,ARGB);    PFont font1 = createFont("arial",12);  textFont(font1, 12); } void draw(){  background(0);  processWater();  image(water,0,0);  fill(1);  text("fps: "+frameRate,10,20); } void processWater(){  float[] dispMap = new float[tankSize];  for(int y=1; y<tankY-1; y++)  for(int x=1; x<tankX-1; x++){    int i=y*tankX+x;    float sumX=waveBuffer2[i-1]+waveBuffer2[i+1];    float sumY=waveBuffer2[i-tankX]+waveBuffer2[i+tankX];    waveBuffer1[i] = ((sumX+sumY)/2) - waveBuffer1[i]*1;    waveBuffer1[i] *= damping*(1-wallMap[i]);        //calc displacement map    sumX=-waveBuffer2[i-1]+waveBuffer2[i+1];    sumY=-waveBuffer2[i-tankX]+waveBuffer2[i+tankX];    int dispX=x-round(sumX*1);    int dispY=y-round(sumY*1);    if(dispX>1 && dispX<tankX-1 && dispY>1 && dispY<tankY-1){      dispMap[dispY*tankX+dispX]+=lightIntensity;    }  }    //draw refractions  water.loadPixels();  for(int y=1; y<tankY-1; y++)  for(int x=1; x<tankX-1; x++){    //water.pixels[y*tankX+x]=color(dispMap[y*tankX+x]/10);    water.pixels[y*tankX+x]=blendColor(color(dispMap[y*tankX+x]/10),bbg.pixels[x+width*y],DIFFERENCE);        color ff= blendColor(color(dispMap[y*tankX+x]/10),bbg.pixels[x+width*y],DIFFERENCE);    //water.pixels[y*tankX+x]=bbg.pixels[x+width*y];    if(wallMap[y*tankX+x] ==1  || wallMap[y*tankX+x] == bbg.pixels[(mouseY)*width+(mouseX)])    {         //   water.pixels[y*tankX+x]=color(0.2);    //     water.pixels[y*tankX+x]=color(bbg.pixels[x+width*y+1]);      color cp = color(bbg.pixels[x+width*y]);      float rr = red(ff);      float gg = green (ff);      float bb = blue (ff);      color po = color (rr,gg,bb);           water.pixels[y*tankX+x]=blendColor(color (rr,gg,bb),cp,DIFFERENCE);          }  }     //swap buffers  temp=waveBuffer1;  waveBuffer1=waveBuffer2;  waveBuffer2=temp;    water.updatePixels(); } void mouseDragged(){   if (mouseButton==37){ //LEFT  if(mouseX>dropSize/2 && mouseX<tankX-dropSize/2 && mouseY>dropSize/2 && mouseY<tankY-dropSize/2)  for(int y=-dropSize/2;y<=dropSize/2;y++)  for(int x=-dropSize/2;x<=dropSize/2;x++){ wallMap[(mouseY+y)*width+(mouseX+x)]= 1;  }     }   if (rise){    if (mouseButton==39){ //RIGHT  if(mouseX>dropSize/2 && mouseX<tankX-dropSize/2 && mouseY>dropSize/2 && mouseY<tankY-dropSize/2)  for(int y=-dropSize/2;y<=dropSize/2;y++)  for(int x=-dropSize/2;x<=dropSize/2;x++)  wallMap[(mouseY+y)*width+(mouseX+x)]=bbg.pixels[(mouseY+y)*width+(mouseX+x)];               }   }  // println(mouseButton); } void keyPressed(){  if(key==' '){ //32 == SPACE    if(mouseX>dropSize/2 && mouseX<tankX-dropSize/2 && mouseY>dropSize/2 && mouseY<tankY-dropSize/2)    for(int y=-dropSize/2;y<=dropSize/2;y++)    for(int x=-dropSize/2;x<=dropSize/2;x++)    waveBuffer1[(mouseY+y)*width+(mouseX+x)]=color(100);//100  }    if (key =='r'){   rise =!rise;   } } int cpass=0; void makebg(Boolean animate, Boolean invert){  bbg = new PImage(width,height);   loadPixels();   color colx = 0; for(int y=0;y<height;y++){     for(int x=0;x<width;x++){         int pos=y*width+x;         color col = pixels[pos] ;//          colx = color(height-y,x,y-x);          if (animate){          //colx = color(height-y,X,cpass+y);           colx = color(height-y,x,cpass-X);          }                  float rr= red(colx);         float bb= blue(colx);         float gg= green(colx);                    rr = colx >> 16 & 0xff;         gg = colx >> 8 & 0xff;         bb = colx  & 0xff;   if (!invert)      bbg.pixels[pos]=color(rr,gg,bb);     if (invert)      bbg.pixels[pos]=-color(rr,gg,bb);     }     if (!online){      arraycopy(bbg.pixels,pixels);      }   }   if (animate){     cpass++;    } if (cpass>4000){   cpass=0;   }  }