旋转相机LookAt点

时间:2019-05-23 17:06:34

标签: c++ opengl glm-math

使用glm :: lookAt函数创建摄影机视图矩阵很好,但无助于存储摄影机欧拉角。尽管计算似乎正确,但视图似乎带来了错误的音调值。

在以下代码中,如果当前相机位置和目的地的Y值相同,则没有问题。但是,如果摄像机位置和目的地的Y值不相等,则视图似乎进一步向下或向上倾斜。 问题是:如果摄像机的Y值和对象位置不相等,为什么摄像机无法正确指向对象。

    float wrapAngle(float angle)
    {
      int break_after = 100;
      constexpr float full_rotation = 2.0 * glm::pi<float>();
      while (angle < 0.0f || angle >= full_rotation)
      {
        if (angle < 0.0f) angle = angle + full_rotation;
        if (angle >= full_rotation) angle = angle - full_rotation;
        if (--break_after == 0) break;
      }
      if (break_after == 0) angle = 0.0f;
      return angle;
    }

    void getLookAtAngle(const glm::vec3& position, const glm::vec3& destination, glm::vec3 &angle)
    {
      //! Find vector of sight toward destination.
      glm::vec3 sight = destination - position;

      //! Find X, Y rotation against the axis (global).
      double yAngle = wrapAngle(std::atan2(sight.x, sight.z));

      glm::mat4 yModel(1);
      yModel = glm::rotate(yModel, static_cast<float>(-yAngle), glm::vec3(0.0f, 1, 0));
      sight = yModel * glm::vec4(sight, 1.0f);

      double xAngle = wrapAngle(-std::atan2(sight.y, sight.z));

      //! assign xAngle, yAngle to the parameter 'angle'
      angle.x = glm::degrees(static_cast<float>(xAngle));
      angle.y = glm::degrees(static_cast<float>(yAngle));
      angle.z = 0.0f;
    }

    void updateCamera(const glm::vec3& position, const glm::vec3& destination)
    {
      glm::vec3 m_rotation(1);
      getLookAtAngle(position, destination, m_rotation)
      m_model = glm::mat4(1);
      m_model = glm::rotate(m_model, glm::radians(m_rotation[0]), glm::vec3(1.0f, 0, 0));
      m_model = glm::rotate(m_model, glm::radians(m_rotation[1]), glm::vec3(0.0f, 1, 0));
      m_model = glm::rotate(m_model, glm::radians(m_rotation[2]), glm::vec3(0.0f, 0, 1));
      m_front = glm::normalize(glm::vec3(m_model * glm::vec4(0, 0, 1.0f, 1.0f)));
      m_right = glm::normalize(glm::cross(m_front, glm::vec3(0, 1.0f, 0)));
      m_up = glm::normalize(glm::cross(m_right, m_front));
      m_view = glm::lookAt(position, position+ m_front, m_up);
    }

0 个答案:

没有答案