Water simulation

Blitz3D Forums/Blitz3D Programming/Water simulation

poopla(Posted 2003) [#1]
I'm writting a smallish water simulation.. Has anyone seen any good tutorials/articles on wave harmonics?

Thanks.


Mac M(Posted 2003) [#2]
Check the water tutorials of http://www.naturewizard.com

The most easy way for realistic ocean waves is the Pierson-Moskowitz math model.


Richard Betson(Posted 2003) [#3]
I used this code:

http://freespace.virgin.net/hugo.elias/graphics/x_water.htm

as a basis for this 3D version:

http://blitz.idigicon.com/project_detailb.asp?ProjectName=Water%20FX%20-%20Real%20Time

L8r,


TartanTangerine (was Indiepath)(Posted 2003) [#4]
here's some code I modified.

[CODE]
Const FPS=60

Include "start.bb"


light = CreateLight(2)
PositionEntity light,-100,20,100


Global faces_no# = 50

Dim buffer1#(faces_no+1,faces_no+1)
Dim buffer2#(faces_no+1,faces_no+1)

For x = 0 To faces_no
For y = 0 To faces_no
Buffer1#(x,y) = 0
Next
Next

; Load Patch
water = CreateFace(faces_no,1)
Global watersurf = GetSurface(water,1)
EntityAlpha water,1
EntityShininess water,1
ScaleEntity water,340,100,340
tex = LoadTexture ("water.tga")
EntityTexture water,tex
EntityType water,SEA_COL


; ########################## create ball ####################

Global ball,mid_ball,picked,ballx#,ballz#,seay#,movex#,boatpiv,boat2,div#,ttold,fps1#,fp2_av#
Global football, water_update = 8
Global accel# = 0, friction# = 0.99, hide=0

Dim wave#(4)
Global floater[4]

; ##################create boat

boatpiv = CreatePivot()


Global campivot = CreatePivot(boatpiv)
Global camera = CreateCamera()
CameraZoom camera,0.8
CameraRange camera,0.1,10000




PositionEntity campivot,0,10,0
PositionEntity camera,0,-5,15
ball = CreateCube(boatpiv)
ScaleMesh ball,1,1,3
EntityColor ball,255,0,0

Dim col(4)


PositionEntity boatpiv,90,0,-120
ScaleEntity boatpiv,2,2,2
For z=1 To 4
floater[z]=CreateSphere(4,boatpiv)
EntityAlpha floater[z],0.5
Next


PositionEntity camera,140,17,-140
PointEntity camera, campivot

Global direction# = -0.01

Global processnow = water_update

registerdrop(1)


period=1000/FPS
time=MilliSecs()-period


While Not KeyHit(1)
;Frame Limiting Code
Repeat
elapsed=MilliSecs()-time
Until elapsed

;how many 'frames' have elapsed
ticks=elapsed/period

;fractional remainder
tween#=Float(elapsed Mod period)/Float(period)

For k=1 To ticks
time=time+period
If k=ticks Then CaptureWorld
; Main updates here >>>>>>>>>>>>>>


If processnow <= 1 Then
ProcessWater()
processnow = water_update

Else
processnow = processnow - 1
End If
RegisterDrop()
processboat()


MoveEntity boatpiv,0,0,-accel
PointEntity camera,boatpiv
TranslateEntity camera,0,MouseZ(),0

UpdateWorld
Next

RenderWorld tween

If KeyDown(200) Then
If accel < 2 Then accel = accel + 0.01
RotateEntity ball,accel*5,0,0
Else
accel = accel * friction
End If

If KeyDown(208) Then accel = accel - 0.01
If KeyDown(203) Then TurnEntity boatpiv,0,1,0
If KeyDown(205) Then TurnEntity boatpiv,0,-1,0
If KeyHit(57) Then
water_update = water_update - 1
If water_update = 0 Then water_update = 10
End If


If KeyHit(28) Then hide = 1 - hide
If Not hide
Text 10,10,"Press Left and/or Right Mouse Button For Ripples"
Text 10,22,"Use the cursors to move your boat thingie"
Text 10,34,"(oh And don't go off the water cause the proggie will crash!)"
Text 10,48,"Use the MouseWheel to Zoom in and out"
Text 10,60,"Press the SpaceBar to cycle though update speeds"
Text 10,72,"Current Update is every "+water_update+" Renders"
Text 10,100,"Original Water Code by : Reda Borchardt"
Text 10,120,"Additional Coding and Optimised by Flynn"
Text 10,140,"Hit ENTER to hide this text and to get some real FPS!"
Text 10,160,"Frames Limted at 60FPS"
End If

Flip False
Wend
End

; process ball position
Function processBoat()


convert(ball)
seay# = buffer2#(Int(ballx),Int(ballz))




; position the floaters around the cube

cnt=1
For z=1 To -1 Step -2
For x=-1 To 1 Step 2
convert(floater[cnt])
dy# = (buffer2#(Int(ballx),Int(ballz))*70) - EntityY(floater[cnt])
PositionEntity floater[cnt],x*2,EntityY(floater[cnt]),z*2
TranslateEntity floater[cnt],0,dy# * 0.1,0
cnt=cnt+1
Next
Next


;align boat to floater
zx#=(EntityX( floater[2],True )+EntityX( floater[4],True ))/2
zx=zx-(EntityX( floater[1],True )+EntityX( floater[3],True ))/2
zy#=(EntityY( floater[2],True )+EntityY( floater[4],True ))/2
zy=zy-(EntityY( floater[1],True )+EntityY( floater[3],True ))/2
zz#=(EntityZ( floater[2],True )+EntityZ( floater[4],True ))/2
zz=zz-(EntityZ( floater[1],True )+EntityZ( floater[3],True ))/2
AlignToVector ball,zx,zy,zz,1,0.8

zx#=(EntityX( floater[1],True )+EntityX( floater[2],True ))/2
zx=zx-(EntityX( floater[3],True )+EntityX( floater[4],True ))/2
zy#=(EntityY( floater[1],True )+EntityY( floater[2],True ))/2
zy=zy-(EntityY( floater[3],True )+EntityY( floater[4],True ))/2
zz#=(EntityZ( floater[1],True )+EntityZ( floater[2],True ))/2
zz=zz-(EntityZ( floater[3],True )+EntityZ( floater[4],True ))/2
AlignToVector ball,zx,zy,zz,3,0.8

dy#=(seay# * 70)-EntityY( ball )

TranslateEntity ball,0,dy*.2,0


End Function

;convert world to array co-order
Function convert(entity)
div = 340 / faces_no
ballx = faces_no-Abs((EntityX(entity,True)-(340/2))/div)
ballz = faces_no-Abs((EntityZ(entity,True)-(340/2))/div)

End Function

; Process Water Ripples
Function ProcessWater()

Local coef# = 2.1
Local dissolve# = 1.01
Local k = 0

For x = 1 To faces_no + 1

For y = 1 To faces_no + 1

If (x < (faces_no - 1)) And (y < (faces_no - 1)) Then
Buffer2#(x,y) = (Buffer1#(x-1,y) + Buffer1#(x+1,y) + Buffer1#(x,y+1) + Buffer1#(x,y-1)) / coef-Buffer2#(x,y)
Buffer2#(x,y) = Buffer2#(x,y) / dissolve
EndIf

VertexCoords(watersurf,k,VertexX(watersurf,k),buffer2#(y-1,x-1),VertexZ(watersurf,k))

temp1# = Buffer1#(x-1,y-1)
temp2# = Buffer2#(x-1,y-1)
Buffer1#(x-1,y-1) = temp2#
Buffer2#(x-1,y-1) = temp1#

k = k + 1
Next
Next

End Function




; Register Drop
Function RegisterDrop(start=0)

If MouseHit(1) Or start = 1
For i = (faces_no - 4) To (faces_no - 3)
For j = (faces_no /2) - 5 To (faces_no/2)
buffer2#(i,j)=0.14
Next
Next
End If
If MouseHit(2) Or start = 1
For i = 1 To 3
For j = faces_no - 7 To faces_no - 3
buffer2#(i,j)=0.34
Next
Next
End If
End Function


;Creates a single sided face
;segmented
Function CreateFace(segs=1,double=False,parent=0)
mesh=CreateMesh( parent )
surf=CreateSurface( mesh )
stx#=-.5
sty#=stx
stp#=Float(1)/Float(segs)
y#=sty
For a=0 To segs
x#=stx
v#=a/Float(segs)
For b=0 To segs
u#=b/Float(segs)
AddVertex(surf,x,0,y,u,v) ; swap these for a different start orientation
x=x+stp
Next
y=y+stp
Next
For a=0 To segs-1
For b=0 To segs-1
v0=a*(segs+1)+b:v1=v0+1
v2=(a+1)*(segs+1)+b+1:v3=v2-1
AddTriangle( surf,v0,v2,v1 )
AddTriangle( surf,v0,v3,v2 )
Next
Next
UpdateNormals mesh
If double=True Then EntityFX mesh,16
Return mesh
End Function
[/CODE]