鼠标的OpenGL怪异旋转结果

问题描述

所以我正在研究3D绘画应用程序。我设法制作了一个基本的渲染器和模型加载器。

我创建了一个摄像头系统,可以用它在场景(鼠标/键盘)中进行导航,但这不是我想要的,所以我将该摄像头设为静态,现在我尝试旋转/摇摄/缩放模型本身。我设法实现了平移和缩放。用于平移,我根据鼠标更改x / y位置;对于缩放,我根据鼠标滚动从z轴添加或减去。

但是现在我希望能够用鼠标旋转3d模型。示例:当我按住鼠标右键并向上移动鼠标时,模型应在其 x轴(螺距)上旋转,如果我向左/向右移动鼠标,则模型应在上旋转y轴(偏航)。我只是做不到。

下面的代码我在屏幕上获得光标的xpos / ypos,计算偏移量并“尝试旋转立方体”。唯一的问题是如果我将鼠标向上移动,则模型不能在X轴和y轴上稍微倾斜地旋转,反之亦然。

这是我的渲染循环中的代码

    shader.use();
    glm::mat4 projection = glm::perspective(glm::radians(45.0f),(float)SCR_WIDTH/(float)SCR_HEIGHT,0.01f,100.0f);
    shader.setMat4f("projection",projection);

    glm::mat4 view = camera.getViewMatrix();
    shader.setMat4f("view",view);

    glm::mat4 modelm = glm::mat4(1.0f);
    modelm = glm::translate(modelm,object_translation);
    // Should rotate cube according to mouse movement
    //modelm = glm::rotate(modelm,glm::radians(angle),glm::vec3(0.0f));
    shader.setMat4f("model",modelm);

    renderer.draw(model,shader);

这是我处理鼠标移动回调的电话:

void mouseCallback(GLFWwindow* window,double xpos,double ypos)
{
if (is_rotating)
{
    if (is_first_mouse)
    {
        lastX = xpos;
        lastY = ypos;
        is_first_mouse = false;
    }

    // xpos and ypos are the cursor coords i get those with the 
    mouse_callback
    double xoffset = xpos - lastX;
    double yoffset = lastY - ypos;

    lastX = xpos;
    lastY = ypos;

    object_rotation.y += xoffset; // If i use yoffset the rotation flips
    object_rotation.x += yoffset;

    rotation_angle += (xoffset + yoffset) * 0.25f;
}
}

鼠标平移效果也很好,旋转时也不能这样说。

解决方法

您将旋转量存储为object_rotation内部的欧拉角。

我建议您使用:

glm::mat4 rotation = glm::eulerAngleYX(object_rotation.y,object_rotation.x); // pitch then yaw

glm::mat4 rotation = glm::eulerAngleXY(object_rotation.x,object_rotation.y); // yaw then roll

在您的情况下,两者都应做的工作,我建议您将来在您的相机内(眼睛,上方,中央)而不是您的物体中存储思想信息,一切都会变得更加简单。

,

我修复了它。经过一番研究后,我被告知您只能一次旋转一圈,而我试图同时做两个x / y轴。一旦我分开两次旋转。现在,对象将首先在x轴上旋转,然后在y轴上旋转。问题已解决。

代码应如下所示:

shader.use();
    glm::mat4 projection = glm::perspective(glm::radians(45.0f),(float)SCR_WIDTH/(float)SCR_HEIGHT,0.01f,100.0f);
    shader.setMat4f("projection",projection);

    glm::mat4 view = camera.getViewMatrix();
    shader.setMat4f("view",view);

    glm::mat4 modelm = glm::mat4(1.0f);
    modelm = glm::scale(modelm,glm::vec3(1.0f));
    modelm = glm::translate(modelm,glm::vec3(0.0f,0.0f,-5.0f));
    // Handle x-axis rotation
    modelm = glm::rotate(modelm,glm::radians(object_orientation_angle_x),glm::vec3(object_rotation_x,0.0f));
    // Handle y-axis rotation
    modelm = glm::rotate(modelm,glm::radians(object_orientation_angle_y),object_rotation_y,0.0f));
    shader.setMat4f("model",modelm);

    renderer.draw(model,shader);