OpenGL rotation matrix, [math] rotates in different direction

Started by
2 comments, last by tonemgub 9 years, 7 months ago

First of all i would like you to see this:

tank01.jpg

Image shows a tank (not rotated, static) with 4 collision spheres (white, red, green, blue)

/ note: three lines what you see (white,red,green) show the positive side of an axis, so for red its +x, for green its +y and for white its +z,

My problem is whenever i try to rotate a tank spheres are rotated backwards. like on this video:

To rotate a tank i use exactly the same rotation matrix i use to rotate these spheres.

now to explain it more deeply: sphere base position (in relation to unrotated tank) is calculated like this:

front_left sphere which is white (span_dist, 0, front_dist) [xyz]

front_right (red) (-span_dist, 0, front_dist) [xyz]

rear_left (green) (span_dist, 0, -front_dist)

rear_right (blue) (-span_dist, 0, -front_dist)

i draw the tank like this:






glPushMatrix();
glLoadIdentity();

gluLookAt(eyepos.x,eyepos.y,eyepos.z,lookat.x,lookat.y,lookat.z,up.x,up.y,up.z);

glTranslatef(pos.x,pos.y,pos.z);
glMultMatrixf(hull.rotation.AIR_MATRIX);
 
						hull.model->DrawSimpleModel();

glPopMatrix(); 

hull.rotation.AIR_MATRIX <- this is my rotation matrix (it only has rotation data, - no translation and scale data)

now i calculate spheres positions like:




float rotm[16];    int i;
for (i=0; i<16;i++) rotm[i] = hull.rotation.AIR_MATRIX[i];

col_front_left = front_left * rotm;
col_front_left = col_front_left + pos;

col_front_right = front_right * rotm;
col_front_right = col_front_right + pos;

col_rear_left = rear_left * rotm;
col_rear_left = col_rear_left + pos;

col_rear_right = rear_right * rotm;
col_rear_right = col_rear_right + pos;

where rotm is a copied hull.rotation.AIR_MATRIX (ofc same values)

a code for multiplying a vertex by a matrix is:




	  t3dpoint operator*(const float in[16]) const
		{     //since its an opengl engine i use this order
		//note that i do not add translation data and do not use scaling
			return t3dpoint(
in[0]*x+in[1]*y+in[2]*z,

in[4]*x+in[5]*y+in[6]*z,

in[8]*x+in[9]*y+in[10]*z);
		}

No i should say something about how do i calculate rotation matrix:

lets say i have three vectors front, right and up vector

i rotate them by calling pitch, yaw, roll funcitons

and then i build a matrix like this:




			AIR_MATRIX[0] = rr.x; //right
			AIR_MATRIX[1] = rr.y;
			AIR_MATRIX[2] = rr.z;
			AIR_MATRIX[3] = 0.0f;
			AIR_MATRIX[4] = ru.x; //up
			AIR_MATRIX[5] = ru.y;
			AIR_MATRIX[6] = ru.z;
			AIR_MATRIX[7] = 0.0f;
			AIR_MATRIX[8]  = -rf.x; //front
			AIR_MATRIX[9]  = -rf.y;
			AIR_MATRIX[10] = -rf.z;
			AIR_MATRIX[11] = 0.0f;
			AIR_MATRIX[12] =  0.0f;  //point
			AIR_MATRIX[13] =  0.0f;
			AIR_MATRIX[14] =  0.0f;
			AIR_MATRIX[15] = 1.0f;

Hopefully its enough info for someone that can help me ;x

oh i forgot to add that whenever i try to pitch the rotation matrix (opengl model draws properly) but i get stranger spheres pos.

Advertisement

When calculating the sphere positions you are multiplying on the wrong side of the matrix


float rotm[16]; int i;
for (i=0; i<16;i++) rotm[i] = hull.rotation.AIR_MATRIX[i];

// switch the order of multiplication here
col_front_left = rotm * front_left;
col_front_left = col_front_left + pos;

col_front_right = rotm * front_right;
col_front_right = col_front_right + pos;

col_rear_left = rotm * rear_left;
col_rear_left = col_rear_left + pos;

col_rear_right = rotm * rear_right;
col_rear_right = col_rear_right + pos;

EDIT: Thought I should explain why this is.

For a rotation matrix, the transpose is the same as the inverse

RT = R-1

Changing the order of multiplication is the same as multiplying by the transpose

R * vector = vector * RT

But since the transpose is the same as the inverse you were basically multiplying the points by the inverse of the rotation.

My current game project Platform RPG

And that worked, thanks alot!


First of all i would like you to see this:

tank01.jpg

...cannot be unseen. You still don't have sufficient buttons. ;)

This topic is closed to new replies.

Advertisement