问题描述
所以我正在研究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);