package com.voxel.engine.core.Camera; import com.voxel.engine.core.Utils.Frustum; import org.lwjgl.opengl.GL11; import org.lwjgl.util.vector.Vector3f; /** * Created with IntelliJ IDEA. * User: Toby's PC * Date: 14/01/14 * Time: 19:10 * To change this template use File | Settings | File Templates. */ public class FPCameraController { public Frustum frustum; //3d vector to store the camera's position in private Vector3f position = null; //the rotation around the Y axis of the camera private float yaw = 0.0f; //the rotation around the X axis of the camera private float pitch = 0.0f; private float walkbias = 0.0f; private float walkbiasangle = 0.0f; private float piover180 = 0.01745329F; public float getWalkBias() { return walkbias; } private static FPCameraController instance = null; public synchronized static FPCameraController getInstance() { if(instance == null) { instance = new FPCameraController(0,4,0,0,0); } return instance; } //Constructor that takes the starting x, y, z location of the camera public FPCameraController(float x, float y, float z, float pitch, float yaw) { frustum = new Frustum(); position = new Vector3f(x, y, z); this.yaw(yaw); this.pitch(pitch); } public float getCameraYaw() { return yaw; } public float getCameraPitch() { return pitch; } public Vector3f getCameraPosition() { return position; } public void setPosition(Vector3f pos) { this.position.x = pos.x; this.position.y = pos.y; this.position.z = pos.z; } //increment the camera's current yaw rotation (Y) public void yaw(float amount) { yaw += amount; if(yaw > 180f) yaw = -180; else if(yaw < -180f) yaw = 180f; } //increment the camera's current pitch rotation (X) public void pitch(float amount) { pitch += amount; if(pitch > 80f) pitch = 80f; else if(pitch < -80f) pitch = -80f; } public void roll(float amount) { // not used } // X is sin(angle) public float getXPos(float angle) { return (float)Math.sin(Math.toRadians(angle)); } // Z is cos(angle) * r public float getZPos(float angle) { return (float)Math.cos(Math.toRadians(angle)); } //moves the camera forward relative to its current rotation (yaw) public void walkForward(Vector3f velocity) { position.x += velocity.x * getXPos(yaw); position.z -= velocity.z * getZPos(yaw); if (walkbiasangle >= 359.0f) { walkbiasangle = 0.0f; } else { walkbiasangle+= 10; } walkbias = (float)Math.sin(walkbiasangle * piover180)/15.0f; } //moves the camera backward relative to its current rotation (yaw) public void walkBackwards(Vector3f velocity)// float distance) { position.x -= velocity.x * getXPos(yaw); position.z += velocity.z * getZPos(yaw); if (walkbiasangle <= 1.0f) // Is walkbiasangle>=359? { walkbiasangle = 359.0f; // Make walkbiasangle Equal 0 } else // Otherwise { walkbiasangle-= 10; // If walkbiasangle < 359 Increase It By 10 } walkbias = (float)Math.sin(walkbiasangle * piover180)/15.0f; } //strafes the camera left relative to its current rotation (yaw) public void strafeLeft(Vector3f velocity) { // player position is x=sin(yaw), z=cos(yaw) // x is distance * sin(yaw) // z is distance * cos(yaw) // we subtract 90 to the angle so to strafe position.x += velocity.x * getXPos(yaw- 90); // .5PI position.z -= velocity.z * getZPos(yaw- 90); // .5PI if (walkbiasangle <= 1.0f) // Is walkbiasangle>=359? { walkbiasangle = 359.0f; // Make walkbiasangle Equal 0 } else // Otherwise { walkbiasangle-= 10; // If walkbiasangle < 359 Increase It By 10 } walkbias = (float)Math.sin(walkbiasangle * piover180)/15.0f; } //strafes the camera right relative to its current rotation (yaw) public void strafeRight(Vector3f velocity) { // x is distance * sin(yaw) // z is distance * cos(yaw) // we add 90 to the angle so to strafe position.x += velocity.x * getXPos(yaw+90); position.z -= velocity.z * getZPos(yaw+90); if (walkbiasangle <= 1.0f) // Is walkbiasangle>=359? { walkbiasangle = 359.0f; // Make walkbiasangle Equal 0 } else // Otherwise { walkbiasangle+= 10; // If walkbiasangle < 359 Increase It By 10 } walkbias = (float)Math.sin(walkbiasangle * piover180)/15.0f; } public void jump(float distance) { position.y += distance; } public void down(float distance) { position.y -= distance; } public void resetPosition(float x, float y, float z, float pitch, float yaw) { position.x = x; position.y = y; position.z = z; this.pitch = pitch; this.yaw = yaw; } //translates and rotate the matrix so that it looks through the camera //this does basically what gluLookAt() does public void lookThrough() { //rotate the pitch around the X axis GL11.glRotatef(pitch, 1.0f, 0.0f, 0.0f); //rotate the yaw around the Y axis // remove line below for third person float ytrans = position.y - (-walkbias-0.25f); GL11.glRotatef(yaw, 0.0f, 1.0f, 0.0f); //translate to the position vector's location GL11.glTranslatef(-position.x, -ytrans, -position.z); frustum.calculateFrustum(); } }