From what I can tell, it's a math problem. I'm pretty rubbish at math so I have no idea what's going on. I'll post a video and my entire camera class.
3DCamera.h
//Camera header
#include "Main.h"
class Camera
{
public:
D3DXMATRIX viewMatrix;
D3DXMATRIX projMatrix;
D3DXVECTOR3 pos;
D3DXVECTOR3 up;
D3DXVECTOR3 target;
D3DXVECTOR3 lookDir;
D3DXVECTOR3 right;
D3DXVECTOR3 acceleration;
D3DXVECTOR3 currentVel;
float maxWalkingVelocity;
void Initialize(D3DXVECTOR3 Position, D3DXVECTOR3 Up, D3DXVECTOR3 Target);
void Update(LPDIRECT3DDEVICE9& d3dDevice);
void Camera::pitch(float A);
void Camera::yaw(float A);
void Camera::roll(float A);
};
3DCamera.cpp
//Camera source file
#include "3DCamera.h"
extern bool ISINFOCUS;
float rotX = 0;
float rotY = 0;
float rotZ = 0;
float currentZRot = 0;
float rollIndex = 0.01f;
void Camera::Initialize(D3DXVECTOR3 Position, D3DXVECTOR3 Up, D3DXVECTOR3 Target)
{
maxWalkingVelocity = 0.3f;
D3DXMatrixPerspectiveFovLH(&projMatrix, D3DXToRadian(45), 800.0f / 600.0f, 1, 2000);
pos = Position;
up = Up;
target = Target;
lookDir = target - pos;
}
void Camera::Update(LPDIRECT3DDEVICE9& d3dDevice)
{
D3DXVec3Normalize(&lookDir, &lookDir);
D3DXVec3Cross(&right, &up, &lookDir);
D3DXVec3Normalize(&right, &right);
//Walk control
if(GetAsyncKeyState(0x57))
acceleration += lookDir * 0.02f;
if (GetAsyncKeyState(0x53))
acceleration += lookDir * -0.02f;
//Strafe control
if (GetAsyncKeyState(0x41))
{
acceleration += D3DXVECTOR3(right.x, 0, right.z) * -0.015f;
if (currentZRot < 0.07f)
rotZ += rollIndex;
}
else
if (GetAsyncKeyState(0x44))
{
acceleration += D3DXVECTOR3(right.x, 0, right.z) * 0.015f;
if (currentZRot > -0.07f)
rotZ -= rollIndex;
}
else
if (currentZRot < 0)
rotZ += rollIndex;
else if (currentZRot > 0)
rotZ -= rollIndex;
//look control
if (GetAsyncKeyState(VK_LEFT))
rotX -= 0.04f;
else
if (GetAsyncKeyState(VK_RIGHT))
rotX += 0.04f;
if (GetAsyncKeyState(VK_UP) && lookDir.y < 0.932f)
rotY -= 0.04f;
else
if (GetAsyncKeyState(VK_DOWN) && lookDir.y > -0.985f)
rotY += 0.04f;
static const float friction = 0.08f;
currentVel += acceleration;
currentVel += ((currentVel * friction * -1));
pos += currentVel;
acceleration = D3DXVECTOR3(0, 0, 0);
pitch(rotY);
yaw(rotX);
roll(rotZ);
D3DXMatrixLookAtLH(&viewMatrix, &pos, &(pos + lookDir), &up);
rotX = 0;
rotY = 0;
currentZRot += rotZ;
rotZ = 0.00f;
}
void Camera::pitch(float A)
{
D3DXMATRIX T;
D3DXMatrixRotationAxis(&T, &right, A);
D3DXVec3TransformCoord(&lookDir, &lookDir, &T);
}
void Camera::yaw(float A)
{
D3DXMATRIX T;
D3DXMatrixRotationY(&T, A);
D3DXVec3TransformCoord(&right, &right, &T);
D3DXVec3TransformCoord(&lookDir, &lookDir, &T);
}
void Camera::roll(float A)
{
D3DXMATRIX T;
D3DXMatrixRotationAxis(&T, &lookDir, A);
D3DXVec3TransformCoord(&right, &right, &T);
D3DXVec3TransformCoord(&up, &up, &T);
}
Then in my update loop I call
camera.Update(d3dDevice);
END EMBARRASSING CODEAs for the video