scl <- function(x) {
  rg <- range(x, na.rm = TRUE);
  (x - rg[1])/diff(rg)
}

meshplot_discrete <- function(x, col = NULL, ...) {
  UseMethod("meshplot_discrete")
}
meshplot_discrete.BasicRaster <- function(x, col = NULL, crs = NULL, ...) {
  print("converting to single RasterLayer")
  meshplot_discrete(x[[1]])
}
meshplot_discrete.RasterLayer <- function(x, col = NULL, crs = NULL, ...) {
  qm <- quadmesh::quadmesh(x, na.rm = FALSE)
  ib <- qm$ib
  xy <- t(qm$vb[1:2, ])
  rm(qm)
  if (!is.null(crs) ) {
    if (!raster::isLonLat(x)) {
      xy <- rgdal::project(xy, raster::projection(x), inv = TRUE)
    }
    if (!raster::isLonLat(crs)) xy <- rgdal::project(xy, crs)
  }
  ## we have to remove any infinite vertices
  ## as this affects the entire thing
  bad <- !is.finite(xy[,1]) | !is.finite(xy[,2])
  ## but we must identify the bad xy in the index
  if (any(bad)) ib <- ib[,-which(bad)]
  ## the scale function must not propagate NA
  xx <- scl(xy[c(ib),1])
  yy <- scl(xy[c(ib),2])
  ## we need a identifier grouping for each 4-vertex polygon
  id <- rep(seq_len(ncol(ib)), each  = nrow(ib))
  grid::grid.newpage()
  
  ## we also have to deal with any values that are NA
  ## because they propagate to destroy the id
  cols <- viridis::viridis(100)[scl(values(x)) * 99 + 1]
  if (any(is.na(cols))) {
    colsna <- rep(cols, each = nrow(ib))
    bad2 <- is.na(colsna)
    xx <- xx[!bad2]
    yy <- yy[!bad2]
    id <- id[!bad2]
    cols <- cols[!is.na(cols)]
  }
  ## turn off col to avoid plotting pixel boundaries
  grid::grid.polygon(xx, yy, id,
                     gp = grid::gpar(col = NA, fill = cols))
  
}



library(raster)
## Loading required package: sp
data("wrld_simpl", package = "maptools")
r <- rasterize(wrld_simpl, raster(wrld_simpl, ncol = 720, nrow = 360))
## show the utility and speed of a mesh plot for near-lossless transformation
system.time(meshplot_discrete(r))

##    user  system elapsed 
##   3.430   0.365   3.799
system.time(meshplot_discrete(r, crs = "+proj=laea +datum=WGS84"))

##    user  system elapsed 
##   2.585   0.222   2.813