rem Water Matrix
rem by TheComet
rem setup screen
set display mode 1024,768,32
sync on
sync rate 60
backdrop on
hide mouse
autocam off
rem set dimensions of water matrix
xres=60
yres=60
numwaves=10
ships=10
rem setup arrays
dim wavepos(numwaves,2)
dim wavestage(numwaves)
dim g#(3,xres,yres)
rem make a mouse pointer object
make object sphere 1,15
rem make ships
for n=2 to ships+1
make object plain n,0,0
make object box n+ships,20,10,50
glue object to limb n+ships,n,0
position object n,rnd(800)+100,0,rnd(800)+100
yrotate object n,rnd(360)
color object n+ships,rgb(112,62,16)
next n
rem make water texture
create bitmap 1,20,20
for t=0 to 10000
c=rnd(128)+40
ink rgb(0,0,c),0
r=rnd(5)
circle rnd(20),rnd(20),r
next t
blur bitmap 1,1
get image 1,0,0,20,20
delete bitmap 1
rem make water matrix
make matrix 1,1000.0,1000.0,xres,yres
prepare matrix texture 1,1,1,1
fill matrix 1,0,1
rem make rock texture
create bitmap 1,80,50
for t=0 to 5
c=(t*12)+40
ink rgb(c+20,c,c),0
box t,t,79-t,49-t
next t
for t=0 to 10000
c=rnd(128)+40
ink rgb(c+20,c,c),0
r=rnd(5)
circle rnd(60)+10,rnd(30)+10,r
next t
blur bitmap 1,1
get image 2,0,0,80,50
delete bitmap 1
rem make surrounding landscape
for n=100 to 103
make object plain n,1000,100
yrotate object n,(n-100)*90
texture object n,2
scale object texture n,15,1
next n
position object 100,500,20,0
position object 101,0,20,500
position object 102,500,20,1000
position object 103,1000,20,500
rem make a light
make light 1
set point light 1,1000,800,20
color light 1,rgb(255,200,150)
rem set variables
wave=1
prev=1
current=2
future=3
sep#=1000/xres
rem main loop
position camera 500,500,-200
point camera 500,-20,500
do
rem control mouse pointer object
position mouse 320,240
xpos=xpos+mousemovex()
ypos=ypos+mousemovey()
if xpos<100 then xpos=100
if xpos>900 then xpos=900
if ypos<100 then ypos=100
if ypos>900 then ypos=900
position object 1,xpos,10,1000-ypos
xspot=xpos/sep#
yspot=ypos/sep#
yspot=yres-yspot
rem trigger a wave if user clicks
if click=-1 and mouseclick()=0 then click=0
if mouseclick()=1 and click>-1
click=1
endif
rem activate wave
if click=1
if wavestage(wave)<=0
wavepos(wave,1)=xspot
wavepos(wave,2)=yspot
wavestage(wave)=180
wave=wave+1
if wave>numwaves then wave=1
click=-1
endif
endif
rem control wave movements
for n=1 to numwaves
if wavestage(n)>0
g#(current,wavepos(n,1),wavepos(n,2))=g#(current,wavepos(n,1),wavepos(n,2))+sin(wavestage(n))*150
wavestage(n)=wavestage(n)-30
endif
next n
rem calculate waves
inc prev
inc current
inc future
if prev>3 then prev=1
if current>3 then current=1
if future>3 then future=1
for x=1 to xres-1
for y=1 to yres-1
g#(future,x,y)=(g#(current,x-1,y)+g#(current,x+1,y)+g#(current,x,y-1)+g#(current,x,y+1))/2-g#(prev,x,y)
g#(future,x,y)=g#(future,x,y)*0.98
next y
next x
rem update matrix
for x=0 to xres
for y=0 to yres
set matrix height 1,x,y,g#(future,x,y)
next y
next x
update matrix 1
rem calculate tilt for ships
for n=2 to ships+1
x#=object position x(n)
z#=object position z(n)
ay#=object angle y(n)
x1#=newxvalue(x#,wrapvalue(ay#+45),5)
x2#=newxvalue(x#,wrapvalue(ay#-45),5)
x3#=newxvalue(x#,wrapvalue(ay#+135),5)
x4#=newxvalue(x#,wrapvalue(ay#-135),5)
z1#=newzvalue(z#,wrapvalue(ay#+45),5)
z2#=newzvalue(z#,wrapvalue(ay#-45),5)
z3#=newzvalue(z#,wrapvalue(ay#+135),5)
z4#=newzvalue(z#,wrapvalue(ay#-135),5)
y1#=get ground height(1,x1#,z1#)
y2#=get ground height(1,x2#,z2#)
y1#=get ground height(1,x3#,z3#)
y2#=get ground height(1,x4#,z4#)
width#=atan((y3#-y1#)+(y4#-y2#))/3.5355339059327376220042218105242
length#=0-(atan((y2#-y1#)+(y4#-y3#))/3.5355339059327376220042218105242)
rem update ships
position object n,x#,get ground height(1,x#,z#)+5,z#
rotate object n+ships,curveangle(wrapvalue(width#),object angle x(n+ships),10),0,curveangle(wrapvalue(length#),object angle z(n+ships),10)
next n
rem refresh screen
sync
rem end of main loop
loop
rem end
end
EDIT : (There is something weird with the lighting of the matrix... Can someone fix that?)
This is using a matrix, but you can easily change it to use a subdivided plain object instead. The best way to manipulate the vertices would be to use the
vertexdata commands.
All credits for the next example go to empty. It should give you an idea on how to deform an object:
make object sphere 1,10,8,8
make object sphere 2,10,8,8
hide object 2
sync on
sync rate 10
rem get the vertex count
lock vertexdata for limb 1,0
maxvertex = get vertexdata vertex count()
unlock vertexdata
repeat
for i = 0 to maxvertex-1
lock vertexdata for limb 2,0
rem get the vertex position and add random values
x# = get vertexdata position x(i) + rnd(10) / 30.0
y# = get vertexdata position y(i) + rnd(10) / 30.0
z# = get vertexdata position z(i) + rnd(10) / 30.0
unlock vertexdata
rem lock the vertexdata for visible object
lock vertexdata for limb 1,0
rem and set the new vertex positions
set vertexdata position i, x#, y#, z#
unlock vertexdata
next i
Text 10,10,"Deforming a sphere..."
sync
until spacekey()
rem end
end
TheComet