У меня есть матрица вращения.Как я могу получить вращение вокруг указанной оси, содержащейся в этой матрице?
Редактировать:
Это трехмерная матрица (4x4), и я хочу знать, как далеко вокруг заданной (не содержится)) ось матрица вращается.Я уже могу разложить матрицу, но D3DX даст только всю матрицу как одно вращение вокруг одной оси, тогда как мне нужно разбить матрицу на угол поворота вокруг уже известной оси, а остальные.
Пример кода и краткое описание проблемы:
D3DXMATRIX CameraRotationMatrix;
D3DXVECTOR3 CameraPosition;
//D3DXVECTOR3 CameraRotation;
inline D3DXMATRIX GetRotationMatrix() {
return CameraRotationMatrix;
}
inline void TranslateCamera(float x, float y, float z) {
D3DXVECTOR3 rvec, vec(x, y, z);
#pragma warning(disable : 4238)
D3DXVec3TransformNormal(&rvec, &vec, &GetRotationMatrix());
#pragma warning(default : 4238)
CameraPosition += rvec;
RecomputeVPMatrix();
}
inline void RotateCamera(float x, float y, float z) {
D3DXVECTOR3 RotationRequested(x, y, z);
D3DXVECTOR3 XAxis, YAxis, ZAxis;
D3DXMATRIX rotationx, rotationy, rotationz;
XAxis = D3DXVECTOR3(1, 0, 0);
YAxis = D3DXVECTOR3(0, 1, 0);
ZAxis = D3DXVECTOR3(0, 0, 1);
#pragma warning(disable : 4238)
D3DXVec3TransformNormal(&XAxis, &XAxis, &GetRotationMatrix());
D3DXVec3TransformNormal(&YAxis, &YAxis, &GetRotationMatrix());
D3DXVec3TransformNormal(&ZAxis, &ZAxis, &GetRotationMatrix());
#pragma warning(default : 4238)
D3DXMatrixIdentity(&rotationx);
D3DXMatrixIdentity(&rotationy);
D3DXMatrixIdentity(&rotationz);
D3DXMatrixRotationAxis(&rotationx, &XAxis, RotationRequested.x);
D3DXMatrixRotationAxis(&rotationy, &YAxis, RotationRequested.y);
D3DXMatrixRotationAxis(&rotationz, &ZAxis, RotationRequested.z);
CameraRotationMatrix *= rotationz;
CameraRotationMatrix *= rotationy;
CameraRotationMatrix *= rotationx;
RecomputeVPMatrix();
}
inline void RecomputeVPMatrix() {
D3DXMATRIX ProjectionMatrix;
D3DXMatrixPerspectiveFovLH(
&ProjectionMatrix,
FoV,
(float)D3DDeviceParameters.BackBufferWidth / (float)D3DDeviceParameters.BackBufferHeight,
FarPlane,
NearPlane
);
D3DXVECTOR3 CamLookAt;
D3DXVECTOR3 CamUpVec;
#pragma warning(disable : 4238)
D3DXVec3TransformNormal(&CamLookAt, &D3DXVECTOR3(1, 0, 0), &GetRotationMatrix());
D3DXVec3TransformNormal(&CamUpVec, &D3DXVECTOR3(0, 1, 0), &GetRotationMatrix());
#pragma warning(default : 4238)
D3DXMATRIX ViewMatrix;
#pragma warning(disable : 4238)
D3DXMatrixLookAtLH(&ViewMatrix, &CameraPosition, &(CamLookAt + CameraPosition), &CamUpVec);
#pragma warning(default : 4238)
ViewProjectionMatrix = ViewMatrix * ProjectionMatrix;
D3DVIEWPORT9 vp = {
0,
0,
D3DDeviceParameters.BackBufferWidth,
D3DDeviceParameters.BackBufferHeight,
0,
1
};
D3DDev->SetViewport(&vp);
}
Фактически, через определенное время, когда вызывается RotateCamera, он начинает вращаться относительно оси X, даже если для ответа на этот запрос передается постоянный нольна ввод мышью, поэтому я знаю, что при перемещении мыши камера вообще не должна катиться.Я попытался спамить 0,0,0 запросов и не увидел изменений (по одному на кадр при 1500 кадров в секунду), поэтому я совершенно уверен, что не вижу ошибки FP или ошибки накопления матрицы.Я попытался написать функцию RotateCameraYZ и убрать все оси X из функции.Я провел несколько дней, пытаясь выяснить, почему это так, и в итоге решил просто взломать его.
Итак, я хочу получить вращение вокруг оси относительных x, преобразовать матрицу CameraRotation, а затем проверить ее, чтобы убедиться, что она такая же, а если нет, добавить корректирующую матрицу.
Просто для справки, я видел несколько диаграмм в Википедии, и у меня на самом деле довольно странное расположение осей: ось Y вверх, но ось X вперед и ось Z вправо, поэтому ось Y рыскание, ось Zшаг, крен оси X.