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#