Terrain

SourceEdit
local function grid(size, subdivisions)
  local vertices = {}
  local indices  = {}
  local step = size / (subdivisions - 1)
  for z = -size / 2, size / 2, step do
    for x = -size / 2, size / 2, step do
      table.insert(vertices, {x, 0, z})
      table.insert(vertices, {x, 0, z + step})
      table.insert(vertices, {x + step, 0, z})
      table.insert(vertices, {x, 0, z + step})
      table.insert(vertices, {x + step, 0, z + step})
      table.insert(vertices, {x + step, 0, z})
    end
  end
  return vertices
end

local function terrain_fn(x, z)
  return 4 * (lovr.math.noise(x * 0.05, z * 0.05) - 0.5)
end

function lovr.load()
  size = 50
  world = lovr.physics.newWorld(0, -9.81, 0, false)
  lovr.graphics.setBackgroundColor(0.208, 0.208, 0.275)
  local vertices, indices = grid(size, 100)
  for vi = 1, #vertices do
    local x,y,z = unpack(vertices[vi])
    vertices[vi][2] = terrain_fn(x, z) -- elevate grid to terrain height
  end
  mesh = lovr.graphics.newMesh(vertices)
  world:newTerrainCollider(size, terrain_fn) -- use callback to define elevations
  box_colliders = {}
end

function lovr.update(dt)
  if lovr.timer.getTime() % 1 < dt then -- spawn new box each second
    local collider = world:newBoxCollider(
      lovr.math.randomNormal(size / 10, 0),
      lovr.math.randomNormal(1, 20),
      lovr.math.randomNormal(size / 10, 0),
      1)
    table.insert(box_colliders, collider)
  end
  world:update(dt)
end

function lovr.draw(pass)
  pass:setColor(0.925, 0.745, 0.137)
  for _, collider in ipairs(box_colliders) do
    pass:box(mat4(collider:getPose()))
  end

  pass:setColor(0.565, 0.404, 0.463)
  pass:draw(mesh)

  pass:setWireframe(true)
  pass:setColor(0.388, 0.302, 0.412, 0.1)
  pass:draw(mesh)
end