Search in sources :

Example 1 with Vector3D

use of org.dynmap.utils.Vector3D in project dynmap by webbukkit.

the class AreaMarkerImpl method testTileForBoostMarkers.

final boolean testTileForBoostMarkers(DynmapWorld w, HDPerspective perspective, final double tile_x, final double tile_y, final double tile_dim) {
    Map<String, BoundingBox> bbc = bb_cache;
    if (bbc == null) {
        bbc = new ConcurrentHashMap<String, BoundingBox>();
    }
    BoundingBox bb = bbc.get(perspective.getName());
    if (bb == null) {
        // No cached bounding box, so generate it
        bb = new BoundingBox();
        Vector3D v = new Vector3D();
        Vector3D v2 = new Vector3D();
        bb.xmin = Double.MAX_VALUE;
        bb.xmax = -Double.MAX_VALUE;
        bb.ymin = Double.MAX_VALUE;
        bb.ymax = -Double.MAX_VALUE;
        if (corners != null) {
            ArrayList<Coord> crn = corners;
            int cnt = crn.size();
            if (cnt == 2) {
                // Special case
                cnt = 4;
                crn = new ArrayList<Coord>();
                Coord c0 = corners.get(0);
                Coord c1 = corners.get(1);
                crn.add(c0);
                crn.add(new Coord(c0.x, c1.z));
                crn.add(c1);
                crn.add(new Coord(c1.x, c0.z));
            }
            double ymid = (this.ytop + this.ybottom) / 2.0;
            bb.xp = new double[cnt];
            bb.yp = new double[cnt];
            for (int i = 0; i < cnt; i++) {
                Coord c = crn.get(i);
                // get coords of point, in world coord
                v.x = c.x;
                // get coords of point, in world coord
                v.y = ymid;
                // get coords of point, in world coord
                v.z = c.z;
                // Transform to map coord
                perspective.transformWorldToMapCoord(v, v2);
                if (v2.x < bb.xmin)
                    bb.xmin = v2.x;
                if (v2.y < bb.ymin)
                    bb.ymin = v2.y;
                if (v2.x > bb.xmax)
                    bb.xmax = v2.x;
                if (v2.y > bb.ymax)
                    bb.ymax = v2.y;
                bb.xp[i] = v2.x;
                bb.yp[i] = v2.y;
            }
        }
        // Log.info("x=" + bb.xmin + " - " + bb.xmax + ",  y=" + bb.ymin + " - " + bb.ymax);
        bbc.put(perspective.getName(), bb);
        bb_cache = bbc;
    }
    final double tile_x2 = tile_x + tile_dim;
    final double tile_y2 = tile_y + tile_dim;
    if ((bb.xmin > tile_x2) || (bb.xmax < tile_x) || (bb.ymin > tile_y2) || (bb.ymax < tile_y)) {
        // Log.info("tile: " + tile_x + " / " + tile_y + " - miss");
        return false;
    }
    final int cnt = bb.xp.length;
    final double[] px = bb.xp;
    final double[] py = bb.yp;
    /* Now see if tile square intersects polygon - start with seeing if any point inside */
    if (MarkerImpl.testPointInPolygon(tile_x, tile_y, px, py)) {
        // If tile corner inside, we intersect
        return true;
    }
    if (MarkerImpl.testPointInPolygon(tile_x2, tile_y, px, py)) {
        // If tile corner inside, we intersect
        return true;
    }
    if (MarkerImpl.testPointInPolygon(tile_x, tile_y2, px, py)) {
        // If tile corner inside, we intersect
        return true;
    }
    if (MarkerImpl.testPointInPolygon(tile_x2, tile_y2, px, py)) {
        // If tile corner inside, we intersect
        return true;
    }
    /* Test if any polygon corners are inside square */
    for (int i = 0; i < cnt; i++) {
        if ((px[i] >= tile_x) && (px[i] <= tile_x2) && (py[i] >= tile_y) && (py[i] <= tile_y2)) {
            // If poly corner inside tile, we intersect
            return true;
        }
    }
    // Log.info("tile: " + tile_x + " / " + tile_y + " - hit");
    return false;
}
Also used : Vector3D(org.dynmap.utils.Vector3D)

Example 2 with Vector3D

use of org.dynmap.utils.Vector3D in project dynmap by webbukkit.

the class CircleMarkerImpl method testTileForBoostMarkers.

