YATTA!
It works. Spherical LOD engine. Very slow mind you but it works! The engine has yet to be updated with real textures, atmospheric effects and climate differences across the planet.
I am very conserned with the speed of the program now, it may not be too noticible whilst walking on the planets surface but whilst flying a plane it can really be anoying. The phythagorus distance function is making it quite slow and I shall try to find an alternative. The smoothing command also makes it quite a bit slower but I think this is nessacary otherwise the planet terrain looks like a chesboard.
Please look at the code and see if you can find anyways to improve speed:
sync on : set display mode 1024,768,32,1 : autocam off : set ambient light 10 : set camera range 1,10000 : hide light 0
make object triangle 60001,0,0,0,0,0,0,0,0,0
make light 1
position light 1,75000,0,-100000
set light range 1,1000000
make light 2
position light 2,-75000,0,-100000
set light range 2,1000000
`generate a grass texture
create bitmap 1,64,64
set current bitmap 1
for x=0 to 64 : for y=0 to 64
color=rnd(200)
ink rgb(50+color,50+color,50+color),0
dot x,y
next y : next x
get image 1,0,0,64,64
`generate water texture
for x=0 to 64 : for y=0 to 64
ink rgb(50+rnd(50),150+rnd(50),200+rnd(50)),0
dot x,y
next y : next x
get image 2,0,0,64,64
delete bitmap 1
`make the basic meshes
`2*2
k#=100
for sx=0 to 1 : for sz=0 to 1
sx#=sx : sz#=sz
make object triangle 2,sx#*k#,0,sz#*k#,sx#*k#,0,(sz#+1)*k#,(sx#+1)*k#,0,(sz#+1)*k#
make mesh from object 1,2
delete object 2
make object triangle 2,sx#*k#,0,sz#*k#,(sx#+1)*k#,0,(sz#+1)*k#,(sx#+1)*k#,0,sz#*k#
make mesh from object 2,2
delete object 2
make object 2,1,0
add limb 2,1,2
make mesh from object (sx+1)*2+(sz+1),2
delete object 2
next sz : next sx
make object triangle 2,0,0,0,0,0,0,0,0,0
for s=1 to 4
add limb 2,s,s+2
next s
make mesh from object 101,2
delete object 2
`8*8
k#=25
for sx=0 to 7 : for sz=0 to 7
sx#=sx : sz#=sz
make object triangle 2,sx#*k#,0,sz#*k#,sx#*k#,0,(sz#+1)*k#,(sx#+1)*k#,0,(sz#+1)*k#
make mesh from object 1,2
delete object 2
make object triangle 2,sx#*k#,0,sz#*k#,(sx#+1)*k#,0,(sz#+1)*k#,(sx#+1)*k#,0,sz#*k#
make mesh from object 2,2
delete object 2
make object 2,1,0
add limb 2,1,2
make mesh from object (sx+1)*8+(sz+1),2
delete object 2
next sz : next sx
make object triangle 2,0,0,0,0,0,0,0,0,0
for s=1 to 64
add limb 2,s,s+8
next s
make mesh from object 102,2
delete object 2
`32*32
k#=6.25
limb=1
make object triangle 3,0,0,0,0,0,0,0,0,0
for sx=0 to 31 : for sz=0 to 31
sx#=sx : sz#=sz
make object triangle 2,sx#*k#,0,sz#*k#,sx#*k#,0,(sz#+1)*k#,(sx#+1)*k#,0,(sz#+1)*k#
make mesh from object 1,2
delete object 2
make object triangle 2,sx#*k#,0,sz#*k#,(sx#+1)*k#,0,(sz#+1)*k#,(sx#+1)*k#,0,sz#*k#
make mesh from object 2,2
delete object 2
make object 2,1,0
add limb 2,1,2
make mesh from object 100,2
delete object 2
add limb 3,limb,100
limb=limb+1
next sz : next sx
make mesh from object 103,3
delete object 3
dim tile#(9,9)
dim tertile#(17,17)
dim terraintile#(33,33)
dim tiles#(6,26,26,3)
`0=limb
`1=altitude
`2=lod state
`0=hidden
`1=2*2
`2=4*4
`3=8*8
for s=1 to 6
for t=1 to 5
x=rnd(7)+1
z=rnd(7)+1
for xx=1 to 3 : for zz=1 to 3
terraintile#(x+xx,z+zz)=rnd(100)+75
next zz : next xx
next t
for x=0 to 13 : for z=0 to 13
h1#=terraintile#(x,z) : h2#=terraintile#(x+1,z) : h3#=terraintile#(x,z+1) : h4#=terraintile#(x+1,z+1)
for xx=0 to 1 : for zz=0 to 1
px#=xx : px#=px#/2 : px2#=1-px#
pz#=zz : pz#=pz#/2 : pz2#=1-pz#
tiles#(s,xx+x*2,zz+z*2,1)=h1#*px2#*pz2#+h2#*px#*pz2#+h3#*px2#*pz#+h4#*px#*pz#
if x>0 and z>0 and x<13 and z<13 then tiles#(s,xx+x*2,zz+z*2,1)=tiles#(s,xx+x*2,zz+z*2,1)+rnd(50)-25
next zz : next xx
next z : next x
next s
for s=1 to 6
ob=49001+1000*s
for x=0 to 25 : for z=0 to 25
make object ob,101,0
position object ob,0,0,0
if s=1 then rotate object ob,0,0,0
if s=2 then rotate object ob,90,0,0
if s=3 then rotate object ob,90,90,0
if s=4 then rotate object ob,90,180,0
if s=5 then rotate object ob,90,270,0
if s=6 then rotate object ob,180,0,0
h1#=tiles#(s,x,z,1)
h2#=tiles#(s,x+1,z,1)
h3#=tiles#(s,x,z+1,1)
h4#=tiles#(s,x+1,z+1,1)
lock vertexdata for limb ob,0
convert object fvf ob,338
verts=get vertexdata vertex count()-1
for v=0 to verts
posx#=get vertexdata position x(v)
posz#=get vertexdata position z(v)
ppx#=(posx#/200) : ppx2#=1 :ppx2#=ppx2#-ppx#
ppz#=(posz#/200) : ppz2#=1 :ppz2#=ppz2#-ppz#
posy#=(h1#*ppx2#*ppz2#)+(h2#*ppx#*ppz2#)+(h3#*ppx2#*ppz#)+(h4#*ppx#*ppz#)
rx#=posx#+x*200-2500 : rz#=posz#+z*200-2500
dist#=sqrt(rx#^2+(2500)^2+rz#^2)
dist#=dist#-2500-posy#
position object 60001,rx#,2500,rz#
point object 60001,0,0,0
move object 60001,dist#
rx#=object position x(60001) : ry#=object position y(60001) : rz#=object position z(60001)
set vertexdata UV v,posx#/100,posz#/100
set vertexdata position v,rx#,ry#,rz#
if posy#>110
SET VERTEXDATA DIFFUSE v,RGB(0,200,0)
else
SET VERTEXDATA DIFFUSE v,RGB(200,150,50)
endif
next v
unlock vertexdata
tiles#(s,x,z,0)=ob
tiles#(s,x,z,2)=1
texture object ob,1 : set object normals ob : set object texture ob,1,1 : set object radius ob,-1
ob=ob+1
next z : next x
next s
make object sphere 2,5200,32,64
position object 2,0,0,0
xrotate object 2,90
set object 2,1,1,1,1,1,1,1
texture object 2,2
set object transparency 2,5
set alpha mapping on 2,75
zoom#=100
ink rgb(0,0,0),0
make object cube 3,10
position object 3,0,3000,0
point object 3,0,0,0
do
text 10,10,"FPS rate: "+str$(screen fps())
text 10,30,"Arrow keys to move, mouse to look"
if upkey()=1 then move object 3,5
if downkey()=1 then move object 3,-5
if rightkey()=1 then roll object right 3,3
if leftkey()=1 then roll object left 3,3
x#=object position x(3)
y#=object position y(3)
z#=object position z(3)
text 10,50,str$(x#)
text 10,70,str$(y#)
text 10,90,str$(z#)
position camera x#,y#,z#
set camera to object orientation 3
move camera -1*zoom#
mmx#=mousemovex()*0.1
mmy#=mousemovey()*0.1
pitch object down 3,mmy#
turn object right 3,mmx#
cx#=camera position x()
cy#=camera position y()
cz#=camera position z()
dist#=sqrt(cx#^2+cy#^2+cz#^2)
if dist#<2600
set object cull 2,0
else
set object cull 2,1
endif
`------------------------------------------------
`-- MAGIC LOD CODE --
`------------------------------------------------
for s=1 to 6
for x=0 to 25 : for z=0 to 25
ob=tiles#(s,x,z,0)
if s=1
xpos#=x*200+100-2500
ypos#=2550
zpos#=z*200+100-2500
endif
if s=2
xpos#=x*200+100-2500
ypos#=-z*200-100+2500
zpos#=2550
endif
if s=3
xpos#=2550
ypos#=-z*200-100+2500
zpos#=-x*200-100+2500
endif
if s=4
xpos#=-x*200-100+2500
ypos#=-z*200-100+2500
zpos#=-2550
endif
if s=5
xpos#=-2550
ypos#=-z*200-100+2500
zpos#=x*200+100-2500
endif
if s=6
xpos#=x*200+100-2500
ypos#=-2550
zpos#=-z*200-100+2500
endif
position object 60001,xpos#,ypos#,zpos#
dst#=sqrt(xpos#^2+ypos#^2+zpos#^2)
point object 60001,0,0,0
move object 60001,dst#-2550
xpos#=object position x(60001) : ypos#=object position y(60001) : zpos#=object position z(60001)
dist#=sqrt((cx#-xpos#)^2+(cy#-ypos#)^2+(cz#-zpos#)^2)
if dist#>2500
if tiles#(s,x,z,2)=1 then hide object ob : tiles#(s,x,z,2)=0
else
if tiles#(s,x,z,2)=0 then show object ob : tiles#(s,x,z,2)=1
endif
change=0
if dist#>400 and tiles#(s,x,z,2)>1
change=1
change mesh tiles#(s,x,z,0),0,101
tiles#(s,x,z,2)=1
endif
if dist#>200 and dist#<400 and tiles#(s,x,z,2)<>2
change=1
change mesh tiles#(s,x,z,0),0,102
tiles#(s,x,z,2)=2
endif
if dist#<200 and tiles#(s,x,z,2)<>3
change=1
change mesh tiles#(s,x,z,0),0,103
tiles#(s,x,z,2)=3
endif
`update the mesh
if change=1
terrainarray(s,x,z)
convert object fvf tiles#(s,x,z,0),338
lock vertexdata for limb tiles#(s,x,z,0),0
verts=get vertexdata vertex count()-1
for v=0 to verts
posx#=get vertexdata position x(v)
posz#=get vertexdata position z(v)
xx#=(posx#/200)*32 : zz#=(posz#/200)*32
xx=ceil(xx#) : zz=ceil(zz#)
posy#=terraintile#(xx,zz)
ppx#=posx#/200 : ppz#=posz#/200
if posx#<1 then posy#=(1-ppz#)*tiles#(s,x,z,1)+ppz#*tiles#(s,x,z+1,1)
if posz#<1 then posy#=(1-ppx#)*tiles#(s,x,z,1)+ppx#*tiles#(s,x+1,z,1)
if posx#>199 then posy#=(1-ppz#)*tiles#(s,x+1,z,1)+ppz#*tiles#(s,x+1,z+1,1)
if posz#>199 then posy#=(1-ppx#)*tiles#(s,x,z+1,1)+ppx#*tiles#(s,x+1,z+1,1)
rx#=posx#+x*200-2500 : rz#=posz#+z*200-2500
dst#=sqrt(rx#^2+(2500)^2+rz#^2)
dst#=dst#-2500-posy#
position object 60001,rx#,2500,rz#
point object 60001,0,0,0
move object 60001,dst#
rx#=object position x(60001) : ry#=object position y(60001) : rz#=object position z(60001)
if tiles#(s,x,z,2)=1 then set vertexdata UV v,posx#/100,posz#/100
if tiles#(s,x,z,2)=2 then set vertexdata UV v,posx#/50,posz#/50
if tiles#(s,x,z,2)=3 then set vertexdata UV v,posx#/25,posz#/25
set vertexdata position v,rx#,ry#,rz#
if posy#>110
SET VERTEXDATA DIFFUSE v,RGB(0,200,0)
else
SET VERTEXDATA DIFFUSE v,RGB(200,150,50)
endif
next v
unlock vertexdata
texture object tiles#(s,x,z,0),1
set object normals tiles#(s,x,z,0)
set object smoothing tiles#(s,x,z,0),25
text 100,100,"UPDATED"
endif
next z : next x
next s
sync
loop
function terrainarray(s,xx,zz)
r=0
h1#=tiles#(s,xx,zz,1)
h2#=tiles#(s,xx+1,zz,1)
h3#=tiles#(s,xx,zz+1,1)
h4#=tiles#(s,xx+1,zz+1,1)
FOR x=0 to 8
x#=x : x#=x#/8
x2#=1 : x2#=x2#-x#
tile#(x,0)=h1#*x2#+h2#*x#
tile#(x,8)=h3#*x2#+h4#*x#
tile#(0,x)=h1#*x2#+h3#*x#
tile#(8,x)=h2#*x2#+h4#*x#
next x
tile#(4,4)=h1#*0.25+h2#*0.25+h3#*0.25+h4#*0.25+fracal(x,z,4,4,4)
tile#(2,4)=tile#(0,4)*0.5+tile#(4,4)*0.5+fracal(xx,zz,2,4,4)
tile#(4,2)=tile#(4,0)*0.5+tile#(4,4)*0.5+fracal(xx,zz,4,2,4)
tile#(6,4)=tile#(8,4)*0.5+tile#(4,4)*0.5+fracal(xx,zz,6,4,4)
tile#(4,6)=tile#(4,8)*0.5+tile#(4,4)*0.5+fracal(xx,zz,4,6,4)
for t=1 to 4
if t=1 then x=2 : z=2
if t=2 then x=6 : z=2
if t=3 then x=2 : z=6
if t=4 then x=6 : z=6
tile#(x,z)=tile#(x-2,z-2)*0.25+tile#(x-2,z+2)*0.25+tile#(x+2,z-2)*0.25+tile#(x+2,z+2)*0.25+fracal(xx,zz,x,z,4)
next t
tile#(2,1)=tile#(2,2)*0.5+tile#(2,0)*0.5+fracal(xx,zz,2,1,3)
tile#(4,1)=tile#(4,2)*0.5+tile#(4,0)*0.5+fracal(xx,zz,4,1,3)
tile#(6,1)=tile#(6,2)*0.5+tile#(6,0)*0.5+fracal(xx,zz,6,1,3)
tile#(1,2)=tile#(2,2)*0.5+tile#(0,2)*0.5+fracal(xx,zz,1,2,3)
tile#(3,2)=tile#(2,2)*0.5+tile#(4,2)*0.5+fracal(xx,zz,3,2,3)
tile#(5,2)=tile#(4,2)*0.5+tile#(6,2)*0.5+fracal(xx,zz,5,2,3)
tile#(7,2)=tile#(6,2)*0.5+tile#(8,2)*0.5+fracal(xx,zz,7,2,3)
tile#(2,3)=tile#(2,4)*0.5+tile#(2,2)*0.5+fracal(xx,zz,2,3,3)
tile#(4,3)=tile#(4,4)*0.5+tile#(4,2)*0.5+fracal(xx,zz,4,3,3)
tile#(6,3)=tile#(6,4)*0.5+tile#(6,2)*0.5+fracal(xx,zz,6,3,3)
tile#(1,4)=tile#(2,4)*0.5+tile#(0,4)*0.5+fracal(xx,zz,1,4,3)
tile#(3,4)=tile#(2,4)*0.5+tile#(4,4)*0.5+fracal(xx,zz,3,4,3)
tile#(5,4)=tile#(4,4)*0.5+tile#(6,4)*0.5+fracal(xx,zz,5,4,3)
tile#(7,4)=tile#(6,4)*0.5+tile#(8,4)*0.5+fracal(xx,zz,7,4,3)
tile#(2,5)=tile#(2,6)*0.5+tile#(2,4)*0.5+fracal(xx,zz,2,5,3)
tile#(4,5)=tile#(4,6)*0.5+tile#(4,4)*0.5+fracal(xx,zz,4,5,3)
tile#(6,5)=tile#(6,6)*0.5+tile#(6,4)*0.5+fracal(xx,zz,6,5,3)
tile#(1,6)=tile#(2,6)*0.5+tile#(0,6)*0.5+fracal(xx,zz,1,6,3)
tile#(3,6)=tile#(2,6)*0.5+tile#(4,6)*0.5+fracal(xx,zz,3,6,3)
tile#(5,6)=tile#(4,6)*0.5+tile#(6,6)*0.5+fracal(xx,zz,5,6,3)
tile#(7,6)=tile#(6,6)*0.5+tile#(8,6)*0.5+fracal(xx,zz,7,6,3)
tile#(2,7)=tile#(2,8)*0.5+tile#(2,6)*0.5+fracal(xx,zz,2,7,3)
tile#(4,7)=tile#(4,8)*0.5+tile#(4,6)*0.5+fracal(xx,zz,4,7,3)
tile#(6,7)=tile#(6,8)*0.5+tile#(6,6)*0.5+fracal(xx,zz,6,7,3)
for t=1 to 16
if t=1 then x=1 : z=1
if t=2 then x=3 : z=1
if t=3 then x=5 : z=1
if t=4 then x=7 : z=1
if t=5 then x=1 : z=3
if t=6 then x=3 : z=3
if t=7 then x=5 : z=3
if t=8 then x=7 : z=3
if t=9 then x=1 : z=5
if t=10 then x=3 : z=5
if t=11 then x=5 : z=5
if t=12 then x=7 : z=5
if t=13 then x=1 : z=7
if t=14 then x=3 : z=7
if t=15 then x=5 : z=7
if t=16 then x=7 : z=7
tile#(x,z)=tile#(x-1,z-1)*0.25+tile#(x-1,z+1)*0.25+tile#(x+1,z-1)*0.25+tile#(x+1,z+1)*0.25+fracal(xx,zz,x,z,3)
next t
for x=0 to 8
tertile#(x*2,0)=tile#(x,0)
tertile#(x*2,17)=tile#(x,8)
tertile#(0,x*2)=tile#(0,x)
tertile#(17,x*2)=tile#(8,x)
tertile#(x*2,1)=tile#(x,0)
tertile#(x*2,16)=tile#(x,8)
tertile#(1,x*2)=tile#(0,x)
tertile#(16,x*2)=tile#(8,x)
if x+1<9
tertile#(x*2+1,0)=tile#(x,0)*0.5+tile#(x+1,0)*0.5
tertile#(x*2+1,17)=tile#(x,8)*0.5+tile#(x+1,8)*0.5
tertile#(0,x*2+1)=tile#(0,x)*0.5+tile#(0,x+1)*0.5
tertile#(17,x*2+1)=tile#(8,x)*0.5+tile#(8,x+1)*0.5
tertile#(x*2+1,1)=tile#(x,0)*0.5+tile#(x+1,0)*0.5
tertile#(x*2+1,16)=tile#(x,8)*0.5+tile#(x+1,8)*0.5
tertile#(1,x*2+1)=tile#(0,x)*0.5+tile#(0,x+1)*0.5
tertile#(16,x*2+1)=tile#(8,x)*0.5+tile#(8,x+1)*0.5
else
tertile#(x*2+1,0)=tile#(x,0)
tertile#(x*2+1,17)=tile#(x,8)
tertile#(0,x*2+1)=tile#(0,x)
tertile#(17,x*2+1)=tile#(8,x)
tertile#(x*2+1,1)=tile#(x,0)
tertile#(x*2+1,16)=tile#(x,8)
tertile#(1,x*2+1)=tile#(0,x)
tertile#(16,x*2+1)=tile#(8,x)
endif
next x
for x=0 to 8 : for z=0 to 8
tertile#(x*2,z*2)=tile#(x,z)+fracal(xx,zz,x*2,z*2,2)
h#=tile#(x,z)*0.5+tile#(x+1,z)*0.5
tertile#(x*2+1,z*2)=h#+fracal(xx,zz,x*2+1,z*2,2)
h#=tile#(x,z)*0.5+tile#(x,z+1)*0.5
tertile#(x*2,z*2+1)=h#+fracal(xx,zz,x*2,z*2+1,2)
h#=tile#(x,z)*0.25+tile#(x+1,z)*0.25+tile#(x,z+1)*0.25+tile#(x+1,z+1)*0.25
tertile#(x*2+1,z*2+1)=h#+fracal(xx,zz,x*2+1,z*2+1,2)
next z : next x
for x=0 to 16 : for z=0 to 16
terraintile#(x*2,z*2)=tertile#(x,z)+fracal(xx,zz,x*2,z*2,1)
h#=tertile#(x,z)*0.5+tertile#(x+1,z)*0.5
terraintile#(x*2+1,z*2)=h#+fracal(xx,zz,x*2+1,z*2,1)
h#=tertile#(x,z)*0.5+tertile#(x,z+1)*0.5
terraintile#(x*2,z*2+1)=h#+fracal(xx,zz,x*2,z*2+1,1)
h#=tertile#(x,z)*0.25+tertile#(x+1,z)*0.25+tertile#(x,z+1)*0.25+tertile#(x+1,z+1)*0.25
terraintile#(x*2+1,z*2+1)=h#+fracal(xx,zz,x*2+1,z*2+1,1)
next z : next x
endfunction
function fracal(xx,zz,x,z,v#)
randomize xx*zz*x*z
r#=(rnd(20)-10)*(v#^2)/25
endfunction r#