OpenGL:当我移动相机时,它会向侧面倾斜
OpenGL: Camera tilts sideways when I move it
我正在尝试在OpenGL中自己实现一个相机(我使用glfw和gml(。 至于现在,我没有任何课程。我稍后会创建它。因此,这是我对相机运动进行编码的尝试;它适用于简单的鼠标移动,但除此之外,相机会侧向倾斜。我仍然是OpenGL的新手,所以我没有太多要展示的内容,但这里有说明我的问题:https://i.stack.imgur.com/7YK5t.jpg
我有几个(目前是全局的(变量:
float lastX = 0.0f, lastY = 0.0f, yaw = 0.0f, pitch = 0.0f;
glm::vec3 cameraPos(0.0f, 0.0f, 3.0f);
glm::vec3 cameraUp(0.0f, 1.0f, 0.0f); // As a reminder, x points to the right, y points upwards and z points towards you
glm::vec3 cameraFront(0.0f, 0.0f, -1.0f);
有了这些,我可以通过这种方式创建一个视图矩阵:
glm::mat4 view;
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
我希望能够在屏幕上垂直(偏航(和横向(俯仰(移动相机,即向上、向下、向右、向左移动。为此,适当地旋转 cameraFront 矢量和 cameraUp 矢量,然后使用更新的矢量更新视图矩阵就足够了。
我的光标位置回调如下所示:
glm::vec3 rotateAroundAxis(glm::vec3 toRotate, float angle, glm::vec3 axisDirection, glm::vec3 axisPoint) { // angle in radians
toRotate -= axisPoint;
glm::mat4 rotationMatrix(1.0f);
rotationMatrix = glm::rotate(rotationMatrix, angle, axisDirection);
glm::vec4 result = rotationMatrix*glm::vec4(toRotate, 1.0f);
toRotate = glm::vec3(result.x, result.y, result.z);
toRotate += axisPoint;
return toRotate;
}
void mouseCallback(GLFWwindow* window, double xpos, double ypos) {
const float maxPitch = float(M_PI) - float(M_PI) / 180.0f;
glm::vec3 cameraRight = -glm::cross(cameraUp, cameraFront);
float xOffset = xpos - lastX;
float yOffset = ypos - lastY;
lastX = xpos;
lastY = ypos;
float sensitivity = 0.0005f;
xOffset *= sensitivity;
yOffset *= sensitivity;
yaw += xOffset; // useless here
pitch += yOffset;
if (pitch > maxPitch) {
yOffset = 0.0f;
}
if (pitch < -maxPitch) {
yOffset = 0.0f;
}
cameraFront = rotateAroundAxis(cameraFront, -xOffset, cameraUp, cameraPos);
cameraFront = rotateAroundAxis(cameraFront, -yOffset, cameraRight, cameraPos);
cameraUp = rotateAroundAxis(cameraUp, -yOffset, cameraRight, cameraPos);
}
正如我所说,它适用于简单的上下左右相机移动,但是当我开始绕圈或像疯子一样移动鼠标时,相机开始纵向旋转(滚动(。
我试图强制 cameraRight.y = cameraPos.y,以便 cameraRight 矢量不会由于数值错误而向上/向下倾斜,但它不能解决问题。我还尝试添加一个(全局(cameraRight矢量来跟踪它,而不是每次都计算它,因此函数的结尾如下所示:
cameraFront = rotateAroundAxis(cameraFront, -xOffset, cameraUp, cameraPos);
cameraRight = rotateAroundAxis(cameraRight, -xOffset, cameraUp, cameraPos);
cameraFront = rotateAroundAxis(cameraFront, -yOffset, cameraRight, cameraPos);
cameraUp = rotateAroundAxis(cameraUp, -yOffset, cameraRight, cameraPos);
但这并不能解决问题。有什么建议吗?
似乎您的右侧有全局 X 轴,Y 轴深入屏幕,Z 轴向上。和你本地摄像头轴系统类似。 所需的行为是将相机旋转到
其当前位置,鼠标左右移动是围绕全局Z 旋转,向上 dowm 鼠标移动是围绕局部 X 旋转。围绕这些旋转进行一些思考,直到您很好地理解它们,以及为什么一个围绕全局而另一个围绕局部方向。想象一下,一个安全摄像头及其运动来可视化轴系统和旋转。
目标是获取用于定义视图转换的参数lookAt
函数。
首先围绕局部X旋转。我们通过反转当前的视图矩阵将这个局部向量转换为全局轴系统,你称之为view
glm::vec3 currGlobalX = glm::normalize((glm::inverse(view) * glm::vec4(1.0, 0.0, 0.0, 0.0)).xyz);
我们不仅需要旋转cameraUp
向量,还需要旋转全局坐标中定义的current target
,即所谓的cameraPos + cameraFront
:
cameraUp = rotateAroundAxis(cameraUp, -yOffset, currGlobalX, glm::vec3(0.0f, 0.0f, 0.0f)); //vector, not needed to translate
cameraUp = glm::normalize(cameraUp);
currenTarget = rotateAroundAxis(currenTarget, -yOffset, currGlobalX, cameraPos); //point, need translation
现在绕全局 Z 轴旋转
cameraUp = rotateAroundAxis(cameraUp, -xOffset, glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, 0.0f)); //vector, not needed to translate
cameraUp = glm::normalize(cameraUp);
currenTarget = rotateAroundAxis(currenTarget, -xOffset, glm::vec3(0.0f, 0.0f, 1.0f), cameraPos); //point, need translation
最后,更新view
:
view = glm::lookAt(cameraPos, currenTarget, cameraUp);
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- Android NDK传感器向事件队列报告奇怪的间隔
- C / C++ 移位/偏移/向左或向右移动位图?
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 只能向C++添加一定数量的字符
- 使用Pybind11向Python公开Eigen::张量
- 码头化的C++应用程序是否向后兼容早期的内核版本
- 在无向图中打印循环
- 在C++中向零方向近似的最佳方法
- llvm构建器向基本块添加终止符
- Visual Studio 2017循环自动向量化问题
- 如何使用ESP8266向谷歌主页发送命令
- 类的前向声明之后的类成员函数定义,在类声明之前
- OpenVR:向视图方向移动
- 三向比较运算符成员与非成员实现
- 如何使用 Google Test 向测试添加元数据 / 如何将数据从 Google Test 发送到 TestEven
- 新的整数数组向右移动?
- 使用 Winsock2.h C++向不和谐 API 发送 HTTP 请求时出现问题
- OpenGL:当我移动相机时,它会向侧面倾斜