diff options
author | Frank v/d Haterd <f.h.a.v.d.haterd@student.tue.nl> | 2014-01-15 16:20:38 +0100 |
---|---|---|
committer | Frank v/d Haterd <f.h.a.v.d.haterd@student.tue.nl> | 2014-01-15 16:20:38 +0100 |
commit | 89782191523f51f7a28db7cee7f86b3ad96122bc (patch) | |
tree | 5a56914935883ee00945958cabbea079c9fe9d36 | |
parent | 4c3b53a48464afc46eb5d71870a105165e4f8498 (diff) | |
download | 2iv60-robots-89782191523f51f7a28db7cee7f86b3ad96122bc.tar.gz |
New heightmap file support.
Updated methods to support this.
When no heightmap is found, the formula is used.
heightAt modified to work with this.
-rw-r--r-- | src/Terrain.java | 106 |
1 files changed, 88 insertions, 18 deletions
diff --git a/src/Terrain.java b/src/Terrain.java index cbd29d4..6a26e17 100644 --- a/src/Terrain.java +++ b/src/Terrain.java @@ -1,8 +1,14 @@ import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Random; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.imageio.ImageIO; import javax.media.opengl.GL; import javax.media.opengl.GL2; import static javax.media.opengl.GL2.*; @@ -34,6 +40,13 @@ class Terrain extends BetterBase { * The array containing all trees of the terrain. */ private Tree[] terrainTrees; + + /** + * Contains the name of the height map file. + */ + private final String heightMapFile; + + private boolean heightMapFileMode; /** * Can be used to set up a display list. @@ -46,20 +59,69 @@ class Terrain extends BetterBase { this.normalMap = new Vector[41][41]; this.waterAlpha = 0.30f; this.terrainTrees = new Tree[10]; + this.heightMapFile = "heightmap.bmp"; + this.heightMapFileMode = true; // Fill the height map array + File f = new File("src/" + heightMapFile); + if(f.exists()) { + try { + heightMap = readHeightMapFromFile(heightMapFile); + } catch (IOException ex) { + Logger.getLogger(Terrain.class.getName()).log(Level.SEVERE, null, ex); + } + } else { + System.err.println("Heightmap file not found, formula heightmap generated instead..."); + this.heightMapFileMode = false; + fillHeightMapFormula(); + } + + // Fill the array containing the normal vectors for drawing triangles + for (int y = 0; y < 41; y++) { + for (int x = 0; x < 41; x++) { + normalMap[x][y] = calculateNormal(x, y); + } + } + } + + /** + * Generate the heightmap based on a formula. + */ + private void fillHeightMapFormula() { for (int y = 0; y < 41; y++) { for (int x = 0; x < 41; x++) { heightMap[x][y] = heightAt(x, y); } } + } + + /** + * Reads an image file and returns a heightmap based on the pixels. + * + * @param fileName name of the image file + * @return float[][] height map array + * @throws IOException + */ + private float[][] readHeightMapFromFile(String fileName) throws IOException { + BufferedImage image = ImageIO.read(getClass().getResource(fileName)); + + float[][] heightArray = new float[41][41]; - // Fill the array containing the normal vectors for drawing triangles for (int y = 0; y < 41; y++) { for (int x = 0; x < 41; x++) { - normalMap[x][y] = calculateNormal(x, y); + int rgb = image.getRGB(x, y); + + // Get red value (since it is black to white only one matters) + Color col = new Color(rgb, true); + int r = col.getRed(); + + // Now divide, so the height will be in the interval [-1, 1] + float height = (r / 127.5f) - 1; + heightArray[x][y] = height; } } + + return heightArray; } /** @@ -69,9 +131,9 @@ class Terrain extends BetterBase { */ private Vector getRandomPosition() { Random r = new Random(); - float x = r.nextFloat() * 36 - 18; - float y = r.nextFloat() * 36 - 18; - return new Vector(x, y, heightAt((float) x + 20, (float) y + 20)); + int x = r.nextInt(37) - 18; + int y = r.nextInt(37) - 18; + return new Vector(x, y, heightAt(x + 20, y + 20)); } /** @@ -84,10 +146,10 @@ class Terrain extends BetterBase { */ private boolean checkPositionFree(Vector position, float marge) { for (Tree tree : terrainTrees) { - float x = (float)position.x(); - float y = (float)position.y(); - float z = (float)position.z(); - + float x = (float) position.x(); + float y = (float) position.y(); + float z = (float) position.z(); + if (tree != null) { if (Math.abs(tree.getPosition().x() - x) < marge) { return false; @@ -95,9 +157,9 @@ class Terrain extends BetterBase { if (Math.abs(tree.getPosition().y() - y) < marge) { return false; } - + // No trees allowed in water - if (z <= 0) { + if (z < 0.25f) { return false; } } @@ -206,7 +268,7 @@ class Terrain extends BetterBase { System.out.println("Terrain created"); } - + /** * Fills the array with new valid trees. */ @@ -225,7 +287,7 @@ class Terrain extends BetterBase { Random r = new Random(); int variation = r.nextInt(2); // 0 (inclusive) and 2 (exclusive) float scale = r.nextFloat() * 1.5f; // 0 - 1.5 - + terrainTrees[i] = new Tree(this, treePosition, scale, variation); } @@ -286,12 +348,12 @@ class Terrain extends BetterBase { gl.glCallList(terrainDisplayList); drawTrees(); } - + /** * Draw all the trees stored in the terrainTrees array on the terrain. */ private void drawTrees() { - for(Tree tree : terrainTrees) { + for (Tree tree : terrainTrees) { tree.drawTree(); } } @@ -299,10 +361,18 @@ class Terrain extends BetterBase { /** * Computes the elevation of the terrain at ({@code x}, {@code y}). */ - public final float heightAt(float x, float y) { - float height = (float) (0.6f * Math.cos(0.3f * x + 0.2f * y) + 0.4f + public final float heightAt(int x, int y) { + float height; + + if(heightMapFileMode == false) { + // Use the formula to return the height + height = (float) (0.6f * Math.cos(0.3f * x + 0.2f * y) + 0.4f * Math.cos(x - 0.5f * y)); - + } else { + // Use the values in the height array instead (file mode) + height = (float) heightMap[x][y]; + } + return height; } |