PDA

View Full Version : OpenGL rotation function?



Quantumcat
05-23-2013, 08:19 PM
I have some objects with vectors of positions. I have been successful getting them to sit on the floor by calculating their centre, and translating them up enough so they sit on the floor object properly (which stretches over the x and z axes with y = 0).

Now I want to try giving them some arbitrary rotations before having them sit on the floor. To do this I'll need to calculate the centre after having rotated each point (so I can make the lowest point on the object touch the floor and not have the object stuck inside the floor or float above it).

I tried searching Google but can only find results about rotation for the purpose of drawing (glRotatef). Is there a ready-made OpenGL function where I can insert a vector (x, y, z) and an angle, and get the vector rotated by that angle?

If not, does anyone have one they have already written that they know works?

If not, if I write out on paper the 4 by 4 rotation matrices, and multiply them in the order X, then Y, then Z, and then multiply the matrix I get by a vector (x, y, z, 1), and use that as the equations in my rotation function, will that work? I have read about gimbal lock, and don't fully understand it, so am not sure if that will cause a problem?

Thanks in advance!

Edit:

I have been playing with the third option and discovered I can get OpenGL to multiply 4 by 4 matrices, so thought I'd let it do the work (maybe I will do it myself when I start looking for ways to speed up my program). I have so far (sorry, I haven't figured out how to make code sections on this forum yet):

float XRot [16] = {1, 0, 0, 0, 0, cos(XAngle), sin(XAngle), 0, 0, -1*sin(XAngle), cos(XAngle), 0, 0, 0, 0, 1};
float YRot [16] = {cos(YAngle), 0, -1*sin(YAngle), 0, 0, 1, 0, 0, sin(YAngle), 0, cos(YAngle), 0, 0, 0, 0, 1};
float ZRot [16] = {cos(ZAngle), sin(ZAngle), 0, 0, -1*sin(ZAngle), cos(ZAngle), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};

glLoadMatrixf(XRot);
glMultMatrixf(YRot);
glMultMatrixf(ZRot);

But how do I get the current matrix out so I can multiply it by the position? I have found how to get, say, the modelview or projection matrix out but not the custom one? Have I done something wrong so far?

bug343
05-23-2013, 11:58 PM
The GLMath (glm) libraries have functions to generate a rotation transformation matrix. These functions have been written by many people for generations of OpenGL releases and the common math functions and routines can be found in the glm library.

The proper way to rotate a vector is to multiply the vector in homogeneous coordinates with a rotation transformation matrix. That rotation transformation matrix can be obtained from math libraries like glm, ex. rotation_matrix = glm::rotate(......)
rotated_vector = original_vector * rotation_matrix

tonyo_au
05-24-2013, 01:19 AM
rotated_vector = rotation_matrix *original_vector

Use this for glm with opengl

viveksrivastava
05-24-2013, 02:36 AM
void rotation_inbuilt()
{
printf("My rotation value of thetax thetay thetaz:- %f\t,%f\t,%f\t",theta_x,theta_y,theta_z);


glRotatef(theta_z,0.0,0.0,1.0);
glRotatef(theta_y,0.0,1.0,0.0);
glRotatef(theta_x,1.0,0.0,0.0);

}
void rotation_matrix()
{
printf("My rotation value of thetax thetay thetaz:- %f\t,%f\t,%f\t",theta_x,theta_y,theta_z);
glMultMatrixf(ZRot);
glMultMatrixf(YRot);
glMultMatrixf(XRot);

}
void rotation_scene()
{

init();
//rotation_inbuilt();
rotation_matrix();
draw_cube();
}

Quantumcat
05-24-2013, 07:53 PM
Thanks everyone. I downloaded glm and included it. In my Rotate function, after I get the matrix and use it, it says I am not allowed to use the operator * on the matrix and vector. Google comes up with exactly zero results for this (a few for other operators, none for the * operator and glm). Here is my Rotate function:



glm::vec3 Rotate (float XAngle, float YAngle, float ZAngle, glm::vec3 Pivot, glm::vec3 P)
{
//..Translate pivot point to origin
glm::mat4 RotationMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(-Pivot.x, 0.0f, 0.0f));
RotationMatrix = glm::translate(RotationMatrix, glm::vec3(0.0f, -Pivot.y, 0.0f));
RotationMatrix = glm::translate(RotationMatrix, glm::vec3(0.0f, 0.0f, -Pivot.z));

//..Do rotations
RotationMatrix = glm::rotate(RotationMatrix, XAngle, glm::vec3(1,0,0));
RotationMatrix = glm::rotate(RotationMatrix, YAngle, glm::vec3(0,1,0));
RotationMatrix = glm::rotate(RotationMatrix, ZAngle, glm::vec3(0,0,1));

//..Put back
RotationMatrix = glm::translate(RotationMatrix, glm::vec3(Pivot.x, 0.0f, 0.0f));
RotationMatrix = glm::translate(RotationMatrix, glm::vec3(0.0f, Pivot.y, 0.0f));
RotationMatrix = glm::translate(RotationMatrix, glm::vec3(0.0f, 0.0f, Pivot.z));

glm::vec3 ResultVec = P * RotationMatrix; //<--error here, the * is underlined in red
//glm::vec3 ResultVec = RotationMatrix * P; //tried the other way just in case, didn't work either

return ResultVec;
}

The exact Intellisense error is: 'Error: no operator "*" matches these operands'

Quantumcat
05-25-2013, 12:44 AM
Never mind!! I figured it out. I am supposed to use a vec4, since the rotations are 4 by 4 matrices and you give the position vector a 1 at the end :-)

perrya
07-12-2013, 01:39 PM
I have a problem similar to this. I would like change the point at which a rotation occurs. The standard response on the Internet is to do the following;


glPushMatrix();
glTranslatef(x, y, z);
glRotatef(angle, rot_axis_x, rot_axis_y, rot_axis_z);
Draw();
glPopMatrix();

However, I am using OpenGL and everything revolves around a matrix. So my code looks like this;



MVP = glm::translate(MVP,position);
MVP = glm::rotate(MVP,angle,direction);
MVP = glm::scale(MVP,scale);
setMVP(MVP);
clazz.drawWheels();
clazz.drawBody();

MVP = glm::translate(MVP,glm::vec3(0,0,1.1));
MVP = glm::rotate(MVP,turrent,direction);
setMVP(MVP);
clazz.drawTurrent();

demoElevation();

MVP = glm::rotate(MVP,elevation,glm::vec3(1.0f, 0.0f, 0.0f));
setMVP(MVP);
clazz.drawBarrel();

It's a tank! And I have managed to draw the body nicely. And I have managed to turn the turrent nicely. One thing I can't seem to do is move the barrel properly. It doesn't seem to have the right rotation point. But this begs the question, how can I change the rotation point before I do a rotate using OpenGL 3.2 MVP (model view perception) matrixes?

New to OpenGL and wonders who out there can shed some light on this for me.

Thanks,

Perry