123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- package eu.tankernn.gameEngine.terrains;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.IOException;
- import javax.imageio.ImageIO;
- import org.lwjgl.util.vector.Vector2f;
- import org.lwjgl.util.vector.Vector3f;
- import eu.tankernn.gameEngine.loader.models.RawModel;
- import eu.tankernn.gameEngine.loader.textures.TerrainTexture;
- import eu.tankernn.gameEngine.loader.textures.TerrainTexturePack;
- import eu.tankernn.gameEngine.renderEngine.Loader;
- import eu.tankernn.gameEngine.util.Maths;
- public class Terrain {
- private static final float SIZE = 800;
- private static final float MAX_HEIGHT = 40;
- private static final float MAX_PIXEL_COLOR = 256 * 256 * 256;
-
- private float x, z;
- private int gridX, gridZ;
- private RawModel model;
- private TerrainTexturePack texturePack;
- private TerrainTexture blendMap;
-
- private float[][] heights;
-
- public Terrain(int gridX, int gridZ, Loader loader, TerrainTexturePack texturePack, TerrainTexture blendMap, String heightMap) {
- this.texturePack = texturePack;
- this.blendMap = blendMap;
- this.gridX = gridX;
- this.gridZ = gridZ;
- this.x = gridX * SIZE;
- this.z = gridZ * SIZE;
- this.model = generateTerrain(loader, heightMap);
- }
-
- public Terrain(int gridX, int gridZ, Loader loader, TerrainTexturePack texturePack, TerrainTexture blendMap, int seed) {
- this.texturePack = texturePack;
- this.blendMap = blendMap;
- this.gridX = gridX;
- this.gridZ = gridZ;
- this.x = gridX * SIZE;
- this.z = gridZ * SIZE;
- this.model = generateTerrain(loader, seed);
- }
-
- private RawModel generateTerrain(Loader loader, String heightMap) {
-
- BufferedImage image = null;
- try {
- image = ImageIO.read(new File("res/" + heightMap + ".png"));
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- int vertexCount = image.getHeight();
- heights = new float[vertexCount][vertexCount];
- int count = vertexCount * vertexCount;
- float[] vertices = new float[count * 3];
- float[] normals = new float[count * 3];
- float[] textureCoords = new float[count * 2];
- int[] indices = new int[6 * (vertexCount - 1) * (vertexCount - 1)];
- int vertexPointer = 0;
- for (int i = 0; i < vertexCount; i++) {
- for (int j = 0; j < vertexCount; j++) {
- vertices[vertexPointer * 3] = (float) j / ((float) vertexCount - 1) * SIZE;
- float height = getHeight(j, i, image);
- heights[j][i] = height;
- vertices[vertexPointer * 3 + 1] = height;
- vertices[vertexPointer * 3 + 2] = (float) i / ((float) vertexCount - 1) * SIZE;
- Vector3f normal = calculateNormal(j, i, image);
- normals[vertexPointer * 3] = normal.x;
- normals[vertexPointer * 3 + 1] = normal.y;
- normals[vertexPointer * 3 + 2] = normal.z;
- textureCoords[vertexPointer * 2] = (float) j / ((float) vertexCount - 1);
- textureCoords[vertexPointer * 2 + 1] = (float) i / ((float) vertexCount - 1);
- vertexPointer++;
- }
- }
- int pointer = 0;
- for (int gz = 0; gz < vertexCount - 1; gz++) {
- for (int gx = 0; gx < vertexCount - 1; gx++) {
- int topLeft = (gz * vertexCount) + gx;
- int topRight = topLeft + 1;
- int bottomLeft = ((gz + 1) * vertexCount) + gx;
- int bottomRight = bottomLeft + 1;
- indices[pointer++] = topLeft;
- indices[pointer++] = bottomLeft;
- indices[pointer++] = topRight;
- indices[pointer++] = topRight;
- indices[pointer++] = bottomLeft;
- indices[pointer++] = bottomRight;
- }
- }
- return loader.loadToVAO(vertices, textureCoords, normals, indices);
- }
-
- private RawModel generateTerrain(Loader loader, int seed) {
- int vertexCount = 128;
- HeightsGenerator generator = new HeightsGenerator(this.gridX, this.gridZ, vertexCount, seed);
-
- heights = new float[vertexCount][vertexCount];
- int count = vertexCount * vertexCount;
- float[] vertices = new float[count * 3];
- float[] normals = new float[count * 3];
- float[] textureCoords = new float[count * 2];
- int[] indices = new int[6 * (vertexCount - 1) * (vertexCount - 1)];
- int vertexPointer = 0;
- for (int i = 0; i < vertexCount; i++) {
- for (int j = 0; j < vertexCount; j++) {
- vertices[vertexPointer * 3] = (float) j / ((float) vertexCount - 1) * SIZE;
- float height = getHeight(j, i, generator);
- heights[j][i] = height;
- vertices[vertexPointer * 3 + 1] = height;
- vertices[vertexPointer * 3 + 2] = (float) i / ((float) vertexCount - 1) * SIZE;
- Vector3f normal = calculateNormal(j, i, generator);
- normals[vertexPointer * 3] = normal.x;
- normals[vertexPointer * 3 + 1] = normal.y;
- normals[vertexPointer * 3 + 2] = normal.z;
- textureCoords[vertexPointer * 2] = (float) j / ((float) vertexCount - 1);
- textureCoords[vertexPointer * 2 + 1] = (float) i / ((float) vertexCount - 1);
- vertexPointer++;
- }
- }
- int pointer = 0;
- for (int gz = 0; gz < vertexCount - 1; gz++) {
- for (int gx = 0; gx < vertexCount - 1; gx++) {
- int topLeft = (gz * vertexCount) + gx;
- int topRight = topLeft + 1;
- int bottomLeft = ((gz + 1) * vertexCount) + gx;
- int bottomRight = bottomLeft + 1;
- indices[pointer++] = topLeft;
- indices[pointer++] = bottomLeft;
- indices[pointer++] = topRight;
- indices[pointer++] = topRight;
- indices[pointer++] = bottomLeft;
- indices[pointer++] = bottomRight;
- }
- }
- return loader.loadToVAO(vertices, textureCoords, normals, indices);
- }
-
- private Vector3f calculateNormal(int x, int z, BufferedImage image) {
- float heightL = getHeight(x - 1, z, image);
- float heightR = getHeight(x + 1, z, image);
- float heightD = getHeight(x, z - 1, image);
- float heightU = getHeight(x, z + 1, image);
- Vector3f normal = new Vector3f(heightL - heightR, 2f, heightD - heightU);
- normal.normalise();
- return normal;
- }
-
- private Vector3f calculateNormal(int x, int z, HeightsGenerator generator) {
- float heightL = getHeight(x - 1, z, generator);
- float heightR = getHeight(x + 1, z, generator);
- float heightD = getHeight(x, z - 1, generator);
- float heightU = getHeight(x, z + 1, generator);
- Vector3f normal = new Vector3f(heightL - heightR, 2f, heightD - heightU);
- normal.normalise();
- return normal;
- }
-
- private float getHeight(int x, int z, BufferedImage image) {
- if (x < 0 || x >= image.getHeight() || z < 0 || z >= image.getHeight()) {
- return 0;
- }
- float height = image.getRGB(x, z);
- height += MAX_PIXEL_COLOR / 2f;
- height /= MAX_PIXEL_COLOR / 2f;
- height *= MAX_HEIGHT;
- return height;
- }
-
- private float getHeight(int x, int z, HeightsGenerator generator) {
- return generator.generateHeight(x, z);
- }
-
- public float getX() {
- return x;
- }
-
- public float getZ() {
- return z;
- }
-
- float getSize() {
- return SIZE;
- }
-
- public RawModel getModel() {
- return model;
- }
-
- public TerrainTexturePack getTexturePack() {
- return texturePack;
- }
-
- public TerrainTexture getBlendMap() {
- return blendMap;
- }
-
- public float getHeightOfTerrain(float worldX, float worldZ) {
- float terrainX = worldX - this.x;
- float terrainZ = worldZ - this.z;
-
- float gridSquareSize = SIZE / ((float) heights.length - 1);
- int gridX = (int) Math.floor(terrainX / gridSquareSize);
- int gridZ = (int) Math.floor(terrainZ / gridSquareSize);
-
- if (gridX >= heights.length - 1 || gridZ >= heights.length - 1 || gridX < 0 || gridZ < 0) {
- return 0;
- }
-
- float xCoord = (terrainX % gridSquareSize) / gridSquareSize;
- float zCoord = (terrainZ % gridSquareSize) / gridSquareSize;
-
- float answer;
- if (xCoord <= (1 - zCoord)) {
- answer = Maths
- .barryCentric(new Vector3f(0, heights[gridX][gridZ], 0), new Vector3f(1,
- heights[gridX + 1][gridZ], 0), new Vector3f(0,
- heights[gridX][gridZ + 1], 1), new Vector2f(xCoord, zCoord));
- } else {
- answer = Maths
- .barryCentric(new Vector3f(1, heights[gridX + 1][gridZ], 0), new Vector3f(1,
- heights[gridX + 1][gridZ + 1], 1), new Vector3f(0,
- heights[gridX][gridZ + 1], 1), new Vector2f(xCoord, zCoord));
- }
- return answer;
- }
- }
|