TGC Codebase Backup



water by Anonymous Coder

12th Sep 2007 14:03
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



Description

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



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    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