3D相机意外滚动 [英] 3d camera has unintended roll

查看:93
本文介绍了3D相机意外滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