我正在使用glfw来获取鼠标位置,然后我计算偏移量(或我在代码中标记它的增量),然后我使用它来围绕x轴和y轴旋转相机。这一切都很好,但是,当我用鼠标做圆圈时,由于某种原因,相机会沿着z轴旋转。
这是我的代码,我计算鼠标的x和y-delta位置:
void input(Window* window, float deltaTime)
{
rotationMatY = Matrix44::CreateIdentity();
rotationMatX = Matrix44::CreateIdentity();
translationMat = Matrix44::CreateIdentity();
float oldXPos = (float)mouseX, oldYPos = (float)mouseY;
glfwGetCursorPos(window->getGLFWWindow(), &mouseX, &mouseY);
float xDelta, yDelta;
xDelta = (float)mouseX - oldXPos;
yDelta = (float)mouseY - oldYPos;
const float R_SPEED = 10.f;
// Rotate the camera around with the mouse according to how much it's moved
// since the last frame
if (getMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT))
{
rotationMatY =
Matrix44::CreateRotateY(DegToRad(R_SPEED * xDelta * deltaTime));
rotationMatX =
Matrix44::CreateRotateX(DegToRad(R_SPEED * yDelta * deltaTime));
}
}
然后我拿出相机的视图矩阵并将其乘以得到的旋转矩阵:
void Crate_full_framework::onRender()
{
view *= rotationMatY;
view *= rotationMatX;
... // Other rendering code here
}
以下是我如何计算x轴和y轴的旋转:
Matrix44 Matrix44::CreateRotateX(float angle)
{
return Matrix44(1.f, 0.f, 0.f, 0.f,
0.f, cosf(angle), sinf(angle), 0.f,
0.f, -sinf(angle), cosf(angle), 0.f,
0.f, 0.f, 0.f, 1.f);
}
Matrix44 Matrix44::CreateRotateY(float angle)
{
return Matrix44(cosf(angle), 0.f, -sinf(angle), 0.f,
0.f, 1.f, 0.f, 0.f,
sinf(angle), 0.f, cosf(angle), 0.f,
0.f, 0.f, 0.f, 1.f);
}
我只是想弄清楚我的数学出错了。我非常确定我必须重置相机的y轴方向,以便它始终处于正y方向,只是不确定如何到达那里。
编辑:我在此处向YouTube上传了一个视频:https://youtu.be/2QXKvOGHXgM,其中只显示了在旋转相机时旋转鼠标时会发生什么。
答案 0 :(得分:1)
观看视频,我看到了这个问题。您正在寻找的是虚拟轨迹球。 Stackoverflow提供:
https://computergraphics.stackexchange.com/questions/151/how-to-implement-a-trackball-in-opengl
您目前使用的是欧拉角,其中包括您刚刚遇到的问题。
来自:http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/
您可以使用四元数来简单地实现它,其解释在上面的源
中提供答案 1 :(得分:0)
我在这里猜测,但可能你应该把整个代码放在getMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT)
条件下。
void input(Window* window, float deltaTime)
{
// Rotate the camera around with the mouse according to how much it's moved
// since the last frame
if (getMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT))
{
rotationMatY = Matrix44::CreateIdentity();
rotationMatX = Matrix44::CreateIdentity();
translationMat = Matrix44::CreateIdentity();
float oldXPos = (float)mouseX, oldYPos = (float)mouseY;
glfwGetCursorPos(window->getGLFWWindow(), &mouseX, &mouseY);
float xDelta, yDelta;
xDelta = (float)mouseX - oldXPos;
yDelta = (float)mouseY - oldYPos;
const float R_SPEED = 10.f;
rotationMatY =
Matrix44::CreateRotateY(DegToRad(R_SPEED * xDelta * deltaTime));
rotationMatX =
Matrix44::CreateRotateX(DegToRad(R_SPEED * yDelta * deltaTime));
}
}
答案 2 :(得分:0)
只需使用我的解决方案更新此主题,以便将来帮助人们。
问题是我每帧都没有创建一个全新的变换矩阵。我试图添加到旧视图矩阵,这就是相机旋转的原因。这将需要旧的向上向量并添加新的向量,这将创建旋转。所以代码就是这样:
view = rotationMatTotal * translationMat;
而不是:
view *= rotationMatTotal * translationMat;
感谢所有回复,他们提供了丰富的信息,我学到了很多东西!