/**
* Copyright 2012 Jason Sorensen (sorensenj@smert.net)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package net.smert.frameworkgl.opengl.camera;
import net.smert.frameworkgl.Fw;
import net.smert.frameworkgl.helpers.InputProcessor;
import net.smert.frameworkgl.helpers.Keyboard;
import net.smert.frameworkgl.math.MathHelper;
import net.smert.frameworkgl.math.Vector3f;
/**
*
* @author Jason Sorensen <sorensenj@smert.net>
*/
public class LegacyCameraController implements InputProcessor {
private final static String KEY_ACTION_LOOK_DOWN = "legCamLookDown";
private final static String KEY_ACTION_LOOK_UP = "legCamLookUp";
private final static String KEY_ACTION_MOVE_BACK = "legCamMoveBack";
private final static String KEY_ACTION_MOVE_DOWN = "legCamMoveDown";
private final static String KEY_ACTION_MOVE_FORWARD = "legCamMoveForward";
private final static String KEY_ACTION_MOVE_LEFT = "legCamMoveLeft";
private final static String KEY_ACTION_MOVE_RIGHT = "legCamMoveRight";
private final static String KEY_ACTION_MOVE_UP = "legCamMoveUp";
private final static String KEY_ACTION_TURN_LEFT = "legCamTurnLeft";
private final static String KEY_ACTION_TURN_RIGHT = "legCamTurnRight";
private float lookSpeed;
private float moveSpeed;
private LegacyCamera camera;
private final Vector3f positionDelta;
private final Vector3f rotationDelta;
public LegacyCameraController() {
lookSpeed = 10f;
moveSpeed = 9f;
positionDelta = new Vector3f();
rotationDelta = new Vector3f();
}
private void correctHeadingPitchAndRoll() {
Vector3f camRotation = camera.getRotation();
if (camRotation.getX() > 90f) {
camera.setRotationX(90f);
} else if (camRotation.getX() < -90f) {
camera.setRotationX(-90f);
}
if ((camRotation.getY() >= 360f) || (camRotation.getY() <= -360f)) {
camera.setRotationY(camRotation.getY() % 360f);
}
if (camRotation.getY() < 0f) {
camera.setRotationY(camRotation.getY() + 360f);
}
}
public float getLookSpeed() {
return lookSpeed;
}
public void setLookSpeed(float lookSpeed) {
this.lookSpeed = lookSpeed;
}
public float getMoveSpeed() {
return moveSpeed;
}
public void setMoveSpeed(float moveSpeed) {
this.moveSpeed = moveSpeed;
}
public LegacyCamera getCamera() {
return camera;
}
public void setCamera(LegacyCamera camera) {
this.camera = camera;
}
public void update() {
float delta = Fw.timer.getDelta();
Vector3f camPosition = camera.getPosition();
Vector3f camRotation = camera.getRotation();
positionDelta.zero();
if (Fw.input.isActionKeyDown(KEY_ACTION_MOVE_BACK)) {
positionDelta.addX(MathHelper.Sin(camRotation.getY() * MathHelper.PI_OVER_180));
positionDelta.addZ(MathHelper.Cos(camRotation.getY() * MathHelper.PI_OVER_180));
}
if (Fw.input.isActionKeyDown(KEY_ACTION_MOVE_FORWARD)) {
positionDelta.addX(-MathHelper.Sin(camRotation.getY() * MathHelper.PI_OVER_180));
positionDelta.addZ(-MathHelper.Cos(camRotation.getY() * MathHelper.PI_OVER_180));
}
if (Fw.input.isActionKeyDown(KEY_ACTION_MOVE_LEFT)) {
positionDelta.addX(MathHelper.Sin((camRotation.getY() - 90f) * MathHelper.PI_OVER_180));
positionDelta.addZ(MathHelper.Cos((camRotation.getY() - 90f) * MathHelper.PI_OVER_180));
}
if (Fw.input.isActionKeyDown(KEY_ACTION_MOVE_RIGHT)) {
positionDelta.addX(MathHelper.Sin((camRotation.getY() + 90f) * MathHelper.PI_OVER_180));
positionDelta.addZ(MathHelper.Cos((camRotation.getY() + 90f) * MathHelper.PI_OVER_180));
}
if (Fw.input.isActionKeyDown(KEY_ACTION_MOVE_DOWN)) {
positionDelta.setY(-1.0f);
}
if (Fw.input.isActionKeyDown(KEY_ACTION_MOVE_UP)) {
positionDelta.setY(1.0f);
}
if (positionDelta.magnitudeSquared() > 0) {
positionDelta.normalize();
positionDelta.multiply(delta * moveSpeed);
camera.setPositionX(camPosition.getX() + positionDelta.getX());
camera.setPositionY(camPosition.getY() + positionDelta.getY());
camera.setPositionZ(camPosition.getZ() + positionDelta.getZ());
}
// Positive rotation delta = counterclockwise rotation
rotationDelta.zero();
if (Fw.input.isActionKeyDown(KEY_ACTION_LOOK_DOWN)) {
rotationDelta.addX(-1.0f);
}
if (Fw.input.isActionKeyDown(KEY_ACTION_LOOK_UP)) {
rotationDelta.addX(1.0f);
}
if (Fw.input.isActionKeyDown(KEY_ACTION_TURN_LEFT)) {
rotationDelta.addY(1.0f);
}
if (Fw.input.isActionKeyDown(KEY_ACTION_TURN_RIGHT)) {
rotationDelta.addY(-1.0f);
}
rotationDelta.addX(Fw.input.getDeltaYWithSensitivity());
rotationDelta.addY(-Fw.input.getDeltaXWithSensitivity());
// LWJGL will return 0 for mouse movement if the frame rate is higher than 125fps. If we just used the delta
// amount then the mouse speed would be reduced. MOUSE_POLL is set for 125fps to compensate for this issue.
// If the frame rate is lower than 125fps then we want the larger delta.
if (rotationDelta.magnitudeSquared() > 0) {
float mousePoll = Math.max(delta, Fw.input.MOUSE_POLL);
rotationDelta.multiply(mousePoll * lookSpeed);
camera.setRotationX(camRotation.getX() - rotationDelta.getX());
camera.setRotationY(camRotation.getY() + rotationDelta.getY());
camera.setRotationZ(camRotation.getZ() - rotationDelta.getZ());
correctHeadingPitchAndRoll();
}
}
@Override
public void registerActions() {
Fw.input.setAction(KEY_ACTION_LOOK_DOWN, Keyboard.DOWN);
Fw.input.setAction(KEY_ACTION_LOOK_UP, Keyboard.UP);
Fw.input.setAction(KEY_ACTION_MOVE_BACK, Keyboard.S);
Fw.input.setAction(KEY_ACTION_MOVE_DOWN, Keyboard.LEFT_SHIFT);
Fw.input.setAction(KEY_ACTION_MOVE_FORWARD, Keyboard.W);
Fw.input.setAction(KEY_ACTION_MOVE_LEFT, Keyboard.A);
Fw.input.setAction(KEY_ACTION_MOVE_RIGHT, Keyboard.D);
Fw.input.setAction(KEY_ACTION_MOVE_UP, Keyboard.SPACE);
Fw.input.setAction(KEY_ACTION_TURN_LEFT, Keyboard.LEFT);
Fw.input.setAction(KEY_ACTION_TURN_RIGHT, Keyboard.RIGHT);
}
@Override
public void unregisterActions() {
Fw.input.removeActionKey(KEY_ACTION_LOOK_DOWN);
Fw.input.removeActionKey(KEY_ACTION_LOOK_UP);
Fw.input.removeActionKey(KEY_ACTION_MOVE_BACK);
Fw.input.removeActionKey(KEY_ACTION_MOVE_DOWN);
Fw.input.removeActionKey(KEY_ACTION_MOVE_FORWARD);
Fw.input.removeActionKey(KEY_ACTION_MOVE_LEFT);
Fw.input.removeActionKey(KEY_ACTION_MOVE_RIGHT);
Fw.input.removeActionKey(KEY_ACTION_MOVE_UP);
Fw.input.removeActionKey(KEY_ACTION_TURN_LEFT);
Fw.input.removeActionKey(KEY_ACTION_TURN_RIGHT);
}
}