/** * a simple processing camera class * easy to use orbit, pan and zoom methods * by georg munkel (munkel@arch.ethz.ch) * * 4 steps to use the class: * * 1. create a camera object with initial distance * Camera myCam = new Camera( 300 ); * or with smooth camera movement * new Camera( 300, true); * * 2. set the target * myCam.setTarget( x, y, z ); * * 3. in the beginning of your draw() method apply the current camera settings * myCam.use(); * * 4. in your preferred mouse method ( e.g. mouseDragged() ) apply changes * myCam.mouseOrbit(); * myCam.mouseZoom(); * myCam.mousePan(); **/ class Camera { float rotationSpeed = 0.01; // speed of rotation float angleX, angleY, angleZ; float currAngleX, currAngleY, currAngleZ; float distance; float currDistance; float transX, transY,transZ; float currTransX, currTransY, currTransZ; boolean smoothOrbit = false; // CONSTRUCTORS Camera(float distance) { setDistance(distance); } Camera(float distance, boolean smoothMovement) { this(distance); smooth(); } //METHODS void mouseOrbit() { float dx = mouseX -pmouseX; float dy = mouseY -pmouseY; orbit(dx, dy); } void mouseZoom() { float dy = mouseY -pmouseY; this.setDistance(this.distance -dy); } void mousePan() { float dx = mouseX -pmouseX; float dy = mouseY -pmouseY; pan(dx, dy); } void pan(float dx, float dy) { this.transX += dx *cos(currAngleZ) ;//+dx*sin(currAngleX); this.transY += -dx*sin(currAngleZ) +dy * cos(currAngleX); this.transZ += -dy *sin(currAngleX) ; } void orbit(float dx, float dy) { this.rotCamZ(-dx *rotationSpeed); this.rotCamX(-dy *rotationSpeed); } void setTarget(float x, float y, float z) { transX = -x; transY = -y; transZ = -z; } void smooth() { smoothOrbit = true; } void noSmooth() { smoothOrbit = false; } void setDistance(float distance) { this.distance = distance; } void rotCamX(float angle) { angleX += angle; } void rotCamY(float angle) { angleY += angle; } void rotCamZ(float angle) { angleZ += angle; } /** * applies the current camera settings * call it in your draw method before any paint job **/ void useCam() { if (smoothOrbit) { if (abs(currAngleX-angleX) > 0.01) currAngleX += (angleX -currAngleX) /10.0 ; if (abs(currAngleY-angleY) > 0.01) currAngleY += (angleY -currAngleY) /10.0 ; if (abs(currAngleZ-angleZ) > 0.01) currAngleZ += (angleZ -currAngleZ) /10.0 ; if (abs(currTransX-transX) > 0.01) currTransX += (transX -currTransX) /10.0 ; if (abs(currTransY-transY) > 0.01) currTransY += (transY -currTransY) /10.0 ; if (abs(currTransZ-transZ) > 0.01) currTransZ += (transZ -currTransZ) /10.0 ; if (abs(currDistance-distance) > 0.01) currDistance += (distance -currDistance) /10.0 ; } else { currAngleX = angleX; currAngleY = angleY; currAngleZ = angleZ; currTransX = transX; currTransY = transY; currTransZ = transZ; currDistance = distance; } camera( 0, 0, this.currDistance, 0, 0, 0, 0, 1, 0 ); rotateX(currAngleX); rotateY(currAngleY); rotateZ(currAngleZ); translate(currTransX, currTransY, currTransZ); } float getAngleX() { return currAngleX; } float getAngleY() { return currAngleY; } float getAngleZ() { return currAngleZ; } }