Кватернионы не имеют части перевода. Перевод должен вестись отдельно, как во втором фрагменте кода.
В любом случае, я не уверен, что код будет делать то, что нужно. Кватернионы не решат блокировку карданного подвеса, если проблема будет сформулирована тем же способом, который вводит блокировку карданного подвеса в первую очередь. Если кватернион устанавливается заново после шага / рыскания / броска каждого кадра, будут возникать те же проблемы, что и раньше, и по тем же причинам. (И если кажется, что это не так, то это потому, что код построения кватерниона делает то же самое, что и код построения матрицы, но в этом случае этого не происходит: вращение вокруг каждой повернутой оси, а не вращение вокруг фиксированный.)
Чтобы исправить это, сохраняйте кватернион как часть состояния объекта и применяйте каждый поворот непосредственно к нему. Это на самом деле не покупает ничего такого, чего нельзя было бы сделать так же легко с помощью матрицы. (Я не подсчитывал операции, так что это не значит, что он может оказаться более эффективным с одной стороны, чем с другой.)
Основным преимуществом кватернионов является то, что их легко интерполировать, получая что-то разумное на каждом промежуточном шаге, просто суммируя взвешенные входные данные и нормализуя результат. 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;
Вышеприведенный текст был найден и заменен в вышеприведенной форме, поэтому я очень надеюсь, что не облажался.