A Camera Class for OpenGL John McGuiness October 2006.
-
Upload
olivia-wilkerson -
Category
Documents
-
view
220 -
download
1
Transcript of A Camera Class for OpenGL John McGuiness October 2006.
A Camera Class for A Camera Class for OpenGLOpenGL
John McGuinessJohn McGuiness
October 2006October 2006
Necessity for a Camera ClassNecessity for a Camera Class
Existing available camera tool - gluLookAt()Existing available camera tool - gluLookAt() Basic utility which encapsulates a series of rotate and Basic utility which encapsulates a series of rotate and
translate commandstranslate commands Allows viewing along an arbitrary line of sight with an “Up” Allows viewing along an arbitrary line of sight with an “Up”
vector definedvector defined Need extra transformations to provide greater Need extra transformations to provide greater
flexibilityflexibility Need to modify “Forward” and “Along” vectors as Need to modify “Forward” and “Along” vectors as
well as “Up” to improve on gluLookAt()well as “Up” to improve on gluLookAt() Camera class may be built to encapsulate commands Camera class may be built to encapsulate commands
for greater ease of usefor greater ease of use
““Up”, “Forward” and “Along”Up”, “Forward” and “Along” The three camera view vectors are defined as shown:The three camera view vectors are defined as shown:
Proposed Camera FeaturesProposed Camera Features The camera class should:The camera class should:
Provide motion along the view vectors as well as arbitrary Provide motion along the view vectors as well as arbitrary axes (in some cases)axes (in some cases)
Provide rotation about the view vectors as well as arbitrary Provide rotation about the view vectors as well as arbitrary axes (in some cases)axes (in some cases)
Maintain the camera’s own orientation by keeping the Maintain the camera’s own orientation by keeping the viewing vectors orthogonal to each otherviewing vectors orthogonal to each other
Need to define motion for two possible types of Need to define motion for two possible types of camera:camera: Land camera – e.g. for road vehicles simulationLand camera – e.g. for road vehicles simulation Air camera – e.g. for flight simulationAir camera – e.g. for flight simulation
Camera MotionCamera Motion WalkingWalking
This is motion along the This is motion along the ForwardForward vector (or Z-axis): vector (or Z-axis):
Camera MotionCamera Motion StrafingStrafing
This is side to side motion on the This is side to side motion on the AlongAlong vector (or X-axis): vector (or X-axis):
Camera MotionCamera Motion FlyingFlying
This is vertical motion on the This is vertical motion on the UpUp vector (or Y-axis): vector (or Y-axis):
Camera RotationCamera Rotation PitchingPitching
This is rotation about the This is rotation about the AlongAlong vector – looking up and down vector – looking up and down
Camera RotationCamera Rotation YawingYawing
This is rotation about the This is rotation about the UpUp vector – looking left and right vector – looking left and right
Camera RotationCamera Rotation RollingRolling
This is rotation about the This is rotation about the ForwardForward vector – twisting left and right vector – twisting left and right
Camera Class DeclarationCamera Class Declaration The camera class uses a type called Vector3D The camera class uses a type called Vector3D
which provides storage and common operations which provides storage and common operations (e.g. dot product, cross product etc.) for vectors(e.g. dot product, cross product etc.) for vectors
#include "Vector3D.h"#include "Vector3D.h"
The enumerated type defined below is used to The enumerated type defined below is used to distinguish between the two types of cameradistinguish between the two types of camera
enum CAM_TYPE { LAND_CAM, AIR_CAM };enum CAM_TYPE { LAND_CAM, AIR_CAM };
Camera Class DeclarationCamera Class Declaration First, we need private variables for each view First, we need private variables for each view
vector as well as the camera type and current vector as well as the camera type and current position:position:
class Camera {class Camera {
private:private:
CAM_TYPE CameraType;CAM_TYPE CameraType;
Vector3D Position;Vector3D Position;
Vector3D Along;Vector3D Along;
Vector3D Up;Vector3D Up;
Vector3D Forward;Vector3D Forward;
......
Camera Class DeclarationCamera Class Declaration Various construction/destruction, update and Various construction/destruction, update and
control functions are then declared publically:control functions are then declared publically:
class Camera {class Camera {
......
public:public:
Camera(CAM_TYPE ct = LAND_CAM); // Default: landCamera(CAM_TYPE ct = LAND_CAM); // Default: land
virtual ~Camera();virtual ~Camera();
void SetCameraType(CAM_TYPE ct);void SetCameraType(CAM_TYPE ct);
Vector3D GetPosition();Vector3D GetPosition();
void Reset();void Reset();
void Update();void Update();
......
Camera Class DeclarationCamera Class Declaration Finally, the motion and rotation functions are declared.Finally, the motion and rotation functions are declared. The boolean array, The boolean array, Wall[4]Wall[4], is an extra feature which , is an extra feature which
modifies the motion of land cameras if they have to modifies the motion of land cameras if they have to slide against walls (as opposed to going through them)slide against walls (as opposed to going through them)class Camera {class Camera {
......
public:public:
......
void Pitch(GLfloat theta);void Pitch(GLfloat theta);
void Yaw(GLfloat theta);void Yaw(GLfloat theta);
void Roll(GLfloat theta);void Roll(GLfloat theta);
void Walk(GLfloat delta, bool Wall[4]);void Walk(GLfloat delta, bool Wall[4]);
void Strafe(GLfloat delta, bool Wall[4]);void Strafe(GLfloat delta, bool Wall[4]);
void Fly(GLfloat delta);void Fly(GLfloat delta);
};};
Setup and Control FunctionsSetup and Control Functions
The code listing on the following two slides is The code listing on the following two slides is fairly self-explanatoryfairly self-explanatory
It comprises the basic constructor and destructor It comprises the basic constructor and destructor as well as a function to alter the camera typeas well as a function to alter the camera type
The Reset() function sets the camera position to The Reset() function sets the camera position to (0,0,0) and aligns the viewing axes with the local (0,0,0) and aligns the viewing axes with the local drawing coordinate systemdrawing coordinate system
Note that the default Forward vector points along Note that the default Forward vector points along the negative Z-axisthe negative Z-axis
Setup and Control FunctionsSetup and Control Functions
Camera::Camera(CAM_TYPE ct) {Camera::Camera(CAM_TYPE ct) {
SetCameraType(ct);SetCameraType(ct);
Reset();Reset();
}}
Camera::~Camera() {Camera::~Camera() {
}}
void Camera::SetCameraType(CAM_TYPEct) {void Camera::SetCameraType(CAM_TYPEct) {
CameraType = ct;CameraType = ct;
}}
Setup and Control FunctionsSetup and Control Functions
Vector3D Camera::GetPosition() {Vector3D Camera::GetPosition() {
return Position;return Position;
}}
void Camera::Reset() {void Camera::Reset() {
Position = Vector3D(0.0, 0.0, 0.0);Position = Vector3D(0.0, 0.0, 0.0);
Along = Vector3D(1.0, 0.0, 0.0);Along = Vector3D(1.0, 0.0, 0.0);
Up = Vector3D(0.0, 1.0, 0.0);Up = Vector3D(0.0, 1.0, 0.0);
Forward = Vector3D(0.0, 0.0, -1.0);Forward = Vector3D(0.0, 0.0, -1.0);
Update();Update();
}}
Building the View MatrixBuilding the View Matrix The last function called by Reset() is probably the The last function called by Reset() is probably the
most importantmost important The Update() function applies all changes made to The Update() function applies all changes made to
the viewing axes and camera position, and updates the viewing axes and camera position, and updates the view in MODELVIEW modethe view in MODELVIEW mode
In actual fact, as with gluLookAt(), the perception of In actual fact, as with gluLookAt(), the perception of camera motion is achieved by moving the objects camera motion is achieved by moving the objects around the scene while keeping the camera at a around the scene while keeping the camera at a fixed positionfixed position
Instead of using translations and rotations, a view Instead of using translations and rotations, a view matrix may be built, meaning that just one OpenGL matrix may be built, meaning that just one OpenGL function call is needed – glLoadMatrix()function call is needed – glLoadMatrix()
Building the View MatrixBuilding the View Matrix
First we obtain the camera virtual position First we obtain the camera virtual position coordinates using the dot product of pairs of the coordinates using the dot product of pairs of the view vectors:view vectors:
void Camera::Update() {void Camera::Update() {
GLfloat x = DotProduct(Along, Position);GLfloat x = DotProduct(Along, Position);
GLfloat y = DotProduct(Up, Position);GLfloat y = DotProduct(Up, Position);
GLfloat z = DotProduct(Forward, Position);GLfloat z = DotProduct(Forward, Position);
......
These will be used to translate the camera (or These will be used to translate the camera (or rather, the scene) to its correct positionrather, the scene) to its correct position
Building the View MatrixBuilding the View Matrix The translation part of the view matrix is shown below:The translation part of the view matrix is shown below:
1 0 0 01 0 0 0
T =T = 0 1 0 00 1 0 0
0 0 1 00 0 1 0
––x –y z 1x –y z 1
Note that we must remember to make z positive, since Note that we must remember to make z positive, since for convenience we have taken “Forward” as meaning for convenience we have taken “Forward” as meaning the direction the direction intointo the screen which is opposite to the screen which is opposite to OpenGL convention (Z-axis is positive outwards)OpenGL convention (Z-axis is positive outwards)
Building the View MatrixBuilding the View Matrix The rotation part of the view matrix is built from The rotation part of the view matrix is built from
the view vectors as shown:the view vectors as shown:
A.x U.x –F.xA.x U.x –F.x
R =R = A.y U.y –F.yA.y U.y –F.y
A.z U.z –F.zA.z U.z –F.z
Again, the Forward vector is reversedAgain, the Forward vector is reversed
Building the View MatrixBuilding the View Matrix Combining these two matrices, we get:Combining these two matrices, we get:
1 0 0 01 0 0 0 A.x U.x –F.x A.x U.x –F.x00 A.x U.x –F.x A.x U.x –F.x00
V =V = 0 1 0 0 .0 1 0 0 . A.y U.y –F.y A.y U.y –F.y0 =0 = A.y U.y –F.y A.y U.y –F.y00
0 0 1 00 0 1 0 A.z U.z –F.z A.z U.z –F.z 00 A.z U.z – A.z U.z –F.zF.z 00
––x –y z 1x –y z 1 0 0 0 0 0 0 11 –x –y z 1 –x –y z 1
The code on the following slides shows the rest of The code on the following slides shows the rest of the implemented functionthe implemented function
Building the View MatrixBuilding the View Matrixvoid Camera::Update() {void Camera::Update() {
......
Glfloat ViewMatrix[4][4];Glfloat ViewMatrix[4][4];
ViewMatrix[0][0] = Along.x;ViewMatrix[0][0] = Along.x;
ViewMatrix[0][1] = Up.x;ViewMatrix[0][1] = Up.x;
ViewMatrix[0][2] = -Forward.x;ViewMatrix[0][2] = -Forward.x;
ViewMatrix[0][3] = 0.0;ViewMatrix[0][3] = 0.0;
ViewMatrix[1][0] = Along.y;ViewMatrix[1][0] = Along.y;
ViewMatrix[1][1] = Up.y;ViewMatrix[1][1] = Up.y;
ViewMatrix[1][2] = -Forward.y;ViewMatrix[1][2] = -Forward.y;
ViewMatrix[1][3] = 0.0;ViewMatrix[1][3] = 0.0;
......
Building the View MatrixBuilding the View Matrix......
ViewMatrix[2][0] = Along.z;ViewMatrix[2][0] = Along.z;
ViewMatrix[2][1] = Up.z;ViewMatrix[2][1] = Up.z;
ViewMatrix[2][2] = -Forward.z;ViewMatrix[2][2] = -Forward.z;
ViewMatrix[2][3] = 0.0;ViewMatrix[2][3] = 0.0;
ViewMatrix[3][0] = -x;ViewMatrix[3][0] = -x;
ViewMatrix[3][1] = -y;ViewMatrix[3][1] = -y;
ViewMatrix[3][2] = z;ViewMatrix[3][2] = z;
ViewMatrix[3][3] = 1.0;ViewMatrix[3][3] = 1.0;
glMatrixMode(GL_MODELVIEW);glMatrixMode(GL_MODELVIEW);
glLoadMatrixf((GLfloat *)&ViewMatrix);glLoadMatrixf((GLfloat *)&ViewMatrix);
}}
Camera Rotation FunctionsCamera Rotation Functions
The Pitch(), Yaw() and Roll() functions change the direction of the The Pitch(), Yaw() and Roll() functions change the direction of the Forward, Along and Up vectors respectivelyForward, Along and Up vectors respectively
In each case, the rotation will result in the alteration of a second In each case, the rotation will result in the alteration of a second view vector, leaving one unchangedview vector, leaving one unchanged
The second modified vector is found by calculating the cross The second modified vector is found by calculating the cross product of the other two vectorsproduct of the other two vectors
This means that mutual orthognality is maintained for the three This means that mutual orthognality is maintained for the three vectorsvectors
Camera Rotation FunctionsCamera Rotation Functions Looking at a yaw from above, we can see how to Looking at a yaw from above, we can see how to
calculate the new direction of the Along vector:calculate the new direction of the Along vector:
Camera Rotation FunctionsCamera Rotation Functions
Thus, for the Yaw function definition, we have:Thus, for the Yaw function definition, we have:
void Camera::Yaw(GLfloat theta) {void Camera::Yaw(GLfloat theta) {
Along = Along * cos(theta * DEG2RAD)Along = Along * cos(theta * DEG2RAD)
+ Forward * sin(theta * DEG2RAD);+ Forward * sin(theta * DEG2RAD);
Along.Normalize();Along.Normalize();
Forward = CrossProduct(Along, Up) * -1.0;Forward = CrossProduct(Along, Up) * -1.0;
Update();Update();
}}
Pitch() and Roll() on the following slide look very Pitch() and Roll() on the following slide look very similarsimilar
Camera Rotation FunctionsCamera Rotation Functionsvoid Camera::Pitch(GLfloat theta) {void Camera::Pitch(GLfloat theta) {
// Invert UP/DOWN for air cameras// Invert UP/DOWN for air cameras
if(CameraType == AIR_CAM) theta = -theta;if(CameraType == AIR_CAM) theta = -theta;
Forward = Forward * cos(theta * DEG2RAD)Forward = Forward * cos(theta * DEG2RAD)
+ Up * sin(theta * DEG2RAD);+ Up * sin(theta * DEG2RAD);
Forward.Normalize();Forward.Normalize();
Up = CrossProduct(Forward, Along) * -1.0;Up = CrossProduct(Forward, Along) * -1.0;
Update();Update();
}}
void Camera::Roll(GLfloat theta) {void Camera::Roll(GLfloat theta) {
if(CameraType == LAND_CAM) return; // Not for land camsif(CameraType == LAND_CAM) return; // Not for land cams
Up = Up * cos(theta * DEG2RAD)Up = Up * cos(theta * DEG2RAD)
- Along * sin(theta * DEG2RAD);- Along * sin(theta * DEG2RAD);
Up.Normalize();Up.Normalize();
Along = CrossProduct(Forward, Up);Along = CrossProduct(Forward, Up);
Update();Update();
}}
Camera Motion FunctionsCamera Motion Functions Walk(), Strafe() and Fly() are a little easier to implementWalk(), Strafe() and Fly() are a little easier to implement In each case, all we have to do is add the correct scaled In each case, all we have to do is add the correct scaled
vector to the camera’s Position vector and updatevector to the camera’s Position vector and update As with rotation functions, motion functions work slightly As with rotation functions, motion functions work slightly
differently depending on the type of camera being useddifferently depending on the type of camera being used For example, when walking forward with a land camera, if For example, when walking forward with a land camera, if
the view has been pitched upwards, we do not want to the view has been pitched upwards, we do not want to move up the camera’s forward vector, but rather along a move up the camera’s forward vector, but rather along a modified vector with the Y componet set to 0 – this will modified vector with the Y componet set to 0 – this will achieve the effect of staying on the ground rather than achieve the effect of staying on the ground rather than taking off into the air.taking off into the air.
Camera Rotation FunctionsCamera Rotation Functions The Walk function with wall handling also The Walk function with wall handling also
implemented:implemented:
void Camera::Walk(GLfloat delta, bool Wall[4]) {void Camera::Walk(GLfloat delta, bool Wall[4]) {
if(CameraType == LAND_CAM)if(CameraType == LAND_CAM)
Position -= Vector3D(Forward.x *Position -= Vector3D(Forward.x *
!(Wall[0] && Forward.x * delta > 0.0 ||!(Wall[0] && Forward.x * delta > 0.0 ||
Wall[1] && Forward.x * delta < 0.0),Wall[1] && Forward.x * delta < 0.0),
0.0, Forward.z *0.0, Forward.z *
!(Wall[2] && Forward.z * delta > 0.0 ||!(Wall[2] && Forward.z * delta > 0.0 ||
Wall[3] && Forward.z * delta < 0.0))Wall[3] && Forward.z * delta < 0.0))
* delta;* delta;
else Position -= Forward * delta; // Air cameraelse Position -= Forward * delta; // Air camera
Update();Update();
}}
Camera Rotation FunctionsCamera Rotation Functions Similarly, the Strafe function is defined as follows:Similarly, the Strafe function is defined as follows:
void Camera::Strafe(GLfloat delta, bool Wall[4]) {void Camera::Strafe(GLfloat delta, bool Wall[4]) {
if(CameraType == LAND_CAM)if(CameraType == LAND_CAM)
Position -= Vector3D(Along.x *Position -= Vector3D(Along.x *
!(Wall[0] && Along.x * delta > 0.0 ||!(Wall[0] && Along.x * delta > 0.0 ||
Wall[1] && Along.x * delta < 0.0),Wall[1] && Along.x * delta < 0.0),
0.0, Along.z *0.0, Along.z *
!(Wall[2] && Along.z * delta > 0.0 ||!(Wall[2] && Along.z * delta > 0.0 ||
Wall[3] && Along.z * delta < 0.0))Wall[3] && Along.z * delta < 0.0))
* delta;* delta;
else Position += Along * delta; // Air cameraelse Position += Along * delta; // Air camera
Update();Update();
}}
Camera Rotation FunctionsCamera Rotation Functions Finally, flying is, of course, only allowed for air Finally, flying is, of course, only allowed for air
cameras:cameras:
void Camera::Fly(GLfloat delta, bool Wall[4]) {void Camera::Fly(GLfloat delta, bool Wall[4]) {
// Don't allow for land cameras// Don't allow for land cameras
if(CameraType == LAND_CAM) return;if(CameraType == LAND_CAM) return;
Position += Up * delta;Position += Up * delta;
Update();Update();
}}
Although flying through walls has been allowed Although flying through walls has been allowed here, this would be implemented in the same here, this would be implemented in the same manner as the previous two functionsmanner as the previous two functions
ReferencesReferences
Frank D. Luna, 2003, Frank D. Luna, 2003, Introduction to 3D Game Introduction to 3D Game Programming with DirectX 9.0Programming with DirectX 9.0, Wordware , Wordware Publishing, Inc.Publishing, Inc.
Silicon Graphics Inc., 1997, Silicon Graphics Inc., 1997, OpenGL Programming OpenGL Programming Guide, Chapter 3 – ViewingGuide, Chapter 3 – Viewing, Addison-Wesley , Addison-Wesley Publishing CompanyPublishing Company
Philipp Crocoll, The Advanced CodeColony Philipp Crocoll, The Advanced CodeColony Camera, Camera, http://http://www.codecolony.de/www.codecolony.de/