final boolean testTileForBoostMarkers(DynmapWorld w, HDPerspective perspective, double tile_x, double tile_y, double tile_dim) {
    Map<String, BoundingBox> bbc = bb_cache;
    if (bbc == null) {
        bbc = new ConcurrentHashMap<String, BoundingBox>();
    }
    BoundingBox bb = bbc.get(perspective.getName());
    if (bb == null) {
        // No cached bounding box, so generate it
        bb = new BoundingBox();
        Vector3D v = new Vector3D();
        Vector3D v2 = new Vector3D();
        bb.xmin = Double.MAX_VALUE;
        bb.xmax = -Double.MAX_VALUE;
        bb.ymin = Double.MAX_VALUE;
        bb.ymax = -Double.MAX_VALUE;
        // Just do 16 points for now
        int cnt = 16;
        bb.xp = new double[cnt];
        bb.yp = new double[cnt];
        for (int i = 0; i < cnt; i++) {
            v.x = this.x + (this.xr * Math.cos(2.0 * Math.PI * i / cnt));
            v.y = this.y;
            v.z = this.z + (this.zr * Math.sin(2.0 * Math.PI * i / cnt));
            // Transform to map coord
            perspective.transformWorldToMapCoord(v, v2);
            if (v2.x < bb.xmin)
                bb.xmin = v2.x;
            if (v2.y < bb.ymin)
                bb.ymin = v2.y;
            if (v2.x > bb.xmax)
                bb.xmax = v2.x;
            if (v2.y > bb.ymax)
                bb.ymax = v2.y;
            bb.xp[i] = v2.x;
            bb.yp[i] = v2.y;
        }
        // Log.info("x=" + bb.xmin + " - " + bb.xmax + ",  y=" + bb.ymin + " - " + bb.ymax);
        bbc.put(perspective.getName(), bb);
        bb_cache = bbc;
    }
    final double tile_x2 = tile_x + tile_dim;
    final double tile_y2 = tile_y + tile_dim;
    if ((bb.xmin > tile_x2) || (bb.xmax < tile_x) || (bb.ymin > tile_y2) || (bb.ymax < tile_y)) {
        // Log.info("tile: " + tile_x + " / " + tile_y + " - miss");
        return false;
    }
    final int cnt = bb.xp.length;
    final double[] px = bb.xp;
    final double[] py = bb.yp;
    /* Now see if tile square intersects polygon - start with seeing if any point inside */
    if (MarkerImpl.testPointInPolygon(tile_x, tile_y, px, py)) {
        // If tile corner inside, we intersect
        return true;
    }
    if (MarkerImpl.testPointInPolygon(tile_x2, tile_y, px, py)) {
        // If tile corner inside, we intersect
        return true;
    }
    if (MarkerImpl.testPointInPolygon(tile_x, tile_y2, px, py)) {
        // If tile corner inside, we intersect
        return true;
    }
    if (MarkerImpl.testPointInPolygon(tile_x2, tile_y2, px, py)) {
        // If tile corner inside, we intersect
        return true;
    }
    /* Test if any polygon corners are inside square */
    for (int i = 0; i < cnt; i++) {
        if ((px[i] >= tile_x) && (px[i] <= tile_x2) && (py[i] >= tile_y) && (py[i] <= tile_y2)) {
            // If poly corner inside tile, we intersect
            return true;
        }
    }
    // Log.info("tile: " + tile_x + " / " + tile_y + " - hit");
    return false;
}
Also used : Vector3D(org.dynmap.utils.Vector3D)

Example 3 with Vector3D

use of org.dynmap.utils.Vector3D in project dynmap by webbukkit.

the class IsoHDPerspective method getTileCoords.

@Override
public List<TileFlags.TileCoord> getTileCoords(DynmapWorld world, int x, int y, int z, int tilescale) {
    HashSet<TileFlags.TileCoord> tiles = new HashSet<TileFlags.TileCoord>();
    Vector3D block = new Vector3D();
    block.x = x;
    block.y = y;
    block.z = z;
    Vector3D corner = new Vector3D();
    int tileSize = 128 << tilescale;
    /* Loop through corners of the cube */
    for (int i = 0; i < 2; i++) {
        double inity = block.y;
        for (int j = 0; j < 2; j++) {
            double initz = block.z;
            for (int k = 0; k < 2; k++) {
                world_to_map.transform(block, corner);
                /* Get map coordinate of corner */
                tiles.add(new TileFlags.TileCoord(fastFloor(corner.x / tileSize), fastFloor(corner.y / tileSize)));
                block.z += 1;
            }
            block.z = initz;
            block.y += 1;
        }
        block.y = inity;
        block.x += 1;
    }
    return new ArrayList<TileFlags.TileCoord>(tiles);
}
Also used : Vector3D(org.dynmap.utils.Vector3D) ArrayList(java.util.ArrayList) TileFlags(org.dynmap.utils.TileFlags) HashSet(java.util.HashSet)

