[EDIT] Link to the project : https://github.com/Zeldarck/TrainingDx12 [/Edit]
My hint was good, it's come from how I do the position update. There is the correct code (miss protection on rotation too high) :
XMFLOAT3 cameraRotation;
void UpdateCamera() {
// Get Datas
XMVECTOR cUp = XMLoadFloat4(&cameraUp);
XMVECTOR cPos = XMLoadFloat4(&cameraPosition);
XMVECTOR cTarg = XMLoadFloat4(&cameraTarget);
//Apply Y Rotate
XMMATRIX rotYMat = XMMatrixRotationAxis(cUp, cameraRotation.y);
cTarg = XMVector4Transform(cTarg, rotYMat);
//Apply Z Rotate
XMMATRIX rotZMat = XMMatrixRotationAxis(cTarg, cameraRotation.z);
cUp = XMVector4Transform(cUp, rotZMat);
//Calculate the vector wich follow X in camera relative space ( cUp is Y and cTarg is Z in this space)
XMVECTOR xvect = XMVector3Cross(cTarg, cUp);
//Apply X Rotate
XMMATRIX rotXMat = XMMatrixRotationAxis(xvect, cameraRotation.x);
cUp = XMVector4Transform(cUp, rotXMat);
cTarg = XMVector4Transform(cTarg, rotXMat);
//Move Up and bottom
if (GetAsyncKeyState('Z')) {
cPos += XMVector3Normalize(cUp)/10000.0f;
}
else if (GetAsyncKeyState('S')) {
cPos -= XMVector3Normalize(cUp) /10000.0f;
}
//Move Right and Left
if (GetAsyncKeyState('Q')) {
cPos += XMVector3Normalize(xvect) / 10000.0f;
}
else if (GetAsyncKeyState('D')) {
cPos -= XMVector3Normalize(xvect) / 10000.0f;
}
//Rotate on Y
if (GetAsyncKeyState('A')) {
cameraRotation.y -= 0.0001f;
}
else if (GetAsyncKeyState('E')) {
cameraRotation.y += 0.0001f;
}
// Rotate On Z
if (GetAsyncKeyState('R')) {
cameraRotation.z -= 0.0001f;
}
else if (GetAsyncKeyState('T')) {
cameraRotation.z += 0.0001f;
}
//Rotate on X
if (GetAsyncKeyState('F')) {
cameraRotation.x -= 0.0001f;
}
else if (GetAsyncKeyState('G')) {
cameraRotation.x += 0.0001f;
}
//Move forward/Backward
if (GetAsyncKeyState('P')) {
cPos += XMVector3Normalize(cTarg) / 10000.0f;
}
else if (GetAsyncKeyState('M')) {
cPos -= XMVector3Normalize(cTarg) / 10000.0f;
}
//Update position
XMStoreFloat4(&cameraPosition, cPos);
//Generate View Matrix of Camera
XMMATRIX ViewMatrix = XMMatrixLookToLH(cPos, cTarg, cUp);
XMStoreFloat4x4(&cameraViewMat, ViewMatrix);
}
EDIT:
Previous code as a problem, I keep it here because I think it can still help. The problem was, now it's my rotation on Y axis wich where not relative to the camera. So I have to keep a track of local axis. (Ithink the best it's to keep track of world and local axis, but I am not sure).
void UpdateCamera() {
// Get Datas
XMVECTOR cUp = XMLoadFloat4(&cameraUp);
XMVECTOR cPos = XMLoadFloat4(&cameraPosition);
XMVECTOR cTarg = XMLoadFloat4(&cameraTarget);
XMVECTOR xvect = XMVector3Cross(cTarg, cUp);
//Move Up and bottom
if (GetAsyncKeyState('Z')) {
cPos += XMVector3Normalize(cUp)/10000.0f;
}
else if (GetAsyncKeyState('S')) {
cPos -= XMVector3Normalize(cUp) /10000.0f;
}
//Move Right and Left
if (GetAsyncKeyState('Q')) {
cPos += XMVector3Normalize(xvect) / 10000.0f;
}
else if (GetAsyncKeyState('D')) {
cPos -= XMVector3Normalize(xvect) / 10000.0f;
}
if (GetAsyncKeyState('A')) {
XMMATRIX rotYMat = XMMatrixRotationAxis(cUp, -0.0001f);
cTarg = XMVector4Transform(cTarg, rotYMat);
}
else if (GetAsyncKeyState('E')) {
XMMATRIX rotYMat = XMMatrixRotationAxis(cUp, 0.0001f);
cTarg = XMVector4Transform(cTarg, rotYMat);
}else if (GetAsyncKeyState('R')) {
XMMATRIX rotZMat = XMMatrixRotationAxis(cTarg, -0.0001f);
cUp = XMVector4Transform(cUp, rotZMat);
}
else if (GetAsyncKeyState('T')) {
XMMATRIX rotZMat = XMMatrixRotationAxis(cTarg, 0.0001f);
cUp = XMVector4Transform(cUp, rotZMat);
}else if (GetAsyncKeyState('F')) {
XMMATRIX rotXMat = XMMatrixRotationAxis(xvect, -0.0001);
cUp = XMVector4Transform(cUp, rotXMat);
cTarg = XMVector4Transform(cTarg, rotXMat);
}
else if (GetAsyncKeyState('G')) {
XMMATRIX rotXMat = XMMatrixRotationAxis(xvect, 0.0001);
cUp = XMVector4Transform(cUp, rotXMat);
cTarg = XMVector4Transform(cTarg, rotXMat);
}
//Move forward/Backward
if (GetAsyncKeyState('P')) {
cPos += XMVector3Normalize(cTarg) / 10000.0f;
}
else if (GetAsyncKeyState('M')) {
cPos -= XMVector3Normalize(cTarg) / 10000.0f;
}
//Update values
XMStoreFloat4(&cameraPosition, cPos);
XMStoreFloat4(&cameraUp, cUp);
XMStoreFloat4(&cameraTarget, cTarg );
//Generate View Matrix of Camera
XMMATRIX ViewMatrix = XMMatrixLookToLH(cPos, cTarg, cUp);
XMStoreFloat4x4(&cameraViewMat, ViewMatrix);
}
EDIT2:
There is a new version with a view matrix wich I update when the camera move. By this way I can keep the local coordonate with cUp, cTarg and cPos