set display mode 1280, 1024, 32 sync on sync rate 0 color backdrop 0 backdrop on autocam off randomize timer() null = make vector3(1) Type Vert x as float y as float z as float nx as float ny as float nz as float u as float v as float EndType #constant TERRAIN_SIZE 64 gosub MAKE_TERRAIN make object sphere 2, 1 color object 2, 0xAAFF4444 set object transparency 2, 3 hide object 2 KeyW = 0 WireFrame = 1 CamX# = -10 : CamTargetX# = CamX# CamZ# = -10 : CamTargetZ# = CamZ# position camera CamX#, 20, CamZ# point camera 10, 0, 10 position mouse screen width() * 0.5, screen height() * 0.5 oldMousePosX = -1 : oldMousePosY = -1 frameTime# = 1.0 startTime = timer() do frameTime# = (frameTime# * 0.8) + ((timer() - startTime) * 0.2) startTime = timer() mx = mousemovex() my = mousemovey() mz = mousemovez() if keystate(17) if KeyW = 0 KeyW = 1 if WireFrame = 1 then WireFrame = 0 else WireFrame = 1 set object wireframe 1, WireFrame endif else KeyW = 0 endif ` text 0, 10, "MC: " + str$(mouseclick()) text 0,0, "Pos: " + str$(object position x(2)) + ", " + str$(object position z(2)) if mouseclick() = 2 x = int(object position x(2)) z = int(object position z(2)) if oldMousePosX = -1 oldMousePosX = mousex() oldMousePosY = mousey() oldH = H(x, z).y endif lock vertexdata for limb 1, 0 `if mz > 0 ` inc H(x, z).y, 0.1 `else ` if mz < 0 then inc H(x, z).y, -0.1 `endif H(x, z).y = oldH - (mousey() - oldMousePosY) for i = 0 to 5 v = WaveVerts(x + ArrayOffsets(i, 0), z + ArrayOffsets(i, 1), i) set vertexdata position v, get vertexdata position x(v), H(x, z).y, get vertexdata position z(v) next i for xR = x-1 to x + 1 for zR = z-1 to z+1 createNormal(1, 1.0, H(xR,zR-1).y, H(xR+1,zR).y, H(xR,zR+1).y, H(xR-1,zR).y) for i = 0 to 5 v = WaveVerts(xR + ArrayOffsets(i, 0), zR + ArrayOffsets(i, 1), i) set vertexdata normals v, x vector3(1), y vector3(1), z vector3(1) next i next zR next xR unlock vertexdata else if oldMousePosX <> -1 position mouse oldMousePosX, oldMousePosY oldMousePosX = -1 : oldMousePosY = -1 : oldH = 0 endif obj = pick object(mousex(), mousey(), 1, 1) `if more than 0 then we are... if obj > 0 `Place the pointer position object 2, int(camera position x() + get pick vector x()), camera position y() + get pick vector y(), int(camera position z() + get pick vector z()) CamTargetX# = get pick vector x() - 30.0 CamTargetZ# = get pick vector z() - 30.0 if object visible(2) = 0 then show object 2 else `hide the pointer hide object 2 endif endif `Sort out the camera CamX# = curvevalue(CamTargetX#, CamX#, 200.0 / frameTime#) CamZ# = curvevalue(CamTargetZ#, CamZ#, 200.0 / frameTime#) position camera CamX#, 20, CamZ# sync loop end MAKE_TERRAIN: `First we need an array to store the verts position/ID Dim WaveVerts(TERRAIN_SIZE, TERRAIN_SIZE, 6) `3rd dimensions... ` 0 = TL ` 1 = BL ` 2 = TR ` 3 = BL ` 4 = BR ` 5 = TR Dim ArrayOffsets(5, 2) ` X Z ArrayOffsets(0, 0) = 0 : ArrayOffsets(0, 1) = 0 ArrayOffsets(1, 0) = 0 : ArrayOffsets(1, 1) = -1 ArrayOffsets(2, 0) = -1 : ArrayOffsets(2, 1) = 0 ArrayOffsets(3, 0) = 0 : ArrayOffsets(3, 1) = -1 ArrayOffsets(4, 0) = -1 : ArrayOffsets(4, 1) = -1 ArrayOffsets(5, 0) = -1 : ArrayOffsets(5, 1) = 0 Dim H(TERRAIN_SIZE, TERRAIN_SIZE) as Vert `Generate a flat terrain for x = 0 to TERRAIN_SIZE for z =0 to TERRAIN_SIZE H(x, z).x = x H(x, z).y = 0 H(x, z).z = z next z next x `Calculate Normals CalculateNormals(1, 1, TERRAIN_SIZE-1, TERRAIN_SIZE-1) make memblock 1, 12 + (TERRAIN_SIZE * TERRAIN_SIZE * 192) write memblock dword 1, 0, 274 : `FVF FORMAT write memblock dword 1, 4, 32 : `SIZE PER VERT write memblock dword 1, 8, TERRAIN_SIZE * TERRAIN_SIZE * 6 : `VERT NO for i = 0 to TERRAIN_SIZE-1 for j = 0 to TERRAIN_SIZE-1 p = ((i * TERRAIN_SIZE) + j) n = 12 + (p * 192) `Poly 1 x = i : z = j : n = WriteMemblockMeshVert(1, n, H(x,z).x, H(x,z).y, H(x,z).z, H(x,z).nx, H(x,z).ny, H(x,z).nz, H(x,z).u, H(x,z).v) x = i : z = j+1 : n = WriteMemblockMeshVert(1, n, H(x,z).x, H(x,z).y, H(x,z).z, H(x,z).nx, H(x,z).ny, H(x,z).nz, H(x,z).u, H(x,z).v) x = i+1 : z = j : n = WriteMemblockMeshVert(1, n, H(x,z).x, H(x,z).y, H(x,z).z, H(x,z).nx, H(x,z).ny, H(x,z).nz, H(x,z).u, H(x,z).v) `Poly 2 x = i : z = j+1 : n = WriteMemblockMeshVert(1, n, H(x,z).x, H(x,z).y, H(x,z).z, H(x,z).nx, H(x,z).ny, H(x,z).nz, H(x,z).u, H(x,z).v) x = i+1 : z = j+1 : n = WriteMemblockMeshVert(1, n, H(x,z).x, H(x,z).y, H(x,z).z, H(x,z).nx, H(x,z).ny, H(x,z).nz, H(x,z).u, H(x,z).v) x = i+1 : z = j : n = WriteMemblockMeshVert(1, n, H(x,z).x, H(x,z).y, H(x,z).z, H(x,z).nx, H(x,z).ny, H(x,z).nz, H(x,z).u, H(x,z).v) WaveVerts(i, j, 0) = (p * 6) + 0 :`Top Left WaveVerts(i, j, 1) = (p * 6) + 1 :`Top Right a WaveVerts(i, j, 2) = (p * 6) + 2 :`Top Right b WaveVerts(i, j, 3) = (p * 6) + 3 :`Bottom Right WaveVerts(i, j, 4) = (p * 6) + 4 :`Bottom Left a WaveVerts(i, j, 5) = (p * 6) + 5 :`Bottom Left b next j next i make mesh from memblock 1, 1 make object 1, 1, 0 delete mesh 1 delete memblock 1 set object wireframe 1, 1 return function CalculateNormals(x1, z1, x2, z2) `Its Normal time baby!! for x = x1 to x2 for z = z1 to z2 createNormal(1, 1.0, H(x,z-1).y, H(x+1,z).y, H(x,z+1).y, H(x-1,z).y) H(x,z).nx = x vector3(1) H(x,z).ny = y vector3(1) H(x,z).nz = z vector3(1) next z next x endfunction function createNormal(v, SIZE#, hUp#, hRight#, hDown#, hLeft#) set vector3 v, hLeft#-hRight#, SIZE#, hUp#-hDown# normalize vector3 v, v endfunction function WriteMemblockMeshVert(m, n, x#, y#, z#, nx#, ny#, nz#, u#, v#) write memblock float 1, n + 0, x# :`X write memblock float 1, n + 4, y# :`Y write memblock float 1, n + 8, z# :`Z write memblock float 1, n + 12, nx# :`NX write memblock float 1, n + 16, ny# :`NY write memblock float 1, n + 20, nz# :`NZ write memblock float 1, n + 24, u# :`X write memblock float 1, n + 28, v# :`Y inc n, 32 endfunction n function RndFloat(max#) r# = (rnd(2147483647) / 2147483647.0) * max# endfunction r#