Help with this code snippet? (glMultMatrix)

Hi everyone,

I’m working with a 3rd party modeling library that defines some data structures within the model file. One of these is a “pivot” value, a 3D vector.

Someone who worked on a project before me had this code in his initialization routine, and I can’t make sense of it. Could someone help me understand what it’s doing?

glPushMatrix();
glLoadIdentity();

ObjectData *d = &model->data.object;

glMultMatrixf(&model->matrix[0][0]);

glTranslatef(-d->pivot[0], -d->pivot[1], -d->pivot[2]);

matrix_copy(M, model->matrix);
matrix_invert(M);

glMultMatrixf(&M[0][0]);

glGetFloatv(GL_MODELVIEW_MATRIX, another_matrix);

glPopMatrix();

Don’t worry too much about the data structures listed. They’re confusing, I know and I apologize for it.

What I’m really interested in knowing is what is going on there with the glMultMatrix calls sandwiching a glTranslate like that?

Here’s what’s happening as best as I can tell. (Correct me if I’m wrong.) The original author starts by setting the 3D object’s internal matrix as the modelview, then translates the 3D object’s “pivot” point to the origin. Then, he inverts the modelview matrix and multiplies that to the existing modelview matrix and saves it in the variable “another_matrix”.

That’s the step by step. What I don’t understand is the purpose behind it-- is he trying to…well, I don’t know what he’s trying to do. If you have an explanation what the purpose of all that might be I’d be grateful. Thanks so much.


glMultMatrixf(&model->matrix[0][0]);

glTranslatef(-d->pivot[0], -d->pivot[1], -d->pivot[2]);

matrix_copy(M, model->matrix);
matrix_invert(M);

glMultMatrixf(&M[0][0]);


I think that code generate a matrix to move an object with the pivot as a reference point (the new origin).

Look at this sample code:


#include <iostream>
#include <cstdlib>

#include <GL/glut.h>

struct Quad
{
  float vertex[16];
 // float transform_matrix[16];
};


GLvoid display(GLvoid);
GLvoid init(GLvoid);

GLvoid reshape(GLsizei w,GLsizei h);
void trigger(int value); 
Quad q;

float pivot[3] = {2.0,0.0,0.0};
static float angle = 0.0;
int main(int argc,char **argv)
{
  glutInit(&argc,argv);
  
  glutTimerFunc(300,trigger,true);
  
  glutInitWindowSize(512,512);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL|GLUT_DOUBLE);
  glutCreateWindow("Pivot");
  
  
  
  
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  init();
  
 
  
  glutMainLoop();
  
  
  return (EXIT_SUCCESS);
}



GLvoid display(GLvoid)
{
  
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
  
  glLoadIdentity();
  //....
  
  //Draw the pivot
  glBegin(GL_POINTS);
  glColor4f(1.0,1.0,0.0,1.0);
  glVertex3fv(pivot);
  glEnd();
  
  glPushMatrix();
  glLoadIdentity();
  
  glRotatef(angle,0.0,0.0,1.0);//transform
  
  glTranslatef(-pivot[0],-pivot[1],-pivot[2]);
  
  glRotatef(-angle,0.0,0.0,1.0);//inverse transform
  
  
  glTranslatef(pivot[0],pivot[1],pivot[2]);
  glColor4f(1.0,1.0,1.0,1.0);
  glBegin(GL_TRIANGLE_STRIP);
  glVertex4fv(&q.vertex[0]);
  glVertex4fv(&q.vertex[4]);
  glVertex4fv(&q.vertex[8]);
  glVertex4fv(&q.vertex[12]);
  glEnd();
  
  glPopMatrix();
  
  glutSwapBuffers();  
}

GLvoid init(GLvoid)
{
  float vertex[16] = {-1.0,-1.0,0.0,1.0,
                      1.0,-1.0,0.0,1.0,
                      -1.0,1.0,0.0,1.0,
                      1.0,1.0,0.0,1.0};
                      
  memcpy(q.vertex,vertex,16*sizeof(float));
  
  glPointSize(2.0);
  glEnable(GL_DEPTH_TEST);
}


GLvoid reshape(GLsizei w,GLsizei h)
{
  glViewport(0,0,w,h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-5.0,5.0,-5.0,5.0,-1.0,1.0);
  glMatrixMode(GL_MODELVIEW);
}


void trigger(int value)
{
  angle += 1.0f;
  display();
  glutTimerFunc(10,trigger,true);
}


The quad will rotate around the pivot.

Thank you, that helps a lot.

So it seems the code is rotating around the pivot point…

That code is equivalent to:


Mat4 multiply_matrix(const Mat4& m1,const Mat4& m2);
Mat4 create_translation_matrix(const vec3& trans);

ObjectData *d = &model->data.object;

Mat4 t = multiply_matrix(model->matrix, create_translation_matrix(-d->pivot));
Mat4 M = model->matrix;  matrix_invert(M);

another_matrix = multiply_matrix(t,M);