I’m currently facing some problems when im trying to keep track of an object’s orientation.
My approach is storing an object’s orientation using the euler angles head (rotation around y-axis), pitch (rotation around x-axis) and roll (rotation around z-axis).
This works fine when im only rotating around the x, y or z axis. But i really can’t figure out or find an algorithm for calculating the head pitch and roll parameters when im using a more general rotation matrix that rotates around an arbitrary normalized axis.
Here’s a short excerpt from my code:
void Object::RotateX(GLfloat rad) {
pitch += rad;
MatRotateX(modelMat, rad); //modelMat = rotationMat * modelMat;
}
void Object::RotateAxis(GLfloat rad, const Vec3& axis) {
//This approach does not work / gives wrong results:
Mat3 rtmat;
SetRotationAxisMat(rtmat, rad, axis);
GLfloat p = asin(rtmat[5]);
pitch += p;
if(cos(p)==0.0) {
roll += atan2(rtmat[1], rtmat[0]);
} else {
head += atan2(-rtmat[2], rtmat[8]);
roll += atan2(-rtmat[3], rtmat[4]);
}
MatRotateAxis(modelMat, rad, axis); //modelMat = rotationMat * modelMat;
}
So basically what i did is treating the rotation matrix as if it was a concatenation of three rotation matrices, RotZ * RotX * RotY, extracting the euler parameters and added them to the former values of head pitch and roll.
I tested it by rotating a cube around the normalized {1.0, 1.0, 1.0} axis, but when the cube is back at it’s initial orientation after a rotation of 360 degrees around this axis the head pitch and roll parameters are (approximately) 210degrees, which is wrong, because when i rotate the cube around the y, x and z axis (in this order) once before any rendering occurs the cube does not have its initial orientation.
Any ideas / hints what im doing wrong here or has anyone had the same problem before?
Completely different approaches to storing an objects orientation are also welcome as well as ideas of how to keep track of shearing transformations.