Конвертировать OpenGL 4-матрицу в VRML T*R*S

Я пытаюсь экспортировать сцену из программы OpenGL прямого режима в VRML.

Как в OpenGL, так и в VRML, лица могут быть сгруппированы в объекты с их собственным перемещением, поворотом и масштабированием относительно начала сцены.

В OpenGL они хранятся в виде 4-матрицы, представляющей перемещение и вращение / масштаб в одной матрице [1]. В VRML они должны быть представлены в виде отдельных векторов перемещения, поворота и масштабирования [2] [3].

Как я могу разложить произвольную 4-матрицу таким образом?

Я бы предпочел использовать библиотечную функцию для этого, чтобы минимизировать код, который я должен поддерживать, и уменьшить вероятность ошибок. Я использую C# на Windows и могу получить доступ к любой CLR или Windows родной DLL.

3 ответа

Решение

Взгляните на код Matrix.Decompose из источников Monogame.

Помните - матрицы OpenGL являются основными по столбцам, а DirectX/XNA - основными по строкам.

Надеюсь, это поможет.

Как я могу разложить произвольную 4-матрицу таким образом?

Самый правый столбец преобразования - вектор трансляции T.

Масштаб и вращение немного сложнее для извлечения. Вам нужно найти ось вращения и угол поворота. По сути, вы имеете дело с проблемой собственных векторов: найдите вектор, который остается неизменным при преобразовании матрицы. Это случай для собственного вектора. Вращения - это ортогональные преобразования. Таким образом, любая ненормальная часть матрицы вращения является масштабированием. Вы можете извлечь это масштабирование, сначала ортонормировав матрицу, получив свои коэффициенты масштабирования S. Наконец, вы можете решить проблему собственных векторов, чтобы найти два антипараллельных собственных вектора, являющихся осью вращения. Соответствующее собственное значение обозначает cos(α) вращения, которое дает вам ось вращения и угол R.

SFMatrix4f/d и SFMatrix3/d имеют встроенные функции для разложения матрицы на ее компоненты. Вот страница из спецификации: http://www.web3d.org/documents/specifications/19777-1/V3.0/Part1/functions.html.

В JavaScript вы можете ввести:

function foo (matrix4f)
{
   var translation = new SFVec3f ();
   var rotation    = new SFRotation ();
   var scale       = new SFVec3f ();

   matrix4f .getTransform (translation, rotation, scale);
}

Некоторые браузеры поддерживают в качестве четвертого и пятого параметра getTransform аргумент scaleOrientation и center.

Другие вопросы по тегам