Hi Daryn,hope all goes well with the audition.
Thanks for the music,have a gift for you as well,check the code snippet when you get chance,it may give you a few more clues as to how to manipulate the vertex data,and from here its a very short jump to using sparkys to pick the point you want to modify rather than a random point this uses.
`%ProjectTitle%
`======================
`©P.Parkinson
`======================
`Main Source File
`*********************************
`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 60
AUTOCAM OFF
HIDE MOUSE
COLOR BACKDROP 0,0
SET TEXT FONT "Arial"
SET TEXT SIZE 12
SET TEXT TRANSPARENT
POSITION CAMERA 50,50,-50
POINT CAMERA 0,0,0
POSITION MOUSE SCREEN WIDTH()/2,SCREEN HEIGHT()/2
dummy=MOUSEMOVEX()
dummy=MOUSEMOVEY()
`*********************************
`declarations and setup starts here
``null=MAKE VECTOR4(1)``used in normal generation routine
`set up the world
`*********************************************************************************************************************************
`the grid_x#,grid_z# is for the hole object data the objects are hard coded at
`present to a 64x64 size so it makes a 8 x 8 grid of objects if you leave them at 512
`if you change this then you will have to change the amount of objects created
`or how many rows each object is made from
GLOBAL grid_x#
GLOBAL grid_z#
grid_x#=512:grid_z#=512`keep these the same
`grid_size# is the size of each polygon used,this will scale the whole world but only the x,z plane so the hills will be more abrupt
`make the changes in the fractal generator function to smooth this out
GLOBAL grid_size#
grid_size#=8.0
GLOBAL u# AS DOUBLE FLOAT:GLOBAL v# AS DOUBLE FLOAT
`hard coded size to match land creation routine uv for texture mapping later
u#=1.0/64.0
v#=1.0/64.0
`set up the array to hold the height map and normal data for each vertex
DIM old_map_data(grid_x#,grid_z#,5) AS FLOAT
DIM new_map_data(grid_x#,grid_z#,5) AS FLOAT
`make a random hight map
RANDOMIZE TIMER()
hmap_fractal()`make random fractal height map these are tileable,be aware that if you clone the objects to increase the landscape size the
`normals of the cloned objects will NOT be smoothed TO match the adjoining tile along the edge of the other map,and the textures are not
`seamless,AND under some circumstances like the maps meeting at a large peek this may look quit odd
`calculate and average normals
GLOBAL avx#:GLOBAL avy#:GLOBAL avz#
null = MAKE VECTOR3(0)
null = MAKE VECTOR3(1)
null = MAKE VECTOR3(2)
null = MAKE VECTOR3(5)
null = MAKE VECTOR3(6)
null = MAKE VECTOR3(9)
null = MAKE VECTOR3(10)
`old_map_data(xpos,zpos,5) array is used like this
`(1)=height (2),(3),(4)=normal x,y,z this is the total for all the normals at that vertex (5)=number of vertex sharing that point
`devides (2),(3),(4) by (5) to get the averaged normal
make_normals()
`find the max number of poly per object
GLOBAL max_num_poly
max_num_poly=64*64*2
`creates a memblock big enough to hold the data for each object
create_memblockobject(1,max_num_poly*3)
`builds all the data into objects starting from obj
obj=100`first object and image number
`find total number of objects
GLOBAL max_objects
max_objects=64
`this is the parts that are hard coded to suit the grid_x/grid_z values
`build the objects
FOR z=0 TO 7
FOR x=0 TO 7
build_memblockobject(obj,x*64,z*64,x*64+64,z*64+64)
INC obj
NEXT x
NEXT z
`copy data arrays
FOR z=0 TO grid_z#
FOR x=0 TO grid_x#
FOR l=1 TO 5
new_map_data(x,z,l)=old_map_data(x,z,l)
NEXT l
NEXT x
NEXT z
`set up camera and lights
POSITION CAMERA 0,1000,0
POINT CAMERA 2000,0,2000
MAKE LIGHT 1
SET POINT LIGHT 1,(grid_x#*grid_size#)/2,(grid_x#*grid_size#)/2,(grid_z#*grid_size#)/2
SET LIGHT RANGE 1,(grid_x#*grid_size#)*5
HIDE LIGHT 0
SET AMBIENT LIGHT 0
MAKE OBJECT SPHERE 10000,-25
COLOR OBJECT 10000,RGB(255,255,0)
lx=LIGHT POSITION X(1)
ly=LIGHT POSITION Y(1)
lz=LIGHT POSITION Z(1)
POSITION OBJECT 10000,lx,ly,lz
`used for updating map data
GLOBAL changed AS INTEGER=0
`*********************************
`main loop starts here
DO
IF SPACEKEY()
changed=1
RESTORE crater
posx=RND(grid_x#)
posz=RND(grid_z#)
scale=rnd(6)
FOR z=0 TO 6
FOR x=0 to 6
READ h
h=h*scale
IF posx+x<=grid_x# AND posz+z<=grid_z#
dec new_map_data(posx+x,posz+z,1),h
ENDIF
NEXT x
NEXT z
ENDIF
`only update the needed objects
IF changed=1
obj=100
FOR z=0 TO 7
FOR x=0 TO 7
object_changed=0
object_changed=check_object_changed(x*64,z*64,x*64+64,z*64+64)
IF object_changed
reset_normal_count(x*64,z*64,x*64+64,z*64+64)
update_normals(x*64,z*64,x*64+64,z*64+64)
update_data_arrays(x*64,z*64,x*64+64,z*64+64)
DELETE OBJECT obj
build_memblockobject(obj,x*64,z*64,x*64+64,z*64+64)
ENDIF
INC obj
NEXT x
NEXT z
ENDIF
TEXT 0,0,"FPS="+STR$(SCREEN FPS())
TEXT 0,20,"Press space to add random dimples"
mouse_control(5.0)
SYNC
changed=0
LOOP
`*********************************
`functions start here
FUNCTION mouse_control(speed AS FLOAT)
XROTATE CAMERA CAMERA ANGLE X()+MOUSEMOVEY()
YROTATE CAMERA CAMERA ANGLE Y()+MOUSEMOVEX()
IF MOUSECLICK()=1 THEN MOVE CAMERA speed
IF MOUSECLICK()=2 THEN MOVE CAMERA (0-speed)
dummy=MOUSEMOVEX()
dummy=MOUSEMOVEY()
ENDFUNCTION
FUNCTION make_normals()
FOR z=0 TO grid_z#-1
FOR x=0 TO grid_x#-1
x1#=x*grid_size#:y1#=old_map_data(x,z,1):z1#=z*grid_size#
x2#=x*grid_size#:y2#=old_map_data(x,z+1,1):z2#=(z+1)*grid_size#
x3#=(x+1)*grid_size#:y3#=old_map_data(x+1,z,1):z3#=z*grid_size#
`find the surface normal of the polygon
normals(x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#)
xn#=avx#
yn#=avy#
zn#=avz#
`add it to any others at that vertex and increment the number of times that vertex has been used
old_map_data(x,z,2)=old_map_data(x,z,2)+xn#
old_map_data(x,z,3)=old_map_data(x,z,3)+yn#
old_map_data(x,z,4)=old_map_data(x,z,4)+zn#
INC old_map_data(x,z,5)
old_map_data(x,z+1,2)=old_map_data(x,z+1,2)+xn#
old_map_data(x,z+1,3)=old_map_data(x,z+1,3)+yn#
old_map_data(x,z+1,4)=old_map_data(x,z+1,4)+zn#
INC old_map_data(x,z+1,5)
old_map_data(x+1,z,2)=old_map_data(x+1,z,2)+xn#
old_map_data(x+1,z,3)=old_map_data(x+1,z,3)+yn#
old_map_data(x+1,z,4)=old_map_data(x+1,z,4)+zn#
INC old_map_data(x+1,z,5)
x1#=(x+1)*grid_size#:y1#=old_map_data(x+1,z+1,1):z1#=(z+1)*grid_size#
x2#=(x+1)*grid_size#:y2#=old_map_data(x+1,z,1):z2#=z*grid_size#
x3#=x*grid_size#:y3#=old_map_data(x,z+1,1):z3#=(z+1)*grid_size#
`find the surface normal of the polygon
normals(x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#)
xn#=avx#
yn#=avy#
zn#=avz#
`add it to any others at that vertex and increment the number of times that vertex has been used
old_map_data(x+1,z+1,2)=old_map_data(x+1,z+1,2)+xn#
old_map_data(x+1,z+1,3)=old_map_data(x+1,z+1,3)+yn#
old_map_data(x+1,z+1,4)=old_map_data(x+1,z+1,4)+zn#
INC old_map_data(x+1,z+1,5)
old_map_data(x+1,z,2)=old_map_data(x+1,z,2)+xn#
old_map_data(x+1,z,3)=old_map_data(x+1,z,3)+yn#
old_map_data(x+1,z,4)=old_map_data(x+1,z,4)+zn#
INC old_map_data(x,z+1,5)
old_map_data(x,z+1,2)=old_map_data(x,z+1,2)+xn#
old_map_data(x,z+1,3)=old_map_data(x,z+1,3)+yn#
old_map_data(x,z+1,4)=old_map_data(x,z+1,4)+zn#
INC old_map_data(x+1,z,5)
NEXT x
NEXT z
`average the normals at each point
FOR z=0 TO grid_z#
FOR x=0 TO grid_x#
dumx#=old_map_data(x,z,2)/old_map_data(x,z,5)
dumy#=old_map_data(x,z,3)/old_map_data(x,z,5)
dumz#=old_map_data(x,z,4)/old_map_data(x,z,5)
old_map_data(x,z,2)=dumx#
old_map_data(x,z,3)=dumy#
old_map_data(x,z,4)=dumz#
NEXT x
NEXT z
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=grid_x# ` units and array size; must be a power of 2
rn=0.10 ` 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 grid_z#
FOR x=0 TO grid_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
FOR z=0 TO grid_z#
FOR x=0 TO grid_x#
av=a(x,z,0)
IF minh#<0 THEN old_map_data(x,z,1)=av+ABS(minh#)
IF minh#>=0 THEN old_map_data(x,z,1)=av-minh#
NEXT x
NEXT z
ENDFUNCTION
FUNCTION create_memblockobject(memnum,v)
MAKE MEMBLOCK memnum,12+(32*v)
WRITE MEMBLOCK DWORD memnum,0,274
WRITE MEMBLOCK DWORD memnum,4,32
WRITE MEMBLOCK DWORD memnum,8,v
ENDFUNCTION
FUNCTION create_vertex(memnum,v,vposx#,vposy#,vposz#,color AS DWORD,u#,v#)
WRITE MEMBLOCK FLOAT memnum,v*32+12,vposx#
WRITE MEMBLOCK FLOAT memnum,v*32+16,vposy#
WRITE MEMBLOCK FLOAT memnum,v*32+20,vposz#
``write memblock dword memnum,v*36+36,color `not needed in 274fvf format diffuse color seems to mess up some shader code
WRITE MEMBLOCK FLOAT memnum,v*32+36,u#
WRITE MEMBLOCK FLOAT memnum,v*32+40,v#
ENDFUNCTION
FUNCTION set_normal(memnum,v,normalx#,normaly#,normalz#)
WRITE MEMBLOCK FLOAT memnum,v*32+24,normalx#
WRITE MEMBLOCK FLOAT memnum,v*32+28,normaly#
WRITE MEMBLOCK FLOAT memnum,v*32+32,normalz#
ENDFUNCTION
FUNCTION make_object(objnum,meshnum,memnum,imgnum)
IF OBJECT EXIST (objnum) THEN DELETE OBJECT objnum
IF MESH EXIST (meshnum) THEN DELETE MESH meshnum
MAKE MESH FROM MEMBLOCK meshnum,memnum
MAKE OBJECT objnum,meshnum,imgnum
ENDFUNCTION
FUNCTION normals(vertex_px1#,vertex_py1#,vertex_pz1#,vertex_px2#,vertex_py2#,vertex_pz2#,vertex_px3#,vertex_py3#,vertex_pz3#)
`zero globals
avx#=0
avy#=0
avz#=0
`vertex 1
SET VECTOR3 0,vertex_px1#, vertex_py1#, vertex_pz1#
`vertex 2
SET VECTOR3 1,vertex_px2#, vertex_py2#, vertex_pz2#
`vertex 3
SET VECTOR3 2,vertex_px3#, vertex_py3#, vertex_pz3#
`find normals
SUBTRACT VECTOR3 5, 0,2 ` -- direction v1
SUBTRACT VECTOR3 6, 1,2 ` -- direction v2
CROSS PRODUCT VECTOR3 9, 5,6 ` -- normal
NORMALIZE VECTOR3 10, 9 ` -- normalized normal
`set globals to vector results
avx#=X VECTOR3(10)
avy#=Y VECTOR3(10)
avz#=Z VECTOR3(10)
ENDFUNCTION
FUNCTION build_memblockobject(obj,start_x,start_z,end_x,end_z)
vertex=0
FOR z=start_z TO end_z-1
FOR x=start_x TO end_x-1
x1#=x*grid_size#:y1#=old_map_data(x,z,1):z1#=z*grid_size#
x2#=x*grid_size#:y2#=old_map_data(x,z+1,1):z2#=(z+1)*grid_size#
x3#=(x+1)*grid_size#:y3#=old_map_data(x+1,z,1):z3#=z*grid_size#
create_vertex(1,vertex,x1#,y1#,z1#,0,u#*(x-start_x),v#*(z-start_z))
set_normal(1,vertex,old_map_data(x,z,2),old_map_data(x,z,3),old_map_data(x,z,4))
INC vertex
create_vertex(1,vertex,x2#,y2#,z2#,0,u#*(x-start_x),v#*(z+1-start_z))
set_normal(1,vertex,old_map_data(x,z+1,2),old_map_data(x,z+1,3),old_map_data(x,z+1,4))
INC vertex
create_vertex(1,vertex,x3#,y3#,z3#,0,u#*(x+1-start_x),v#*(z-start_z))
set_normal(1,vertex,old_map_data(x+1,z,2),old_map_data(x+1,z,3),old_map_data(x+1,z,4))
INC vertex
x1#=(x+1)*grid_size#:y1#=old_map_data(x+1,z+1,1):z1#=(z+1)*grid_size#
x2#=(x+1)*grid_size#:y2#=old_map_data(x+1,z,1):z2#=z*grid_size#
x3#=x*grid_size#:y3#=old_map_data(x,z+1,1):z3#=(z+1)*grid_size#
create_vertex(1,vertex,x1#,y1#,z1#,0,u#*(x+1-start_x),v#*(z+1-start_z))
set_normal(1,vertex,old_map_data(x+1,z+1,2),old_map_data(x+1,z+1,3),old_map_data(x+1,z+1,4))
INC vertex
create_vertex(1,vertex,x2#,y2#,z2#,0,u#*(x+1-start_x),v#*(z-start_z))
set_normal(1,vertex,old_map_data(x+1,z,2),old_map_data(x+1,z,3),old_map_data(x+1,z,4))
INC vertex
create_vertex(1,vertex,x3#,y3#,z3#,0,u#*(x-start_x),v#*(z+1-start_z))
set_normal(1,vertex,old_map_data(x,z+1,2),old_map_data(x,z+1,3),old_map_data(x,z+1,4))
INC vertex
NEXT x
NEXT z
make_object(obj,1,1,0)
ENDFUNCTION
FUNCTION update_data_arrays(start_x,start_z,end_x,end_z)
FOR x=start_x TO end_x-1
FOR z=start_z TO end_z-1
FOR l=1 TO 5
old_map_data(x,z,l)=new_map_data(x,z,l)
NEXT l
NEXT z
NEXT x
ENDFUNCTION
FUNCTION check_object_changed(start_x,start_z,end_x,end_z)
ret=0
FOR x=start_x TO end_x-1
FOR z=start_z TO end_z-1
IF new_map_data(x,z,1)<>old_map_data(x,z,1)
ret=1
endif
NEXT z
NEXT x
ENDFUNCTION ret
FUNCTION update_normals(start_x,start_z,end_x,end_z)
FOR z=start_z TO end_z-1
FOR x=start_x TO end_x-1
x1#=x*grid_size#:y1#=new_map_data(x,z,1):z1#=z*grid_size#
x2#=x*grid_size#:y2#=new_map_data(x,z+1,1):z2#=(z+1)*grid_size#
x3#=(x+1)*grid_size#:y3#=new_map_data(x+1,z,1):z3#=z*grid_size#
`find the surface normal of the polygon
normals(x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#)
xn#=avx#
yn#=avy#
zn#=avz#
`add it to any others at that vertex and increment the number of times that vertex has been used
new_map_data(x,z,2)=new_map_data(x,z,2)+xn#
new_map_data(x,z,3)=new_map_data(x,z,3)+yn#
new_map_data(x,z,4)=new_map_data(x,z,4)+zn#
INC new_map_data(x,z,5)
new_map_data(x,z+1,2)=new_map_data(x,z+1,2)+xn#
new_map_data(x,z+1,3)=new_map_data(x,z+1,3)+yn#
new_map_data(x,z+1,4)=new_map_data(x,z+1,4)+zn#
INC new_map_data(x,z+1,5)
new_map_data(x+1,z,2)=new_map_data(x+1,z,2)+xn#
new_map_data(x+1,z,3)=new_map_data(x+1,z,3)+yn#
new_map_data(x+1,z,4)=new_map_data(x+1,z,4)+zn#
INC new_map_data(x+1,z,5)
x1#=(x+1)*grid_size#:y1#=new_map_data(x+1,z+1,1):z1#=(z+1)*grid_size#
x2#=(x+1)*grid_size#:y2#=new_map_data(x+1,z,1):z2#=z*grid_size#
x3#=x*grid_size#:y3#=new_map_data(x,z+1,1):z3#=(z+1)*grid_size#
`find the surface normal of the polygon
normals(x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#)
xn#=avx#
yn#=avy#
zn#=avz#
`add it to any others at that vertex and increment the number of times that vertex has been used
new_map_data(x+1,z+1,2)=new_map_data(x+1,z+1,2)+xn#
new_map_data(x+1,z+1,3)=new_map_data(x+1,z+1,3)+yn#
new_map_data(x+1,z+1,4)=new_map_data(x+1,z+1,4)+zn#
INC new_map_data(x+1,z+1,5)
new_map_data(x+1,z,2)=new_map_data(x+1,z,2)+xn#
new_map_data(x+1,z,3)=new_map_data(x+1,z,3)+yn#
new_map_data(x+1,z,4)=new_map_data(x+1,z,4)+zn#
INC new_map_data(x,z+1,5)
new_map_data(x,z+1,2)=new_map_data(x,z+1,2)+xn#
new_map_data(x,z+1,3)=new_map_data(x,z+1,3)+yn#
new_map_data(x,z+1,4)=new_map_data(x,z+1,4)+zn#
INC new_map_data(x+1,z,5)
NEXT x
NEXT z
`average the normals at each point
FOR z=start_z TO end_z-1
FOR x=start_x TO end_x-1
dumx#=new_map_data(x,z,2)/new_map_data(x,z,5)
dumy#=new_map_data(x,z,3)/new_map_data(x,z,5)
dumz#=new_map_data(x,z,4)/new_map_data(x,z,5)
new_map_data(x,z,2)=dumx#
new_map_data(x,z,3)=dumy#
new_map_data(x,z,4)=dumz#
NEXT x
NEXT z
ENDFUNCTION
FUNCTION reset_normal_count(start_x,start_z,end_x,end_z)
FOR x=start_x TO end_x-1
FOR z=start_z TO end_z-1
new_map_data(x,z,5)=0
NEXT z
NEXT x
ENDFUNCTION
crater:
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,15,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
Good look