Orientation of objects

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.

Any ideas / hints what im doing wrong here

Yes: you’re using Euler angles. Stop that.

What do you mean by ‘storing an objects orientation’? Do you mean writing the orientation to a file which can be replayed? If so, you could write the modelview matrix to the file (yes, all 16 elements), then read it in and apply it using loadmatrix or multmatrix. The modelview matrix can be retrieved using glGet(GL_MODELVIEW_MATRIX). That way you don’t have to fuss with Euler Sequences or Quaternions. BTW, what is driving your object’s orientation - some sort of interaction via the keyboard? Good luck.

So you’re saying i should be using quaternions?

Yeah that’s exactly what i want to do, store the objects orientation so that it can be replayed, but i want to do so independently from the position, scaling and shearing, so i rather want to store a few floats describing the objects orientation (be it euler angles or quaternions) than the whole matrix. I also have other uses for this data than just replaying the transformations after i restart the program. For example im using the scale factors to make computation of the normals in the vertex shader faster / i want to output an objects current transformation state in a human readable format / etc.

At the moment only the program itself is modifying the objects transformations, but later this will also be possible by keyboard, i.e. being totally unpredictable.