|
@@ -1,235 +1,122 @@
|
|
|
package eu.tankernn.gameEngine.terrains;
|
|
|
|
|
|
-import java.awt.image.BufferedImage;
|
|
|
-import java.io.File;
|
|
|
-import java.io.IOException;
|
|
|
-
|
|
|
-import javax.imageio.ImageIO;
|
|
|
+import static eu.tankernn.gameEngine.settings.Settings.TERRAIN_SIZE;
|
|
|
|
|
|
+import org.apache.commons.lang3.tuple.Pair;
|
|
|
import org.lwjgl.util.vector.Vector2f;
|
|
|
import org.lwjgl.util.vector.Vector3f;
|
|
|
|
|
|
import eu.tankernn.gameEngine.loader.Loader;
|
|
|
-import eu.tankernn.gameEngine.loader.models.RawModel;
|
|
|
import eu.tankernn.gameEngine.loader.textures.TerrainTexturePack;
|
|
|
import eu.tankernn.gameEngine.loader.textures.Texture;
|
|
|
+import eu.tankernn.gameEngine.renderEngine.RawModel;
|
|
|
+import eu.tankernn.gameEngine.util.InternalFile;
|
|
|
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 Texture blendMap;
|
|
|
-
|
|
|
+
|
|
|
private float[][] heights;
|
|
|
-
|
|
|
- public Terrain(int gridX, int gridZ, Loader loader, TerrainTexturePack texturePack, Texture blendMap, String heightMap) {
|
|
|
- this.texturePack = texturePack;
|
|
|
- this.blendMap = blendMap;
|
|
|
+
|
|
|
+ public Terrain(int gridX, int gridZ, Loader loader, TerrainTexturePack texturePack, Texture blendMap,
|
|
|
+ InternalFile heightMap) {
|
|
|
this.gridX = gridX;
|
|
|
this.gridZ = gridZ;
|
|
|
- this.x = gridX * SIZE;
|
|
|
- this.z = gridZ * SIZE;
|
|
|
- this.model = generateTerrain(loader, heightMap);
|
|
|
+ this.texturePack = texturePack;
|
|
|
+ this.blendMap = blendMap;
|
|
|
+ this.x = gridX * TERRAIN_SIZE;
|
|
|
+ this.z = gridZ * TERRAIN_SIZE;
|
|
|
+ TerrainModelData data = new TerrainModelData(gridX, gridZ, heightMap);
|
|
|
+ this.model = data.getModel(loader);
|
|
|
+ this.heights = data.getHeights();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public Terrain(int gridX, int gridZ, Loader loader, TerrainTexturePack texturePack, Texture blendMap, int seed) {
|
|
|
+ this.gridX = gridX;
|
|
|
+ this.gridZ = gridZ;
|
|
|
this.texturePack = texturePack;
|
|
|
this.blendMap = blendMap;
|
|
|
+ this.x = gridX * TERRAIN_SIZE;
|
|
|
+ this.z = gridZ * TERRAIN_SIZE;
|
|
|
+ TerrainModelData data = new TerrainModelData(gridX, gridZ, seed);
|
|
|
+ this.model = data.getModel(loader);
|
|
|
+ this.heights = data.getHeights();
|
|
|
+ }
|
|
|
+
|
|
|
+ public Terrain(int gridX, int gridZ, Loader loader, TerrainTexturePack texturePack, Texture blendMap,
|
|
|
+ TerrainModelData data) {
|
|
|
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);
|
|
|
+ this.texturePack = texturePack;
|
|
|
+ this.blendMap = blendMap;
|
|
|
+ this.x = gridX * TERRAIN_SIZE;
|
|
|
+ this.z = gridZ * TERRAIN_SIZE;
|
|
|
+ this.model = data.getModel(loader);
|
|
|
+ this.heights = data.getHeights();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public float getX() {
|
|
|
return x;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public float getZ() {
|
|
|
return z;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
float getSize() {
|
|
|
- return SIZE;
|
|
|
+ return TERRAIN_SIZE;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public RawModel getModel() {
|
|
|
return model;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public TerrainTexturePack getTexturePack() {
|
|
|
return texturePack;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public Texture getBlendMap() {
|
|
|
return blendMap;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ public Pair<Integer, Integer> getGridPosition() {
|
|
|
+ return Pair.of(this.gridX, this.gridZ);
|
|
|
+ }
|
|
|
+
|
|
|
public float getHeightOfTerrain(float worldX, float worldZ) {
|
|
|
float terrainX = worldX - this.x;
|
|
|
float terrainZ = worldZ - this.z;
|
|
|
-
|
|
|
- float gridSquareSize = SIZE / ((float) heights.length - 1);
|
|
|
+
|
|
|
+ float gridSquareSize = TERRAIN_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));
|
|
|
+ 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));
|
|
|
+ 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;
|
|
|
}
|
|
|
+
|
|
|
+ public void delete() {
|
|
|
+ model.delete();
|
|
|
+ }
|
|
|
}
|