Package engine.utility

Source Code of engine.utility.Space

package engine.utility;

import engine.geometry.Polygon;
import game.terrain.Chunk;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class Space {
    private static final int CELL_WIDTH = Chunk.WIDTH;
    private static final int CELL_HEIGHT = Chunk.HEIGHT;
    private final int rows;
    private final int cols;

    private static class ObjectPolygonHashMap extends HashMap<Object, Polygon> {
        private static final long serialVersionUID = -8752904839878943392L;
    }

    private Map<Object, Polygon> all;
    private Map<Object, Polygon>[][] grid;
    private Map<Object, Polygon> outside;

    public Space(double width, double height) {
        rows = (int) Math.ceil(height / CELL_HEIGHT);
        cols = (int) Math.ceil(width / CELL_WIDTH);
        all = new ObjectPolygonHashMap();
        grid = new ObjectPolygonHashMap[rows][cols];
        for (int r = 0; r < rows; r++) {
            for (int c = 0; c < cols; c++) {
                grid[r][c] = new ObjectPolygonHashMap();
            }
        }
        outside = new ObjectPolygonHashMap();
    }

    public Polygon putObject(Object object, Polygon polygon) {
        Polygon oldPolygon = null;
        if (all.containsKey(object)) {
            oldPolygon = removeObject(object);
        }
        all.put(object, new Polygon(polygon));
        int r1 = (int) Math.floor(polygon.getMinY() / CELL_HEIGHT);
        int r2 = (int) Math.ceil(polygon.getMaxY() / CELL_HEIGHT);
        int c1 = (int) Math.floor(polygon.getMinX() / CELL_WIDTH);
        int c2 = (int) Math.ceil(polygon.getMaxX() / CELL_WIDTH);
        boolean outsideHandled = false;
        for (int r = r1; r < r2; r++) {
            for (int c = c1; c < c2; c++) {
                try {
                    grid[r][c].put(object, polygon);
                } catch (ArrayIndexOutOfBoundsException e) {
                    if (!outsideHandled) {
                        outside.put(object, polygon);
                        outsideHandled = true;
                    }
                }
            }
        }
        return oldPolygon;
    }

    public Polygon removeObject(Object object) {
        Polygon polygon = all.remove(object);
        if (polygon == null) {
            return null;
        }
        int r1 = (int) Math.floor(polygon.getMinY() / CELL_HEIGHT);
        int r2 = (int) Math.ceil(polygon.getMaxY() / CELL_HEIGHT);
        int c1 = (int) Math.floor(polygon.getMinX() / CELL_WIDTH);
        int c2 = (int) Math.ceil(polygon.getMaxX() / CELL_WIDTH);
        boolean outsideHandled = false;
        for (int r = r1; r < r2; r++) {
            for (int c = c1; c < c2; c++) {
                try {
                    grid[r][c].remove(object);
                } catch (ArrayIndexOutOfBoundsException e) {
                    if (!outsideHandled) {
                        outside.remove(object);
                        outsideHandled = true;
                    }
                }
            }
        }
        return polygon;
    }

    /** @return all the objects which intersect the given polygon */
    public Set<Object> findObjects(Polygon polygon) {
        Set<Object> result = new HashSet<Object>();
        int r1 = (int) Math.floor(polygon.getMinY() / CELL_HEIGHT);
        int r2 = (int) Math.ceil(polygon.getMaxY() / CELL_HEIGHT);
        int c1 = (int) Math.floor(polygon.getMinX() / CELL_WIDTH);
        int c2 = (int) Math.ceil(polygon.getMaxX() / CELL_WIDTH);
        boolean outsideHandled = false;
        for (int r = r1; r < r2; r++) {
            for (int c = c1; c < c2; c++) {
                try {
                    for (Entry<Object, Polygon> e : grid[r][c].entrySet()) {
                        if (Physics.intersects(polygon, e.getValue())) {
                            result.add(e.getKey());
                        }
                    }
                } catch (ArrayIndexOutOfBoundsException ex) {
                    if (!outsideHandled) {
                        for (Entry<Object, Polygon> e : outside.entrySet()) {
                            if (Physics.intersects(polygon, e.getValue())) {
                                result.add(e.getKey());
                            }
                        }
                        outsideHandled = true;
                    }
                }
            }
        }
        return result;
    }

    /**
     * @return all the objects which intersect the given polygon that are of the
     *         given type
     */
    public <T> Set<T> findObjects(Polygon polygon, Class<T> type) {
        Set<T> result = new HashSet<T>();
        int r1 = (int) Math.floor(polygon.getMinY() / CELL_HEIGHT);
        int r2 = (int) Math.ceil(polygon.getMaxY() / CELL_HEIGHT);
        int c1 = (int) Math.floor(polygon.getMinX() / CELL_WIDTH);
        int c2 = (int) Math.ceil(polygon.getMaxX() / CELL_WIDTH);
        boolean outsideHandled = false;
        for (int r = r1; r < r2; r++) {
            for (int c = c1; c < c2; c++) {
                try {
                    for (Entry<Object, Polygon> e : grid[r][c].entrySet()) {
                        if (type.isInstance(e.getKey())) {
                            if (Physics.intersects(polygon, e.getValue())) {
                                @SuppressWarnings("unchecked")
                                T t = (T) e.getKey();
                                result.add(t);
                            }
                        }
                    }
                } catch (ArrayIndexOutOfBoundsException ex) {
                    if (!outsideHandled) {
                        for (Entry<Object, Polygon> e : outside.entrySet()) {
                            if (type.isInstance(e.getKey())) {
                                if (Physics.intersects(polygon, e.getValue())) {
                                    @SuppressWarnings("unchecked")
                                    T t = (T) e.getKey();
                                    result.add(t);
                                }
                            }
                        }
                        outsideHandled = true;
                    }
                }
            }
        }
        return result;
    }

    /**
     * @return a single object which intersects the given polygon and is of the
     *         given type
     */
    public <T> T findObject(Polygon polygon, Class<T> type) {
        int r1 = (int) Math.floor(polygon.getMinY() / CELL_HEIGHT);
        int r2 = (int) Math.ceil(polygon.getMaxY() / CELL_HEIGHT);
        int c1 = (int) Math.floor(polygon.getMinX() / CELL_WIDTH);
        int c2 = (int) Math.ceil(polygon.getMaxX() / CELL_WIDTH);
        boolean outsideHandled = false;
        for (int r = r1; r < r2; r++) {
            for (int c = c1; c < c2; c++) {
                try {
                    for (Entry<Object, Polygon> e : grid[r][c].entrySet()) {
                        if (type.isInstance(e.getKey())) {
                            if (Physics.intersects(polygon, e.getValue())) {
                                @SuppressWarnings("unchecked")
                                T t = (T) e.getKey();
                                return t;
                            }
                        }
                    }
                } catch (ArrayIndexOutOfBoundsException ex) {
                    if (!outsideHandled) {
                        for (Entry<Object, Polygon> e : outside.entrySet()) {
                            if (type.isInstance(e.getKey())) {
                                if (Physics.intersects(polygon, e.getValue())) {
                                    @SuppressWarnings("unchecked")
                                    T t = (T) e.getKey();
                                    return t;
                                }
                            }
                        }
                        outsideHandled = true;
                    }
                }
            }
        }
        return null;
    }
}
TOP

Related Classes of engine.utility.Space

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.