I have a 3D camera with its current rotation stored as a quaternion, and I\'m having trouble rotating it correctly. I want the camera to rotate incrementally around its local ax
Because I could not find any working example how to set up a first person camera using DirectXMath and because I spent two days working on my solution I decided to post my solution here. Perhaps there is anyone who is working on the same problem. My solution is not that optimized but the math behind it should be correct.
inline DX11FRAMEWORK_API DirectX::XMFLOAT4X4 MatrixCameraFirstPersonQuaternion(DirectX::XMFLOAT3 &Pos, DirectX::XMFLOAT3 &DeltaPos, DirectX::XMFLOAT3 &DeltaAngles,
DirectX::XMVECTOR &RotationQuaternion, DirectX::XMFLOAT3 *At = nullptr, DirectX::XMFLOAT3 *Up = nullptr)
{
using namespace DirectX;
static const XMFLOAT3 OriginalAt = { 1.f, 0.f, 0.f };
static const XMFLOAT3 OriginalUp = { 0.f, 1.f, 0.f };
static const XMFLOAT3 OriginalRight = { 0.f, 0.f, 1.f };
// performing rotation of x-axis (here roll) und z-axis (here pitch) round camera axis using quaternion
RotationQuaternion = XMQuaternionMultiply(RotationQuaternion, XMQuaternionRotationRollPitchYaw(DeltaAngles.z, 0.f, -DeltaAngles.x));
// performing rotation of y-axis (yaw) round world axis
XMMATRIX MRotation = XMMatrixMultiply(XMMatrixRotationQuaternion(RotationQuaternion), XMMatrixRotationRollPitchYaw(0.f, -DeltaAngles.y, 0.f));
// keep track of rotation round y-axis because it is rotated round world axis
DeltaAngles = { 0.f, DeltaAngles.y, 0.f };
// generating camera axis
XMFLOAT3 CameraAt, CameraRight, CameraUp;
XMStoreFloat3(&CameraAt, XMVector3TransformCoord(XMLoadFloat3(&OriginalAt), MRotation));
XMStoreFloat3(&CameraRight, XMVector3TransformCoord(XMLoadFloat3(&OriginalRight), MRotation));
XMStoreFloat3(&CameraUp, XMVector3TransformCoord(XMLoadFloat3(&OriginalUp), MRotation));
// performing translation
Pos += CameraAt * DeltaPos.x;
Pos += CameraUp * DeltaPos.y;
Pos += CameraRight * DeltaPos.z;
DeltaPos = { 0.f, 0.f, 0.f };
CameraAt += Pos;
if (At)
*At = CameraAt;
if (Up)
*Up = CameraUp;
// finally generate view matrix
DirectX::XMFLOAT4X4 Camera;
DirectX::XMStoreFloat4x4(&Camera, DirectX::XMMatrixLookAtLH(DirectX::XMLoadFloat3(&Pos), DirectX::XMLoadFloat3(&CameraAt), DirectX::XMLoadFloat3(&CameraUp)));
return Camera;
}