I posted some code a while ago that does this:
//Apply heightmap function by Kaedroho
//Free for use in commercial and non commercial projects
//Applies a heightmap to a sphere by looping through the vertices then calculating the new height
//objectid - a sphere object
//imgnum - the heightmap (must be greyscale)
//min - the height of the terrain when the heightmap shows black
//max - the height of the terrain when the heightmap shows white
Function ApplyHeightmap(objectid,imgnum,min#,max#)
//Find a free memblock (replace this with your own code)
FreeMemblock=1
//First make a memblock from your heightmap, this will let you get height data quickly
make memblock from image FreeMemblock,imgnum
//Now, get the width and height of the heightmap, these are stored in the first 2 dwords of the memblock
hwidth=memblock dword(FreeMemblock,0)
hheight=memblock dword(FreeMemblock,4)
//Now, lock the object and loop through each vertex of the geosphere
lock vertexdata for limb objectid,0
for i=0 to get vertexdata vertex count()-1
//Now, Get the UVs and multiply them by the width and height of the heightmap, this will give you the cordinates of the point you need to get heightmap data from
u#=get vertexdata U(i)
v#=get vertexdata V(i)
x=floor(u#*hwidth) : if x=>hwidth then x=hwidth-1 : if x<0 then x=0
y=floor(v#*hheight) : if y=>hheight then y=hheight-1 : if y<0 then y=0
//Now, calculate the position you need to get the height from inside the memblock
position=12+(x+y*(hwidth-1))*4
//Now get the height
height#=min#+rgbr(memblock dword(FreeMemblock,position))*((max#-min#)/255.0)
//Make a direction vector for the point
dx#=get vertexdata position x(i)
dy#=get vertexdata position y(i)
dz#=get vertexdata position z(i)
dist#=sqrt(dx#*dx#+dy#*dy#+dz#*dz#)
nx#=dx#/dist#
ny#=dy#/dist#
nz#=dz#/dist#
//Calculate new position
newx#=height#*nx#
newy#=height#*ny#
newz#=height#*nz#
//Set vertex position
set vertexdata position i,newx#,newy#,newz#
next i
unlock vertexdata
//Delete the memblock
delete memblock FreeMemblock
endfunction