繁体   English   中英

3D第一人称视角相机横冲直撞

[英]3D First Person Camera strafing at angle

我在DirectX 11中有一个简单的相机类,它允许向前移动和向左和向右旋转。 我正在尝试实施,但是遇到了一些问题。

在没有相机旋转的情况下,扫射有效,因此,当相机从0、0、0开始时。但是,沿任一方向旋转相机后,它似乎会以一定角度扫射或倒转或出现一些奇怪的东西。

这是上传到Dropbox的视频,显示了此行为。 https://dl.dropboxusercontent.com/u/287​​3587/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);
}

经过数小时的烦恼,实施摄像头系统后,Id提出建议,这与您的视图矩阵未进行正交归一化有关。 那是种花哨的说法-矩阵中表示的三个向量的长度不保持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)
}

你有主意吗? 那只是一个粗糙的例子,只是为了让您思考。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM