1 / 33

A Camera Class for OpenGL

A Camera Class for OpenGL. John McGuiness October 2006. 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

hal
Télécharger la présentation

A Camera Class for OpenGL

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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. A Camera Class for OpenGL John McGuiness October 2006

  2. 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

  3. “Up”, “Forward” and “Along” • The three camera view vectors are defined as shown:

  4. 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

  5. Camera Motion • Walking • This is motion along the Forward vector (or Z-axis):

  6. Camera Motion • Strafing • This is side to side motion on the Along vector (or X-axis):

  7. Camera Motion • Flying • This is vertical motion on the Up vector (or Y-axis):

  8. Pitching This is rotation about the Along vector – looking up and down Camera Rotation

  9. Yawing This is rotation about the Up vector – looking left and right Camera Rotation

  10. Rolling This is rotation about the Forward vector – twisting left and right Camera Rotation

  11. 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 };

  12. 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; ...

  13. 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(); ...

  14. 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); };

  15. 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

  16. Setup and Control Functions Camera::Camera(CAM_TYPE ct) { SetCameraType(ct); Reset(); } Camera::~Camera() { } void Camera::SetCameraType(CAM_TYPEct) { CameraType = ct; }

  17. 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(); }

  18. 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()

  19. 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

  20. 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)

  21. 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

  22. 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

  23. 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; ...

  24. 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); }

  25. 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

  26. Camera Rotation Functions • Looking at a yaw from above, we can see how to calculate the new direction of the Along vector:

  27. 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

  28. 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(); }

  29. 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.

  30. 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(); }

  31. 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(); }

  32. 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

  33. 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/

More Related