Simple Camera

An easy to use camera class. Features orbit, zoom and pan

watch the demo ->

Download the source file

Table Of Contents

Source - applet


Camera myCam;
boolean smoothMove = true;

void setup()
{
        size(400, 400, P3D);

        // create a camera with distance 700 and smooth movement
        myCam = new Camera( 800, smoothMove );

        // the center of the orbit is assigned
        myCam.setTarget( 200, 200, 100 );

}

void draw()
{
        // must be called in the beginning of the draw loop
        // translate and rotate actions are called inside!
        myCam.useCam();


        // place your draw job here
        background(255);

        lights();
        directionalLight(255, 255, 200, 0, 0.2, -1);
        directionalLight(200, 200, 255, 1, 0.2, 0);

        drawSomeCubes();

        // draw a ground
        fill(255, 200);
        stroke(0);
        translate(200, 200, -11);
        ellipse(0,0, 80000, 80000);

}

// the camera movement is combined here with mouse action
void mouseDragged()
{
        if (mouseButton == LEFT)
        {
                myCam.mouseOrbit();
        }
        else if (mouseButton == RIGHT)
        {
                myCam.mouseZoom();
        }
        else if (mouseButton == CENTER)
        {
                myCam.mousePan();
        }
}

// the camera movement is combined here with key action
void keyPressed()
{
        if (key == CODED)
        {
                if      (keyCode == UP)    myCam.pan(  0,  30);
                else if (keyCode == DOWN)  myCam.pan(  0, -30);
                else if (keyCode == LEFT)  myCam.pan( 30,   0);
                else if (keyCode == RIGHT) myCam.pan(-30,   0);
        }
        else
        {
                if (key == ' ')
                {
                        smoothMove = !smoothMove;
                        if (smoothMove) myCam.smooth();
                        else myCam.noSmooth();
                }
                else if (key == 'a') myCam.orbit( 30,  0 );
                else if (key == 'd') myCam.orbit(-30,  0 );
                else if (key == 'w') myCam.orbit(  0, 30 );
                else if (key == 's') myCam.orbit(  0,-30 );
                else if (key == 'q'){
                        myCam.setTarget( 200, 200, 0 );
                        myCam.setDistance( 700 );
                }
        }

}

// simple paintjob
void drawSomeCubes()
{
        float offset = 100;
        noStroke();
        stroke(255, 40);
        for (int i=0; i<5; i++)
        {
                for (int k=0; k<5; k++)
                {
                        for (int m=0; m<5; m++)
                        {
                                color c = color( i * (255/5), k * (255/5), m * (255/5) );
                                fill( c );
                                cube(offset *i, offset*k, offset* m, 20);
                        }
                }
        }
}

void cube(float x, float y, float z, float bSize)
{
        pushMatrix();
        translate(x, y, z);
        box(bSize);
        popMatrix();
}


Source - class Camera


/**
* 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;
        }
}