glRotate

I’ve finally done some texturing of the ball in my game Hyper Blazer (http://www.gagaplay.com/hypblazer/hypblazer.jnlp but then of course it has to rotate according to movement:
It has to rotate forwards according to your speed, and left-right according to steering.

So what I did is this, which I already feared wouldn’t do what I want:


GL11.glPushMatrix();
GL11.glTranslatef(0, y + DIAMETER, -3); // translate to pos of the ball
GL11.glRotatef(zRot, 1, 0, 0); // forward rotation
GL11.glRotatef(xRot, 0, 0, 1); // left-right rotation
drawBall();            
GL11.glPopMatrix();

Obviously, the left-right rotation doesn’t do what I want because the orientation has been changed by the previous (forward) rotation.
The thing is, It’s probably something trivial but I can’t wrap my head around how the rotation should be done. I’ve googled for it, but what came up is some hefty matrix math that’s waaaay above my head. :-[

Any ideas?

After reading some more about it, it doesn’t seem as trivial as I hoped it would be (I googled for ‘rotating around an arbitrary axis’).

Although not really what I want, I now worked around it a bit in a somewhat acceptable way by ‘steering’ the ball like a car (I uploaded this version).
So now the ball is rotated around the y axis for steering, and then around the x axis for forward motion.


GL11.glPushMatrix();
GL11.glTranslatef(0, y + DIAMETER, -3); // translate to pos of the ball

GL11.glRotatef(zRot, 1, 0, 0); // forward rotation

GL11.glPushMatrix();
GL11.glRotatef(xRot, 0, 0, 1); // left-right rotation
drawBall(); 
GL11.glPopMatrix();

           
GL11.glPopMatrix();

bit rusty with my opengl but i believe you can use some glpush and glpop matrix stuff to solve this, not sure if the above code is correct but should point you in right direction.

Pseudo code to rotate a sphere so that it matches its movement:


// level init
// the current ball transform
Matrix transform;

// per frame
Point a // position at start of frame
Point b // position at end of frame
Matrix frameRotation = getFrameRotation(a, b);

// add frame rotation to ball transform
rotation.mul(frameRotation)

// TODO: add frame translation

// set opengl matrix
GLXX.setMatrix(transform)

/**
 * Gets frame rotation given translation vector
 */
private Matrix getFrameRotation(Point a, Point b) {
   Vector ab = b - a;

   // rotate around the side axis wich is perpendicular to the forward and up vectors
   Vector axis = cross(ab, UP)

   // amount of rotation depends on the distance traveled and ball radius
   double angle = ab.length() / (2 * PI * radius)

   return matrixRotatedUsingAxisAngle (angke, axis);
}

@kapta
Thanks, but unless I’m totally misunderstanding something, doesn’t your example just push the matrix once more without changing anything otherwise? ???

@tom
Thanks! I’ll see if I can translate that into compilable code.

Maybe you need to use quaternations to get your rotations right. They are merily a different notation which allows for easier combination of rotations. The Ogre guys have a primer on this: http://www.ogre3d.org/wiki/index.php/Quaternion_and_Rotation_Primer. There should be code java available somewhere as well… just google.

Thanks for that, cylab.
Quarternations did come up during my googling. I was hoping there was an easy solution to my problem, but I guess just have to bite the bullet and learn to use those quarterthings :).

it separates the rotations, so the first rotation does not affect the second, have you given it a try?

It helps if you’ve got a vecmath lib when doing this kind of things. The LWJGL vector package is a bit too simplistic. Java3d got a good vecmath.jar that can be used.
Javadoc: http://java.sun.com/products/java-media/3D/forDevelopers/J3D_1_3_API/j3dapi/index.html.
download: https://java3d.dev.java.net/binary-builds.html (inside the zip binaries)

Quaternions and matrices can both be used to represent roatations, and they both do pretty much the same job. Since you need to send a matrix to oengl, you might as well use it all the way.

[quote]it separates the rotations, so the first rotation does not affect the second, have you given it a try?
[/quote]
As a sanity check, I just tried it but there was indeed no change.
My understanding of pushing and popping the matrix is that glPushMatrix simply pushes the matrix on the stack and glPopMatrix restores it (pops it off the stack) again, so glPushMatrix doesn’t affect the state of the current matrix. Your example simply stores the matrix once more but makes no difference otherwise; the second rotation is still affected by the first one.

@tom
Thanks again, that might indeed be useful.