package com.vitco.core;
import com.threed.jpct.Camera;
import com.threed.jpct.SimpleVector;
import com.vitco.settings.VitcoSettings;
import java.util.ArrayList;
/**
* Basic camera interaction.
*/
public class CCamera extends Camera {
private final float[] amountShifted = new float[2]; // current shift distance
private final float[] amountShifted2D = new float[2]; // current shift distance
private float zoom = 400; // current zoom distance
private final float[] amountRotated = new float[2];
private SimpleVector resetViewLookAt = new SimpleVector(1,1,1).normalize();
// defaults to (0,0,0)
private final SimpleVector centerShift = new SimpleVector();
// the zoom limit
private float ZOOM_OUT_MAX = -1;
private float ZOOM_IN_MAX = -1;
public final void setZoomLimits(float zoom_in_max, float zoom_out_max) {
ZOOM_OUT_MAX = zoom_out_max;
ZOOM_IN_MAX = zoom_in_max;
}
// to disable all camera interaction
private boolean enableCamera = true;
public final void setEnabled(boolean b) {
enableCamera = b;
}
// getter for enabled
public final boolean isEnabled() {
return enableCamera;
}
// camera change listener
private final ArrayList<CameraChangeListener> listener = new ArrayList<CameraChangeListener>();
// add listener
public void addCameraChangeListener(CameraChangeListener ccl) {
listener.add(ccl);
}
// remove listener
public void removeCameraChangeListener(CameraChangeListener ccl) {
listener.remove(ccl);
}
// notify all listeners
private void notifyListener() {
for (CameraChangeListener ccl : listener) {
ccl.onCameraChange();
}
}
public final void setCenterShift(SimpleVector centerShift) {
this.centerShift.set(centerShift);
// reset the "complex shift"
amountShifted[0] = 0;
amountShifted[1] = 0;
amountShifted2D[0] = 0;
amountShifted2D[1] = 0;
update();
}
// get the current origin
private SimpleVector getOrigin() {
return new SimpleVector(-centerShift.x, -centerShift.y-amountShifted[1], -centerShift.z);
}
public void zoomIn(float speed) {
if (enableCamera && speed != 0) {
speed = Math.abs(speed);
if (zoom - speed > ZOOM_IN_MAX || ZOOM_IN_MAX == -1) {
zoom -= speed;
} else {
zoom = ZOOM_IN_MAX;
}
update();
}
}
public void zoomOut(float speed) {
if (enableCamera && speed != 0) {
speed = Math.abs(speed);
if (zoom + speed < ZOOM_OUT_MAX || ZOOM_OUT_MAX == -1) {
zoom += speed;
} else {
zoom = ZOOM_OUT_MAX;
}
update();
}
}
public void rotate(float amountX, float amountY) {
if (enableCamera && (amountX != 0 || amountY != 0)) {
amountRotated[0] += amountX;
amountRotated[1] += amountY;
update();
}
}
public void shift(float amountX, float amountY, float factor) {
if (enableCamera && (amountX != 0 || amountY != 0)) {
amountShifted[0] += amountX*factor;
amountShifted[1] += amountY*factor;
update();
}
}
// shift view (to current perspective)
public void shift2D(float amountX, float amountY, float factor) {
if (enableCamera && (amountX != 0 || amountY != 0)) {
amountShifted2D[0] += amountX*factor;
amountShifted2D[1] += amountY*factor;
update();
}
}
public final void setView(SimpleVector pos) {
if (enableCamera) {
centerShift.set(SimpleVector.ORIGIN);
resetViewLookAt.set(pos);
resetViewLookAt = resetViewLookAt.normalize();
resetViewLookAt.scalarMul(-1);
amountRotated[0] = 0;
amountRotated[1] = 0;
amountShifted[0] = 0;
amountShifted[1] = 0;
amountShifted2D[0] = 0;
amountShifted2D[1] = 0;
zoom = pos.distance(getOrigin()); // needs to go last
update();
}
}
private void update() {
// set camera position and look at our inverted view pos point
SimpleVector origin = getOrigin();
this.setPosition(origin);
origin.add(resetViewLookAt);
this.lookAt(origin);
// rotate the camera correctly
this.rotateAxis(this.getYAxis(), amountRotated[0] * VitcoSettings.MAIN_VIEW_ROTATION_Y_FACTOR);
this.rotateX(-amountRotated[1] * VitcoSettings.MAIN_VIEW_ROTATION_X_FACTOR);
// move the camera out
this.moveCamera(Camera.CAMERA_MOVEOUT, zoom);
// shift the camera
this.moveCamera(new SimpleVector(0, -1, 0), amountShifted[1]);
this.moveCamera(Camera.CAMERA_MOVELEFT, amountShifted[0]);
// shift the camera 2D
this.moveCamera(Camera.CAMERA_MOVELEFT, amountShifted2D[0]);
this.moveCamera(Camera.CAMERA_MOVEUP, amountShifted2D[1]);
// notify all the listeners
notifyListener();
}
}