官术网_书友最值得收藏!

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:

  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:

See also

主站蜘蛛池模板: 历史| 凯里市| 南郑县| 稻城县| 磴口县| 汶上县| 三都| 亚东县| 上思县| 综艺| 海林市| 蕲春县| 锡林郭勒盟| 晋州市| 荆州市| 靖远县| 阳曲县| 东光县| 承德市| 嵩明县| 丁青县| 综艺| 仲巴县| 麻栗坡县| 依安县| 高淳县| 新乡市| 天祝| 临沧市| 漯河市| 贞丰县| 淮北市| 兴山县| 北流市| 宣恩县| 洪泽县| 景洪市| 塘沽区| 象州县| 彩票| 石柱|