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

meshplot_discrete <- function(x, crs = NULL, ...) {
  UseMethod("meshplot_discrete")
}
meshplot_discrete.BasicRaster <- function(x, crs = NULL, ...) {
  print("converting to single RasterLayer")
  meshplot_discrete(x[[1]])
}
meshplot_discrete.RasterLayer <- function(x, 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))

}

meshplot_discrete.Spatial <- function(x, crs = NULL,  ...) {
  #if (!is.null(field)) vals <- x[[field]] else vals <- seq_len(nrow(x))
  x <- rangl::rangl(x)

  tt <- rangl:::th3d()

  tt$vb <- t(cbind(x$v$x_, x$v$y_, 0, 1))

  vv <- x$v[, "vertex_"]
  vv$row_n <- seq(nrow(vv))
  pindex <- dplyr::inner_join(dplyr::inner_join(x$o[, c("object_")], x$t), x$tXv)
  vindex <- dplyr::inner_join(x$tXv, vv, "vertex_")
  tt$it <- t(matrix(vindex$row_n, ncol = 3, byrow = TRUE))

  it <- tt$it
  xy <- t(tt$vb[1:2, ])
  rm(tt)
  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)) it <- it[,-which(bad)]
  ## the scale function must not propagate NA
  xx <- scl(xy[c(it),1])
  yy <- scl(xy[c(it),2])
  ## we need a identifier grouping for each 4-vertex polygon
  id <- rep(seq_len(ncol(it)), each  = nrow(it))
  colid <- seq_len(ncol(it))
  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(colid) * 99 + 1]
  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.375   0.427   3.802
system.time(meshplot_discrete(r, crs = "+proj=laea +datum=WGS84"))

##    user  system elapsed 
##   2.581   0.187   2.768
system.time(meshplot_discrete(wrld_simpl, crs = "+proj=laea +datum=WGS84"))
## Warning in rgl.init(initValue, onlyNULL): RGL: unable to open X11 display
## Warning: 'rgl_init' failed, running with rgl.useNULL = TRUE
## Joining, by = "object_"
## Joining, by = "triangle_"

##    user  system elapsed 
##  22.698   0.330  23.072