3D相机意外滚动 [英] 3d camera has unintended roll
问题描述
我一直在使用C ++在opengl中制作3d相机。
I've been working on a 3d camera in opengl using C++.
当我环顾相机时,有时相机会意外滚动,
When I look around with the camera, sometimes there will be unexpected roll in the camera, especially when I am rotating the camera in circles.
我怀疑这是一个浮点错误,但我不知道如何检测。
I suspect this is a floating point error, but I don't know how to detect it.
这是相机类别:
#ifndef CAMERA_H
#define CAMERA_H
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/rotate_vector.hpp>
#include <glm/gtx/euler_angles.hpp>
#include <glm/gtx/string_cast.hpp>
#include <iostream>
using glm::vec3;
using glm::mat4;
using glm::quat;
enum CamDirection {
CAM_FORWARD,
CAM_BACKWARD,
CAM_LEFT,
CAM_RIGHT
};
class Camera {
public:
void cameraUpdate();
mat4 getViewMatrix();
Camera();
Camera(vec3 startPosition);
void move(CamDirection dir, GLfloat deltaTime);
void look(double xOffset, double yOffset);
void update();
private:
mat4 viewMatrix;
const GLfloat camSpeed = 5.05f;
};
mat4 Camera::getViewMatrix() {
return viewMatrix;
}
Camera::Camera(){}
Camera::Camera(vec3 startPos):
viewMatrix(glm::lookAt(startPos, vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f)))
{}
void Camera::move(CamDirection dir, GLfloat deltaTime) {
mat4 trans;
const vec3 camForward = vec3(viewMatrix[0][2], viewMatrix[1][2], viewMatrix[2][2]);
const vec3 camRight = vec3(viewMatrix[0][0], viewMatrix[1][0], viewMatrix[2][0]);
if (dir == CAM_FORWARD)
trans = glm::translate(trans, (camSpeed * deltaTime) * camForward);
else if (dir == CAM_BACKWARD)
trans = glm::translate(trans, -1 * (camSpeed * deltaTime) * camForward);
else if (dir == CAM_RIGHT)
trans = glm::translate(trans, -1 * (camSpeed * deltaTime) * camRight);
else
trans = glm::translate(trans, (camSpeed * deltaTime) * camRight);
viewMatrix *= trans;
}
void Camera::look(double xOffset, double yOffset) {
// 2 * acos(q[3])
quat rotation = glm::angleAxis((GLfloat)xOffset, vec3( 0.0f, 1.0f, 0.0f));
viewMatrix = glm::mat4_cast(rotation) * viewMatrix;
rotation = glm::angleAxis((GLfloat)yOffset, vec3(-1.0f, 0.0f, 0.0f));
mat4 rotMatrix = glm::mat4_cast(rotation);
viewMatrix = rotMatrix * viewMatrix;
}
void Camera::update() {
}
#endif // CAMERA_H
推荐答案
我设法弄清楚了。尽管我必须完全重写才能做到。
I managed to figure it out. Although I had to completely rewrite it to do it.
我的问题在以下几行:
quat rotation = glm::angleAxis((GLfloat)xOffset, vec3( 0.0f, 1.0f, 0.0f));
viewMatrix = glm::mat4_cast(rotation) * viewMatrix;
rotation = glm::angleAxis((GLfloat)yOffset, vec3(-1.0f, 0.0f, 0.0f));
mat4 rotMatrix = glm::mat4_cast(rotation);
建立一个中间四元数来存储方向是可行的,我可以替换
Building an intermediate quaternion to store orientation worked instead, and I could replace the look
method with this:
quat pitch = quat(vec3(-yOffset, 0.0f, 0.0f));
quat yaw = quat(vec3(0.f, xOffset, 0.f));
orientation = pitch * orientation * yaw;
通过将方向乘以最后一行的方式,不会发生意外滚动。
By multiplying the orientation the way on the last line, no unintended roll can happen.
这篇关于3D相机意外滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!