package com.ericsson.tic.vi; /** * Keeps track of all common camera related variables. * * @author Sami Matilainen * @version 1.0 (2008-12-04) */ public class Camera { /** The view id for this camera. */ private int id; /** Specifies if we are currently in tilting mode. */ public boolean tilting; /** A flag used to determine wheter the mouse is dragging or not. */ public boolean dragging; /** Camera coordinate. */ public float camX, camY, camZ; /** Camera look at coordinate. */ public float lookX, lookY, lookZ; /** The Camera "up" vector coordinate. */ public float upX, upY, upZ; /** The zoom distance of the camera. */ public float zoom; /** Mouse coordinate given by mouse events. */ public int mouseX, mouseY; /** The motion vector calculated by mouse events. */ public float speedX, speedY; /** Angle which determines how much the world/globe should be rotated relative to the camera */ public float rotAngle; /** Angle which determines the tilt angle (around relative camera x axis). */ public float tiltAngle; /** A counter which is used to keep track of inertia. */ public int moveCounter; /** The parent panel of this camera. pv stands for Parent View. */ private ViewPanel pv; /** This is the tilt of the lookAt vector. This is not the same as tiltAngle which specifies tilt of the camera. */ private float tilt = 0.0f; /** * A constructor which sets up the camera. * * @param id The view id for this camera. * @param parentView The ViewPanel which this camera belongs to. */ public Camera(int id, ViewPanel parentView) { this.id = id; dragging = false; camX = 0; camY = 0; camZ = 0; lookX = 0; lookY = 0; lookZ = 0; upX = 0; upY = 1; upZ = 0; speedX = 0; speedY = 0; moveCounter = VI.GLOBE_MOVE_DELAY; zoom = VI.GLOBE_ZOOM_DEFAULT; tiltAngle = VI.GLOBE_TILT_ANGLE_DEFAULT; rotAngle = VI.GLOBE_ROT_ANGLE_DEFAULT; tilting = false; this.pv = parentView; } /** * To be called when the mouse is pressed. Sets dragging mode on. * * @param x Mouse coordinate. * @param y Mouse coordinate. */ public void mPressed(int x, int y) { mouseX = x; mouseY = y; moveCounter = VI.GLOBE_MOVE_DELAY; dragging = true; } /** * Updates the tilt of the tilt of the lookAt vector. * * @param t Specifies the magnitude and direction of the tilt. */ public void tilt(float t) { tilt = tilt + t/50.0f; if (tilt <= -1.0f) { tilt = -1.0f; } else if (tilt >= 1.0f) { tilt = 1.0f; } } /** * To be called when the mouse is pressed. Cancels dragging mode. */ public void mReleased() { dragging = false; } /** * To be called when the mousewheel is scrolled. Updates the zoom. * * @param w The amount the wheel was scrolled. */ public void mWheelMoved(int w) { zoom = zoom - w/VI.ZOOM_DECAY; if (pv.globeViewOn) { if (zoom > VI.GLOBE_ZOOM_MAX) { zoom = VI.GLOBE_ZOOM_MAX; } if (zoom < VI.GLOBE_ZOOM_MIN) { zoom = VI.GLOBE_ZOOM_MIN; } } else if (pv.planeViewOn) { if (zoom > VI.PLANE_ZOOM_MAX) { zoom = VI.PLANE_ZOOM_MAX; } if (zoom < VI.PLANE_ZOOM_MIN) { zoom = VI.PLANE_ZOOM_MIN; } } } /** * To be called when the mouse is dragged. Updates the speed/motion vector. * * @param x Mouse coordinate. * @param y Mouse coordinate. */ public void mDragged(int x, int y) { if (dragging) { if (VI.shiftPressed) { } else { if (VI.ignoreShift) { speedY = y - mouseY; speedX = x - mouseX; } else { if (VI.shiftPressed) { speedY = y - mouseY; } else { speedX = x - mouseX; } } mouseX = x; mouseY = y; moveCounter = VI.GLOBE_MOVE_DELAY; } } } /** * Updates the camera. Should be called with even intervalls. * Tuned for 20-30ups (updates per second). * Keeps track of cool stuff like the up-vector and inertia. */ public void update() { upY = 1.0f; if (pv.globeViewOn) { lookY = lookY + tilt; tilt = tilt/10.0f; if (tilt <= 0.01f && -0.01f <= tilt) { tilt = 0.0f; } // negative rotation is clockwise rotAngle = rotAngle+(speedX*0.1f*zoom); tiltAngle = tiltAngle+(speedY*0.1f*zoom); camY = (float)(zoom*Math.sin(Math.toRadians(tiltAngle))); camZ = (float)(zoom*Math.cos(Math.toRadians(tiltAngle))); if (tiltAngle >= 360.0f) { tiltAngle = tiltAngle - 360.0f; } if (tiltAngle < 0.0f) { tiltAngle = tiltAngle + 360.0f; } // change up-vector when moving from positive to negative z if (0.0f <= tiltAngle && tiltAngle <= 90.0f) { upY = 1.0f; } if (90.0f < tiltAngle && tiltAngle < 270.0f) { upY = -1.0f; } if (270.0f <= tiltAngle && tiltAngle <= 360.0f) { upY = 1.0f; } } else if (pv.planeViewOn) { camX = camX - speedX/(500.0f/zoom); camY = camY + speedY/(500.0f/zoom); camZ = zoom; lookX = lookX - speedX/(500.0f/zoom); lookY = lookY + speedY/(500.0f/zoom); lookZ = 0.0f; if (camX > VI.PLANE_PAN_X_MAX) { camX = VI.PLANE_PAN_X_MAX; lookX = VI.PLANE_PAN_X_MAX; } else if (camX < (0.0f - VI.PLANE_PAN_X_MAX)) { camX = 0.0f - VI.PLANE_PAN_X_MAX; lookX = 0.0f - VI.PLANE_PAN_X_MAX; } if (camY > VI.PLANE_PAN_Y_MAX) { camY = VI.PLANE_PAN_Y_MAX; lookY = VI.PLANE_PAN_Y_MAX; } else if (camY < (0.0f - VI.PLANE_PAN_Y_MAX)) { camY = 0.0f - VI.PLANE_PAN_Y_MAX; lookY = 0.0f - VI.PLANE_PAN_Y_MAX; } } else if (pv.globePhasingOut || pv.nodesMovingToPlaneTarget || pv.planePhasingIn) { lookX = 0.0f; lookY = 0.0f; lookZ = 0.0f; if (rotAngle > 0) { rotAngle = rotAngle - Math.abs(rotAngle) * 0.9f - 0.05f; } else if (rotAngle < 0) { rotAngle = rotAngle + Math.abs(rotAngle) * 0.9f + 0.05f; } if (-0.1f < rotAngle && rotAngle < 0.1f) { rotAngle = 0.0f; } if (tiltAngle > 0) { tiltAngle = tiltAngle - Math.abs(tiltAngle) * 0.9f - 0.05f; } else if (tiltAngle < 0) { tiltAngle = tiltAngle + Math.abs(tiltAngle) * 0.9f + 0.05f; } if (-0.1f < tiltAngle && tiltAngle < 0.1f) { tiltAngle = 0.0f; } if (zoom > VI.GLOBE_ZOOM_DEFAULT) { zoom = zoom - (zoom-VI.GLOBE_ZOOM_DEFAULT)*0.2f; } else if (zoom < VI.GLOBE_ZOOM_DEFAULT) { zoom = zoom + (VI.GLOBE_ZOOM_DEFAULT-zoom)*0.2f; } if (VI.GLOBE_ZOOM_DEFAULT-0.1f < zoom && zoom < VI.GLOBE_ZOOM_DEFAULT+0.1f) { zoom = VI.GLOBE_ZOOM_DEFAULT; } camY = (float)(zoom*Math.sin(Math.toRadians(tiltAngle))); camZ = (float)(zoom*Math.cos(Math.toRadians(tiltAngle))); if (tiltAngle >= 360.0f) { tiltAngle = tiltAngle - 360.0f; } if (tiltAngle < 0.0f) { tiltAngle = tiltAngle + 360.0f; } // change up-vector when moving from positive to negative z if (0.0f <= tiltAngle && tiltAngle <= 90.0f) { upY = 1.0f; } if (90.0f < tiltAngle && tiltAngle < 270.0f) { upY = -1.0f; } if (270.0f <= tiltAngle && tiltAngle <= 360.0f) { upY = 1.0f; } } else if (pv.planePhasingOut || pv.nodesMovingToGlobeTarget || pv.globePhasingIn) { if (camX > 0) { camX = camX - Math.abs(camX) * 0.05f - 0.05f; lookX = lookX - Math.abs(lookX) * 0.05f - 0.05f; } else if (camX < 0) { camX = camX + Math.abs(camX) * 0.05f + 0.05f; lookX = lookX + Math.abs(lookX) * 0.05f + 0.05f; } if (-0.05f < camX && camX < 0.05f) { camX = 0.0f; lookX = 0.0f; } if (camY > 0) { camY = camY - Math.abs(camY) * 0.05f - 0.05f; lookY = lookY - Math.abs(lookY) * 0.05f - 0.05f; } else if (camY < 0) { camY = camY + Math.abs(camY) * 0.05f + 0.05f; lookY = lookY + Math.abs(lookY) * 0.05f + 0.05f; } if (-0.05f < camY && camY < 0.05f) { camY = 0.0f; lookY = 0.0f; } if (zoom > VI.GLOBE_ZOOM_DEFAULT) { zoom = zoom - (zoom-VI.GLOBE_ZOOM_DEFAULT)*0.05f; } else if (zoom < VI.GLOBE_ZOOM_DEFAULT) { zoom = zoom + (VI.GLOBE_ZOOM_DEFAULT-zoom)*0.05f; } if (VI.GLOBE_ZOOM_DEFAULT-0.05f < zoom && zoom < VI.GLOBE_ZOOM_DEFAULT+0.05f) { zoom = VI.GLOBE_ZOOM_DEFAULT; } camZ = zoom; tiltAngle = 0.0f; rotAngle = 0.0f; } if (!VI.infiniteMoveDelayOn) { moveCounter--; } if (VI.panMoveDelayOn) { if (moveCounter <= 0) { if (speedX > 0) { speedX = speedX - Math.abs(speedX)/VI.SPEED_DECAY_ROT; } else { speedX = speedX + Math.abs(speedX)/VI.SPEED_DECAY_ROT; } } } else { speedX = 0.0f; } if (VI.tiltMoveDelayOn) { if (moveCounter <= 0) { if (speedY > 0) { speedY = speedY - Math.abs(speedY)/VI.SPEED_DECAY_TILT; } else { speedY = speedY + Math.abs(speedY)/VI.SPEED_DECAY_TILT; } } } else { speedY = 0.0f; } if (Math.abs(speedX) < 0.1f) { speedX = 0.0f; } if (Math.abs(speedY) < 0.1f) { speedY = 0.0f; } } }