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 void doFileWrites(
      final File fname,
      final KzedMapTile mtile,
      final KzedBufferedImage img,
      final KzedBufferedImage img_day,
      final KzedZoomedMapTile zmtile,
      final File zoomFile,
      final KzedBufferedImage zimg,
      final KzedBufferedImage zimg_day,
      boolean rendered) {

    /* 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 */
    FileLockManager.getWriteLock(fname);
    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;
    if ((!fname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(), null, tx, ty))) {
      Debug.debug("saving image " + fname.getPath());
      try {
        ImageIO.write(img.buf_img, "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.getWorld(), new Client.Tile(mtile.getFilename()));
      hashman.updateHashCode(mtile.getKey(), null, tx, ty, crc);
      updated_fname = true;
    }
    KzedMap.freeBufferedImage(img);
    FileLockManager.releaseWriteLock(fname);
    MapManager.mapman.updateStatistics(mtile, null, true, updated_fname, !rendered);

    mtile.file = fname;

    boolean updated_dfname = false;
    File dfname = new File(fname.getParent(), mtile.getDayFilename());
    if (img_day != null) {
      FileLockManager.getWriteLock(dfname);
      crc = hashman.calculateTileHash(img.argb_buf);
      if ((!dfname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(), "day", tx, ty))) {
        Debug.debug("saving image " + dfname.getPath());
        try {
          ImageIO.write(img_day.buf_img, "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.getWorld(), new Client.Tile(mtile.getDayFilename()));
        hashman.updateHashCode(mtile.getKey(), "day", tx, ty, crc);
        updated_dfname = true;
      }
      KzedMap.freeBufferedImage(img_day);
      FileLockManager.releaseWriteLock(dfname);
      MapManager.mapman.updateStatistics(mtile, "day", true, updated_dfname, !rendered);
    }

    // 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);
    if (updated_fname || (!zoomFile.exists())) {
      saveZoomedTile(zmtile, zoomFile, zimg, ox, oy);
      MapManager.mapman.pushUpdate(zmtile.getWorld(), new Client.Tile(zmtile.getFilename()));
      ztile_updated = true;
    }
    KzedMap.freeBufferedImage(zimg);
    FileLockManager.releaseWriteLock(zoomFile);
    MapManager.mapman.updateStatistics(zmtile, null, true, ztile_updated, !rendered);

    if (zimg_day != null) {
      File zoomFile_day = new File(zoomFile.getParent(), zmtile.getDayFilename());
      ztile_updated = false;
      FileLockManager.getWriteLock(zoomFile_day);
      if (updated_dfname || (!zoomFile_day.exists())) {
        saveZoomedTile(zmtile, zoomFile_day, zimg_day, ox, oy);
        MapManager.mapman.pushUpdate(zmtile.getWorld(), new Client.Tile(zmtile.getDayFilename()));
        ztile_updated = true;
      }
      KzedMap.freeBufferedImage(zimg_day);
      FileLockManager.releaseWriteLock(zoomFile_day);
      MapManager.mapman.updateStatistics(zmtile, "day", true, ztile_updated, !rendered);
    }
  }
  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;
  }
Example #4
0
  @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;
  }