Как инвертировать вращение одной оси в матрице камеры (например, OSG CameraViewMatrix)

Для приложения дополненной реальности я использую некоторый алгоритм удара, чтобы предсказать текущую ориентацию моего мобильного телефона.

Алгоритм (LSD-Slam) предоставляет текущую позу в форме группы лжи SE3 (с использованием Sophus::Sim3f). Если я правильно понял, этот тип содержит матрицу, которую можно интерпретировать как матрицу просмотра камеры. После инициализации, т.е. матрица выглядит так:

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

Для визуализации 3D-контента я использую OpenSceneGraph. К счастью, в OSG вы можете установить положение камеры напрямую, используя матрицу вида:

camera->setViewMatrix(matrix);

Теперь, когда я запускаю код, кажется, что все работает нормально, если я вращаюсь вокруг Y (крен) или Z (рыскание). Но когда я поворачиваюсь вокруг X (шага), моя цифровая камера в OSG, кажется, делает прямо противоположное тому, что она должна делать.

Например: представьте себе 3D-модель прямо перед камерой. Если затем я медленно наклоню камеру вверх (вокруг X), 3D-модель также будет двигаться вверх, в то время как на самом деле она должна покидать экран в нижней части. Я попытался проиллюстрировать это поведение следующим рисунком:поведение оси

Возможно, для этого есть действительно простое решение, но я просто не смог исправить его даже после нескольких часов попыток. Если я правильно понял, первые столбцы представляют собой вращение вокруг определенной оси, поэтому я попытался инвертировать отдельные векторы, например. сделал это:

u u u 0       -u u u 0          -u -u -u 0
v v v 0   =>  -v v v 0   ...     v v v 0 
n n n 0       -n n n 0           n n n 0
0 0 0 1        0 0 0 1           0 0 0 1

В то время как некоторые попытки действительно решили проблему подачи, они затем испортили другую ось. Всегда кажется, что по крайней мере одна ось неверна. Кто-нибудь знает, как это решить? Буду очень признателен за любые подсказки по этой проблеме.


person Christoph Göttert    schedule 31.01.2017    source источник


Ответы (2)


Если поза, которую вы получаете из библиотеки, соответствует матрице представления OpenGL, вы сможете передать ее непосредственно в камеру osg, как вы упомянули.

Однако имейте в виду, что OSG принимает соглашение о матрице основной строки (см., например, этот пост), поэтому вам может понадобиться переключить строку/столбец в вашей матрице.

Если это не сработает, я предлагаю вам убедиться в соглашениях о позах, используемых Sophus (какие повороты относительно какой позиции покоя в мировых координатах) и воссоздать такое же преобразование с помощью osg с нуля.

person rickyviking    schedule 01.02.2017
comment
Спасибо за ответ, переключение строк/столбцов не помогло. Поэтому я последовал твоему совету и снова проверил Софуса. Я принял ваш ответ, но я опубликую свой собственный ответ, если кто-то наткнется на подобную проблему. - person Christoph Göttert; 01.02.2017

После повторной проверки Sophus я обнаружил, что могу получить матрицу вращения, а также вектор перевода отдельно. Используя этот пост, я преобразовал матрицу вращения в углы Эйлера. С углами Эйлера я смог установить вращение каждой оси отдельно:

  rotationMatrix.makeRotate(
  osg::DegreesToRadians(-angleZ), osg::Vec3(0,1,0), // roll
  osg::DegreesToRadians(angleX), osg::Vec3(1,0,0) , // pitch
  osg::DegreesToRadians(angleY), osg::Vec3(0,0,1) ); // heading

Перевернутый вал наконец-то помог...

person Christoph Göttert    schedule 01.02.2017