Since I could not find any working example of how to configure the first-person camera using DirectXMath, and because I spent two days on my solution, I decided to post my solution here. Perhaps there is someone who is working on the same issue. My solution is not optimized, but the math behind it must 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; }
Julian
source share