Example 4 with Vector3D

use of org.dynmap.utils.Vector3D in project dynmap by webbukkit.

the class IsoHDPerspective method getRequiredChunks.

@Override
public List<DynmapChunk> getRequiredChunks(MapTile tile) {
    if (!(tile instanceof HDMapTile))
        return Collections.emptyList();
    HDMapTile t = (HDMapTile) tile;
    int min_chunk_x = Integer.MAX_VALUE;
    int max_chunk_x = Integer.MIN_VALUE;
    int min_chunk_z = Integer.MAX_VALUE;
    int max_chunk_z = Integer.MIN_VALUE;
    int tileSize = tile.getTileSize();
    /* Make corners for volume: 
         * 0 = bottom-lower-left (xyz), 
         * 1 = top-lower-left (xyZ), 
         * 2 = bottom-upper-left (xYz), 
         * 3 = top-upper-left (xYZ),
         * 4 = bottom-lower-right (Xyz), 
         * 5 = top-lower-right (XyZ), 
         * 6 = bottom-upper-right (XYz), 
         * 7 = top-upper-right (XYZ) */
    Vector3D[] corners = new Vector3D[8];
    double dx = -basemodscale, dy = -basemodscale;
    /* Add 1 block on each axis */
    for (int x = t.tx, idx = 0; x <= (t.tx + 1); x++) {
        dy = -basemodscale;
        for (int y = t.ty; y <= (t.ty + 1); y++) {
            for (int z = 0; z <= 1; z++) {
                corners[idx] = new Vector3D();
                corners[idx].x = x * tileSize + dx;
                corners[idx].y = y * tileSize + dy;
                corners[idx].z = (z == 1) ? t.getDynmapWorld().worldheight : t.getDynmapWorld().minY;
                map_to_world.transform(corners[idx]);
                /* Compute chunk coordinates of corner */
                int cx = fastFloor(corners[idx].x / 16);
                int cz = fastFloor(corners[idx].z / 16);
                /* Compute min/max of chunk coordinates */
                if (min_chunk_x > cx)
                    min_chunk_x = cx;
                if (max_chunk_x < cx)
                    max_chunk_x = cx;
                if (min_chunk_z > cz)
                    min_chunk_z = cz;
                if (max_chunk_z < cz)
                    max_chunk_z = cz;
                idx++;
            }
            dy = basemodscale;
        }
        dx = basemodscale;
    }
    /* Make rectangles of X-Z projection of each side of the tile volume, 0 = top, 1 = bottom, 2 = left, 3 = right,
         * 4 = upper, 5 = lower */
    Polygon[] side = new Polygon[6];
    for (int sidenum = 0; sidenum < side.length; sidenum++) {
        side[sidenum] = new Polygon();
        for (int corner = 0; corner < corners_by_side[sidenum].length; corner++) {
            int cid = corners_by_side[sidenum][corner];
            side[sidenum].addVertex(corners[cid].x, corners[cid].z);
        }
    }
    /* Now, need to walk through the min/max range to see which chunks are actually needed */
    ArrayList<DynmapChunk> chunks = new ArrayList<DynmapChunk>();
    for (int x = min_chunk_x; x <= max_chunk_x; x++) {
        for (int z = min_chunk_z; z <= max_chunk_z; z++) {
            boolean hit = false;
            for (int sidenum = 0; (!hit) && (sidenum < side.length); sidenum++) {
                if (side[sidenum].clip(16.0 * x, 16.0 * z, 16.0 * (x + 1), 16.0 * (z + 1)) != null) {
                    hit = true;
                }
            }
            // xs += c;
            if (hit) {
                DynmapChunk chunk = new DynmapChunk(x, z);
                chunks.add(chunk);
            }
        }
    }
    return chunks;
}
Also used : DynmapChunk(org.dynmap.DynmapChunk) Vector3D(org.dynmap.utils.Vector3D) ArrayList(java.util.ArrayList) Polygon(org.dynmap.utils.Polygon)

Example 5 with Vector3D

use of org.dynmap.utils.Vector3D in project dynmap by webbukkit.

the class IsoHDPerspective method render.

