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
Figured out the problem. For a mouse-controled first-person camera like the one I'm going for, I want to rotate around the local x-axis to look up and down, but the global y-axis for looking side to side.
So this is correct for the x-axis:
m_rot = m_rot * q;
But I need to do this for the y-axis:
m_rot = d * m_rot;
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;
}