[DEV] tutorial 22 'terrain collision detection' implementation

This commit is contained in:
Edouard DUPIN 2020-04-24 00:19:50 +02:00
parent 3f7ece604e
commit e31adfe7c6
4 changed files with 63 additions and 22 deletions

View File

@ -80,31 +80,32 @@ public class MainGameLoop {
TerrainTexture blendMap = new TerrainTexture(loader.loadTexture("blendMap"));
Terrain terrain = new Terrain(0,-1,loader, texturePack, blendMap, "heightmap");
Terrain terrain2 = new Terrain(-1,-1,loader, texturePack, blendMap, "heightmap");
List<Entity> entities = new ArrayList<Entity>();
Random random = new Random();
for (int iii=0; iii<500; iii++) {
float x = random.nextFloat()*800 - 400;
float z = random.nextFloat() * -600;
float y = terrain.getHeightOfTerrain(x, z);
entities.add(new Entity(staticModel,
new Vector3f(random.nextFloat()*800 - 400, 0, random.nextFloat() * -600),
new Vector3f(x, y, z),
new Vector3f(0,0,0),3));
entities.add(new Entity(grassModel,
new Vector3f(random.nextFloat()*800 - 400, 0, random.nextFloat() * -600),
new Vector3f(0,0,0),1));
}
for (int iii=0; iii<500; iii++) {
float x = random.nextFloat()*800 - 400;
float z = random.nextFloat() * -600;
float y = terrain.getHeightOfTerrain(x, z);
entities.add(new Entity(fernModel,
new Vector3f(random.nextFloat()*800 - 400, 0, random.nextFloat() * -600),
new Vector3f(x, y, z),
new Vector3f(0,0,0),0.6f));
entities.add(new Entity(flowerModel,
new Vector3f(random.nextFloat()*800 - 400, 0, random.nextFloat() * -600),
new Vector3f(0,0,0),1.5f));
}
TexturedModel playerModel = new TexturedModel(OBJLoader.loadObjModel("person", loader),
new ModelTexture(loader.loadTexture("playerTexture")));
Player player = new Player(playerModel, new Vector3f(0,0,-50), new Vector3f(0,3.14f,0), 0.4f);
Player player = new Player(playerModel, new Vector3f(0,terrain.getHeightOfTerrain(0, -50),-50), new Vector3f(0,3.14f,0), 0.4f);
Camera camera = new Camera(player);
@ -116,9 +117,8 @@ public class MainGameLoop {
//entity.increaseRotation(0, 0, 0.01f);
//entity.increaseRotation(0.01f, 0.02f, 0.0f);
camera.move();
player.move();
player.move(terrain);
renderer.processTerrain(terrain);
renderer.processTerrain(terrain2);
renderer.processEntity(player);
for (Entity entity : entities) {
entity.increaseRotation(0, 0.01f, 0.0f);

View File

@ -4,6 +4,7 @@ import org.atriaSoft.etk.math.Vector3f;
import models.TexturedModel;
import renderEngine.DisplayManager;
import terrains.Terrain;
public class Player extends Entity {
@ -25,7 +26,7 @@ public class Player extends Entity {
}
public void move() {
public void move(Terrain terrain) {
checkInputs();
if (isInAir == false) {
super.increaseRotation(0, this.currentTurnSpeed * DisplayManager.getFrameTimeSecconds(), 0);
@ -36,9 +37,10 @@ public class Player extends Entity {
super.increasePosition(dx, 0, dz);
upwardSpeed += GRAVITY * DisplayManager.getFrameTimeSecconds();
super.increasePosition(0, upwardSpeed * DisplayManager.getFrameTimeSecconds(), 0);
if (super.getPosition().y < TERRAIN_HEIGHT) {
float terrainHeight = terrain.getHeightOfTerrain(super.getPosition().x, super.getPosition().z);
if (super.getPosition().y < terrainHeight) {
upwardSpeed = 0;
super.getPosition().y = TERRAIN_HEIGHT;
super.getPosition().y = terrainHeight;
isInAir = false;
}
}

View File

@ -6,11 +6,13 @@ import java.io.IOException;
import javax.imageio.ImageIO;
import org.atriaSoft.etk.math.Vector2f;
import org.atriaSoft.etk.math.Vector3f;
import models.RawModel;
import renderEngine.Loader;
import textures.ModelTexture;
import toolbox.Maths;
public class Terrain {
private static final float SIZE = 800;
@ -23,16 +25,42 @@ public class Terrain {
private TerrainTexturePack texturePack;
private TerrainTexture blendMap;
public Terrain(int girdX, int girdZ, Loader loader,
private float[][] heights;
public Terrain(int gridX, int gridZ, Loader loader,
TerrainTexturePack texturePack, TerrainTexture blendMap,
String heightMap) {
this.texturePack = texturePack;
this.blendMap = blendMap;
this.x = girdX * SIZE;
this.z = girdZ * SIZE;
this.x = gridX * SIZE;
this.z = gridZ * SIZE;
this.model = generateTerrain(loader, heightMap);
}
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;
}
private RawModel generateTerrain(Loader loader, String heightMap) {
BufferedImage image = null;
@ -42,7 +70,7 @@ public class Terrain {
e.printStackTrace();
}
int VERTEX_COUNT = image.getHeight();
heights = new float[VERTEX_COUNT][VERTEX_COUNT];
int count = VERTEX_COUNT * VERTEX_COUNT;
float[] vertices = new float[count * 3];
float[] normals = new float[count * 3];
@ -52,7 +80,9 @@ public class Terrain {
for(int i=0;i<VERTEX_COUNT;i++){
for(int j=0;j<VERTEX_COUNT;j++){
vertices[vertexPointer*3] = (float)j/((float)VERTEX_COUNT - 1) * SIZE;
vertices[vertexPointer*3+1] = getHeight(j,i, image);
float height = getHeight(j,i, image);
heights[j][i] = height;
vertices[vertexPointer*3+1] = height;
vertices[vertexPointer*3+2] = (float)i/((float)VERTEX_COUNT - 1) * SIZE;
Vector3f normal = calculateNormal(j,i, image);
normals[vertexPointer*3] = normal.x;

View File

@ -1,12 +1,21 @@
package toolbox;
import org.atriaSoft.etk.math.Matrix4f;
import org.atriaSoft.etk.math.Vector2f;
import org.atriaSoft.etk.math.Vector3f;
import entities.Camera;
public class Maths {
public static float barryCentric(Vector3f p1, Vector3f p2, Vector3f p3, Vector2f pos) {
float det = (p2.z - p3.z) * (p1.x - p3.x) + (p3.x - p2.x) * (p1.z - p3.z);
float l1 = ((p2.z - p3.z) * (pos.x - p3.x) + (p3.x - p2.x) * (pos.y - p3.z)) / det;
float l2 = ((p3.z - p1.z) * (pos.x - p3.x) + (p1.x - p3.x) * (pos.y - p3.z)) / det;
float l3 = 1.0f - l1 - l2;
return l1 * p1.y + l2 * p2.y + l3 * p3.y;
}
public static Matrix4f createTransformationMatrix(Vector3f translation, Vector3f rotation, float scale) {
// Need to rework all of this this is really not optimum ...
Matrix4f matrix = new Matrix4f();