Hello all. I apologize in advance if this is the wrong section. This is my first post on any forum and i know this question has been asked before but i cant seem to figure out what im doing wrong. Ive referenced multiple tutorials on youtube and different websites.. my problem is this: im trying to create a camera that moves around a 3d space. i apply a rotation matrix to it so i can look around and i add/subtract a forward vector when i want to move the camera pos.. so the rotation works fine but when i move the camera pos it seems to be translating it around the origin. In other words if i walk out 10 ft from the origin and turn, instead of rotation in place, im rotating around the origin. With this said i understand that the order in which rotations/translations matter but ive tried rotation first AND after and i get the same result so im slowly losing my sanity… someone please save me!! ive been trying to problem solve this for days :( maybe i havent been searching in the right areas but support for beginners in this “field” is proving hard to find personally.
EDIT: it seems when i leave forward as look at - camera, the camera will move only down the z axis but will allow me to turn properly. perhaps the fault lies in my forward vector?
class GameCamera
{
public:
XMMATRIX World;
XMMATRIX View;
XMMATRIX Proj;
XMMATRIX YawPitchRoll;
XMMATRIX Translation;
ID3D11Buffer* constant_buffer_ptr;
bool Initialize(ID3D11Device* device_ptr);
void Update(ID3D11DeviceContext* device_context_ptr);
void GetInput();
void GetDirections();
private:
XMVECTOR default_look_at = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
XMVECTOR default_up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMVECTOR default_camera_pos = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
XMVECTOR look_at;
XMVECTOR up;
XMVECTOR camera_pos;
D3D11_BUFFER_DESC constant_buffer_desc;
D3D11_MAPPED_SUBRESOURCE mappedResource;
Constant_Buffer MVP;
float yaw;
float pitch;
float roll;
float latitude;
float longitude;
XMVECTOR forward;
XMVECTOR back;
XMVECTOR left;
XMVECTOR right;
XMFLOAT4 temp;
};
bool GameCamera::Initialize(ID3D11Device* device_ptr)
{
constant_buffer_ptr = NULL;
yaw = 0;
pitch = 0;
roll = 0;
latitude = 0;
longitude = 0;
look_at = default_look_at;
camera_pos = default_camera_pos;
up = default_up;
World = XMMatrixIdentity();
View = XMMatrixLookAtLH(default_camera_pos, default_look_at, default_up);
Proj = XMMatrixPerspectiveFovLH(XM_PIDIV2, 1.0f, 0.1f, 1000.0f);
ZeroMemory(&constant_buffer_desc, sizeof(D3D11_BUFFER_DESC));
constant_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
constant_buffer_desc.MiscFlags = 0;
constant_buffer_desc.StructureByteStride = 0;
constant_buffer_desc.ByteWidth = sizeof(Constant_Buffer);
constant_buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constant_buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
HRESULT hr = device_ptr->CreateBuffer(&constant_buffer_desc, 0, &constant_buffer_ptr);
assert(SUCCEEDED(hr));
return true;
}
void GameCamera::Update(ID3D11DeviceContext* device_context_ptr)
{
GetDirections();
XMStoreFloat4(&temp, forward);
YawPitchRoll = XMMatrixRotationRollPitchYaw(pitch, yaw, 0.0f);
Translation = XMMatrixTranslation(temp.x * longitude, -1.0f, temp.z * longitude);
View = XMMatrixLookAtLH(camera_pos, look_at, up);
View *= XMMatrixMultiply(Translation, YawPitchRoll);
MVP.MVP = XMMatrixMultiply(World, XMMatrixMultiply(View, Proj));
HRESULT hr = device_context_ptr->Map(constant_buffer_ptr, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
assert(SUCCEEDED(hr));
CopyMemory(mappedResource.pData, &MVP, sizeof(Constant_Buffer));
device_context_ptr->Unmap(constant_buffer_ptr, 0);
device_context_ptr->VSSetConstantBuffers(0, 1, &constant_buffer_ptr);
}
void GameCamera::GetInput()
{
if (GetAsyncKeyState(VK_LEFT) < 0)
{
yaw -= 0.03;
}
if (GetAsyncKeyState(VK_RIGHT) < 0)
{
yaw += 0.03;
}
if (GetAsyncKeyState(VK_UP) < 0)
{
pitch -= 0.03;
}
if (GetAsyncKeyState(VK_DOWN) < 0)
{
pitch += 0.03;
}
if (GetAsyncKeyState('W') < 0)
{
longitude += 0.01;
}
if (GetAsyncKeyState('S') < 0)
{
longitude -= 0.01;
}
}
void GameCamera::GetDirections()
{
forward = look_at - camera_pos;
forward += look_at;
//forward = XMVector3TransformCoord(look_at, YawPitchRoll);
//forward += camera_pos;
}
P.S. Initialize() is called once, GetInput() is called every loop and so is Update()