Implementing the target camera

The target camera works the opposite way. Rather than the position, the target remains fixed, while the camera moves or rotates around the target. Some operations like panning, move both the target and the camera position together.

Getting ready

The following figure shows an illustration of a target camera. Note that the small box is the target position for the camera.

Getting ready

The code for this recipe resides in the Chapter2/TargetCamera directory. The CTargetCamera class is defined in the Chapter2/src/TargetCamera.[h/cpp] files. The class declaration is as follows:

class CTargetCamera : public CAbstractCamera
{
public:
  CTargetCamera(void);
  ~CTargetCamera(void);
  void Update();
  void Rotate(const float yaw, const float pitch, const float roll);
  void SetTarget(const glm::vec3 tgt);
  const glm::vec3 GetTarget() const;
  void Pan(const float dx, const float dy);
  void Zoom(const float amount );
  void Move(const float dx, const float dz);
protected:
  glm::vec3 target;
  float minRy, maxRy;
  float distance;
  float minDistance, maxDistance;
};

How to do it…

We implement the target camera as follows:

  1. Define the CTargetCamera class with a target position (target), the rotation limits (minRy and maxRy), the distance between the target and the camera position (distance), and the distance limits (minDistance and maxDistance).
  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);
  3. Use the distance to get a vector and then translate this vector by the current rotation matrix:
    glm::vec3 T = glm::vec3(0,0,distance);
    T = glm::vec3(R*glm::vec4(T,0.0f));
  4. Get the new camera position by adding the translation vector to the target position:
    position = target + T;
  5. Recalculate the orthonormal basis and then the view matrix:
    look = glm::normalize(target-position);
    up = glm::vec3(R*glm::vec4(UP,0.0f));
    right = glm::cross(look, up);
    V = glm::lookAt(position, target, up);

There's more…

The Move function moves both the position and target by the same amount in both look and right vector directions.

void CTargetCamera::Move(const float dx, const float dy) {
  glm::vec3 X = right*dx;
  glm::vec3 Y = look*dy;
  position += X + Y;
  target += X + Y;
  Update();
}

The Pan function moves in the xy plane only, hence the up vector is used instead of the look vector:

void CTargetCamera::Pan(const float dx, const float dy) {
  glm::vec3 X = right*dx;
  glm::vec3 Y = up*dy;
  position += X + Y;
  target += X + Y;
  Update();
}

The Zoom function moves the position in the look direction:

void CTargetCamera::Zoom(const float amount) { 
  position += look * amount;
  distance = glm::distance(position, target); 
  Distance = std::max(minDistance, std::min(distance, maxDistance));
  Update();
}

The demonstration for this recipe renders an infinite checkered plane, as in the previous recipe, and is shown in the following figure:

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
3.138.33.87