Quaternion -> matrix [16] - хорошо, что теперь? (Как вывести объект из кватерниона?) - PullRequest
2 голосов
/ 26 октября 2010

У меня есть вращение и перевод моего объекта в кватернионе, который я преобразовал в матрицу [16].

Как передать эту матрицу в OpenGL? Я бы подумал, что смогу просто выполнить glLoadMatrix () с моей новой матрицей с модными штанами, и все будет хорошо, но я получаю пустой экран.

(Я немного похож на GL n00b, поэтому печатайте медленно и используйте маленькие слова;)

Мой код выглядит примерно так:

glPushMatrix();

[quaternion makeIdentity];         // reset quat
[quaternion setPitch: rotation.x yaw: rotation.y roll: rotation.z];  // Set up with rotation coords (NOTE: setPitch:yaw:roll: is smart about degrees->radians)

GLdouble matrix[16];
[quaternion matrix: &matrix[0]];   // get quat -> matrix
matrix[12] =  location.x;          // fill in the translation
matrix[13] =  location.y;
matrix[14] =  location.z;

glLoadMatrixd(matrix);

glScaled(scale.x, scale.y, scale.z);

// draw geometry here -- snip

glPopMatrix();

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

ПРИМЕЧАНИЕ: когда я пропускаю кватернионную часть и делаю что-то вроде этого:

glPushMatrix();

glTranslatef(location.x, location.y, location.z);

glRotated(rotation.z,   0,   0, 1.0);
glRotated(rotation.x, 1.0,   0,   0);
glRotated(rotation.y,   0, 1.0,   0);

// draw geometry here -- snip

glPopMatrix();

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

Ответы [ 2 ]

2 голосов
/ 26 октября 2010

Если вы не забыли установить текущий режим матрицы на GL_MODELVIEW, ваша матрица должна быть загружена правильно. Проверьте кват -> матричные вычисления. Я бы начал с поворота на нулевой угол и сравнил бы результат с единичной матрицей.

1 голос
/ 01 ноября 2010

Кватернионы не имеют части перевода. Перевод должен вестись отдельно, как во втором фрагменте кода.

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

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

Основным преимуществом кватернионов является то, что их легко интерполировать, получая что-то разумное на каждом промежуточном шаге, просто суммируя взвешенные входные данные и нормализуя результат. SLERP также вариант. Эквивалентная операция над матрицами в некоторых ситуациях не выполняется (например, если две матрицы представляют противоположные ориентации, вы получите столбец, состоящий полностью из нулей ...), и попытаетесь сделать нечто подобное с помощью pitch / yaw / roll просто создает большой беспорядок.

Что касается преобразования единицы в матрицу, если у вас есть кватернион с векторной частью (qx,qy,qz) и скалярной частью qw, вы можете превратить его в матрицу OpenGL, используя такой код:

mtx[0]=1.f-2.f*qy*qy-2.f*qz*qz;
mtx[1]=0.f+2.f*qx*qy+2.f*qw*qz;
mtx[2]=0.f+2.f*qx*qz-2.f*qw*qy;
mtx[3]=0.f;

mtx[4]=0.f+2.f*qx*qy-2.f*qw*qz;
mtx[5]=1.f-2.f*qx*qx-2.f*qz*qz;
mtx[6]=0.f+2.f*qy*qz+2.f*qw*qx;
mtx[7]=0.f;

mtx[8]=0.f+2.f*qx*qz+2.f*qw*qy;
mtx[9]=0.f+2.f*qy*qz-2.f*qw*qx;
mtx[10]=1.f-2.f*qx*qx-2.f*qy*qy;
mtx[11]=0.f;

mtx[12]=0.f;
mtx[13]=0.f;
mtx[14]=0.f;
mtx[15]=1.f;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...