Cheers guys - i think normals are correct now so been doing little bits on UV
// show all errors
SetErrorMode(2)
#constant screenwidth=1024
#constant screenheight=768
#constant landheight#=150
global chunksize=5
global worldsize#=40
#constant speed#=1
// set window properties
SetWindowTitle( "Mesh Template" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 60, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
// perlin initialised
global permutations as integer[512] = [151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180]
for i=0 to 256
permutations[i+256] = permutations[i]
next
global moon
// Mesh initialise
Type Triangle
v1 as integer
v2 as integer
v3 as integer
endtype
Type Vertex
x as float
y as float
z as float
oldx as float
oldy as float
oldz as float
nx as float
ny as float
nz as float
u as float
v as float
endtype
Type Mesh
VertexList as Vertex[]
TriangleList as Triangle[]
endtype
global lander as Mesh
//
global angx#, angy#, startx#, starty#,camx#,camy#,camz#
global howmanylandblocks
startx#=screenwidth/2
starty#=screenheight/2
SetRawMousePosition(startx#,starty#)
img = createtexture()
SetImageMagFilter(img,0)
SetImageMinFilter(img,0)
SetupSkyandFog()
t= CreateText("Generating Terrain")
SetTextSize(t,64)
// create world of chunks
global worldchunks as integer[50,50]
text = CreateText("IM HOME")
SetTextSize(text,64)
SetTextPosition(text,screenwidth,screenheight/2)
x=0:z=0
for wx#=-worldsize#/2 to worldsize#/2
for wz#=-worldsize#/2 to worldsize#/2
emptymesh(lander)
createchunk(wx#*chunksize,0,wz#*chunksize,chunksize)
worldchunks[x,z] = CreateObjectFromMesh(lander)
SetObjectImage(worldchunks[x,z],img,1)
SetObjectPosition(worldchunks[x,z],0,0,0)
SetObjectLightMode(worldchunks[x,z],1)
SetTextPosition(t, screenwidth/2-GetTextTotalWidth(t)/2, screenheight/2-GetTextTotalHeight(t)/2)
sync()
inc z
next
inc x
z=0
next
DeleteText(t)
//ocean=createOcean()
//FixObjectToObject(ocean,land)
global bounce#=20
global bounceup=0
scale#=256 : offsetx#=0 : offsetz#=0
global angle#=0
time#=15.0 : skytime#=0
SetRawMousePosition(startx#,starty#)
CreatePointLight(1,getcamerax(1),getcameray(1),getcameraz(1),150,255,0,0)
lighttime#=1
SetSunActive(0)
lightb = CreateObjectCapsule(10,10,10)
homeb = CreateObjectCapsule(.5,1000,10)
SetObjectColor(homeb,255,0,0,255)
camx#=random2(-worldsize#/2 * chunksize, worldsize#/2 * chunksize)
camz#=random2(-worldsize#/2 * chunksize, worldsize#/2 * chunksize)
camy#=noise3D(camx#,0,camz#)+10
camx#=0
camz#=0
camy#=noise3D(camx#,0,camz#)+10
print(camx#)
print(camy#)
print(camz#)
MoveCameraLocalX(1,camx#)
MoveCameraLocalZ(1,camz#)
MoveCameraLocalY(1,camy#)
do
if GetTextExists(text)
SetTextPosition(text,gettextx(text)-10,screenheight/2)
endif
SetObjectPosition(lightb,0,noise3D(0,0,0)+10,0)
SetObjectPosition(homeb,0,noise3D(0,0,0)+10,0)
// fade the lights for fun
SetPointLightColor(1,255,0,0)
SetPointLightPosition(1,getobjectx(lightb),noise3D(0,0,0)-10,getobjectz(lightb))
getkeycontrols()
move_camera()
// interop the sky colour
// inc time#,.01
time#=ValFloat(mid(GetCurrentTime(),1,2) + "." + mid(GetCurrentTime(),4,2))
// time#=ValFloat("20.00")
if time#>5 and time#<=17
//SetSunActive(1)
dec skytime#,.002 // through a day
endif
if time#=18
SetSkyBoxSkyColor(mix(fract(time#)*2,135,0),mix(fract(time#)*2,206,0),mix(fract(time#)*2,235,0))
SetSkyBoxHorizonColor(mix(fract(time#)*2,0,0),mix(fract(time#)*2,119,0),mix(fract(time#)*2,190,0))
//SetSunActive(0) // for the lights to work
endif
if time#>18
SetSkyBoxSkyColor(mix(1,135,0),mix(1,206,0),mix(1,235,0))
SetSkyBoxHorizonColor(mix(1,0,0),mix(1,119,0),mix(1,190,0))
//SetSunActive(0) // for the lights to work
endif
if time#>=0 and time#<=5 then inc skytime#,.01 // through the night
setskysystemontimeofday("19:00")
print("time " + GetCurrentTime())
sync()
print(ScreenFPS())
loop
function setskysystemontimeofday(time$)
time# = ValFloat(mid(time$,1,2) + "." + mid(time$,4,2))
angle#=time# * 15
SetSunDirection(sin(angle#), cos(angle#),sin(angle#))
//SetObjectPosition(moon, 1000*sin(angle#),1000*cos(angle#),1000*sin(angle#))
//requires interopolation between different daylight/nighttime colours for better effect - coming soon
// time = val(mid(timeofday$,1,2))
time#=val(mid(time$,1,2))
/* if floor(time#)>24 // eveing
SetSkyBoxSkyColor(0,0,0)
SetSkyBoxHorizonColor(0,0,0)
else
if floor(time#)<5 // early morning
SetSkyBoxSkyColor(0,0,0)
SetSkyBoxHorizonColor(0,0,0)
else // day
SetSkyBoxSkyColor(135,206,235)
SetSkyBoxHorizonColor(0,119,190)
endif
endif
*/
endfunction
function getkeycontrols()
if GetRawKeyState(37)
MoveCameraLocalX(1,-speed#)
endif
if GetRawKeyState(38) or GetRawMouseLeftState() then MoveCameraLocalZ(1,speed#)
if GetRawKeyState(39) then MoveCameraLocalX(1,speed#)
if GetRawKeyState(40) then MoveCameraLocalZ(1,-speed#)
// hold down F and WS to fly up and down
if GetRawKeyState(70)
if GetRawKeyState(87) then inc camy#,speed#
if GetRawKeyState(83) then dec camy#,speed#
else
camy#=getheight(getcamerax(1), getcameraz(1)) + 5
endif
if GetRawKeyPressed(27) then end
//keep mouse in the window
if getpointerx()<100 then SetRawMousePosition(100,getpointery())
if getpointery()<100 then SetRawMousePosition(getpointerx(),100)
if getpointerx()>screenwidth-100 then SetRawMousePosition(screenwidth-100,getpointery())
if getpointery()>screenheight-100 then SetRawMousePosition(getpointerx(),screenheight-100)
endfunction
function move_camera()
SetCameraPosition(1, getcamerax(1),camy#,getcameraz(1))
// SetCameraPosition(1,camx#,camy#,camz#)
//move cam with mouse
fDiffX# = (GetPointerX() - startx#)/3.0
fDiffY# = (GetPointerY() - starty#)/3.0
newX# = angx# + fDiffY#
if ( newX# > 89 ) then newX# = 89
if ( newX# < -89 ) then newX# = -89
SetCameraRotation( 1, newX#, angy# + fDiffX#, 0 )
endfunction
function getheight(x#,z#)
scale#=200
start#=worldsize#*1000
ret#=noise3D((start#+ x#-5)/scale#,0,(start#+z#-5)/scale#) * landheight#
endfunction ret#
function createtexture()
// this creates 2 different images along the X
// and 1 in the Y
// it will show after
// in the createplan function the UMAX needs to be 2 and VMAX needs to be 1 as per this structure.
swap()
scale#=512
for x#=0 to 32
for y#=0 to 32
c=MakeColor(0,random(0,255),0)
DrawBox(x#,y#,x#+1,y#+1,c,c,c,c,1)
c=MakeColor(0,random(0,255),random(0,255))
DrawBox(x#+32,y#,x#+32+1,y#+1,c,c,c,c,1)
c=MakeColor(random(0,255),0,0)
DrawBox(x#+64,y#,x#+64+1,y#+1,c,c,c,c,1)
next
next
render()
img = GetImage(0,0,96,32)
sync()
sleep(1000)
endfunction img
function createplane(wx#, wy#, wz#, x#,y#,z#, size#, umax#, vmax#)
// umax# = how many different textures along the X on the Atlas created with CreateTexture Function? - default is 2 - see function above
// vmax# = how many different textures along the X on the Atlas created with CreateTexture Function? - default is 2 - see function above
scale#=200.0
pos#=size#/2.0
start#=worldsize#*1000
// find heights of the triangle points
y1#=noise3D((start#+((wx#)+x#-pos#))/scale#,y#,(start#+((wz#)+z#-pos#))/scale#) * landheight#
y2#=noise3D((start#+((wx#)+x#+pos#))/scale#,y#,(start#+((wz#)+z#-pos#))/scale#) * landheight#
y3#=noise3D((start#+((wx#)+x#+pos#))/scale#,y#,(start#+((wz#)+z#+pos#))/scale#) * landheight#
// work out normals for triangle 1
nx1#=wx#+x#-pos# : ny1#=y1# : nz1#=wz#+z#-pos#
len#=1.0/sqrt ( (nx1# * nx1#) + (ny1# * ny1#) + (nz1#*nz1#))
nx1#=nx1#/len# : ny1#=ny1#/len# : nz1#=nz1#/len#
nx2#=wx#+x#+pos# : ny2#=y2#: nz2#=wz#+z#-pos#
len#=1.0/sqrt ( (nx2# * nx2#) + (ny2# * ny2#) + (nz2#*nz2#))
nx2#=nx2#/len# : ny2#=ny2#/len# : nz2#=nz2#/len#
nx3#=wx#+x#+pos#: ny3#=y3#: nz3#=wz#+z#+pos#
len#=1.0/sqrt ( (nx3# * nx3#) + (ny3# * ny3#) + (nz3#*nz3#))
nx3#=nx3#/len# : ny3#=ny3#/len# : nz3#=nz3#/len#
if ny1#>0 then ny1#=ny1#*-1
if ny2#>0 then ny2#=ny2#*-1
if ny3#>0 then ny3#=ny3#*-1
// Render triangle 1
r#=random(0,umax#-1) * 1.0
AddVertex(lander, wx#+x#-pos#,y1#, wz#+z#-pos#, nx1#,ny1#,nz1#,(1.0/umax#)*r# ,0)
AddVertex(lander, wx#+x#+pos#,y2#, wz#+z#-pos#, nx2#,ny2#,nz2#,((1.0/umax#)*r#)+ (1.0/umax#) ,0)
AddVertex(lander, wx#+x#+pos#,y3#, wz#+z#+pos#, nx3#,ny3#,nz3#,((1.0/umax#)*r#) + (1.0/umax#) ,1)
// Find height of the triangle 2 points
y1#=noise3D((start#+((wx#)+x#-pos#))/scale#,y#,(start#+((wz#)+z#-pos#))/scale#) * landheight#
y2#=noise3D((start#+((wx#)+x#+pos#))/scale#,y#,(start#+((wz#)+z#+pos#))/scale#) * landheight#
y3#=noise3D((start#+((wx#)+x#-pos#))/scale#,y#,(start#+((wz#)+z#+pos#))/scale#) * landheight#
// work out normals for triangle 1
// ( v1 - v0 ) ^ (v2 - v1)
nx1#=wx#+x#-pos# : ny1#=y1# : nz1#=wz#+z#-pos#
len#=1.0/sqrt ( (nx1# * nx1#) + (ny1# * ny1#) + (nz1#*nz1#))
nx1#=nx1#/len# : ny1#=ny1#/len# : nz1#=nz1#/len#
nx2#=wx#+x#+pos# : ny2#=y2# : nz2#=wz#+z#+pos#
len#=1.0/sqrt ( (nx2# * nx2#) + (ny2# * ny2#) + (nz2#*nz2#))
nx2#=nx2#/len# : ny2#=ny2#/len# : nz2#=nz2#/len#
nx3#=wx#+x#-pos# : ny3#=y3# : nz3#=wz#+z#+pos#
len#=1.0/sqrt ( (nx3# * nx3#) + (ny3# * ny3#) + (nz3#*nz3#))
nx3#=nx3#/len# : ny3#=ny3#/len# : nz3#=nz3#/len#
if ny1#>0 then ny1#=ny1#*-1
if ny2#>0 then ny2#=ny2#*-1
if ny3#>0 then ny3#=ny3#*-1
// render triangle 2
AddVertex(lander, wx#+x#-pos#,y1#, wz#+z#-pos#,nx1#,ny1#,nz1#,(1.0/umax#)*r# ,0)
AddVertex(lander, wx#+x#+pos#,y2#, wz#+z#+pos#,nx2#,ny2#,nz2#,((1.0/umax#)*r#)+ (1.0/umax#) ,1)
AddVertex(lander, wx#+x#-pos#,y3#, wz#+z#+pos#,nx3#,ny3#,nz3#,(1.0/umax#)*r# ,1)
inc howmanylandblocks
endfunction
function createchunk(wx,wy,wz,chunksize)
scale#=256
chunksize#=32
for x#=-chunksize/2 to chunksize/2
for yy#=0 to 0
for z#=-chunksize/2 to chunksize/2
createplane(wx*chunksize#, wy, wz*chunksize#, x#*chunksize#,yy#,z#*chunksize#,chunksize#,3,1)
next
next
next
endfunction
Function AddVertex(m ref as Mesh, x as float, y as float, z as float, nx as float, ny as float,nz as float, u as float, v as float)
vert as vertex
vert.x = x
vert.y = y
vert.z = z
vert.oldx = x
vert.oldy = y
vert.oldz = z
vert.nx = nx
vert.ny = ny
vert.nz = nz
vert.u = u
vert.v = v
m.VertexList.Insert(vert)
endfunction
Function AddTriangle(m ref as Mesh, v1 as integer, v2 as integer, v3 as integer)
t as Triangle
t.v1 = v1
t.v2 = v2
t.v3 = v3
m.TriangleList.Insert(t)
endfunction
Function CreateObjectFromMesh(m ref as mesh)
s=60
l=32
VertexCount = m.VertexList.Length + 1
IndexCount = (m.TriangleList.Length + 1) * 3
IndexOffset = s + VertexCount*l
//VertexCount = m.VertexList.Length + 1
//IndexCount=0
//IndexOffset = 72 + VertexCount*36
memblock = CreateMemblock(IndexOffset+IndexCount*4)
SetMemblockInt(memblock,0,VertexCount)
SetMemblockInt(memblock,4,IndexCount)
SetMemblockInt(Memblock,8,3)
SetMemblockInt(memblock,12,l)
SetmemblockInt(memblock,16,s)
SetMemblockInt(memblock,20,IndexOffset)
SetMemblockInt(memblock,24,0x0c000300)
SetMemblockString(Memblock,28,"position")
SetMemblockInt(memblock,40,0x08000300)
SetMemblockString(memblock,44,"normal")
SetMemblockInt(memblock,52,0x04000200)
SetMemblockString(memblock,56,"uv")
// SetMemblockInt(memblock,60,0x08010401)
//SetMemblockString(memblock,64,"color")
for i = 0 to m.VertexList.Length
SetMemblockFloat(memblock,s+i*l,m.VertexList[i].x)
SetMemblockFloat(memblock,s+4+i*l,m.VertexList[i].y)
SetMemblockFloat(memblock,s+8+i*l,m.VertexList[i].z)
SetMemblockFloat(memblock,s+12+i*l,m.VertexList[i].nx)
SetMemblockFloat(memblock,s+16+i*l,m.VertexList[i].ny)
SetMemblockFloat(memblock,s+20+i*l,m.VertexList[i].nz)
SetMemblockFloat(memblock,s+24+i*l,m.VertexList[i].u)
SetMemblockFloat(memblock,s+28+i*l,m.VertexList[i].v)
// SetMemblockInt(memblock,104+i*36,m.VertexList[i].color)
next
for i = 0 to m.TriangleList.Length
SetMemblockInt(memblock,IndexOffset+i*12,m.TriangleList[i].v1)
SetMemblockInt(memblock,IndexOffset+i*12+4,m.TriangleList[i].v2)
SetMemblockInt(memblock,IndexOffset+i*12+8,m.TriangleList[i].v3)
next
id = CreateObjectFromMeshMemblock(memblock)
DeleteMemblock(memblock)
endfunction id
function emptymesh(c ref as Mesh)
c.VertexList.length=-1
c.TriangleList.length=-1
endfunction
function createOcean()
ocean = CreateObjectPlane(5000,5000)
SetObjectRotation(ocean, 90,0,0)
SetObjectPosition(ocean,0,noise3d(0,0,0)-10,0)
SetObjectColor(ocean,0,119,190,255)
endfunction ocean
function SetupSkyAndFog()
SetSkyBoxSkyColor(135,206,235)
SetSkyBoxHorizonColor(0,119,190)
SetSkyBoxHorizonSize(10,10)
SetSkyBoxSunColor(252,212,64)
SetFogMode(0)
SetFogRange(500,1000)
SetFogColor(220,219,223)
SetSkyBoxVisible(1)
SetCameraRange(1,.01,2000)
moon=CreateObjectSphere(50,50,50)
moonx#=1000 * -sin(angle#)
moony#=1000 * -cos(angle#)
moonz#=1000 * -sin(angle#)
SetObjectPosition(moon,moonx#,moony#,moonz#)
SetObjectColor(moon,255,255,255,255)
endfunction
// Perlin routines
function grad(hash,x#,y#,z#)
h = hash && 15
if h<8
u#=x#
else
u#=y#
endif
if h<4
v#=y#
if h=12 then v#=x#
if h=14 then v#=z#
endif
if h&&1 = 0
h1# = u#
else
h1# = -u#
endif
if h && 2 = 0
h2# = v#
else
h2# = -v#
endif
ret# = h1# + h2#
endfunction ret#
function mix( t#, a#, b#)
ret# = a# + t# * (b# - a#)
endfunction ret#
function fade( t# )
ret# = t# * t# * t# * (t# * (t# * 6.0-15.0) + 10.0)
endfunction ret#
function noise3D (x#,y#,z#)
x = floor(x#) && 0xff: y = floor(y#) && 0xff : z = floor(z#) && 0xff
dec x#, x : dec y#, y : dec z#, z
u# = fade(x#) : v# = fade(y#) : w# = fade(z#)
A = permutations[x+1] + y : AA = permutations[a+1]+z : AB = permutations[a+2]+z : b = permutations[x+2]+y : ba = permutations[b+1]+z : bb = permutations[b+2]+z
ret# = mix(w#, mix(v#, mix(u#, grad(permutations[AA +1 ], x# , y# , z# ), grad(permutations[BA +1 ], x#-1, y# , z# )), mix(u#, grad(permutations[AB +1 ], x# , y#-1, z# ), grad(permutations[BB +1 ], x#-1, y#-1, z# ))), mix(v#, mix(u#, grad(permutations[AA+2], x# , y# , z#-1 ), grad(permutations[BA+2], x#-1, y# , z#-1 )),mix(u#, grad(permutations[AB+2], x# , y#-1, z#-1 ),grad(permutations[BB+2], x#-1, y#-1, z#-1 ))))
endfunction ret#
function smoothstep(x#,y#,z#)
ret# = x#*x#*(3.0-2.0*x#)
endfunction ret#
function fract(value#)
whole=floor(value#)
ret#=abs(whole-value#)
endfunction ret#
function randomise(x#,y#)
endfunction
function dist(x#, y#)
ret# = sqrt (x# + y#)
endfunction ret#
function dist2D(x1#, y1#, x2#, y2#)
deltax# = x1# - x2#
deltay# = y1# - y2#
ret#=sqrt((deltax# * deltax#) + (deltay# * deltay#))
endfunction ret#
function dist3D(x1#, y1#, z1#, x2#, y2#, z2#, x3#, y3#, z3#)
ret#=sqrt((x1# * x2# * x3#) + (y1# * y2# * y3#) + (z1#*z2#*z3#))
endfunction ret#
Can tweak the constant LANDHEIGHT# to change the heights of the perlin
Hope some find it useful to learn and adapt
Come back soon with more if and when i get chance.