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.
Answer
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.
No comments:
Post a Comment