- By
**hal** - Follow User

- 370 Views
- Uploaded on

Download Presentation
## PowerPoint Slideshow about 'A Camera Class for OpenGL' - hal

**An Image/Link below is provided (as is) to download presentation**

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript

Necessity for a Camera Class

- Existing available camera tool - gluLookAt()
- Basic utility which encapsulates a series of rotate and translate commands
- Allows viewing along an arbitrary line of sight with an “Up” vector defined
- Need extra transformations to provide greater flexibility
- Need to modify “Forward” and “Along” vectors as well as “Up” to improve on gluLookAt()
- Camera class may be built to encapsulate commands for greater ease of use

“Up”, “Forward” and “Along”

- The three camera view vectors are defined as shown:

Proposed Camera Features

- The camera class should:
- Provide motion along the view vectors as well as arbitrary axes (in some cases)
- Provide rotation about the view vectors as well as arbitrary axes (in some cases)
- Maintain the camera’s own orientation by keeping the viewing vectors orthogonal to each other
- Need to define motion for two possible types of camera:
- Land camera – e.g. for road vehicles simulation
- Air camera – e.g. for flight simulation

Camera Motion

- Walking
- This is motion along the Forward vector (or Z-axis):

Camera Motion

- Strafing
- This is side to side motion on the Along vector (or X-axis):

Camera Motion

- Flying
- This is vertical motion on the Up vector (or Y-axis):

Camera Class Declaration

- The camera class uses a type called Vector3D which provides storage and common operations (e.g. dot product, cross product etc.) for vectors

#include "Vector3D.h"

- The enumerated type defined below is used to distinguish between the two types of camera

enum CAM_TYPE { LAND_CAM, AIR_CAM };

Camera Class Declaration

- First, we need private variables for each view vector as well as the camera type and current position:

