2013-10-21 77 views
0

我有一個簡單的相機類在directx 11中工作,允許向前和向左和向右旋轉。我試圖實施掃射,但有一些問題。3D第一人稱相機在角度拍攝

當沒有相機旋轉時,掃射工作,所以當相機在0,0,0開始時。但是在任一方向旋轉相機後,它似乎會以某個角度或倒置或僅僅是一些奇怪的東西拍攝。

這是一個上傳到Dropbox的視頻,顯示了這種行爲。 https://dl.dropboxusercontent.com/u/2873587/IncorrectStrafing.mp4

這是我的相機類。我有一個預感,它與相機位置的計算有關。我嘗試了各種不同的計算方法,他們似乎都遵循相同的模式和相同的行爲。此外,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); 
} 

回答

0

用我多小時的挫折實現攝像系統標識表明其是與不是鄰標準化視圖矩陣。這是一種奇特的說法 - 矩陣中表示的三個向量不保持長度爲1(歸一化),也不是正交(相互成90度)。

代表旋轉的視圖矩陣的3x3部分代表3個向量,它們描述了在任何給定時間您視圖的當前x,y和z軸。由於四捨五入浮點值不精確所導致的錯誤,這三個向量可以伸縮,縮小和分叉以引起各種頭痛。

因此,一般策略是在每旋轉幾圈後重新正交歸一化,還有另外一件事情 - 當使用視圖當前值或向前/向後更改位置時,掃射。

e.g

//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) 
} 

你的想法?這只是讓你思考的一個粗略的例子。