@Override
public boolean render(MapChunkCache cache, HDMapTile tile, String mapname) {
    final long startTimestamp = System.currentTimeMillis();
    Color rslt = new Color();
    MapIterator mapiter = cache.getIterator(0, 0, 0);
    DynmapWorld world = tile.getDynmapWorld();
    int tileSize = tile.getTileSize();
    int scaled = 0;
    if ((tile.boostzoom > 0) && MarkerAPIImpl.testTileForBoostMarkers(cache.getWorld(), this, tile.tx * tileSize, tile.ty * tileSize, tileSize)) {
        scaled = tile.boostzoom;
    }
    int sizescale = 1 << scaled;
    /* Build shader state object for each shader */
    HDShaderState[] shaderstate = MapManager.mapman.hdmapman.getShaderStateForTile(tile, cache, mapiter, mapname, sizescale * this.basemodscale);
    int numshaders = shaderstate.length;
    if (numshaders == 0)
        return false;
    /* Check if nether world */
    boolean isnether = world.isNether();
    /* 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][];
    boolean[] isOpaque = new boolean[numshaders];
    int[] bgday = new int[numshaders];
    int[] bgnight = new int[numshaders];
    for (int i = 0; i < numshaders; i++) {
        HDLighting lighting = shaderstate[i].getLighting();
        im[i] = DynmapBufferedImage.allocateBufferedImage(tileSize * sizescale, tileSize * sizescale);
        argb_buf[i] = im[i].argb_buf;
        if (lighting.isNightAndDayEnabled()) {
            dayim[i] = DynmapBufferedImage.allocateBufferedImage(tileSize * sizescale, tileSize * sizescale);
            day_argb_buf[i] = dayim[i].argb_buf;
        }
        isOpaque[i] = !shaderstate[i].getMap().getImageFormat().getEncoding().hasAlpha;
        bgday[i] = shaderstate[i].getMap().getBackgroundARGBDay();
        bgnight[i] = shaderstate[i].getMap().getBackgroundARGBNight();
    }
    // Mark the tiles we're going to render as validated
    for (int i = 0; i < numshaders; i++) {
        MapTypeState mts = world.getMapState(shaderstate[i].getMap());
        if (mts != null) {
            mts.validateTile(tile.tx, tile.ty);
        }
    }
    /* Create perspective state object */
    OurPerspectiveState ps = new OurPerspectiveState(mapiter, isnether, scaled);
    ps.top = new Vector3D();
    ps.bottom = new Vector3D();
    ps.direction = new Vector3D();
    double xbase = tile.tx * tileSize;
    double ybase = tile.ty * tileSize;
    boolean[] shaderdone = new boolean[numshaders];
    boolean[] rendered = new boolean[numshaders];
    double height = maxheight;
    if (height == Integer.MIN_VALUE) {
        /* Not set - assume world height - 1 */
        if (isnether)
            height = 127;
        else
            height = tile.getDynmapWorld().worldheight - 1;
    }
    double miny = minheight;
    if (miny == Integer.MIN_VALUE) {
        /* Not set - assume world height - 1 */
        miny = tile.getDynmapWorld().minY;
    }
    for (int x = 0; x < tileSize * sizescale; x++) {
        ps.px = x;
        for (int y = 0; y < tileSize * sizescale; y++) {
            ps.top.x = ps.bottom.x = xbase + (x + 0.5) / sizescale;
            /* Start at center of pixel at Y=height+0.5, bottom at Y=-0.5 */
            ps.top.y = ps.bottom.y = ybase + (y + 0.5) / sizescale;
            ps.top.z = height + 0.5;
            ps.bottom.z = miny - 0.5;
            map_to_world.transform(ps.top);
            /* Transform to world coordinates */
            map_to_world.transform(ps.bottom);
            ps.direction.set(ps.bottom);
            ps.direction.subtract(ps.top);
            ps.py = y / sizescale;
            for (int i = 0; i < numshaders; i++) {
                shaderstate[i].reset(ps);
            }
            try {
                ps.raytrace(cache, shaderstate, shaderdone);
            } catch (Exception ex) {
                Log.severe("Error while raytracing tile: perspective=" + this.name + ", coord=" + mapiter.getX() + "," + mapiter.getY() + "," + mapiter.getZ() + ", blockid=" + mapiter.getBlockType() + ", lighting=" + mapiter.getBlockSkyLight() + ":" + mapiter.getBlockEmittedLight() + ", biome=" + mapiter.getBiome().toString(), ex);
                ex.printStackTrace();
            }
            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);
                int c_argb = rslt.getARGB();
                if (c_argb != 0)
                    rendered[i] = true;
                if (isOpaque[i] && (c_argb == 0)) {
                    argb_buf[i][(tileSize * sizescale - y - 1) * tileSize * sizescale + x] = bgnight[i];
                } else {
                    argb_buf[i][(tileSize * sizescale - y - 1) * tileSize * sizescale + x] = c_argb;
                }
                if (day_argb_buf[i] != null) {
                    shaderstate[i].getRayColor(rslt, 1);
                    c_argb = rslt.getARGB();
                    if (isOpaque[i] && (c_argb == 0)) {
                        day_argb_buf[i][(tileSize * sizescale - y - 1) * tileSize * sizescale + x] = bgday[i];
                    } else {
                        day_argb_buf[i][(tileSize * sizescale - y - 1) * tileSize * sizescale + x] = c_argb;
                    }
                }
            }
        }
    }
    boolean renderone = false;
    /* Test to see if we're unchanged from older tile */
    MapStorage storage = world.getMapStorage();
    for (int i = 0; i < numshaders; i++) {
        long crc = MapStorage.calculateImageHashCode(argb_buf[i], 0, argb_buf[i].length);
        boolean tile_update = false;
        String prefix = shaderstate[i].getMap().getPrefix();
        MapStorageTile mtile = storage.getTile(world, shaderstate[i].getMap(), tile.tx, tile.ty, 0, MapType.ImageVariant.STANDARD);
        mtile.getWriteLock();
        try {
            if (mtile.matchesHashCode(crc) == false) {
                /* Wrap buffer as buffered image */
                if (rendered[i]) {
                    mtile.write(crc, im[i].buf_img, startTimestamp);
                } else {
                    mtile.delete();
                }
                MapManager.mapman.pushUpdate(tile.getDynmapWorld(), new Client.Tile(mtile.getURI()));
                tile_update = true;
                renderone = true;
            } else {
                if (!rendered[i]) {
                    mtile.delete();
                }
            }
        } finally {
            mtile.releaseWriteLock();
            DynmapBufferedImage.freeBufferedImage(im[i]);
        }
        MapManager.mapman.updateStatistics(tile, prefix, true, tile_update, !rendered[i]);
        /* Handle day image, if needed */
        if (dayim[i] != null) {
            crc = MapStorage.calculateImageHashCode(day_argb_buf[i], 0, day_argb_buf[i].length);
            mtile = storage.getTile(world, shaderstate[i].getMap(), tile.tx, tile.ty, 0, MapType.ImageVariant.DAY);
            mtile.getWriteLock();
            tile_update = false;
            try {
                if (mtile.matchesHashCode(crc) == false) {
                    /* Wrap buffer as buffered image */
                    if (rendered[i]) {
                        mtile.write(crc, dayim[i].buf_img, startTimestamp);
                    } else {
                        mtile.delete();
                    }
                    MapManager.mapman.pushUpdate(tile.getDynmapWorld(), new Client.Tile(mtile.getURI()));
                    tile_update = true;
                    renderone = true;
                } else {
                    if (!rendered[i]) {
                        mtile.delete();
                    }
                }
            } finally {
                mtile.releaseWriteLock();
                DynmapBufferedImage.freeBufferedImage(dayim[i]);
            }
            MapManager.mapman.updateStatistics(tile, prefix + "_day", true, tile_update, !rendered[i]);
        }
    }
    return renderone;
}
Also used : MapStorageTile(org.dynmap.storage.MapStorageTile) Color(org.dynmap.Color) MapIterator(org.dynmap.utils.MapIterator) MapTypeState(org.dynmap.MapTypeState) MapStorage(org.dynmap.storage.MapStorage) DynmapBufferedImage(org.dynmap.utils.DynmapBufferedImage) Vector3D(org.dynmap.utils.Vector3D) DynmapWorld(org.dynmap.DynmapWorld) Client(org.dynmap.Client)

Aggregations

Vector3D (org.dynmap.utils.Vector3D)6 ArrayList (java.util.ArrayList)3 File (java.io.File)1 IOException (java.io.IOException)1 InputStreamReader (java.io.InputStreamReader)1 LineNumberReader (java.io.LineNumberReader)1 BitSet (java.util.BitSet)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 ZipFile (java.util.zip.ZipFile)1 Client (org.dynmap.Client)1 Color (org.dynmap.Color)1 DynmapChunk (org.dynmap.DynmapChunk)1 DynmapWorld (org.dynmap.DynmapWorld)1 MapTypeState (org.dynmap.MapTypeState)1 DynmapBlockState (org.dynmap.renderer.DynmapBlockState)1 RenderPatch (org.dynmap.renderer.RenderPatch)1 SideVisible (org.dynmap.renderer.RenderPatchFactory.SideVisible)1 MapStorage (org.dynmap.storage.MapStorage)1 MapStorageTile (org.dynmap.storage.MapStorageTile)1