参考 https://zhuanlan.zhihu.com/p/646496824 使用 glm 库实现一个传统的 Orbit Camera Controller

// https://zhuanlan.zhihu.com/p/646496824

void Camera::rotate(float x_offset, float y_offset) {
    glm::vec3 from_target = eye - target;
    float radius = glm::length(from_target);
    // azimuth angle(方位角), angle between from_target and z-axis,[-pi, pi]
    // atan2 return the angle between positive x-axis (in 2d form)
    float phi = atan2(from_target[0], from_target[2]);
    // polar angle(天顶角), angle between from_target and y-axis, [0, pi]
    float theta = acos(from_target[1] / radius);

    float factor = 1.5 * M_PI;

    phi	  += x_offset * factor;
    theta += y_offset * factor;
    if (theta > M_PI) theta = M_PI - EPSILON * 100;
    if (theta < 0)  theta = EPSILON * 100;

    this->eye[0] = this->target[0] + radius * sin(phi) * sin(theta);
    this->eye[1] = this->target[1] + radius * cos(theta);
    this->eye[2] = this->target[2] + radius * sin(theta) * cos(phi);

    glm::vec3 refUp(0.0f, 1.0f, 0.0f);
    glm::vec3 front = glm::normalize(this->target - this->eye);
    glm::vec3 right = glm::normalize(glm::cross(front, refUp));
    this->upVec = glm::normalize(glm::cross(right, front));
}