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)