I have it working now. Here is some sample code if anyone is interested. You can change the wavelength, frequency and amplitude with some keys. I think they are the right terms.
`setup
sync on
sync rate 60
autocam off
global OceanObj = 1
global MeshObj = 2
global MeshSize# = 1600.0
global X_Tiles = 16
global Z_Tiles = 16
global X_Limbs = 4
global Z_Limbs = 4
global LimbCount = 0
global wavelength# = 10.0
global amplitude# = 250.0
global frequency# = 1.0
global new_height# = 0.0
global last_height# = 0.0
global start_height# = 0.0
global new_start# = 135.0
global start_wave = 0
position camera 0,2000,0
point camera -6000, 200, -4800
set camera range 1, 50000
` object to use as limbs
make_geo_grid(MeshObj,MeshSize#,MeshSize#,X_Tiles,Z_Tiles,rgb(128,128,128))
make mesh from object MeshObj, MeshObj
delete object MeshObj
` base object for mesh
make object plain OceanObj, 0, 0
LimbNum = 1
` add limbs for each x and z
For Z = 1 to Z_Limbs
For X = 1 to X_Limbs
` add mesh as limb
xx# = MeshSize#*X
zz# = MeshSize#*Z
add limb OceanObj, LimbNum, MeshObj
offset limb OceanObj, LimbNum, xx#, 0, zz#
inc LimbNum, 1
Next X
Next Z
LimbCount = LimbNum - 1
set object wireframe OceanObj, 1
set object cull OceanObj, 1
` position centre of object at 0,0,0
position object OceanObj, MeshSize#+MeshSize#*X_Limbs/2, 0, MeshSize#+MeshSize#*Z_Limbs/2
set text font "arial"
set text size 12
do
rotate camera camera angle x(0)+(mousemovey()/2.0),camera angle y(0)+(mousemovex()/2.0),0
if upkey() = 1 then move camera 10
if downkey() = 1 then move camera -10
text 10,10, "a/z to change Wavelength, s/x to change Frequency, d/c to change Amplitude"
make_wave()
if scancode()=30 then inc wavelength#, 0.5
if scancode()=44 then dec wavelength#, 0.5
if scancode()=31 then inc frequency#, 0.5
if scancode()=45 then dec frequency#, 0.5
if scancode()=32 then inc amplitude#, 10.0
if scancode()=46 then dec amplitude#, 10.0
text 10, 20, "Wavelength = " + str$(Int((1/wavelength#)*250.0)) + " Frequency = " + str$(Int(frequency#)) + " Amplitude = " + str$(Int(amplitude#))
sync
loop
function make_wave()
VertNum = 0
NumVerts = X_Tiles + 1
dec start_height#, frequency#
if start_height# <= -amplitude# then start_height# = -amplitude# + 360.0
` do all limbs except the last row. Last row needs to have a breaking wave
for LimbNum = 1 to LimbCount
lock vertexdata for limb OceanObj,LimbNum,1
` for each grid
for a = 1 to NumVerts
` check if on first row of limbs and first row of the grid
if LimbNum <= X_Limbs and a = 1
new_height# = start_height#
endif
if LimbNum > X_Limbs and a = 1
new_height# = last_height#
endif
` if last vertex row of last grid in row, remember height for next row
if a = NumVerts
` check for last limb in each row
for L = 1 to Z_Limbs - 1
if (LimbNum = X_Limbs * L)
last_height# = new_height#
endif
next L
endif
` sin wave
height# = sin(new_height#) * amplitude#
` increment for next height#
inc new_height#, wavelength#
new_height# = wrapvalue(new_height#)
` for each row
for b = 1 to NumVerts
x# = get vertexdata position x(VertNum)
z# = get vertexdata position z(VertNum)
` if middle row of vertices, of last row of limbs, and wave height is maximum, start wave
`if (LimbNum > LimbCount - X_Limbs) and (a >= Z_Tiles/2) and (height# = amplitude#) then start_wave = 1
` change z values if start_wave = 1
`if start_wave = 1 then z# = get vertexdata position z(VertNum)-(a-Z_Tiles/2)
`if b = NumVerts then start_wave = 0
set vertexdata position VertNum, x#, height#, z#
` last row, stop wave
inc VertNum, 1
next b
next a
unlock vertexdata
VertNum = 0
next LimbNum
endfunction
` This code was downloaded from The Game Creators
` It is reproduced here with full permission
` http://www.thegamecreators.com
function make_geo_grid(id as integer, x_width# as float, z_height# as float, x_cols as integer, z_rows as integer,clr as dword)
rem This code created by Visigoth, aka Mike Shihrer
rem You may use this, modify it,etc, but give credit where credit is due.
rem limit size to 20k polys maximum
If x_cols > 100
x_cols = 100
endif
If z_rows > 100
z_rows = 100
endif
` total_verts = number of overlapping verts that can be welded
total_verts = ((x_cols + 1) * (z_rows + 1))
` total_polys = number of polygons
total_polys = (x_cols * z_rows) * 2
` total_cells = number of square cells
total_cells = (x_cols * z_rows)
` real_verts = total number of verts
real_verts = (total_polys * 3)
` cell_width = width of grid / number columns
cell_width# = x_width# / x_cols
` cell_height = height of grid / number rows
cell_height# = z_height# / z_rows
` mem_size = number of verts * 36 bytes per vert, plus 12 bytes for fvf info
mem_size = (real_verts * 36) + 12
` starting place
x_pos# = 0
y_pos# = 0
z_pos# = 0
mem_pos = 12
df_clr as dword
df_clr = clr
` make memblock the right size to fit everthing
make memblock 1,mem_size
` write fvf format to first 4 bytes
write memblock dword 1,0,338
` write size of data for each vert in next 4 bytes
write memblock dword 1,4,36
` write number of real verts into next 4 bytes
write memblock dword 1,8,real_verts
rem calculate list of unique verts and put into memblock
col = 0
row = 0
` loop and write vert info into memblock
for i = 1 to total_verts ` was real_verts but wasn't needed
` mem_pos starts at 12 and increments 4 for each piece of data
write memblock float 1,mem_pos,x_pos# : inc mem_pos,4 rem x coord
write memblock float 1,mem_pos,y_pos# : inc mem_pos,4 rem y coord
write memblock float 1,mem_pos,z_pos# : inc mem_pos,4 rem z coord
write memblock float 1,mem_pos,0 : inc mem_pos,4 rem x normal
write memblock float 1,mem_pos,1 : inc mem_pos,4 rem y normal
write memblock float 1,mem_pos,0 : inc mem_pos,4 rem z normal
write memblock dword 1,mem_pos,df_clr : inc mem_pos,4 rem diffuse color
write memblock float 1,mem_pos,0 : inc mem_pos,4 rem U coord
write memblock float 1,mem_pos,1 : inc mem_pos,4 rem z coord
inc col,1
inc x_pos#,cell_width#
if col = (x_cols + 1)
col = 0
inc row,1
inc z_pos#,cell_height#
x_pos# = 0
endif
if row = (z_rows + 1)
row = 0
x_pos# = 0
z_pos# = 0
endif
next i
rem It won't let me change the vertexdata if I make a mesh from a memblock, so I have to make an object, then a mesh
make mesh from memblock 1,1
make object id,1,0
delete mesh 1
make mesh from object 1,id
delete object id
rem reorder the indexdata to point at the correct vertices (weld the verts)
rem this is the algorithem for the triangle strip we are drawing
v1_1 = 0
v1_2 = (x_cols + 1)
v1_3 = 1
v2_1 = (x_cols + 1)
v2_2 = (x_cols + 2)
v2_3 = 1
i_pos = 0
lock vertexdata for mesh 1
delete mesh from vertexdata total_verts,real_verts,0,0 rem get rid of all the verts we don't need in the vertex data
col = 0
for i = 1 to total_cells
set indexdata i_pos,v1_1 : inc i_pos,1 : inc v1_1,1 rem triangle 1, vertice 1
set indexdata i_pos,v1_2 : inc i_pos,1 : inc v1_2,1 rem triangle 1, vertice 2
set indexdata i_pos,v1_3 : inc i_pos,1 : inc v1_3,1 rem triangle 1, vertice 3
set indexdata i_pos,v2_1 : inc i_pos,1 : inc v2_1,1 rem triangle 2, vertice 1
set indexdata i_pos,v2_2 : inc i_pos,1 : inc v2_2,1 rem triangle 2, vertice 2
set indexdata i_pos,v2_3 : inc i_pos,1 : inc v2_3,1 rem triangle 2, vertice 3
inc col,1
If col = x_cols
col = 0
inc v1_1,1 : inc v1_2,1 : inc v1_3,1
inc v2_1,1 : inc v2_2,1 : inc v2_3,1
endif
next i
rem set uv coordinates to stretch across object
rem loop throught the texture coordinates and determine what percent of total width, height the vertex is at
a = get vertexdata vertex count()
for i = 0 to a
set vertexdata uv i, get vertexdata position x(i) / x_width#, get vertexdata position z(i) / z_height#
u# = get vertexdata position x(i) / x_width#
v# = get vertexdata position z(i) / z_height#
next i
unlock vertexdata
make object id,1,0
delete mesh 1
delete memblock 1
endfunction
I have been trying to work out how to make it roll over in the last row of limbs like a wave breaking, but it is beyond me at the moment. If anyone can improve on what I have done or can make the wave rollover like it is breaking, I'd really appreciate it. I have never learnt trigonometry or anything like that and my coding skills are pretty basic so I am sure my code is laughable and can be improved.