package teamcomm.gui; import com.jogamp.opengl.GL2; import com.jogamp.opengl.glu.GLU; /** * Class for modeling the viewer position in a 3D environment. * * @author Felix Thielke */ public class Camera { private static final float NEAR_PLANE = 1; private static final float FAR_PLANE = 20; private float theta = 45; private float phi = 0; private float radius = 9; private boolean flipped = false; /** * Rotate the camera by 180 degrees around the z axis. * * @param gl OpenGL context */ public void flip(final GL2 gl) { flipped = !flipped; gl.glRotatef(180, 0, 0, 1); } /** * Adds the given angle to the theta angle (for rotation around the x axis). * theta is clipped to the range [0,90]. * * @param amount angle */ public void addTheta(final float amount) { theta += amount; if (theta < 0) { theta = 0; } else if (theta > 90) { theta = 90; } } /** * Adds the given angle to the phi angle (for rotation around the z axis). * phi is clipped to the range [-90,90]. * * @param amount angle */ public void addPhi(final float amount) { phi += amount; if (phi < -90) { phi = -90; } else if (phi > 90) { phi = 90; } } /** * Adds the given distance to the camera radius. The radius is clipped so * that the field is always within the viewing frustum. * * @param amount distance */ public void addRadius(final float amount) { radius += amount; if (radius < NEAR_PLANE) { radius = NEAR_PLANE; } else if (radius > FAR_PLANE - 5) { radius = FAR_PLANE - 5; } } /** * Sets up the viewing frustum of the camera on the given GL context. To be * called once whenever the ratio of width and height changes. * * @param gl OpenGL context * @param displayRatio ratio of width to height */ public void setupFrustum(final GL2 gl, final double displayRatio) { final GLU glu = GLU.createGLU(gl); gl.glMatrixMode(GL2.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(40, displayRatio, NEAR_PLANE, FAR_PLANE); gl.glMatrixMode(GL2.GL_MODELVIEW); } /** * Performs transformations on the given OpenGL context which correspond to * the position of the camera. * * @param gl OpenGL context */ public void positionCamera(final GL2 gl) { gl.glTranslatef(0, 0, -radius); gl.glRotatef(-theta, 1, 0, 0); gl.glRotatef(phi, 0, 0, 1); } /** * Performs transformations on the given OpenGl context so that the Z axis * points towards the position of the camera. Useful for rendering text. * * @param gl OpenGL context */ public void turnTowardsCamera(final GL2 gl) { gl.glRotatef((flipped ? 180 : 0) - phi, 0, 0, 1); gl.glRotatef(theta, 1, 0, 0); } }