diff --git a/src/main/java/org/terasology/navgraph/BaseRegion.java b/src/main/java/org/terasology/navgraph/BaseRegion.java index e5b69b2..392a41d 100644 --- a/src/main/java/org/terasology/navgraph/BaseRegion.java +++ b/src/main/java/org/terasology/navgraph/BaseRegion.java @@ -20,6 +20,9 @@ /** * @author synopia + * Abstract class representing a 2d region which floors {@link Floor} and regions {@link Region} derive + * from. They allow us to divide the landscape and store information about the nature of blocks + * (Passable or not) making it easier to handle. */ public abstract class BaseRegion { public int id; @@ -27,23 +30,51 @@ public abstract class BaseRegion { protected BitMap map; protected Floor floor; + /** + * Creates a BaseRegion. The newly created Base Region has a fixed size defined by in-game ChunkConstants + * + * @param id the id of the base region. It is used to uniquely identify a base region, Floor or Region and + * is particularly useful while merging regions when they are connected + */ protected BaseRegion(int id) { this.id = id; map = new BitMap(); } + /** + * Marks a point in the region as walkable by characters + * + * @param x the x co-ordinate of the point with respect to region's top-left corner (the corner with the + * smallest x and y values) + * @param y the y co-ordinate of the point with respect to region's top-left corner (the corner with the + * smallest x and y values) + */ public void setPassable(int x, int y) { map.setPassable(x, y); } + /** + * Function to get the map representing the region + * + * @return bitmap of the region + */ public BitMap getMap() { return map; } + /** + * Returns neighbours with whom this region shares a side The neighbour regions are random and the order depends on + * the landscape + * + * @return set of neighbouring regions + */ public Set getNeighborRegions() { return neighborRegions; } + /** + * @return the id of the base region along with the number of neighbouring regions + */ @Override public String toString() { return id + "\nrc = " + neighborRegions.size(); diff --git a/src/main/java/org/terasology/navgraph/BitMap.java b/src/main/java/org/terasology/navgraph/BitMap.java index 14eff0b..e47326d 100644 --- a/src/main/java/org/terasology/navgraph/BitMap.java +++ b/src/main/java/org/terasology/navgraph/BitMap.java @@ -19,13 +19,19 @@ import java.util.List; /** - * @author synopia + * @author synopia Representation of a region or floor {@link Floor} The BitMap consists of a number of bits, each of + * which represent a block. A value of true or 1 means that the block is passable */ public class BitMap { public static final int KERNEL_SIZE = 3; public static final float SQRT_2 = (float) Math.sqrt(2); BitSet map; + /** + * Creates a new Bitmap + * A bitmap created this way always has a fixed number of nodes, decided by in-game Chunk + * constants The default value for all the bits are false or 0. + */ public BitMap() { map = new BitSet(getNumberOfNodes()); } @@ -53,6 +59,12 @@ public boolean isPassable(int x, int y) { return isPassable(offset(x, y)); } + /** + * Function that adds all the possible nodes that you could possibly go to from the current position + * + * @param offset the offset of the current position + * @param successors the list into which the successor nodes will be added + */ public void getSuccessors(int offset, List successors) { int x = getX(offset); int y = getY(offset); @@ -83,16 +95,32 @@ public void getSuccessors(int offset, List successors) { } } + /** + * Tells you whether there is any overlap between 'this' (the one that called the function) map and 'other' map + * + * @param other the map with which you want to check overlap + * @return true if there is any overlap + */ public boolean overlap(BitMap other) { BitSet temp = (BitSet) map.clone(); temp.and(other.map); return temp.cardinality() > 0; } + /** + * Merges 'this' map and 'other' and sets its value to 'this' + * + * @param other bitmap with which you want to merge + */ public void merge(BitMap other) { map.or(other.map); } + /** + * Gives information about the map with 'X's representing Walkable Blocks and spaces representing blocked areas + * + * @return + */ @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -114,6 +142,11 @@ public String toString() { return sb.toString(); } + /** + * Function that return number of nodes in the bitmap + * + * @return number of cells in the map + */ public int getNumberOfNodes() { return getWidth() * getHeight(); } @@ -126,6 +159,11 @@ public int getHeight() { return NavGraphChunk.SIZE_Z; } + /** + * @param from start position + * @param to end postion + * @return the Euclidean distance between two neighbouring cells in 2D + */ public float exactDistance(int from, int to) { int diff = to - from; if (diff == -getWidth() || diff == 1 || diff == getWidth() || diff == -1) { diff --git a/src/main/java/org/terasology/navgraph/Floor.java b/src/main/java/org/terasology/navgraph/Floor.java index 664f445..326fb1f 100644 --- a/src/main/java/org/terasology/navgraph/Floor.java +++ b/src/main/java/org/terasology/navgraph/Floor.java @@ -115,7 +115,7 @@ public boolean isEntrance(int x, int y) { * Sets entranceMap[x + y * NavGraphChunk.SIZE_Z] to an entrance. * @param x the x location of the Block * @param y the y location of the Block - * @return Entrance object at (x,y) + * @return entrance object at (x,y) */ public Entrance setEntrance(int x, int y) { if (entranceMap[x + y * NavGraphChunk.SIZE_Z] != null) { @@ -175,7 +175,7 @@ public List entrances() { * Returns the block at the parameters location with getCell(x,y) and sets this object as the floor of the block. * @param fx the x coordinate in the Chunk * @param fy the y coordinate in the Chunk - * @return The block at (fx,fy) + * @return the block at (fx,fy) */ WalkableBlock getBlock(int fx, int fy) { NavGraphCell cell = navGraphChunk.getCell(fx, fy); diff --git a/src/main/java/org/terasology/navgraph/FloorFinder.java b/src/main/java/org/terasology/navgraph/FloorFinder.java index 1f7dde1..c378f56 100644 --- a/src/main/java/org/terasology/navgraph/FloorFinder.java +++ b/src/main/java/org/terasology/navgraph/FloorFinder.java @@ -27,6 +27,7 @@ /** * @author synopia + * Marks all the regions, floors and sweeps in a chunk */ public class FloorFinder { private List regions = Lists.newArrayList(); diff --git a/src/main/java/org/terasology/navgraph/NavGraphCell.java b/src/main/java/org/terasology/navgraph/NavGraphCell.java index 38ce90f..25932de 100644 --- a/src/main/java/org/terasology/navgraph/NavGraphCell.java +++ b/src/main/java/org/terasology/navgraph/NavGraphCell.java @@ -20,10 +20,17 @@ /** * @author synopia + * Represents each cell in a region. */ public class NavGraphCell { public final List blocks = new ArrayList(); + /** + * Adds a Walkable block to a Cell in the map. + * Since the cells, are only in 2D, each cell can have multiple WalkableBlocks at different heights + * + * @param walkableBlock the Walkable Block you want to add to the NavGraphCell + */ public void addBlock(WalkableBlock walkableBlock) { if (blocks.size() == 0) { blocks.add(walkableBlock); @@ -32,6 +39,12 @@ public void addBlock(WalkableBlock walkableBlock) { } } + /** + * Returns a Walkable block at a particular height in the NavGraphCell + * + * @param height the height of the Walkable Block you want + * @return the Walkable Block at some height in this NavGraphCell + */ public WalkableBlock getBlock(int height) { for (WalkableBlock block : blocks) { if (block.height() == height) { diff --git a/src/main/java/org/terasology/navgraph/NavGraphChanged.java b/src/main/java/org/terasology/navgraph/NavGraphChanged.java index b61b6e4..ecb1072 100644 --- a/src/main/java/org/terasology/navgraph/NavGraphChanged.java +++ b/src/main/java/org/terasology/navgraph/NavGraphChanged.java @@ -19,6 +19,7 @@ /** * Created by synopia on 02.02.14. + * An Event that is called when the NavGraphChunk is updated either by block placement or removal in the terrain */ public class NavGraphChanged implements Event { } diff --git a/src/main/java/org/terasology/navgraph/NavGraphChunk.java b/src/main/java/org/terasology/navgraph/NavGraphChunk.java index 5d8913f..284b611 100644 --- a/src/main/java/org/terasology/navgraph/NavGraphChunk.java +++ b/src/main/java/org/terasology/navgraph/NavGraphChunk.java @@ -29,6 +29,7 @@ /** * @author synopia + * Represents a Chunk in the terrain with it's floors and walkable blocks */ public class NavGraphChunk { public static final int SIZE_X = ChunkConstants.SIZE_X; @@ -56,6 +57,12 @@ public class NavGraphChunk { /* package protected */ NavGraphCell[] cells = new NavGraphCell[SIZE_X * SIZE_Z]; private WorldProvider world; + /** + * Creates a new NavGraphChunk and the NavGraphCells that belong to it + * + * @param world the WorldProvider of the currently rendered world + * @param chunkPos position of the Chunk which the newly created NavGraphChunk will represent + */ public NavGraphChunk(WorldProvider world, Vector3i chunkPos) { this.world = world; this.worldPos = new Vector3i(chunkPos); @@ -65,6 +72,10 @@ public NavGraphChunk(WorldProvider world, Vector3i chunkPos) { } } + /** + * Called when there is a change in terrain. + * It re-marks all the floors within the NavGraphChunk. + */ public void update() { new WalkableBlockFinder(world).findWalkableBlocks(this); new FloorFinder().findFloors(this); @@ -117,6 +128,9 @@ public void connectNeighborMaps(NavGraphChunk left, NavGraphChunk up, NavGraphCh } } + /** + * Sets all the entrances that connect two floors together + */ public void findContour() { for (Floor floor : floors) { floor.resetEntrances(); @@ -135,6 +149,15 @@ public void findContour() { } } + /** + * Connects a block to a block from a different NavGraphChunk + * + * @param block the block which you want to connect + * @param dx the x co-ordinate of the neighbouring block with respect to neighbour chunk + * @param dz the z co-ordinate of the neighbouring block with respect to neighbour chunk + * @param neighbor the neighbouring NavGraphChunk we want to connect to + * @param neighborId the id of the neighbour NavGraphChunk + */ private void connectToNeighbor(WalkableBlock block, int dx, int dz, NavGraphChunk neighbor, int neighborId) { if (dx < 0 || dx >= NavGraphChunk.SIZE_X || dz < 0 || dz >= NavGraphChunk.SIZE_Z) { return; @@ -218,6 +241,12 @@ public WalkableBlock getBlock(int x, int y, int z) { return getCell(x - worldPos.x, z - worldPos.z).getBlock(y); } + /** + * Returns a floor of a particuar id + * + * @param id id of the floor we want + * @return the floor with corresponding id + */ public Floor getFloor(int id) { for (Floor floor : floors) { if (floor.id == id) { diff --git a/src/main/java/org/terasology/navgraph/NavGraphSystem.java b/src/main/java/org/terasology/navgraph/NavGraphSystem.java index f1a3e35..aad2637 100644 --- a/src/main/java/org/terasology/navgraph/NavGraphSystem.java +++ b/src/main/java/org/terasology/navgraph/NavGraphSystem.java @@ -67,6 +67,10 @@ public void shutdown() { taskMaster.shutdown(new ShutdownTask(), false); } + /** + * Checks if the terrain has been changed and sends a NavGraphChanged event which rebuilds the NavGraphChunk. + * @param delta The time (in seconds) since the last engine update. + */ @Override public void update(float delta) { if (dirty) { @@ -79,6 +83,12 @@ public void update(float delta) { } } + /** + * Called whenever a block is changed in the terrain + * @param pos position of the changed block + * @param newBlock the block it was changed to + * @param originalBlock the block it initially was + */ @Override public void onBlockChanged(Vector3i pos, Block newBlock, Block originalBlock) { Vector3i chunkPos = ChunkMath.calcChunkPos(pos); @@ -90,6 +100,11 @@ public void chunkReady(OnChunkLoaded event, EntityRef worldEntity) { taskMaster.offer(new UpdateChunkTask(event.getChunkPos())); } + /** + * + * @param pos Position of the Walkable Block + * @return WalkableBlock at that position + */ public WalkableBlock getBlock(Vector3i pos) { Vector3i chunkPos = ChunkMath.calcChunkPos(pos); NavGraphChunk navGraphChunk = heightMaps.get(chunkPos); @@ -100,11 +115,21 @@ public WalkableBlock getBlock(Vector3i pos) { } } + /** + * Gives the WalkableBlock on which a minion is + * @param minion The minion Walkable Block + * @return a Walkable Block on which the minion is + */ public WalkableBlock getBlock(EntityRef minion) { Vector3f pos = minion.getComponent(LocationComponent.class).getWorldPosition(); return getBlock(pos); } + /** + * Approximates the WalkableBlock based on float coordinates + * @param pos The position at which we want the WalkableBlock + * @return WalkableBlock at pos + */ public WalkableBlock getBlock(Vector3f pos) { Vector3i blockPos = new Vector3i(pos.x + 0.25f, pos.y, pos.z + 0.25f); WalkableBlock block = getBlock(blockPos); diff --git a/src/main/java/org/terasology/navgraph/Sweep.java b/src/main/java/org/terasology/navgraph/Sweep.java index c9b5c28..15bde07 100644 --- a/src/main/java/org/terasology/navgraph/Sweep.java +++ b/src/main/java/org/terasology/navgraph/Sweep.java @@ -17,6 +17,7 @@ /** * @author synopia + * Represents connected NavGraphCells in the same row (no holes or corners) */ public class Sweep { public Region region; diff --git a/src/main/java/org/terasology/navgraph/WalkableBlock.java b/src/main/java/org/terasology/navgraph/WalkableBlock.java index 6e1ca8d..d6518f4 100644 --- a/src/main/java/org/terasology/navgraph/WalkableBlock.java +++ b/src/main/java/org/terasology/navgraph/WalkableBlock.java @@ -19,6 +19,8 @@ /** * @author synopia + * Represents a Block through which characters can walk through. They are blocks which have at least 2 + * penetrable blocks above them and are themselves not penetrable */ public class WalkableBlock { public WalkableBlock[] neighbors = new WalkableBlock[8]; @@ -50,6 +52,10 @@ public String toString() { return position.toString(); } + /** + * @param block + * @return if the block has a neighbour. + */ public boolean hasNeighbor(WalkableBlock block) { for (WalkableBlock neighbor : neighbors) { if (neighbor == block) { diff --git a/src/main/java/org/terasology/navgraph/WalkableBlockFinder.java b/src/main/java/org/terasology/navgraph/WalkableBlockFinder.java index d4723cd..490a8f8 100644 --- a/src/main/java/org/terasology/navgraph/WalkableBlockFinder.java +++ b/src/main/java/org/terasology/navgraph/WalkableBlockFinder.java @@ -29,6 +29,12 @@ public WalkableBlockFinder(WorldProvider world) { this.world = world; } + /** + * Finds Walkable Blocks in NavGraphChunk. Blocks are considered Walkable only if there is enough space above them + * to allow for walking + * + * @param map the NavGraphChunk inside which we want to find WalkableBlocks + */ public void findWalkableBlocks(NavGraphChunk map) { int[] airMap = new int[NavGraphChunk.SIZE_X * NavGraphChunk.SIZE_Z]; Vector3i blockPos = new Vector3i(); @@ -72,6 +78,15 @@ private void findNeighbors(NavGraphChunk map) { } } + /** + * Connects each cell to it's adjacent cells if possible + * + * @param map bitmap of the NavGraphChunk + * @param x x co-ordinate of the block + * @param z z co-ordinate of the block + * @param block the Walkable Block which we want to connect to its neigbbours + * @param direction the direction in which we want to try and connect + */ private void connectToDirection(NavGraphChunk map, int x, int z, WalkableBlock block, int direction) { int dx = NavGraphChunk.DIRECTIONS[direction][0]; int dy = NavGraphChunk.DIRECTIONS[direction][1]; @@ -87,6 +102,13 @@ private void connectToDirection(NavGraphChunk map, int x, int z, WalkableBlock b } } + /** + * Connects to adjacent blocks iff the difference in height is small and there is enough free space above + * + * @param block the block which we want to connect + * @param neighborBlock the neighbour block that we want to connect to + * @param direction the direction in which the neighbour block is located + */ private void connectBlocks(WalkableBlock block, WalkableBlock neighborBlock, int direction) { int heightDiff = block.height() - neighborBlock.height(); boolean diagonal = (direction % 2) != 0;