Water simulation
Blitz3D Forums/Blitz3D Programming/Water simulation
| ||
I'm writting a smallish water simulation.. Has anyone seen any good tutorials/articles on wave harmonics? Thanks. |
| ||
Check the water tutorials of http://www.naturewizard.com The most easy way for realistic ocean waves is the Pierson-Moskowitz math model. |
| ||
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, |
| ||
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] |