2017-01-31 20 views
1

Для приложения с дополненной реальностью я использую некоторый алгоритм slam для прогнозирования текущей ориентации моего мобильного телефона.Как инвертировать поворот одной оси в матрице камеры (например, OSG CameraViewMatrix)

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

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

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

camera->setViewMatrix(matrix); 

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

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

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

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 

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

ответ

1

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

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

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

+0

Спасибо за ваш ответ, переключения строк/colums не помогло. Поэтому я последовал твоему совету, чтобы снова проверить Софуса. Я принял ваш ответ, но я отправлю свой собственный ответ, если кто-нибудь столкнется с подобной проблемой. –

0

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

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 

переворачивая рулет сделал трюк, наконец ...