The problem lies in the ordering of the transformations. The modelview transformation is represented as a 4x4 matrix. Each time you do a transformation operation (translate, scale, rotate) a 4x4 matrix representing this transformation is multiplied to the current modelview matrix. Matrix multiplication is not commutative, so the order in which you call these operations is important. In your code, when you call
gl.glTranslated(-centroid.getX(), -centroid.getY(), -centroid.getZ());
The point at ‘centroid’ will not actually be translated to (0, 0, 0) since you have done a bunch of other translations before namely the implicit one in gluLookAt and the keyboard one. Additionaly there’s a scale in between there, which also modifies the result of the translation, so in fact after the
gl.glTranslated(-centroid.getX(), -centroid.getY(), -centroid.getZ());
you are translating to
(xScale * (xTrans - centroidX), yScale * (yTrans - centroidY), -100 + zScale * (zTrans - centroidZ))
The simplest solution is to do the rotation first, then perform all the other transformations. If I’m not mistaken the following code should do the trick:
// reset the modelview matrix
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
// Translate the center of the model the origin, rotate and translate back
gl.glTranslated(-centroid.getX(), -centroid.getY(), -centroid.getZ());
gl.glRotatef(xRot, 1.0f, 0.0f, 0.0f);
gl.glRotatef(yRot, 0.0f, 1.0f, 0.0f);
gl.glRotatef(zRot, 0.0f, 0.0f, 1.0f);
gl.glTranslated(centroid.getX(), centroid.getY(), centroid.getZ());
// viewing transformation
glu.gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, -100.0, 0.0, 1.0, 0.0);
// modeling transformation
gl.glScalef(xScale, yScale, zScale);
// these translations are keyboard inputs to move (translate) the model
gl.glTranslatef(xTrans, yTrans, zTrans);
An alternative solution would be to take all the previous transformations into account. To do this you could take the point ‘centroid’, transform it using the model-view matrix and then translate using the transformed point.
// reset the modelview matrix
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
// viewing transformation
glu.gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, -100.0, 0.0, 1.0, 0.0);
// modeling transformation
gl.glScalef(xScale, yScale, zScale);
// these translations are keyboard inputs to move (translate) the model
gl.glTranslatef(xTrans, yTrans, zTrans);
// Translate the center of the model the origin, rotate and translate back
float[] modelViewMatrix = new float[16];
gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, modelViewMatrix);
float[] centroid = new float[] {centroid.getX(), centroid.getY(), centroid.getZ(), 1};
... do matrix multiplication here (centroid * modelViewMatrix);
gl.glTranslated(-centroid.getX(), -centroid.getY(), -centroid.getZ());
gl.glRotatef(xRot, 1.0f, 0.0f, 0.0f);
gl.glRotatef(yRot, 0.0f, 1.0f, 0.0f);
gl.glRotatef(zRot, 0.0f, 0.0f, 1.0f);
gl.glTranslated(centroid.getX(), centroid.getY(), centroid.getZ());
This is all off the top of my head, so I hope I didn’t make any obvious mistakes 