OpenGL 奇怪的鼠标旋转结果
OpenGL weird rotation result with mouse
所以我正在开发 3d 绘画应用程序。我设法制作了一个基本的渲染器和模型加载器。
我创建了一个相机系统,我可以用它在场景中导航(mouse/keyboard),但这不是我想要的,所以我把相机设为静态,现在我 尝试 rotate/pan/zoom 模型本身 。我 设法实现了平移和缩放 。对于平移,我根据鼠标更改 x/y 位置,对于缩放,我根据鼠标滚动在 z 轴上添加或减去。
但现在我希望能够用鼠标旋转 3d 模型。示例:当我按住鼠标右键并将鼠标向上移动时,模型应该在其 x 轴(间距) 上旋转,如果我将鼠标移动到 left/right 它应该在 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-axis 。一旦我分开两个旋转。 对象现在将首先在 x-axis 上旋转,然后 y-axis 问题已解决。
代码应该是这样的:
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, 0.0f));
// Handle y-axis rotation
modelm = glm::rotate(modelm, glm::radians(object_orientation_angle_y), glm::vec3(0.0f, object_rotation_y, 0.0f));
shader.setMat4f("model", modelm);
renderer.draw(model, shader);
所以我正在开发 3d 绘画应用程序。我设法制作了一个基本的渲染器和模型加载器。
我创建了一个相机系统,我可以用它在场景中导航(mouse/keyboard),但这不是我想要的,所以我把相机设为静态,现在我 尝试 rotate/pan/zoom 模型本身 。我 设法实现了平移和缩放 。对于平移,我根据鼠标更改 x/y 位置,对于缩放,我根据鼠标滚动在 z 轴上添加或减去。
但现在我希望能够用鼠标旋转 3d 模型。示例:当我按住鼠标右键并将鼠标向上移动时,模型应该在其 x 轴(间距) 上旋转,如果我将鼠标移动到 left/right 它应该在 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-axis 。一旦我分开两个旋转。 对象现在将首先在 x-axis 上旋转,然后 y-axis 问题已解决。
代码应该是这样的:
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, 0.0f));
// Handle y-axis rotation
modelm = glm::rotate(modelm, glm::radians(object_orientation_angle_y), glm::vec3(0.0f, object_rotation_y, 0.0f));
shader.setMat4f("model", modelm);
renderer.draw(model, shader);