От кватернионов до вращений OpenGL
У меня есть объект, который я хочу повернуть через ключи. Объект должен рыскать, качаться и катиться. После многих попыток я понял, что glRotate
имеет свои ограничения, и с этой функцией невозможно будет реализовать что-то подобное.
Я немного исследовал и узнал о вращении на основе кватернионов. Было бы также возможно вращаться через матрицу вращения, но почти все описывают кватернионы как лучшие когда-либо.
Я читал об кватернионы и понимали их довольно хорошо, но как их реализовать в моей программе OpenGL по-прежнему остается загадкой. Кто-нибудь знает небольшой пример? Не как реализовать класс quaternion, а как его использовать. Я не понимаю, как собрать все воедино.
2 ответов
наиболее важным является реализация метода, который будет строить матрицы вращения из кватерниона. Затем, как и в случае с обычной матрицей вращения, просто умножьте ее на матрицу modelview.
это простой пример, который использовался для поворота куба с движением мыши. Как вы видите, мне нужно было реализовать три метода:toMatrix
, quaternionFromAxis
, multiplyWith
. Предполагая, что вы понимаете, кватернионы, это должно быть ясно, что они делают.
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
// Multiply quaternion with current modelview matrix
glMultMatrixf(cameraQuaternion.toMatrix());
// Some other transformations
glTranslatef(-0.5f, -0.5f, -0.5f);
// Draw something, i.e. cube
glDrawArrays(GL_TRIANGLES, 0, 36);
glDrawArrays(GL_TRIANGLES, 0, 36);
glPopMatrix();
}
void mouseMoved(float dx, float dy) {
float axisY[] = { 0, 1, 0 },
axisX[] = { 1, 0, 0 };
float sensitivity = 0.005f;
Quaternion *q1 = Quaternion.quaternionFromAxis(axisY, dx * sensitivity];
Quaternion *q2 = Quaternion.quaternionFromAxis(axisX, dy * sensitivity];
// Multiply two quaternions with camera
cameraQuaternion = (q1.multiplyWith(q2)).multiplyWith(cameraQuaternion);
}
вы можете легко построить матрицы вращения из единичных кватернионов.
учитывая единицу кватернион a + bi + cj + dk, вы можете построить следующую матрицу 3x3:
добавьте последнюю строку и столбец, взятые из Матрицы identity 4x4,glMultMatrix
и ты молодец :)