class Camera {

private:

CAM_TYPE CameraType;

Vector3D Position;

Vector3D Along;

Vector3D Up;

Vector3D Forward;

...

Camera Class Declaration

- Various construction/destruction, update and control functions are then declared publically:

class Camera {

...

public:

Camera(CAM_TYPE ct = LAND_CAM); // Default: land

virtual ~Camera();

void SetCameraType(CAM_TYPE ct);

Vector3D GetPosition();

void Reset();

void Update();

...

Camera Class Declaration

- Finally, the motion and rotation functions are declared.
- The boolean array, Wall[4], is an extra feature which modifies the motion of land cameras if they have to slide against walls (as opposed to going through them)

class Camera {

...

public:

...

void Pitch(GLfloat theta);

void Yaw(GLfloat theta);

void Roll(GLfloat theta);

void Walk(GLfloat delta, bool Wall[4]);

void Strafe(GLfloat delta, bool Wall[4]);

void Fly(GLfloat delta);

};

Setup and Control Functions

- The code listing on the following two slides is fairly self-explanatory
- It comprises the basic constructor and destructor as well as a function to alter the camera type
- The Reset() function sets the camera position to (0,0,0) and aligns the viewing axes with the local drawing coordinate system
- Note that the default Forward vector points along the negative Z-axis

Setup and Control Functions

Camera::Camera(CAM_TYPE ct) {

SetCameraType(ct);

Reset();

}

Camera::~Camera() {

}

void Camera::SetCameraType(CAM_TYPEct) {

CameraType = ct;

}

Setup and Control Functions

Vector3D Camera::GetPosition() {

return Position;

}

void Camera::Reset() {

Position = Vector3D(0.0, 0.0, 0.0);

Along = Vector3D(1.0, 0.0, 0.0);

Up = Vector3D(0.0, 1.0, 0.0);

Forward = Vector3D(0.0, 0.0, -1.0);

Update();

}

Building the View Matrix

- The last function called by Reset() is probably the most important
- The Update() function applies all changes made to the viewing axes and camera position, and updates the view in MODELVIEW mode
- In actual fact, as with gluLookAt(), the perception of camera motion is achieved by moving the objects around the scene while keeping the camera at a fixed position
- Instead of using translations and rotations, a view matrix may be built, meaning that just one OpenGL function call is needed – glLoadMatrix()

Building the View Matrix

- First we obtain the camera virtual position coordinates using the dot product of pairs of the view vectors:

void Camera::Update() {

GLfloat x = DotProduct(Along, Position);

GLfloat y = DotProduct(Up, Position);

GLfloat z = DotProduct(Forward, Position);

...

- These will be used to translate the camera (or rather, the scene) to its correct position

Building the View Matrix

- The translation part of the view matrix is shown below:

1 0 0 0

T = 0 1 0 0

0 0 1 0

–x –y z 1

- Note that we must remember to make z positive, since for convenience we have taken “Forward” as meaning the direction into the screen which is opposite to OpenGL convention (Z-axis is positive outwards)

Building the View Matrix

- The rotation part of the view matrix is built from the view vectors as shown:

A.x U.x –F.x

R = A.y U.y –F.y

A.z U.z –F.z

- Again, the Forward vector is reversed

Building the View Matrix

- Combining these two matrices, we get:

1 0 0 0 A.x U.x –F.x 0 A.x U.x –F.x 0

V = 0 1 0 0 . A.y U.y –F.y 0 = A.y U.y –F.y 0

0 0 1 0 A.z U.z –F.z 0 A.z U.z –F.z 0

–x –y z 1 0 0 0 1 –x –y z 1

- The code on the following slides shows the rest of the implemented function

Building the View Matrix

void Camera::Update() {

...

Glfloat ViewMatrix[4][4];

ViewMatrix[0][0] = Along.x;

ViewMatrix[0][1] = Up.x;

ViewMatrix[0][2] = -Forward.x;

ViewMatrix[0][3] = 0.0;

ViewMatrix[1][0] = Along.y;

ViewMatrix[1][1] = Up.y;

ViewMatrix[1][2] = -Forward.y;

ViewMatrix[1][3] = 0.0;

...

Building the View Matrix

...

ViewMatrix[2][0] = Along.z;

ViewMatrix[2][1] = Up.z;

ViewMatrix[2][2] = -Forward.z;

ViewMatrix[2][3] = 0.0;

ViewMatrix[3][0] = -x;

ViewMatrix[3][1] = -y;

ViewMatrix[3][2] = z;

ViewMatrix[3][3] = 1.0;

glMatrixMode(GL_MODELVIEW);

glLoadMatrixf((GLfloat *)&ViewMatrix);

}

Camera Rotation Functions

- The Pitch(), Yaw() and Roll() functions change the direction of the Forward, Along and Up vectors respectively
- In each case, the rotation will result in the alteration of a second view vector, leaving one unchanged
- The second modified vector is found by calculating the cross product of the other two vectors
- This means that mutual orthognality is maintained for the three vectors

Camera Rotation Functions

- Looking at a yaw from above, we can see how to calculate the new direction of the Along vector:

Camera Rotation Functions

- Thus, for the Yaw function definition, we have:

void Camera::Yaw(GLfloat theta) {

Along = Along * cos(theta * DEG2RAD)

+ Forward * sin(theta * DEG2RAD);

Along.Normalize();

Forward = CrossProduct(Along, Up) * -1.0;

Update();

}

- Pitch() and Roll() on the following slide look very similar

Camera Rotation Functions

void Camera::Pitch(GLfloat theta) {

// Invert UP/DOWN for air cameras

if(CameraType == AIR_CAM) theta = -theta;

Forward = Forward * cos(theta * DEG2RAD)

+ Up * sin(theta * DEG2RAD);

Forward.Normalize();

Up = CrossProduct(Forward, Along) * -1.0;

Update();

}

void Camera::Roll(GLfloat theta) {

if(CameraType == LAND_CAM) return; // Not for land cams

Up = Up * cos(theta * DEG2RAD)

- Along * sin(theta * DEG2RAD);

Up.Normalize();

Along = CrossProduct(Forward, Up);

Update();

}

Camera Motion Functions

- Walk(), Strafe() and Fly() are a little easier to implement
- In each case, all we have to do is add the correct scaled vector to the camera’s Position vector and update
- As with rotation functions, motion functions work slightly differently depending on the type of camera being used
- For example, when walking forward with a land camera, if the view has been pitched upwards, we do not want to move up the camera’s forward vector, but rather along a modified vector with the Y componet set to 0 – this will achieve the effect of staying on the ground rather than taking off into the air.

Camera Rotation Functions

- The Walk function with wall handling also implemented:

void Camera::Walk(GLfloat delta, bool Wall[4]) {

if(CameraType == LAND_CAM)

Position -= Vector3D(Forward.x *

!(Wall[0] && Forward.x * delta > 0.0 ||

Wall[1] && Forward.x * delta < 0.0),

0.0, Forward.z *

!(Wall[2] && Forward.z * delta > 0.0 ||

Wall[3] && Forward.z * delta < 0.0))

* delta;

else Position -= Forward * delta; // Air camera

Update();

}

Camera Rotation Functions

- Similarly, the Strafe function is defined as follows:

void Camera::Strafe(GLfloat delta, bool Wall[4]) {

if(CameraType == LAND_CAM)

Position -= Vector3D(Along.x *

!(Wall[0] && Along.x * delta > 0.0 ||

Wall[1] && Along.x * delta < 0.0),

0.0, Along.z *

!(Wall[2] && Along.z * delta > 0.0 ||

Wall[3] && Along.z * delta < 0.0))

* delta;

else Position += Along * delta; // Air camera

Update();

}

Camera Rotation Functions

- Finally, flying is, of course, only allowed for air cameras:

void Camera::Fly(GLfloat delta, bool Wall[4]) {

// Don't allow for land cameras

if(CameraType == LAND_CAM) return;

Position += Up * delta;

Update();

}

- Although flying through walls has been allowed here, this would be implemented in the same manner as the previous two functions

References

- Frank D. Luna, 2003, Introduction to 3D Game Programming with DirectX 9.0, Wordware Publishing, Inc.
- Silicon Graphics Inc., 1997, OpenGL Programming Guide, Chapter 3 – Viewing, Addison-Wesley Publishing Company
- Philipp Crocoll, The Advanced CodeColony Camera, http://www.codecolony.de/

Download Presentation

Connecting to Server..