Implementing the free camera

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.

Getting ready

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.

Getting ready

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

How to do it…

The steps needed to implement the free camera are as follows:

  1. Define the CFreeCamera class and add a vector to store the current translation.
  2. In the 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);

    Note

    Make sure that the yaw, pitch, and roll angles are in radians.

  3. Translate the camera position by the translation amount:
    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);
  4. Transform the 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);
  5. Determine the camera target point:
    glm::vec3 tgt = position+look;
  6. Use the glm::lookat function to calculate the new view matrix using the camera position, target, and the up vector:
    V = glm::lookAt(position, tgt, up); 

There's more…

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.

There's more…

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.51.117