I have an object which I want to rotate via keys. The object should yaw, pitch and roll. After trying a lot, I figured out that glRotate
has its limitations and it won't be possible to implement something like that with that function.
I've researched a bit and found out about quaternion-based rotation. It would be also possible to rotate via a rotation matrix, but almost everyone describes the quaternions as the best ever.
I have read about the quaternions and understood them fairly well, but how to implement them in my OpenGL program is still a mystery. Does anyone know a small example? Not how to implement the quaternion class but how to use it. I don't get how to put the things together.
The most important is to implement method that will build rotation matrices from quaternion. Then, as you'll do with normal rotation matrix, just multiply it with your modelview matrix.
This is simple example that was used to rotate cube with mouse movement. As you see I've needed to implement three methods: toMatrix
, quaternionFromAxis
, multiplyWith
. Assuming that you understand quaternions, this should be clear what they do.
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);
}
You can easily build rotation matrices out of unit quaternions.
Given a unit quaternion a + bi + cj + dk, you can build the following 3x3 matrix:
Add the last line and column taken from the identity 4x4 matrix, glMultMatrix
and you're done :)