package game;
import org.lwjgl.opengl.GL11;
public class Camera {
public static final int FORWARD = 0;
public static final int BACKWARD = 1;
public static final int RIGHT = 2;
public static final int LEFT = 3;
public static final float MAX_GRAVITY_SPEED = 1.0f;
public static final float GRAVITY_ACCEL = 0.01f;
public float gravitySpeed = 0.0f;
public boolean grounded = false;
public boolean hasGravitiedThisFrame = false;
public Vector3f coordinates;
public Vector3f rotation;
public Vector3f target;
public boolean hasTarget = false;
private ChunkManager terrain;
public Camera(Vector3f coordinates, Vector3f rotation, ChunkManager terrain) {
this.coordinates = coordinates;
this.rotation = rotation;
this.terrain = terrain;
this.target = new Vector3f(0f, 0f, 0f);
}
public void updateLookingAt()
{
float delta = 0.5f;
Vector3f myCoords = new Vector3f(coordinates.x, coordinates.y, coordinates.z);
for (int i = 0; i < 10; i++)
{
myCoords.x += Math.cos(Math.toRadians(rotation.x)) * -Math.sin(Math.toRadians(rotation.y)) * delta;
myCoords.y += Math.sin(Math.toRadians(rotation.x)) * delta;
myCoords.z += Math.cos(Math.toRadians(rotation.x)) * -Math.cos(Math.toRadians(rotation.y)) * delta;
if (terrain.solidAt(myCoords)) {
target = new Vector3f(myCoords.x, myCoords.y, myCoords.z);
hasTarget = true;
return;
}
}
hasTarget = false;
}
public void move(float delta, int direction, float gravityDelta, boolean collisionChecking, boolean flyMode) {
Vector3f newCoordinates = new Vector3f(coordinates.x, coordinates.y, coordinates.z);
if (newCoordinates.y < -0.0f)
newCoordinates.y = 128.0f;
if(direction == FORWARD) {
if(flyMode) {
// Includes moving in the Y-direction
newCoordinates.x += Math.cos(Math.toRadians(rotation.x)) * -Math.sin(Math.toRadians(rotation.y)) * delta;
newCoordinates.y += Math.sin(Math.toRadians(rotation.x)) * delta;
newCoordinates.z += Math.cos(Math.toRadians(rotation.x)) * -Math.cos(Math.toRadians(rotation.y)) * delta;
} else {
// No moving in the Y-direction. (2D version, use if flying is forbidden)
newCoordinates.x += -Math.sin(Math.toRadians(rotation.y)) * delta;
newCoordinates.z += -Math.cos(Math.toRadians(rotation.y)) * delta;
}
} else if(direction == BACKWARD) {
if(flyMode) {
// Includes moving in the Y-direction
newCoordinates.x -= Math.cos(Math.toRadians(rotation.x)) * -Math.sin(Math.toRadians(rotation.y)) * delta;
newCoordinates.y -= Math.sin(Math.toRadians(rotation.x)) * delta;
newCoordinates.z -= Math.cos(Math.toRadians(rotation.x)) * -Math.cos(Math.toRadians(rotation.y)) * delta;
} else {
// No moving in the Y-direction. (2D version, use if flying is forbidden)
newCoordinates.x -= -Math.sin(Math.toRadians(rotation.y)) * delta;
newCoordinates.z -= -Math.cos(Math.toRadians(rotation.y)) * delta;
}
} else if(direction == RIGHT) {
// Only move in the XZ-directions
newCoordinates.x += Math.sin(Math.toRadians(rotation.y + 90)) * delta;
newCoordinates.z += Math.sin(Math.toRadians(-rotation.y)) * delta;
} else if(direction == LEFT) {
// Only move in the XZ-directions
newCoordinates.x -= Math.sin(Math.toRadians(rotation.y + 90)) * delta;
newCoordinates.z -= Math.sin(Math.toRadians(-rotation.y)) * delta;
}
// Add false gravity
//newCoordinates.y -= gravityDelta;
if (!hasGravitiedThisFrame) {
newCoordinates.y -= gravitySpeed;
hasGravitiedThisFrame = true;
}
// Collision detection
if(collisionChecking) {
if(!collision(newCoordinates.x, coordinates.y, coordinates.z)) {
coordinates.x = newCoordinates.x;
}
if(!collision(coordinates.x, newCoordinates.y, coordinates.z)) {
coordinates.y = newCoordinates.y;
}
else
{
gravitySpeed = 0.0f;
grounded = true;
}
if(!collision(coordinates.x, coordinates.y, newCoordinates.z)) {
coordinates.z = newCoordinates.z;
}
} else {
coordinates.x = newCoordinates.x;
coordinates.y = newCoordinates.y;
coordinates.z = newCoordinates.z;
}
}
public boolean collision(float x, float y, float z) {
// Simulate a cube cross around the point
float cubeSize = 0.8f;
Vector3f c1 = new Vector3f(x - cubeSize / 2, y, z);
Vector3f c2 = new Vector3f(x + cubeSize / 2, y, z);
Vector3f c3 = new Vector3f(x, y - 1.5f, z); // This is 1.5f to simulate the proportions of a human (head/camera at top of body)
Vector3f c4 = new Vector3f(x, y + cubeSize / 2, z);
Vector3f c5 = new Vector3f(x, y, z - cubeSize / 2);
Vector3f c6 = new Vector3f(x, y, z + cubeSize / 2);
Vector3f c7 = new Vector3f(x - cubeSize / 2, y - 1.5f, z);
Vector3f c8 = new Vector3f(x + cubeSize / 2, y - 1.5f, z);
Vector3f c9 = new Vector3f(x, y - 1.5f, z - cubeSize / 2);
Vector3f c10 = new Vector3f(x, y - 1.5f, z + cubeSize / 2);
if(!terrain.solidAt(c1) &&
!terrain.solidAt(c2) &&
!terrain.solidAt(c3) &&
!terrain.solidAt(c4) &&
!terrain.solidAt(c5) &&
!terrain.solidAt(c6) &&
!terrain.solidAt(c7) &&
!terrain.solidAt(c8) &&
!terrain.solidAt(c9) &&
!terrain.solidAt(c10)) {
return false;
}
return true;
}
/* Use this when adding rotation instead of Vector3f.add since this function makes the numbers stay under 360. */
public void addRotation(Vector3f rot) {
rotation.x += rot.x;
rotation.y += rot.y;
rotation.z += rot.z;
if(rotation.x >= 360.0f || rotation.x <= -360.0f)
rotation.x = rotation.x % 360.0f;
if(rotation.y >= 360.0f || rotation.y <= -360.0f)
rotation.y = rotation.y % 360.0f;
if(rotation.z >= 360.0f || rotation.z <= -360.0f)
rotation.z = rotation.z % 360.0f;
// Gimbal lock
if(rotation.x <= -90.0f)
rotation.x = -90.0f;
else if(rotation.x >= 90.0f)
rotation.x = 90.0f;
}
public void applyMatrix() {
// Rotate
GL11.glRotatef(-rotation.x, 1.0f, 0.0f, 0.0f);
GL11.glRotatef(-rotation.y, 0.0f, 1.0f, 0.0f);
GL11.glRotatef(-rotation.z, 0.0f, 0.0f, 1.0f);
// Translate
GL11.glTranslatef(-coordinates.x, -coordinates.y, -coordinates.z);
}
public void updateGravity() {
if (gravitySpeed < MAX_GRAVITY_SPEED) gravitySpeed += GRAVITY_ACCEL;
// TODO Auto-generated method stub
}
}