Small code sample i made a long time ago,shows how to make up a large segmented plain with welded verts,it also shows how to edit the vertexdata in real time across all the planes without breaking the seams apart and alters the diffuse just to show whats been changed.It does use a few plugins but they are free ones with the exception of ezrotate,but that is only used for calculating the face normals and can be substituted for other normal calculation routines if you dont have it.
`%basic terraform code%
`======================
`©P.Parkinson
`======================
`Main Source File
`Uses Sparkys Collision DLL
`Uses EZRotate DLL for normal calulation
`Uses Matrix1 DLL for object creation
`*********************************
`enviroment set up
IF CHECK DISPLAY MODE(1024,768,32)
SET DISPLAY MODE 1024,768,32
h=DESKTOP HEIGHT()
w=DESKTOP WIDTH()
posx=w/2-512
posy=h/2-384
ELSE
SET DISPLAY MODE 640,480,32
h=DESKTOP HEIGHT()
w=DESKTOP WIDTH()
posx=w/2-320
posy=h/2-240
ENDIF
SET WINDOW POSITION posx,posy
SYNC ON
SYNC RATE 0
AUTOCAM OFF
COLOR BACKDROP 0,0
SET TEXT FONT "Arial"
SET TEXT SIZE 18
SET TEXT TRANSPARENT
POSITION MOUSE SCREEN WIDTH()/2,SCREEN HEIGHT()/2
dummy=MOUSEMOVEX()
dummy=MOUSEMOVEY()
`set up camera and lights
POSITION CAMERA 0,5000,0
POINT CAMERA 0,0,0
MAKE LIGHT 1
SET POINT LIGHT 1,15000,15000,0
SET LIGHT RANGE 1,100000
HIDE LIGHT 0
SET AMBIENT LIGHT 0
SET CAMERA RANGE 1,15000
`*********************************
`declarations and setup starts here
``size variables for terrain creation
GLOBAL tiles_on_x_axis AS INTEGER=16 ``terrains are square so x and z must be same value and a power of 2
GLOBAL tiles_on_z_axis AS INTEGER=16 ``terrains are square so x and z must be same value and a power of 2
GLOBAL points_per_tile_x_axis AS INTEGER=32 ``tiles are square so this is the same for x and z and is how many points along each tile side 8,16,32,64
GLOBAL points_per_tile_z_axis AS INTEGER=32 ``tiles are square so this is the same for x and z and is how many points along each tile side 8,16,32,64
GLOBAL point_spacing AS INTEGER=32 ``the spacing between each of the points
GLOBAL data_size_x AS INTEGER
data_size_x=points_per_tile_x_axis*tiles_on_x_axis
GLOBAL data_size_z AS INTEGER
data_size_z=points_per_tile_z_axis*tiles_on_z_axis
``set up a data type for all the map data
TYPE map
pos_x AS FLOAT
pos_y AS FLOAT
pos_z AS FLOAT
norm_x AS FLOAT
norm_y AS FLOAT
norm_z AS FLOAT
shared_normals AS FLOAT
tex_u AS FLOAT
tex_v AS FLOAT
diff as integer
ENDTYPE
``setup a data type to hold start and end points of data per tile
TYPE tile
start_x AS INTEGER
end_x AS INTEGER
start_z AS INTEGER
end_z AS INTEGER
obj_num AS INTEGER
ENDTYPE
``array to hold all the map data
DIM map_data(data_size_x,data_size_z) AS map
``array to hold tile data
DIM tile_data(tiles_on_x_axis,tiles_on_z_axis) as tile
``uv setup for texturing later,1 image for whole terrain
GLOBAL u_step AS DOUBLE FLOAT
u_step=1.0/data_size_x
GLOBAL v_step AS DOUBLE FLOAT
v_step=1.0/data_size_z
``make fractal landscape data
hmap_fractal()
``calculate AND average normals
make_normals(1.0,0,0,data_size_x,data_size_z)``brightness can be changed here 1.0 is 100%
``make all the tiles
obj=1
start_x=0
start_z=0
end_x=points_per_tile_x_axis
end_z=points_per_tile_z_axis
obj=1
CENTER TEXT SCREEN WIDTH()/2,SCREEN HEIGHT()/2,"Pleas Wait,Building Start Terrain"
SYNC
SYNC
FOR z=1 TO tiles_on_z_axis
FOR x=1 TO tiles_on_x_axis
tile_data(x,z).start_x=start_x
tile_data(x,z).start_z=start_z
tile_data(x,z).end_x=end_x
tile_data(x,z).end_Z=end_z
tile_data(x,z).obj_num=obj
make_tile(obj,start_x,start_z,end_x,end_z)
``TEXTURE OBJECT obj,1
start_x=end_x
INC end_x,points_per_tile_x_axis
INC obj
NEXT x
start_x=0
end_x=points_per_tile_x_axis
start_z=end_z
INC end_z,points_per_tile_z_axis
NEXT z
CLS
`set up variables returned after colision tests
GLOBAL cx AS FLOAT
GLOBAL cy AS FLOAT
GLOBAL cz AS FLOAT
GLOBAL col_obj AS INTEGER
GLOBAL nx AS FLOAT
GLOBAL ny AS FLOAT
GLOBAL nz AS FLOAT
GLOBAL face_hit AS INTEGER
GLOBAL tile_x AS INTEGER
GLOBAL tile_z AS INTEGER
GLOBAL data_x AS INTEGER
GLOBAL data_z AS INTEGER
`global for mousewheel check
GLOBAL msz AS FLOAT
msz=MOUSEZ()
`*********************************
`main loop starts here
DO
`check for raycast to landscape and place marker
raycast_landscape()
```terraform code here
terraform()
TEXT 0,0,"Marker On Object "+STR$(col_obj)
TEXT 0,20,"At Position x="+STR$(cx)+" y="+STR$(cy)+" z="+STR$(cz)
TEXT 0,40,"Screen FPS="+STR$(SCREEN FPS())
TEXT 0,60,"Object Face Hit="+STR$(face_hit)
TEXT 0,80,"Tile X="+STR$(tile_x)+" Tile Z="+STR$(tile_z)
TEXT 0,100,"Data X="+STR$(data_x)+" Data Z="+STR$(data_z)
TEXT 0,120,"Mouse Wheel To Zoom In/Out"
TEXT 0,140,"Left & Right Mouse Buttons To Raise & Lower"
mouse_control(100.0)
SYNC
LOOP
`*********************************
`functions start here
FUNCTION mouse_control(Speed AS FLOAT)
XROTATE CAMERA CAMERA ANGLE X()+MOUSEMOVEY()
YROTATE CAMERA CAMERA ANGLE Y()+MOUSEMOVEX()
IF msz<MOUSEZ() THEN MOVE CAMERA Speed:msz=MOUSEZ()
IF msz>MOUSEZ() THEN MOVE CAMERA (0-Speed):msz=MOUSEZ()
r=MOUSEMOVEX()
r=MOUSEMOVEY()
ENDFUNCTION
FUNCTION hmap_fractal()
``thanks to who ever did this code,had it so long,and it never fails to work for me
av AS FLOAT
rn AS FLOAT
s=data_size_x``units and array size; must be a power of 2 this can be either x or y as they are both the same
rn=0.02``bigger numbers = smoother, smaller = spikier
smt=1``how many times to smooth matrix
DIM a(s,s,1) AS FLOAT
``do the diamond square algorithm
``paying special attention to wrapping around
c=s
REPEAT
FOR z=0 TO (s-c) STEP c
FOR x=0 TO (s-c) STEP c
av=(a(x,z)+a(x+c,z)+a(x,z+c)+a(x+c,z+c))/4.0
av=av+((-50+RND(100))/rn)
a(x+(c/2),z+(c/2))=av
NEXT x
NEXT z
w=1
FOR z=0 TO (s-(c/2)) STEP (c/2)
FOR x=0 TO (s-c) STEP c
x2=x+(w*(c/2))
av=a(x2,z+(c/2))+a(x2+(c/2),z)
IF x2=0
av=av+a(s-(c/2),z)
ELSE
av=av+a(x2-(c/2),z)
ENDIF
IF z=0
av=av+a(x2,s-(c/2))
ELSE
av=av+a(x2,z-(c/2))
ENDIF
av=av/4.0
av=av+((-50+RND(100))/rn)
a(x2,z,0)=av
IF x2=0 THEN a(s,z,0)=av
IF z=0 THEN a(x2,s,0)=av
NEXT x
w=1-w
NEXT z
c=c/2
rn=rn*2.0
UNTIL c < 2
``smooth the result
FOR multiple=1 TO smt
FOR x=0 TO s-1
x2=x-1 : IF x2 < 0 THEN x2=s-1
FOR z=0 TO s-1
z2=z-1 : IF z2 < 0 THEN z2=s-1
v1#=a(x2,z+1,0)
v2#=a(x,z+1,0)
v3#=a(x+1,z+1,0)
v4#=a(x+1,z,0)
v5#=a(x+1,z2,0)
v6#=a(x,z2,0)
v7#=a(x2,z2,0)
v8#=a(x2,z,0)
av#=(v1#+v2#+v3#+v4#+v5#+v6#+v7#+v8#)/8.0
a(x,z,0)=av#
NEXT z
NEXT x
FOR f=0 TO s
a(s,f,0)=a(0,f,0)
a(f,s,0)=a(f,0,0)
NEXT f
NEXT multiple
``find min/max height
minh#=5000:maxh#=-5000
FOR z=0 TO data_size_z
FOR x=0 TO data_size_x
IF a(x,z,0)<minh# THEN minh#=a(x,z,0)
IF a(x,z,0)>maxh# THEN maxh#=a(x,z,0)
NEXT x
NEXT z
``update data array and make raise it up so the lowest point is>=0
``and the x and z positions and the uv are also set here
x_pos=((data_size_x*point_spacing)/2)*-1
z_pos=(data_size_z*point_spacing)/2
FOR z=0 TO data_size_z
FOR x=0 TO data_size_x
av=a(x,z,0)
IF minh#<0
map_data(x,z).pos_x=x_pos
map_data(x,z).pos_y=av+ABS(minh#)
map_data(x,z).pos_z=z_pos
ENDIF
IF minh#>=0
map_data(x,z).pos_x=x_pos
map_data(x,z).pos_y=av-minh#
map_data(x,z).pos_z=z_pos
ENDIF
``set uv data
map_data(x,z).tex_u=u_step*x
map_data(x,z).tex_v=v_step*z
map_data(x,z).diff=rgb(rnd(255),rnd(255),rnd(255))
INC x_pos,point_spacing
NEXT x
x_pos=((data_size_x*point_spacing)/2)*-1
DEC z_pos,point_spacing
NEXT z
ENDFUNCTION
FUNCTION make_tile(obj,start_x,start_z,end_x,end_z)
``if collision object is setp then delete it first
IF SC_COLLISIONSTATUS(obj)
SC_REMOVEOBJECT obj
ENDIF
``if object exist then delete it first
IF OBJECT EXIST(obj)
DELETE OBJECT obj
ENDIF
``make object (matrix1)
max_vertex=(points_per_tile_x_axis+1)*(points_per_tile_z_axis+1)
max_index=(points_per_tile_x_axis)*(points_per_tile_z_axis)*6
MAKE OBJECT NEW obj,max_vertex,max_index,338
LOCK VERTEXDATA FOR LIMB obj,0
``set all the vertex points
vertex=0
FOR z=start_z TO end_z
FOR x=start_x TO end_x
SET VERTEXDATA POSITION vertex,map_data(x,z).pos_x,map_data(x,z).pos_y,map_data(x,z).pos_z
SET VERTEXDATA NORMALS vertex,map_data(x,z).norm_x,map_data(x,z).norm_y,map_data(x,z).norm_z
SET VERTEXDATA UV vertex,map_data(x,z).tex_u,map_data(x,z).tex_v
set vertexdata diffuse vertex,map_data(x,z).diff
INC vertex
NEXT x
NEXT z
``set all the index data
vertex=0
col=0
FOR index=0 TO max_index-1 STEP 6
SET INDEXDATA index,vertex
SET INDEXDATA index+1,vertex+1
SET INDEXDATA index+2,vertex+points_per_tile_x_axis+1
SET INDEXDATA index+3,vertex+1
SET INDEXDATA index+4,vertex+1+points_per_tile_x_axis+1
SET INDEXDATA index+5,vertex+points_per_tile_x_axis+1
INC vertex
INC col
IF col=points_per_tile_x_axis
col=0
INC vertex
ENDIF
NEXT index
UNLOCK VERTEXDATA
``set up collision for new tile
SC_SETUPCOMPLEXOBJECT obj,0,2
SC_ALLOWOBJECTSCALING obj
``SET OBJECT WIREFRAME obj,1
ENDFUNCTION
FUNCTION raycast_landscape()
`target point in the distance
PICK SCREEN MOUSEX(),MOUSEY(),50000
ex=GET PICK VECTOR X()+CAMERA POSITION X()
ey=GET PICK VECTOR Y()+CAMERA POSITION Y()
ez=GET PICK VECTOR Z()+CAMERA POSITION Z()
`start point up against the camera
PICK SCREEN MOUSEX(),MOUSEY(),0
sx=GET PICK VECTOR X()+CAMERA POSITION X()
sy=GET PICK VECTOR Y()+CAMERA POSITION Y()
sz=GET PICK VECTOR Z()+CAMERA POSITION Z()
col_obj=SC_RAYCAST(0,sx,sy,sz,ex,ey,ez,0)
``col_obj=SC_RAYCAST(0,CAMERA POSITION X(),CAMERA POSITION Y(),CAMERA POSITION Z(),OBJECT POSITION X(ray_cast_obj_target),OBJECT POSITION Y(ray_cast_obj_target),OBJECT POSITION Z(ray_cast_obj_target),0)
IF col_obj>0
cx = SC_GETSTATICCOLLISIONX() : nx = SC_GETCOLLISIONNORMALX()
cy = SC_GETSTATICCOLLISIONY() : ny = SC_GETCOLLISIONNORMALY()
cz = SC_GETSTATICCOLLISIONZ() : nz = SC_GETCOLLISIONNORMALZ()
``POSITION OBJECT ray_cast_obj_marker,cx,cy,cz
``POINT OBJECT ray_cast_obj_marker,cx+(nx*1000),cy+(ny*1000),cz+(nz*1000)
face_hit=SC_GETFACEHIT()
object_hit_to_tile_x_z()
data_z=data_pos_z()
data_x=data_pos_x()
INC tile_x
INC tile_z
ELSE
cx=0.0
cy=0.0
cz=0.0
nx=0.0
ny=0.0
nz=0.0
face_hit=0
tile_x=0
tile_z=0
data_x=0
data_z=0
ENDIF
ENDFUNCTION
FUNCTION object_hit_to_tile_x_z()
tile_z=(col_obj-1)/tiles_on_z_axis
tile_x=col_obj-(tile_z*tiles_on_z_axis)-1
ENDFUNCTION
FUNCTION data_pos_x
fh=face_hit/2
dz=fh/points_per_tile_z_axis
dx=fh-(dz*points_per_tile_z_axis)
dx=dx+(tile_x*points_per_tile_x_axis)
ENDFUNCTION dx
FUNCTION data_pos_z
fh=face_hit/2
dz=fh/points_per_tile_z_axis
dz=dz+(tile_z*points_per_tile_z_axis)
ENDFUNCTION dz
FUNCTION free_object()
REPEAT
INC i
IF OBJECT EXIST(i)=0 THEN found=1
UNTIL found
ENDFUNCTION i
FUNCTION terraform()
amount AS FLOAT
mk=MOUSECLICK()
IF mk>0
RESTORE crater
READ dx,dz
pos_x=data_x-dx/2
pos_z=data_z-dz/2
FOR z=0 TO dz-1
FOR x=0 TO dx-1
READ amount
// amount=amount*RND(100.0)/50.0
// amount=amount-0.5+(rnd(100.0)/100.0)
IF pos_x>=0 AND pos_x<=data_size_x AND pos_Z>=0 AND pos_z<=data_size_z
IF mk=1 THEN INC map_data(pos_x,pos_z).pos_x,amount:inc map_data(pos_x,pos_z).pos_y,amount:inc map_data(pos_x,pos_z).pos_z,amount
IF mk=2 THEN DEC map_data(pos_x,pos_z).pos_x,amount:dec map_data(pos_x,pos_z).pos_y,amount:dec map_data(pos_x,pos_z).pos_z,amount
if mk=1 then map_data(pos_x,pos_z).diff=rgb(255,0,0)
if mk=2 then map_data(pos_x,pos_z).diff=rgb(0,0,255)
INC pos_x
ENDIF
NEXT x
pos_x=data_x-dx/2
INC pos_z
NEXT z
pos_x=data_x-dx/2
pos_z=data_z-dz/2
make_normals(1.0,pos_x-2,pos_Z-2,pos_x+dx+2,pos_z+dz+2)
IF col_obj>0
rebuild_tile(col_obj)
IF col_obj-1>0
IF OBJECT EXIST(col_obj-1)THEN rebuild_tile(col_obj-1)
ENDIF
IF OBJECT EXIST(col_obj+1)THEN rebuild_tile(col_obj+1)
IF OBJECT EXIST(col_obj+tiles_on_x_axis)THEN rebuild_tile(col_obj+tiles_on_x_axis)
IF col_obj-tiles_on_x_axis>0
IF OBJECT EXIST(col_obj-tiles_on_x_axis)THEN rebuild_tile(col_obj-tiles_on_x_axis)
ENDIF
IF col_obj-tiles_on_x_axis-1>0
IF OBJECT EXIST(col_obj-tiles_on_x_axis-1)THEN rebuild_tile(col_obj-tiles_on_x_axis-1)
ENDIF
IF col_obj-tiles_on_x_axis+1>0
IF OBJECT EXIST(col_obj-tiles_on_x_axis+1)THEN rebuild_tile(col_obj-tiles_on_x_axis+1)
ENDIF
IF OBJECT EXIST(col_obj+tiles_on_x_axis-1)THEN rebuild_tile(col_obj+tiles_on_x_axis-1)
IF OBJECT EXIST(col_obj+tiles_on_x_axis+1)THEN rebuild_tile(col_obj+tiles_on_x_axis+1)
ENDIF
ENDIF
ENDFUNCTION
FUNCTION make_normals(brightness#,start_x,start_z,end_x,end_z)
FOR z=start_z TO end_z
FOR x=start_x TO end_X
IF x>=0 AND x<=data_size_x AND z>=0 AND z<=data_size_z
map_data(x,z).norm_x=0
map_data(x,z).norm_y=0
map_data(x,z).norm_z=0
map_data(x,z).shared_normals=0
IF x+1<=data_size_x AND z-1>=0
x1#=map_data(x,z).pos_x:y1#=map_data(x,z).pos_y:z1#=map_data(x,z).pos_z
x2#=map_data(x,z-1).pos_x:y2#=map_data(x,z-1).pos_y:z2#=map_data(x,z-1).pos_z
x3#=map_data(x+1,z).pos_x:y3#=map_data(x+1,z).pos_y:z3#=map_data(x+1,z).pos_z
EZRO_FINDNORMAL x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#
xn#=EZRO_GETNORMALX():map_data(x,z).norm_x=map_data(x,z).norm_x+xn#
yn#=EZRO_GETNORMALY():map_data(x,z).norm_y=map_data(x,z).norm_y+yn#
zn#=EZRO_GETNORMALZ():map_data(x,z).norm_z=map_data(x,z).norm_z+zn#
INC map_data(x,z).shared_normals
ENDIF
IF x+1<=data_size_x AND z+1<=data_size_z
x1#=map_data(x,z).pos_x:y1#=map_data(x,z).pos_y:z1#=map_data(x,z).pos_z
x2#=map_data(x+1,z).pos_x:y2#=map_data(x+1,z).pos_y:z2#=map_data(x+1,z).pos_z
x3#=map_data(x,z+1).pos_x:y3#=map_data(x,z+1).pos_y:z3#=map_data(x,z+1).pos_z
EZRO_FINDNORMAL x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#
xn#=EZRO_GETNORMALX():map_data(x,z).norm_x=map_data(x,z).norm_x+xn#
yn#=EZRO_GETNORMALY():map_data(x,z).norm_y=map_data(x,z).norm_y+yn#
zn#=EZRO_GETNORMALZ():map_data(x,z).norm_z=map_data(x,z).norm_z+zn#
INC map_data(x,z).shared_normals
ENDIF
IF x-1>=0 AND z+1<=data_size_z
x1#=map_data(x,z).pos_x:y1#=map_data(x,z).pos_y:z1#=map_data(x,z).pos_z
x2#=map_data(x,z+1).pos_x:y2#=map_data(x,z+1).pos_y:z2#=map_data(x,z+1).pos_z
x3#=map_data(x-1,z).pos_x:y3#=map_data(x-1,z).pos_y:z3#=map_data(x-1,z).pos_z
EZRO_FINDNORMAL x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#
xn#=EZRO_GETNORMALX():map_data(x,z).norm_x=map_data(x,z).norm_x+xn#
yn#=EZRO_GETNORMALY():map_data(x,z).norm_y=map_data(x,z).norm_y+yn#
zn#=EZRO_GETNORMALZ():map_data(x,z).norm_z=map_data(x,z).norm_z+zn#
INC map_data(x,z).shared_normals
ENDIF
IF x-1>=0 AND z-1>=0
x1#=map_data(x,z).pos_x:y1#=map_data(x,z).pos_y:z1#=map_data(x,z).pos_z
x2#=map_data(x-1,z).pos_x:y2#=map_data(x-1,z).pos_y:z2#=map_data(x-1,z).pos_z
x3#=map_data(x,z-1).pos_x:y3#=map_data(x,z-1).pos_y:z3#=map_data(x,z-1).pos_z
EZRO_FINDNORMAL x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#
xn#=EZRO_GETNORMALX():map_data(x,z).norm_x=map_data(x,z).norm_x+xn#
yn#=EZRO_GETNORMALY():map_data(x,z).norm_y=map_data(x,z).norm_y+yn#
zn#=EZRO_GETNORMALZ():map_data(x,z).norm_z=map_data(x,z).norm_z+zn#
INC map_data(x,z).shared_normals
ENDIF
map_data(x,z).norm_x=map_data(x,z).norm_x/map_data(x,z).shared_normals
map_data(x,z).norm_y=map_data(x,z).norm_y/map_data(x,z).shared_normals
map_data(x,z).norm_z=map_data(x,z).norm_z/map_data(x,z).shared_normals
map_data(x,z).norm_x=map_data(x,z).norm_x*brightness#
map_data(x,z).norm_y=map_data(x,z).norm_y*brightness#
map_data(x,z).norm_z=map_data(x,z).norm_z*brightness#
ENDIF
NEXT x
NEXT z
ENDFUNCTION
FUNCTION rebuild_tile(obj)
FOR z=1 TO tiles_on_z_axis
FOR x=1 TO tiles_on_x_axis
IF obj=tile_data(x,z).obj_num
start_data_x=tile_data(x,z).start_x
end_data_x=tile_data(x,z).end_x
start_data_z=tile_data(x,z).start_z
end_data_z=tile_data(x,z).end_z
ENDIF
NEXT x
NEXT z
LOCK VERTEXDATA FOR LIMB obj,0
FOR z=start_data_z TO end_data_z
FOR x=start_data_x TO end_data_x
old_height#=GET VERTEXDATA POSITION Y(vertex)
new_height#=map_data(x,z).pos_y
IF old_height#<>new_height#
SET VERTEXDATA POSITION vertex,GET VERTEXDATA POSITION X(vertex),new_height#,GET VERTEXDATA POSITION Z(vertex)
SET VERTEXDATA NORMALS vertex,map_data(x,z).norm_x,map_data(x,z).norm_y,map_data(x,z).norm_z
set vertexdata diffuse vertex,map_data(x,z).diff
ENDIF
INC vertex
NEXT x
NEXT z
UNLOCK VERTEXDATA
SC_UPDATEOBJECT obj
ENDFUNCTION
crater:
//DATA 7,7
//DATA 0,1,2,4,2,1,0
//DATA 1,2,4,8,4,2,1
//DATA 2,4,8,10,8,4,2
//DATA 4,8,10,10,10,8,4
//DATA 2,4,8,10,8,4,2
//DATA 1,2,4,8,4,2,1
//DATA 0,1,2,4,2,1,0
DATA 11,11
DATA 0,0,0,0,1,1,1,0,0,0,0
DATA 0,0,1,1,2,2,2,1,1,0,0
DATA 0,1,2,2,2,3,2,2,2,1,0
DATA 0,1,2,3,3,4,3,3,2,1,0
DATA 1,2,2,3,4,5,4,3,2,2,1
DATA 1,2,3,4,5,5,5,4,3,2,1
DATA 1,2,2,3,4,5,4,3,2,2,1
DATA 0,1,2,3,3,4,3,3,2,1,0
DATA 0,1,2,2,2,3,2,2,2,1,0
DATA 0,0,1,1,2,2,2,1,1,0,0
DATA 0,0,0,0,1,1,1,0,0,0,0
Hope this helps and gives you some ideas.