Free camera is the first camera type which we will implement in this recipe. A free camera does not have a fixed target. However it does have a fixed position from which it can look in any direction.
The following figure shows a free viewing camera. When we rotate the camera, it rotates at its position. When we move the camera, it keeps looking in the same direction.
The source code for this recipe is in the Chapter2/FreeCamera
directory. The CFreeCamera
class is defined in the Chapter2/src/FreeCamera.[h/cpp]
files. The class interface is as follows:
class CFreeCamera : public CAbstractCamera { public: CFreeCamera(void); ~CFreeCamera(void); void Update(); void Walk(const float dt); void Strafe(const float dt); void Lift(const float dt); void SetTranslation(const glm::vec3& t); glm::vec3 GetTranslation() const; void SetSpeed(const float speed); const float GetSpeed() const; protected: float speed; //move speed of camera in m/s glm::vec3 translation; };
The steps needed to implement the free camera are as follows:
CFreeCamera
class and add a vector to store the current translation.Update
method, calculate the new orientation (rotation) matrix, using the current camera orientations (that is, yaw, pitch, and roll amount):glm::mat4 R = glm::yawPitchRoll(yaw,pitch,roll);
position+=translation;
If we need to implement a free camera which gradually comes to a halt, we should gradually decay the translation vector by adding the following code after the key events are handled:
glm::vec3 t = cam.GetTranslation(); if(glm::dot(t,t)>EPSILON2) { cam.SetTranslation(t*0.95f); }
If no decay is needed, then we should clear the translation vector to 0
in the CFreeCamera::Update
function after translating the position:
translation = glm::vec3(0);
look
vector by the current rotation matrix, and determine the right
and up
vectors to calculate the orthonormal basis:look = glm::vec3(R*glm::vec4(0,0,1,0)); up = glm::vec3(R*glm::vec4(0,1,0,0)); right = glm::cross(look, up);
glm::vec3 tgt = position+look;
glm::lookat
function to calculate the new view matrix using the camera position, target, and the up
vector:V = glm::lookAt(position, tgt, up);
The Walk
function simply translates the camera in the look direction:
void CFreeCamera::Walk(const float dt) { translation += (look*dt); }
The Strafe
function translates the camera in the right direction:
void CFreeCamera::Strafe(const float dt) { translation += (right*dt); }
The Lift
function translates the camera in the up direction:
void CFreeCamera::Lift(const float dt) { translation += (up*dt); }
Running the demo application renders an infinite checkered plane as shown in the following figure. The free camera can be moved around by pressing the keys W, S, A, D, Q, and Z. Left-clicking the mouse rotates the camera at the current position to change the look direction. Middle-click zooms the camera in the look direction.
18.116.51.117