2
\$\begingroup\$

Im writing a game for which, one of the models are loaded from an .obj file.

It's a model of a plane, and I want to rotate the propeller. The object file is broken into groups, and the propeller is identified, so that's all good. I'm writing the game in C++ with OpenGl/GLFW The drawing function is:

int win_width;
int win_height;
glfwGetWindowSize(&win_width, &win_height);
float win_aspect = (float)win_width / (float)win_height;
glViewport(0, 0, win_width, win_height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, win_aspect, 1, 100.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 30.0, 0, 0, 0, 0.0, 1.0, 0.0);

glEnable(GL_DEPTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE); 
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3f(0.0f, 0.0f, 0.0f);
int vertexIndex = 0, normalIndex;
glRotatef(90, 0, 1, 0);
glPushMatrix();
for(int a = 0; a < (int)groups.size(); a++)
{
    if(groups[a].type == "prop")
    {
//Code for rotation
        glPopMatrix();
        glPushMatrix();
        float x,y,z;
        x = y = z = 0;
        int Count = 0;
        for(int k = 0; k < groups[a].faces.size(); k++)
        {
            for(int p = 0; p < groups[a].faces[k].vertices.size(); p++)
            {
                int _index = groups[a].faces[k].vertices[p];
                y += vertices[_index].Dimensions[_y] ;
                z += vertices[_index].Dimensions[_z];
                Count++;
            }
        }
        z /= Count;
        y /= Count;
        glTranslatef(0, -y, -z);
        glRotatef(angle, 1, 0, 0);
        glTranslatef(0, y, z);
    }
    for(int b = 0; b < (int)groups[a].faces.size(); b++)
    {
        glBegin(GL_POLYGON);
        for(int c = 0; c < (int)groups[a].faces[b].vertices.size(); c++)
        {
            vertexIndex = groups[a].faces[b].vertices[c];
            glVertex3d(vertices[vertexIndex].Dimensions[_x], vertices[vertexIndex].Dimensions[_y], vertices[vertexIndex].Dimensions[_z]);
        }
        glEnd();
    }
}
glPopMatrix();
glfwSwapBuffers();

Since I don't know the exact centre of the propeller, that's what the for loop before the rotation is for. It finds the average of the y and z co-ordinates.

After I find it, I translate to -y,-z , rotate it, and then translate back. This makes the propeller spin as I want it to, but it also rotates along the origin >.< http://people.sc.fsu.edu/~jburkardt/data/obj/cessna.obj <- This is the object file.

groups is a vector of objects and each object has a vector of faces. I'm sure that the vertices and faces are being loaded correctly, since the whole model renders correctly.

\$\endgroup\$
3
\$\begingroup\$

OpenGL uses a column vector convention, which means the matrices must be applied in the opposite of the order in which you actually want the transformations to occur. Just replace this:

glTranslatef(0, -y, -z);
glRotatef(angle, 1, 0, 0);
glTranslatef(0, y, z);

with this:

glTranslatef(0, y, z);
glRotatef(angle, 1, 0, 0);
glTranslatef(0, -y, -z);

and that should fix it.

\$\endgroup\$
  • \$\begingroup\$ Hi, Nathan. I have been searching for hours. My question is: why do we always need to translate while making rotation? I have read something like "because it always rotates around (0, 0, 0)". Why (0, 0, 0)? What is it? Is this where the camera is at by default, so that when making rotation, we need to translate the object to (0, 0, 0) and then back to its original position? Could we just rotate the object at its own axis without needing to do translation? Thank you. \$\endgroup\$ – Unheilig Oct 24 '16 at 21:11
  • \$\begingroup\$ @nathan-reed , Could you please explain what column vector convention is? And why we have to apply the matrices in the opposite order? \$\endgroup\$ – neevek Jun 23 '17 at 16:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.