限制在 opengl 中围绕 x 轴的旋转

Limiting rotation around the x-axis in opengl

本文关键字:旋转 opengl      更新时间:2023-10-16

为了好玩,我用opengl制作了一个3D相机。它运行良好,除了我无法弄清楚如何限制围绕 x 轴的旋转。如果向上滚动太多,向上和向下控件将反转。我尝试将camFront.y变量限制为任意值,但相机仍然会在 x 轴上翻转。

这是我的代码:

#ifndef CAMERA_H
#define CAMERA_H
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/quaternion.hpp>
#define WORLD_UP glm::vec3(0.0f, 1.0f, 0.0f)
#include <iostream>

enum CamDirection {
    CAM_FORWARD,
    CAM_BACKWARD,
    CAM_LEFT,
    CAM_RIGHT
};

class Camera {
public:
    void cameraUpdate();
    glm::mat4 getViewMatrix();
    Camera();
    Camera(glm::vec3 startPosition);
    void move(CamDirection dir, GLfloat deltaTime);
    void look(double xOffset, double yOffset);
    void update();
private:
    glm::vec3 camPos;
    glm::vec3 camFront;
    glm::vec3 camUp;
    glm::vec3 camRight;
    const GLfloat camSpeed = 5.05f;
};
glm::mat4 Camera::getViewMatrix() {
    return glm::lookAt(camPos, camPos + camFront, camUp);
}
Camera::Camera():
    camPos  (glm::vec3(0.0f, 0.0f,  0.0f)),
    camFront(glm::vec3(0.0f, 0.0f, -1.0f)),
    camUp   (WORLD_UP)
{}
Camera::Camera(glm::vec3 startPos):
    camPos   (startPos),
    camFront (glm::vec3(0.0f, 0.0f, -1.0f)),
    camUp    (WORLD_UP)
{}
void Camera::move(CamDirection dir, GLfloat deltaTime) {
    const GLfloat v = camSpeed * deltaTime;
    if (dir == CAM_FORWARD)
        camPos += v * camFront;
    else if (dir == CAM_BACKWARD)
        camPos -= v * camFront;
    else if (dir == CAM_RIGHT)
        camPos += v * camRight;
    else
        camPos -= v * camRight;
}
void Camera::look(double xOffset, double yOffset) {
    glm::quat startQuat = {0, camFront.x, camFront.y, camFront.z};
    glm::quat rotation = glm::angleAxis((GLfloat)xOffset, glm::vec3(0.0f, 1.0f, 0.0f));
    glm::quat view = startQuat * rotation;
    rotation = glm::angleAxis((GLfloat)yOffset, glm::vec3(-1.0f, 0.0f, 0.0f));
    view = view * rotation;
    camFront = glm::vec3(view.x, view.y, view.z);
    std::cerr << camFront.x << ' ' << camFront.y << ' ' << camFront.z << std::endl;
}
void Camera::update() {
        // Also re-calculate the Right and Up vector
        camRight = glm::normalize(glm::cross(camFront, WORLD_UP));  // Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
        camUp    = glm::normalize(glm::cross(camRight, camFront));
}
#endif // CAMERA_H

我该如何解决这个问题?

在将它们分配给 camFront 之前,您需要限制 view.yview.z 值,最大为 89 度,最小为 -89 度。在 90 度和 -90 度时,它开始反转。所以一个非常简单的方法可能是,

if(view.y > 89)
{
  view.y = 89;
}
if(view.y < -89)
{
  view.y = -89;
}
if(view.z > 89)
{
  view.z = 89;
}
if(view.z < -89)
{
  view.z = -89;
}