簡體   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