Code: Select all
IncludeFile "fluid.pbi"
InitSprite()
InitKeyboard()
InitMouse()
Define X.i, Y.i
Define x1.f,y1.f,x2.f,y2.f,r.f,G.f,b.f
Global mouseX.i, mouseY.i, mouseX0.i, mouseY0.i
OpenScreen(800,600,32,"fluid")
#Fluid_Width = 40 : #Fluid_Height = 30
Global XSize = 800 / #Fluid_Width, YSize = 600 / #Fluid_Height
Global HXSize = XSize / 2, HYSize = YSize / 2
;/ create fluid: 
fluid_create(#Fluid_Width,#Fluid_Height,0.1,0,0,3,#True,10)
;/ create arrays to hold the output informations: !!! size must be (width+1)x(height+1) !!!
Global Dim *densR.f(#Fluid_Width + 1,#Fluid_Height + 1): Global Dim *densG.f(#Fluid_Width + 1,#Fluid_Height + 1) : Global Dim *densB.f(#Fluid_Width + 1,#Fluid_Height + 1)
Global Dim *velH.f(#Fluid_Width + 1,#Fluid_Height + 1) : Global Dim *velV.f(#Fluid_Width + 1,#Fluid_Height + 1)
Macro myMax(c)
  If c > 255
    c=255
  EndIf
EndMacro
Procedure input_stuff()
  
  Protected X.i,Y.i
  
  mouseX = MouseX() : mouseY = MouseY()
  
  *densR() = fluid_density_input(1)
  *densG() = fluid_density_input(2)
  *densB() = fluid_density_input(3)
  
  *velH() = fluid_velocity(#fluid_horizontal)
  *velV() = fluid_velocity(#fluid_vertical)
  
  X = mouseX * #Fluid_Width / 800 + 1
  Y = mouseY * #Fluid_Height / 600 + 1
  
  If KeyboardPushed(#PB_Key_1)
    *densR(X,Y) = 5000
  EndIf
  If KeyboardPushed(#PB_Key_2)
    *densG(X,Y) = 5000
  EndIf
  If KeyboardPushed(#PB_Key_3)
    *densB(X,Y) = 5000
  EndIf
  If KeyboardPushed(#PB_Key_4)
    fluid_wall_create(X,Y,2,2)
    fluid_wall_purge()
  EndIf
  If MouseButton(1)
    *velH(X-1,Y-1) = (mouseX-mouseX0)/2
    *velV(X-1,Y-1) = (mouseY-mouseY0)/2
    
    *densR(X-1,Y-1) = 5000
    If Random(1)
      *densG(X-1,Y-1) = 2500
    EndIf
  EndIf
  If MouseButton(2)
    *velH(X,Y) = (mouseX-mouseX0)/2
    *velV(X,Y) = (mouseY-mouseY0)/2
    *densB(X,Y) = 0
    *densR(X,Y) = 0
    *densG(X,Y) = 0
  EndIf
  If KeyboardReleased(#PB_Key_5)
    fluid_density_reset()
    fluid_wall_clear()
    For X = 1 To #Fluid_Width
      For Y = 1 To #Fluid_Height 
        *densR(X,Y) = 100
        *densG(X,Y) = 100
        *densB(X,Y) = 100
      Next
    Next
    
  EndIf
  If KeyboardReleased(#PB_Key_Up)
    fluid_emitter_velocity(X,Y,1,0,-1)
  EndIf
  If KeyboardReleased(#PB_Key_Down)
    fluid_emitter_velocity(X,Y,1,0,1)
  EndIf
  If KeyboardReleased(#PB_Key_Left)
    fluid_emitter_velocity(X,Y,1,-1,0)
  EndIf
  If KeyboardReleased(#PB_Key_Right)
    fluid_emitter_velocity(X,Y,1,1,0)
  EndIf
  
  mouseX0 = mouseX : mouseY0 = mouseY
  
EndProcedure
Repeat
  
  ExamineKeyboard()
  ExamineMouse()
  
  ;/ take out some density, otherwise it will get very full
  fluid_density_reset(1.000001)
  input_stuff()
  
  ;/ calculate the next density step. All emitters will be used automatically here.
  fluid_calc()
    ;/ Read out the density layers / velocity directions to draw some output
    *densR() = fluid_density(1)
    *densG() = fluid_density(2)
    *densB() = fluid_density(3)
    
    *velH() = fluid_velocity(#fluid_horizontal)
    *velV() = fluid_velocity(#fluid_vertical)
    
    CreateImage(1,#Fluid_Width,#Fluid_Height)
    StartDrawing(ImageOutput(1))
    
      For X=0 To #Fluid_Width-1
        For Y=0 To #Fluid_Height-1
        ; draw the density as boxes
        r  = *densR(X,Y) : G  =  *densG(X,Y) : b  =  *densB(X,Y)
        myMax(r) : myMax(G) : myMax(b) ;cut to high values
        
        ; check if wall
        If fluid_iswall(X,Y)
          Plot(X,Y,$FFFFFF)
        Else
          Plot(X,Y,RGB(r,G,b))
        EndIf
      Next
    Next
    StopDrawing()
    ResizeImage(1,800,600,1)
    
    StartDrawing(ScreenOutput())
      DrawImage(ImageID(1),0,0)
      For X = 1 To #Fluid_Width
        For Y = 1 To #Fluid_Height
          ; draw some velocity Vectors into the center of every box. We multiply them by a factor to get good visuals
          x1 = (X-1)*XSize + HXSize  : y1 = (Y-1)*YSize + HYSize
          x2 = x1+*velH(X,Y)*20 : y2 = y1+*velV(X,Y)*20
          LineXY(x1,y1,x2,y2,$FF3F3F)
        Next
      Next
      DrawingMode(#PB_2DDrawing_Transparent )
      DrawText(0,0,"Press following buttons: ",$FFFFFF,$0)
      DrawText(0,20,"1-3: add R/G/B density",$FFFFFF,$0)
      DrawText(0,40,"4: add wall",$FFFFFF,$0)
      DrawText(0,60,"5: clear",$FFFFFF,$0)
      DrawText(0,80,"arrow keys: Add velocity emitter in this direction",$FFFFFF,$0)
      DrawText(0,100,"L-Mouse: hold and move to 'create' velocity",$FFFFFF,$0)
      DrawText(0,120,"Disable Debugger!",$0000FF,$0)
      DrawingMode(#PB_2DDrawing_Default)
      Box(mouseX-1,mouseY-1,3,3,RGB(255,255,255))
    StopDrawing()
    FreeImage(1)
    
  FlipBuffers()
  
Until KeyboardPushed(#PB_Key_Escape)