OpenGL,俯仰强制偏航为0

Posted

技术标签:

【中文标题】OpenGL,俯仰强制偏航为0【英文标题】:OpenGL, pitch forces yaw to be 0 【发布时间】:2018-08-02 19:19:51 【问题描述】:

所以我一直在学习opengl和3d游戏编程,我开始尝试制作一个相机类并实现鼠标移动和查看。

移动完美无缺,但用鼠标环顾四周却无法正常工作。

仰视只有在偏航角为0°时才有效,然后我可以直视。但是当 yaw 0 时,向上看不会是笔直向上而是更像这样 ) 或 ( .

我还注意到,当偏航不是 0 时,无论是向下还是向上看,都会强制偏航为 0。

我不明白为什么会发生这种情况,为什么俯仰只有在 yaw 为 0 时才能正常工作,而当它不是为什么强制 yaw 为 0 时才正常工作。

我正在按照教程进行操作,似乎没有什么问题

处理鼠标移动和更新

void Camera::processMouseMovement(GLfloat xOffset, GLfloat yOffset)

    GLboolean constrainPitch = true;

    xOffset *= this->mouseSensitivity;
    yOffset *= this->mouseSensitivity;

    this->yaw += xOffset;
    this->pitch += yOffset;

    if(constrainPitch)
    
        if(this->pitch > 90.0f)
        
            this->pitch = 90.0f;
        

        if(this->pitch < -90.0f)
        
            this->pitch = -90.0f;
        
    

    this->updateCameraVectors();

这是我的更新功能

void Camera::updateCameraVectors()

    Vector3 front;
    Matrix4 mat4;
    front.x = cos((DEG2RAD * this->yaw) * cos(DEG2RAD * this->pitch));
    front.y = sin(DEG2RAD * this->pitch);
    front.z = sin((DEG2RAD * this->yaw) * cos(DEG2RAD * this->pitch));

    this->front = mat4.normalize(front);
    this->right = mat4.normalize(mat4.cross(this->front, this->worldUp));
    this->up = mat4.normalize(mat4.cross(this->right, this->front));

    std::cout << "yaw: " << yaw << std::endl;
    std::cout << "pitch: " << pitch << std::endl;

在 main.cpp 中

Camera camera(Vector3(0.0f, 0.0f, 0.0f));
GLfloat lastX = width / 2.0f;
GLfloat lastY = height / 2.0f;

GLboolean key[1024];
GLboolean firstMouse = true;

GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;

使用 glfw 输入,在 main.cpp 中也是如此

    glfwSetKeyCallback(window, keyCallBack);
    glfwSetCursorPosCallback(window, mouseCallBack);

    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

在主循环中

    GLfloat currentFrame = glfwGetTime();
    deltaTime = currentFrame - lastFrame;
    lastFrame = currentFrame;

    glfwPollEvents();
    doMovement();


    proj = proj.perspective(camera.getZoom(), float(700 / 600), 1.0f, 1000.0f);
    glUniformMatrix4fv(uniProj, 1, GL_FALSE, proj.get());

    view = camera.getViewMatrix();

鼠标回调函数

void mouseCallBack(GLFWwindow *window, GLdouble xPos, GLdouble yPos)

    if(firstMouse)
    
        lastX = xPos;
        lastY = yPos;
        firstMouse = false;
    

    GLfloat xOffset = lastX - xPos;
    GLfloat yOffset = yPos - lastY;

    lastX = xPos;
    lastY = yPos;

    std::cout << "mouse position x: " << xPos << std::endl;
    std::cout << "mouse position y: " << yPos << std::endl;

    camera.processMouseMovement(xOffset, yOffset);

谢谢你:)

【问题讨论】:

您有一个具体的问题吗?这似乎非常广泛,到处都是。更喜欢问具体的“为什么这个位做这个而不是那个”的问题。 您使用的是哪个数学库? mat4.normalize(front) 看起来很奇怪。矩阵与归一化有什么关系? 哦,它是一个自定义的,我要把普通函数从矩阵类移到我的数学类。 我确实尝试使用 glm ,但出现同样的问题 mat4 是自定义矩阵,归一化只是在该类中尚未将其移至数学类 【参考方案1】:

假设 front 是您的平均每日前向向量,我会这样计算:

front.x = cos(DEG2RAD * this->yaw) * sin(DEG2RAD * this->pitch);
front.y = sin(DEG2RAD * this->yaw);
front.z = cos(DEG2RAD * this->yaw) * cos(DEG2RAD * this->pitch);

我对三角函数不够热衷,无法理解您的代码在做什么。

更新:我盯着你的代码看了一会儿......看起来你代码中的括号外集是一个错误。我的代码和我的代码之间唯一的其他区别是我在计算 forward.x 时使用了sin,它只会交换一个轴。

【讨论】:

有人刚刚指出(然后删除了他们的评论)我的 z 轴在零俯仰和偏航时是正的,这在 OpenGL 视图矩阵术语中是向后的,其中前向 z 轴是负的.确实如此。我从来没有注意到我的任何相机实例。 Tysm,我稍微改了一下,没有注意到括号的错误,现在它确实有效。但是没有必要将 cos 变为 sin。

以上是关于OpenGL,俯仰强制偏航为0的主要内容,如果未能解决你的问题,请参考以下文章

给出初始和目标位置以及初始滚动,俯仰和偏航角度的目标滚动,俯仰和偏航角度

VNDetectFaceRectanglesRequest 对于偏航/俯仰/滚动总是返回 0

使用四元数计算 iphone 的偏航、俯仰和滚动?

如何从前向矢量计算俯仰和偏航值

2 个传感器读数融合(偏航、俯仰)

CoreMotion 不会让我滚动、俯仰和偏航