
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.

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:
- Define the
CTargetCamera
class with a target position (target
), the rotation limits (minRy
andmaxRy
), the distance between the target and the camera position (distance
), and the distance limits (minDistance
andmaxDistance
). - 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);
- 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));
- Get the new camera position by adding the translation vector to the target position:
position = target + T;
- 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:

See also
- DHPOWare OpenGL camera demo – Part 1 (http://www.dhpoware.com/demos/glCamera1.html)
- DHPOWare OpenGL camera demo – Part 2 (http://www.dhpoware.com/demos/glCamera2.html)
- DHPOWare OpenGL camera demo – Part 3 (http://www.dhpoware.com/demos/glCamera3.html)