CodeBase - water
Return to the CodeBase listing
Category: Complete Applications
Version: 1.0
Information
Uploaded: 12th Sep 2007 14:03
Modified: 1st Jan 1970 01:00
Author: Anonymous Coder
Summary
rem Basic water tank simulation (REALLY basic!) set display mode 1024,768,32 sync on:sync rate 30 autocam off rem generate a plain texture cls rgb(32,192,255) get image 3,0,0,32,32 rem A few particles nbpart=192 dim partX#(nbpart):dim partY#(nbpart):dim partZ#(nbpart) dim partXd#(nbpart):dim partYd#(nbpart):dim partZd#(nbpart) dim partXTarget#(nbpart):dim partYTarget#(nbpart):dim partZTarget#(nbpart):dim partStatus#(nbpart) for i=0 to 8 load image "splash0"+str$(i+1)+".bmp",500+i next i rem Size of the water matrix matrixSizeX#=120:matrixSizeZ#=90 nsquarex=32:nsquarez=24 tileSizeX#=matrixSizeX#/nsquarex:tileSizeZ#=matrixSizeZ#/nsquarez rem A sine table, to speed up calculations dim sineTable#(360) for i=0 to 359 sineTable#(i)=sin(i) next i rem Create the tank, and texture it with a caustics texture make object box 2,matrixSizeX#,matrixSizeZ#/2,matrixSizeZ# scale object 2,-100,-100,-100 position object 2,0,(matrixSizeZ#/-4),0 load image "caustics.bmp",2:texture object 2,2 rem These variables are used for the movement of the caustics scru#=0.001:scrud#=-0.00001 scrv#=-0.0005:scrvd#=0.000005 rem Create the water matrix make matrix 1,matrixSizeX#,matrixSizeZ#,nsquarex,nsquarez position matrix 1,matrixSizeX#/-2,0,matrixSizeZ#/-2 dim waves(nsquarex,nsquarez) for i=0 to nsquarex for j=0 to nsquarez waves(i,j)=(rnd(72))*5 next j next i rem The wave height is set according to the size of the water matrix wave_height#=matrixSizeX#/60.00 rem Texture the water matrix load image "water.bmp",1 prepare matrix texture 1,1,nsquarex,nsquarez n=0 for j=nsquarez-1 to 0 step -1 for i=0 to nsquarex-1 step 1 inc n set matrix tile 1,i,j,n next i next j ghost matrix on 1 rem Camera initialization camdist#=matrixSizeZ#:bearing#=90:azimuth#=300:camchanged=1 rem Main loop do rem recalculate the height of each vertex of the matrix in a wavy way for i=0 to nsquarex for j=0 to nsquarez set matrix height 1,i,j,sineTable#(waves(i,j))*wave_height# waves(i,j)=waves(i,j)+5 if waves(i,j)>359 then waves(i,j)=0 next j next i rem Smooth matrix normals. Not very useful; just to see how to do it. SmoothMatrixNormals(1,nsquarex,nsquarez,tileSizeX#,tileSizeZ#) rem Change matrix aspect select scancode() case 2 prepare matrix texture 1,1,nsquarex,nsquarez n=0 for j=nsquarez-1 to 0 step -1 for i=0 to nsquarex-1 step 1 inc n set matrix tile 1,i,j,n next i next j ghost matrix on 1 endcase case 3 prepare matrix texture 1,3,nsquarex,nsquarez ghost matrix off 1 endcase case 4 prepare matrix texture 1,3,nsquarex,nsquarez set matrix wireframe on 1 endcase endselect rem Update matrix update matrix 1 rem Scroll the caustics texture scru#=scru#+scrud#:if (scru#<=-0.001 and scrud#<0) or (scru#>=0.001 and scrud#>0) then scrud#=scrud#*-1 scrv#=scrv#+scrvd#:if (scrv#<=-0.001 and scrvd#<0) or (scrv#>=0.001 and scrvd#>0) then scrvd#=scrvd#*-1 scroll object texture 2,scru#,scrv# rem Create some "splashes" here and there if ecla<2 and timer()-oldtimer>1000 x#=(matrixSizeX#/2.00)-rnd(matrixSizeX#):y#=0:z#=(matrixSizeZ#/2.00)-rnd(matrixSizeZ#) oldtimer=timer() for i=ecla*20 to (ecla*20)+19 if object exist(500+i) = 0 make object plain 500+i,2,2 texture object 500+i,500+rnd(8):ghost object on 500+i else show object 500+i endif partX#(i)=x#:partY#(i)=y#:partZ#(i)=z# partXd#(i)=((matrixSizeX#/10.00)-rnd(matrixSizeX#/5.00))/20.00 partZd#(i)=((matrixSizeZ#/10.00)-rnd(matrixSizeZ#/5.00))/20.00 partYd#(i)=(rnd(matrixSizeZ#/3.00)/15.00) partYtarget#(i)=partY#(i):partStatus#(i)=ecla+1 next i endif rem Animate those "splashes" ecla=0 for i=0 to 192 if partStatus#(i)>0 if partStatus#(i)>ecla then ecla=partStatus#(i) partX#(i)=partX#(i)+partXd#(i) partY#(i)=partY#(i)+partYd#(i) partZ#(i)=partZ#(i)+partZd#(i) partYd#(i)=partYd#(i)-(matrixSizeZ#/1000.00) position object 500+i,partX#(i),partY#(i),partZ#(i) set object to camera orientation 500+i if partY#(i) < partYtarget#(i) then hide object 500+i:partStatus#(i)=0 endif next i rem Move and zoom the camera with mouse movex=mousemovex():movey=mousemovey() if movex<>0 or movey<>0 azimuth# = azimuth# + movey bearing# = wrapvalue(bearing# + movex/2) if azimuth#<280 then azimuth#=280 if azimuth#>350 then azimuth#=350 camchanged = 1 endif click=mouseclick() if click>0 if click=1 and camdist#>matrixSizeZ#/2.00 then dec camdist#:camchanged = 1 if click=2 and camdist#<matrixSizeZ#*2.00 then inc camdist#:camchanged = 1 endif rem If the camera moved, recalculate its position if camchanged=1 camx# = camdist# * sin(azimuth#) * cos(bearing#) camz# = camdist# * sin(azimuth#) * sin(bearing#) camy# = camdist# * cos(azimuth#) position camera camx#,camy#,camz# point camera 0,0,0 camchanged = 0 endif rem And that's it ! text 10,10,str$( screen fps() )+" FPS; Hit 1,2,or 3 to switch modes" sync loop rem Use matrix normals to make it smooth (from the DarkBasic help: "help\examples\matrix3d\exam08.dba") function SmoothMatrixNormals(numMatrix,sizeX,sizeZ,tileSizeX#,tileSizeZ#) for z=1 to sizeZ-1 for x=1 to sizeX-1 rem Get matrix heights h8#=get matrix height(numMatrix,x,z-1) h4#=get matrix height(numMatrix,x-1,z) h#=get matrix height(numMatrix,x,z) h2#=get matrix height(numMatrix,x,z) rem Calculate projected angle X using heights x1#=(x-1)*tileSizeX# : y1#=h# x2#=(x+0)*tileSizeX# : y2#=h4# dx#=x2#-x1# dy#=y2#-y1# ax#=atanfull(dx#,dy#) ax#=wrapvalue(90-ax#) rem Calculate projected angle Z using heights z1#=(z-1)*tileSizeZ# : y1#=h2# z2#=(z+0)*tileSizeZ# : y2#=h8# dz#=z2#-z1# dy#=y2#-y1# az#=atanfull(dz#,dy#) az#=wrapvalue(90-az#) rem Make normal from projected angle nx#=sin(ax#) ny#=cos(ax#) nz#=sin(az#) rem Setting matrix normal for smoothness set matrix normal numMatrix,x,z,nx#,ny#,nz# next x next z endfunction
Full Description
rem Basic water tank simulation (REALLY basic!)<br /> <br /> set display mode 1024,768,32<br /> sync on:sync rate 30<br /> autocam off<br /> <br /> rem generate a plain texture<br /> cls rgb(32,192,255)<br /> get image 3,0,0,32,32<br /> <br /> rem A few particles<br /> nbpart=192<br /> dim partX#(nbpart):dim partY#(nbpart):dim partZ#(nbpart)<br /> dim partXd#(nbpart):dim partYd#(nbpart):dim partZd#(nbpart)<br /> dim partXTarget#(nbpart):dim partYTarget#(nbpart):dim partZTarget#(nbpart):dim partStatus#(nbpart)<br /> for i=0 to 8<br /> load image "splash0"+str$(i+1)+".bmp",500+i<br /> next i<br /> <br /> rem Size of the water matrix<br /> matrixSizeX#=120:matrixSizeZ#=90<br /> nsquarex=32:nsquarez=24<br /> tileSizeX#=matrixSizeX#/nsquarex:tileSizeZ#=matrixSizeZ#/nsquarez<br /> <br /> rem A sine table, to speed up calculations<br /> dim sineTable#(360)<br /> for i=0 to 359<br /> sineTable#(i)=sin(i)<br /> next i<br /> <br /> rem Create the tank, and texture it with a caustics texture<br /> make object box 2,matrixSizeX#,matrixSizeZ#/2,matrixSizeZ#<br /> scale object 2,-100,-100,-100<br /> position object 2,0,(matrixSizeZ#/-4),0<br /> load image "caustics.bmp",2:texture object 2,2<br /> rem These variables are used for the movement of the caustics<br /> scru#=0.001:scrud#=-0.00001<br /> scrv#=-0.0005:scrvd#=0.000005<br /> <br /> rem Create the water matrix<br /> make matrix 1,matrixSizeX#,matrixSizeZ#,nsquarex,nsquarez<br /> position matrix 1,matrixSizeX#/-2,0,matrixSizeZ#/-2<br /> dim waves(nsquarex,nsquarez)<br /> for i=0 to nsquarex<br /> for j=0 to nsquarez<br /> waves(i,j)=(rnd(72))*5<br /> next j<br /> next i<br /> rem The wave height is set according to the size of the water matrix<br /> wave_height#=matrixSizeX#/60.00<br /> <br /> rem Texture the water matrix<br /> load image "water.bmp",1<br /> prepare matrix texture 1,1,nsquarex,nsquarez<br /> n=0<br /> for j=nsquarez-1 to 0 step -1<br /> for i=0 to nsquarex-1 step 1<br /> inc n<br /> set matrix tile 1,i,j,n<br /> next i<br /> next j<br /> ghost matrix on 1<br /> <br /> rem Camera initialization<br /> camdist#=matrixSizeZ#:bearing#=90:azimuth#=300:camchanged=1<br /> <br /> rem Main loop<br /> do<br /> rem recalculate the height of each vertex of the matrix in a wavy way<br /> for i=0 to nsquarex<br /> for j=0 to nsquarez<br /> set matrix height 1,i,j,sineTable#(waves(i,j))*wave_height#<br /> waves(i,j)=waves(i,j)+5<br /> if waves(i,j)>359 then waves(i,j)=0<br /> next j<br /> next i<br /> rem Smooth matrix normals. Not very useful; just to see how to do it.<br /> SmoothMatrixNormals(1,nsquarex,nsquarez,tileSizeX#,tileSizeZ#)<br /> <br /> rem Change matrix aspect<br /> select scancode()<br /> case 2<br /> prepare matrix texture 1,1,nsquarex,nsquarez<br /> n=0<br /> for j=nsquarez-1 to 0 step -1<br /> for i=0 to nsquarex-1 step 1<br /> inc n<br /> set matrix tile 1,i,j,n<br /> next i<br /> next j<br /> ghost matrix on 1<br /> endcase<br /> case 3<br /> prepare matrix texture 1,3,nsquarex,nsquarez<br /> ghost matrix off 1<br /> endcase<br /> case 4<br /> prepare matrix texture 1,3,nsquarex,nsquarez<br /> set matrix wireframe on 1<br /> endcase<br /> endselect<br /> <br /> rem Update matrix<br /> update matrix 1<br /> <br /> rem Scroll the caustics texture<br /> scru#=scru#+scrud#:if (scru#<=-0.001 and scrud#<0) or (scru#>=0.001 and scrud#>0) then scrud#=scrud#*-1<br /> scrv#=scrv#+scrvd#:if (scrv#<=-0.001 and scrvd#<0) or (scrv#>=0.001 and scrvd#>0) then scrvd#=scrvd#*-1<br /> scroll object texture 2,scru#,scrv#<br /> <br /> rem Create some "splashes" here and there<br /> if ecla<2 and timer()-oldtimer>1000<br /> x#=(matrixSizeX#/2.00)-rnd(matrixSizeX#):y#=0:z#=(matrixSizeZ#/2.00)-rnd(matrixSizeZ#)<br /> oldtimer=timer()<br /> for i=ecla*20 to (ecla*20)+19<br /> if object exist(500+i) = 0<br /> make object plain 500+i,2,2<br /> texture object 500+i,500+rnd(8):ghost object on 500+i<br /> else<br /> show object 500+i<br /> endif<br /> partX#(i)=x#:partY#(i)=y#:partZ#(i)=z#<br /> partXd#(i)=((matrixSizeX#/10.00)-rnd(matrixSizeX#/5.00))/20.00<br /> partZd#(i)=((matrixSizeZ#/10.00)-rnd(matrixSizeZ#/5.00))/20.00<br /> partYd#(i)=(rnd(matrixSizeZ#/3.00)/15.00)<br /> partYtarget#(i)=partY#(i):partStatus#(i)=ecla+1<br /> next i<br /> endif<br /> <br /> rem Animate those "splashes"<br /> ecla=0<br /> for i=0 to 192<br /> if partStatus#(i)>0<br /> if partStatus#(i)>ecla then ecla=partStatus#(i)<br /> partX#(i)=partX#(i)+partXd#(i)<br /> partY#(i)=partY#(i)+partYd#(i)<br /> partZ#(i)=partZ#(i)+partZd#(i)<br /> partYd#(i)=partYd#(i)-(matrixSizeZ#/1000.00)<br /> position object 500+i,partX#(i),partY#(i),partZ#(i)<br /> set object to camera orientation 500+i<br /> if partY#(i) < partYtarget#(i) then hide object 500+i:partStatus#(i)=0<br /> endif<br /> next i<br /> <br /> rem Move and zoom the camera with mouse<br /> movex=mousemovex():movey=mousemovey()<br /> if movex<>0 or movey<>0<br /> azimuth# = azimuth# + movey<br /> bearing# = wrapvalue(bearing# + movex/2)<br /> if azimuth#<280 then azimuth#=280<br /> if azimuth#>350 then azimuth#=350<br /> camchanged = 1<br /> endif<br /> click=mouseclick()<br /> if click>0<br /> if click=1 and camdist#>matrixSizeZ#/2.00 then dec camdist#:camchanged = 1<br /> if click=2 and camdist#<matrixSizeZ#*2.00 then inc camdist#:camchanged = 1<br /> endif<br /> <br /> rem If the camera moved, recalculate its position<br /> if camchanged=1<br /> camx# = camdist# * sin(azimuth#) * cos(bearing#)<br /> camz# = camdist# * sin(azimuth#) * sin(bearing#)<br /> camy# = camdist# * cos(azimuth#)<br /> position camera camx#,camy#,camz#<br /> point camera 0,0,0<br /> camchanged = 0<br /> endif<br /> <br /> rem And that's it !<br /> text 10,10,str$( screen fps() )+" FPS; Hit 1,2,or 3 to switch modes"<br /> sync<br /> loop<br /> <br /> rem Use matrix normals to make it smooth (from the DarkBasic help: "help\examples\matrix3d\exam08.dba")<br /> function SmoothMatrixNormals(numMatrix,sizeX,sizeZ,tileSizeX#,tileSizeZ#)<br /> for z=1 to sizeZ-1<br /> for x=1 to sizeX-1<br /> <br /> rem Get matrix heights<br /> h8#=get matrix height(numMatrix,x,z-1)<br /> h4#=get matrix height(numMatrix,x-1,z)<br /> h#=get matrix height(numMatrix,x,z)<br /> h2#=get matrix height(numMatrix,x,z)<br /> <br /> rem Calculate projected angle X using heights<br /> x1#=(x-1)*tileSizeX# : y1#=h#<br /> x2#=(x+0)*tileSizeX# : y2#=h4#<br /> dx#=x2#-x1#<br /> dy#=y2#-y1#<br /> ax#=atanfull(dx#,dy#)<br /> ax#=wrapvalue(90-ax#)<br /> <br /> rem Calculate projected angle Z using heights<br /> z1#=(z-1)*tileSizeZ# : y1#=h2#<br /> z2#=(z+0)*tileSizeZ# : y2#=h8#<br /> dz#=z2#-z1#<br /> dy#=y2#-y1#<br /> az#=atanfull(dz#,dy#)<br /> az#=wrapvalue(90-az#)<br /> <br /> rem Make normal from projected angle<br /> nx#=sin(ax#)<br /> ny#=cos(ax#)<br /> nz#=sin(az#)<br /> <br /> rem Setting matrix normal for smoothness<br /> set matrix normal numMatrix,x,z,nx#,ny#,nz#<br /> <br /> next x<br /> next z<br /> endfunction
Comments
No comments yet.