Получить векторы глаз, цели и вверх из матрицы просмотра

#vector #matrix #directx #rotation #direct3d

#вектор #матрица #directx #вращение #direct3d #поворот

Вопрос:

В Direct3D я использую матрицу.Функция LookAtLH для вычисления матрицы просмотра.

Я использую это для камеры, которая вращается вокруг цели, перемещая начало координат в целевое положение, поворачивая, а затем перемещая начало координат обратно в (0,0,0).

Это умножается на матрицу, которая была первоначально вычислена из LookAtLH.

Есть ли способ, которым я могу, после нескольких из этих операций, разложить матрицу, чтобы получить положение глаз, целевое положение и вектор вверх?

Ответ №1:

Из матриц просмотра очень легко извлекать данные. Ознакомьтесь с документацией по используемой вами функции (я использовал документацию для D3DXMatrixLookAtLH):

http://msdn.microsoft.com/en-us/library/bb205342(v=vs.85).aspx

Как вы можете видеть в нижней части страницы, матрица внутренне генерируется следующим образом:

 zaxis = normal(At - Eye)
xaxis = normal(cross(Up, zaxis))
yaxis = cross(zaxis, xaxis)

 xaxis.x           yaxis.x           zaxis.x          0
 xaxis.y           yaxis.y           zaxis.y          0
 xaxis.z           yaxis.z           zaxis.z          0
-dot(xaxis, eye)  -dot(yaxis, eye)  -dot(zaxis, eye)  1
  

Имейте в виду, это справедливо только для DirectX; транспонируйте вышеупомянутую матрицу при переносе тех же вычислений в OpenGL, потому что система координат в DirectX является обратной к норме.

Комментарии:

1. Система координат OpenGL не является обратной! Это обратная система координат DirectX:-P

2. Верно! Меня учил программист DirectX, поэтому я выучил все задом наперед. Спустя годы я узнал, что все время использую транспонированные матрицы… Я обновил ответ, спасибо, что обратили на это внимание.

3. Я знаю, что это старое, но это ни вперед, ни назад. Конвейер фиксированных функций OpenGL использовал основное соглашение о столбцах, и все, что касается OpenGL, находится ниже по потоку от этого. Программируемому конвейеру все равно. Direct3D и его библиотеки используют соглашение о строках major. Вы можете использовать любой из них, если вы согласны с вашим матричным умножением.

Ответ №2:

Два варианта :

  • Долго и сложно: извлечь eye, up и LookAt из новой вычисленной матрицы
  • Простая версия: примените ваши преобразования (перевод, поворот, translation) к копии вашего eye, up и LookAt. Таким образом, вы очень легко получите новые векторы.