【问题标题】:3D First Person Camera strafing at angle3D 第一人称相机角度扫射
【发布时间】:2013-10-21 00:39:11
【问题描述】:

我有一个在 directx 11 中工作的简单相机类,允许向前和左右旋转。我正在尝试对其进行扫射,但遇到了一些问题。

当没有相机旋转时,扫射会起作用,因此当相机从 0、0、0 开始时。但在任一方向旋转相机后,它似乎会以一定角度扫射或倒置或只是一些奇怪的东西。

这是一个上传到 Dropbox 的视频,展示了这种行为。 https://dl.dropboxusercontent.com/u/2873587/IncorrectStrafing.mp4

这是我的相机课。我有一种预感,它与相机位置的计算有关。我在 strafe 中尝试了各种不同的计算,它们似乎都遵循相同的模式和相同的行为。 m_camera_rotation 也代表 Y 旋转,因为尚未实现俯仰。

#include "camera.h"


camera::camera(float x, float y, float z, float initial_rotation) {
m_x = x;
m_y = y;
m_z = z;
m_camera_rotation = initial_rotation;

updateDXZ();
}


camera::~camera(void)
{
}

void camera::updateDXZ() {
m_dx = sin(m_camera_rotation * (XM_PI/180.0));
m_dz = cos(m_camera_rotation * (XM_PI/180.0));
}

void camera::Rotate(float amount) {
m_camera_rotation += amount;

updateDXZ();
}

void camera::Forward(float step) {
m_x += step * m_dx;
m_z += step * m_dz;
}

void camera::strafe(float amount) {
float yaw = (XM_PI/180.0) * m_camera_rotation;

m_x += cosf( yaw ) * amount;
m_z += sinf( yaw ) * amount;
}

XMMATRIX camera::getViewMatrix() {
updatePosition();

return XMMatrixLookAtLH(m_position, m_lookat, m_up);
}

void camera::updatePosition() {
m_position = XMVectorSet(m_x, m_y, m_z, 0.0);
m_lookat = XMVectorSet(m_x + m_dx, m_y, m_z + m_dz, 0.0);
m_up = XMVectorSet(0.0, 1.0, 0.0, 0.0);
}

【问题讨论】:

    标签: c++ matrix 3d camera directx


    【解决方案1】:

    由于我在实施相机系统方面经历了数小时的挫折,我认为这与您的视图矩阵未进行正交归一化有关。这是一种奇特的说法——矩阵中表示的三个向量的长度不保持为 1(归一化),也不正交(彼此成 90 度)。

    表示旋转的视图矩阵的 3x3 部分表示 3 个向量,这些向量描述了在任何给定时间视图的当前 x、y 和 z 轴。由于浮点值不精确导致的舍入误差,这三个向量可能会拉伸、收缩和发散,从而导致各种令人头疼的问题。

    因此,一般策略是在旋转时每隔几帧重新正交归一化以及另一件事 - 在扫射或向后/向前移动时,使用您的视图/查看向量的当前值来更改位置.

    例如

    //deltaTime for all of these examples is the amount of time elapsed since the last  
    //frame of your game loop - this ensures smooth movement, or you could fix your   
    //timestep -  Glen Fielder did a great article on that please google for it!
    
    void MoveForward(float deltaTime)
    {
      position += (deltaTime * lookAtVector); 
    }
    
    void MoveBackwards(float deltaTime)
    {
      position -= (deltaTime * lookAtVector);
    }
    
    void StrafeLeft(float deltaTime)
    {
      position -= (deltaTime * rightVector);
    }
    
    //do something similar for StrafeRight but use a +=
    

    不管怎样,旋转只是旋转视图和右向量,也许重写你的类如下

    class Camera
    {
      Vector3 rightVec,lookVec,position;
    
      void Rotate(float deltaTime)
    }
    

    你明白了吗?这是一个粗略的例子,只是为了让你思考。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多