private void saveZoomedTile( final KzedZoomedMapTile zmtile, final File zoomFile, final DynmapBufferedImage zimg, int ox, int oy, String subkey) { BufferedImage zIm = null; DynmapBufferedImage kzIm = null; try { zIm = ImageIO.read(zoomFile); } catch (IOException e) { } catch (IndexOutOfBoundsException e) { } boolean zIm_allocated = false; if (zIm == null) { /* create new one */ kzIm = DynmapBufferedImage.allocateBufferedImage(KzedMap.tileWidth, KzedMap.tileHeight); zIm = kzIm.buf_img; zIm_allocated = true; Debug.debug("New zoom-out tile created " + zmtile.getFilename()); } else { Debug.debug("Loaded zoom-out tile from " + zmtile.getFilename()); } /* blit scaled rendered tile onto zoom-out tile */ zIm.setRGB( ox, oy, KzedMap.tileWidth / 2, KzedMap.tileHeight / 2, zimg.argb_buf, 0, KzedMap.tileWidth / 2); /* save zoom-out tile */ if (!zoomFile.getParentFile().exists()) zoomFile.getParentFile().mkdirs(); try { FileLockManager.imageIOWrite(zIm, ImageFormat.FORMAT_PNG, zoomFile); Debug.debug("Saved zoom-out tile at " + zoomFile.getName()); } catch (IOException e) { Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e); } catch (java.lang.NullPointerException e) { Debug.error("Failed to save zoom-out tile (NullPointerException): " + zoomFile.getName(), e); } if (zIm_allocated) DynmapBufferedImage.freeBufferedImage(kzIm); else zIm.flush(); }
private boolean doFileWrites( final File fname, final KzedMapTile mtile, final DynmapBufferedImage img, final DynmapBufferedImage img_day, final KzedZoomedMapTile zmtile, final File zoomFile, final DynmapBufferedImage zimg, final DynmapBufferedImage zimg_day) { boolean didwrite = false; /* Get coordinates of zoomed tile */ int ox = (mtile.px == zmtile.getTileX()) ? 0 : KzedMap.tileWidth / 2; int oy = (mtile.py == zmtile.getTileY()) ? 0 : KzedMap.tileHeight / 2; /* Test to see if we're unchanged from older tile */ TileHashManager hashman = MapManager.mapman.hashman; long crc = hashman.calculateTileHash(img.argb_buf); boolean updated_fname = false; int tx = mtile.px / KzedMap.tileWidth; int ty = mtile.py / KzedMap.tileHeight; FileLockManager.getWriteLock(fname); try { if ((!fname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(prefix), null, tx, ty))) { Debug.debug("saving image " + fname.getPath()); if (!fname.getParentFile().exists()) fname.getParentFile().mkdirs(); try { FileLockManager.imageIOWrite(img.buf_img, ImageFormat.FORMAT_PNG, fname); } catch (IOException e) { Debug.error("Failed to save image: " + fname.getPath(), e); } catch (java.lang.NullPointerException e) { Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e); } MapManager.mapman.pushUpdate(mtile.getDynmapWorld(), new Client.Tile(mtile.getFilename())); hashman.updateHashCode(mtile.getKey(prefix), null, tx, ty, crc); updated_fname = true; didwrite = true; } } finally { FileLockManager.releaseWriteLock(fname); DynmapBufferedImage.freeBufferedImage(img); } MapManager.mapman.updateStatistics(mtile, prefix, true, updated_fname, true); mtile.file = fname; boolean updated_dfname = false; File dfname = new File(mtile.getDynmapWorld().worldtilepath, mtile.getDayFilename()); if (img_day != null) { crc = hashman.calculateTileHash(img.argb_buf); FileLockManager.getWriteLock(dfname); try { if ((!dfname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(prefix), "day", tx, ty))) { Debug.debug("saving image " + dfname.getPath()); if (!dfname.getParentFile().exists()) dfname.getParentFile().mkdirs(); try { FileLockManager.imageIOWrite(img_day.buf_img, ImageFormat.FORMAT_PNG, dfname); } catch (IOException e) { Debug.error("Failed to save image: " + dfname.getPath(), e); } catch (java.lang.NullPointerException e) { Debug.error("Failed to save image (NullPointerException): " + dfname.getPath(), e); } MapManager.mapman.pushUpdate( mtile.getDynmapWorld(), new Client.Tile(mtile.getDayFilename())); hashman.updateHashCode(mtile.getKey(prefix), "day", tx, ty, crc); updated_dfname = true; didwrite = true; } } finally { FileLockManager.releaseWriteLock(dfname); DynmapBufferedImage.freeBufferedImage(img_day); } MapManager.mapman.updateStatistics(mtile, prefix + "_day", true, updated_dfname, true); } // Since we've already got the new tile, and we're on an async thread, just // make the zoomed tile here boolean ztile_updated = false; FileLockManager.getWriteLock(zoomFile); try { if (updated_fname || (!zoomFile.exists())) { saveZoomedTile(zmtile, zoomFile, zimg, ox, oy, null); MapManager.mapman.pushUpdate( zmtile.getDynmapWorld(), new Client.Tile(zmtile.getFilename())); zmtile.getDynmapWorld().enqueueZoomOutUpdate(zoomFile); ztile_updated = true; } } finally { FileLockManager.releaseWriteLock(zoomFile); DynmapBufferedImage.freeBufferedImage(zimg); } MapManager.mapman.updateStatistics(zmtile, null, true, ztile_updated, true); if (zimg_day != null) { File zoomFile_day = new File(zmtile.getDynmapWorld().worldtilepath, zmtile.getDayFilename()); ztile_updated = false; FileLockManager.getWriteLock(zoomFile_day); try { if (updated_dfname || (!zoomFile_day.exists())) { saveZoomedTile(zmtile, zoomFile_day, zimg_day, ox, oy, "day"); MapManager.mapman.pushUpdate( zmtile.getDynmapWorld(), new Client.Tile(zmtile.getDayFilename())); zmtile.getDynmapWorld().enqueueZoomOutUpdate(zoomFile_day); ztile_updated = true; } } finally { FileLockManager.releaseWriteLock(zoomFile_day); DynmapBufferedImage.freeBufferedImage(zimg_day); } MapManager.mapman.updateStatistics(zmtile, "day", true, ztile_updated, true); } return didwrite; }
@Override public boolean render(MapChunkCache cache, HDMapTile tile, String mapname) { Color rslt = new Color(); MapIterator mapiter = cache.getIterator(0, 0, 0); /* Build shader state object for each shader */ HDShaderState[] shaderstate = MapManager.mapman.hdmapman.getShaderStateForTile(tile, cache, mapiter, mapname); int numshaders = shaderstate.length; if (numshaders == 0) return false; /* Check if nether world */ boolean isnether = tile.getWorld().getEnvironment() == Environment.NETHER; /* Create buffered image for each */ DynmapBufferedImage im[] = new DynmapBufferedImage[numshaders]; DynmapBufferedImage dayim[] = new DynmapBufferedImage[numshaders]; int[][] argb_buf = new int[numshaders][]; int[][] day_argb_buf = new int[numshaders][]; for (int i = 0; i < numshaders; i++) { HDShader shader = shaderstate[i].getShader(); HDLighting lighting = shaderstate[i].getLighting(); if (shader.isEmittedLightLevelNeeded() || lighting.isEmittedLightLevelNeeded()) need_emittedlightlevel = true; if (shader.isSkyLightLevelNeeded() || lighting.isSkyLightLevelNeeded()) need_skylightlevel = true; im[i] = DynmapBufferedImage.allocateBufferedImage(tileWidth, tileHeight); argb_buf[i] = im[i].argb_buf; if (lighting.isNightAndDayEnabled()) { dayim[i] = DynmapBufferedImage.allocateBufferedImage(tileWidth, tileHeight); day_argb_buf[i] = dayim[i].argb_buf; } } /* Create perspective state object */ OurPerspectiveState ps = new OurPerspectiveState(mapiter, isnether); ps.top = new Vector3D(); ps.bottom = new Vector3D(); double xbase = tile.tx * tileWidth; double ybase = tile.ty * tileHeight; boolean shaderdone[] = new boolean[numshaders]; boolean rendered[] = new boolean[numshaders]; for (int x = 0; x < tileWidth; x++) { ps.px = x; for (int y = 0; y < tileHeight; y++) { ps.top.x = ps.bottom.x = xbase + x + 0.5; /* Start at center of pixel at Y=127.5, bottom at Y=-0.5 */ ps.top.y = ps.bottom.y = ybase + y + 0.5; ps.top.z = maxheight + 0.5; ps.bottom.z = minheight - 0.5; map_to_world.transform(ps.top); /* Transform to world coordinates */ map_to_world.transform(ps.bottom); ps.py = y; for (int i = 0; i < numshaders; i++) { shaderstate[i].reset(ps); } ps.raytrace(cache, mapiter, shaderstate, shaderdone); for (int i = 0; i < numshaders; i++) { if (shaderdone[i] == false) { shaderstate[i].rayFinished(ps); } else { shaderdone[i] = false; rendered[i] = true; } shaderstate[i].getRayColor(rslt, 0); argb_buf[i][(tileHeight - y - 1) * tileWidth + x] = rslt.getARGB(); if (day_argb_buf[i] != null) { shaderstate[i].getRayColor(rslt, 1); day_argb_buf[i][(tileHeight - y - 1) * tileWidth + x] = rslt.getARGB(); } } } } boolean renderone = false; /* Test to see if we're unchanged from older tile */ TileHashManager hashman = MapManager.mapman.hashman; for (int i = 0; i < numshaders; i++) { long crc = hashman.calculateTileHash(argb_buf[i]); boolean tile_update = false; String prefix = shaderstate[i].getMap().getPrefix(); if (rendered[i]) { renderone = true; MapType.ImageFormat fmt = shaderstate[i].getMap().getImageFormat(); String fname = tile.getFilename(prefix, fmt); File f = new File(tile.getDynmapWorld().worldtilepath, fname); FileLockManager.getWriteLock(f); try { if ((!f.exists()) || (crc != hashman.getImageHashCode(tile.getKey(), prefix, tile.tx, tile.ty))) { /* Wrap buffer as buffered image */ Debug.debug("saving image " + f.getPath()); if (!f.getParentFile().exists()) f.getParentFile().mkdirs(); try { FileLockManager.imageIOWrite(im[i].buf_img, fmt.getFileExt(), f); } catch (IOException e) { Debug.error("Failed to save image: " + f.getPath(), e); } catch (java.lang.NullPointerException e) { Debug.error("Failed to save image (NullPointerException): " + f.getPath(), e); } MapManager.mapman.pushUpdate(tile.getWorld(), new Client.Tile(fname)); hashman.updateHashCode(tile.getKey(), prefix, tile.tx, tile.ty, crc); tile.getDynmapWorld().enqueueZoomOutUpdate(f); tile_update = true; } else { Debug.debug("skipping image " + f.getPath() + " - hash match"); } } finally { FileLockManager.releaseWriteLock(f); DynmapBufferedImage.freeBufferedImage(im[i]); } MapManager.mapman.updateStatistics(tile, prefix, true, tile_update, !rendered[i]); /* Handle day image, if needed */ if (dayim[i] != null) { fname = tile.getDayFilename(prefix, fmt); f = new File(tile.getDynmapWorld().worldtilepath, fname); FileLockManager.getWriteLock(f); prefix = prefix + "_day"; tile_update = false; try { if ((!f.exists()) || (crc != hashman.getImageHashCode(tile.getKey(), prefix, tile.tx, tile.ty))) { /* Wrap buffer as buffered image */ Debug.debug("saving image " + f.getPath()); if (!f.getParentFile().exists()) f.getParentFile().mkdirs(); try { FileLockManager.imageIOWrite(dayim[i].buf_img, fmt.getFileExt(), f); } catch (IOException e) { Debug.error("Failed to save image: " + f.getPath(), e); } catch (java.lang.NullPointerException e) { Debug.error("Failed to save image (NullPointerException): " + f.getPath(), e); } MapManager.mapman.pushUpdate(tile.getWorld(), new Client.Tile(fname)); hashman.updateHashCode(tile.getKey(), prefix, tile.tx, tile.ty, crc); tile.getDynmapWorld().enqueueZoomOutUpdate(f); tile_update = true; } else { Debug.debug("skipping image " + f.getPath() + " - hash match"); } } finally { FileLockManager.releaseWriteLock(f); DynmapBufferedImage.freeBufferedImage(dayim[i]); } MapManager.mapman.updateStatistics(tile, prefix, true, tile_update, !rendered[i]); } } } return renderone; }