Math Problem with Rotation

Hi everybody

In my game, the user can look around using the mouse. The mouse position is translated into viewangle_vertical and viewangle_horizontal. I use those variables to compute the correct values for GLULookAt. That works great so far.
(Just to clarify: viewangle_vertical is always between -PI/2 and PI/2)
Now I’d like to have a model at the player location that looks in the same direction as the player does. Similar to a Gun in a Shooter (the gun moves with the player, and always points in the player’s direction).

I already have my Object Loader, so rendering the thing isn’t a problem. Here’s my rendering code: (simplieifed)


glPushMatrix();

glLoadIdentity();
gluLookAt(pos.x, pos.y, pos.z, lookat.x, lookat.y, lookat.z, 0, 1, 0);
		
		glTranslated(x, y, z);
		glRotated(rot_x, 1, 0, 0);
		glRotated(rot_y, 0, 1, 0);
		glRotated(rot_z, 0, 0, 1);
		
		//Actual call to glDrawArrays or similar
		
		glPopMatrix();

I already figured out that
x = X part of Player’s ViewVector
y = Y part of Player’s ViewVector
z = Z part of Player’s ViewVector
rot_y = viewangle_horizontal*RAD2ANG (RAD2ANG = 180.0 / Math.PI)

So as long as viewangle_vertical equals 0, this works perfectly. (My gun stays clearly visible in front of the player, and points away from the player)
If I look up or down, however, the Gun is at the correct position, but isn’t rotated correctly (well, rot_x and rot_z = 0, so this isn’t surprising)

I tried setting


rot_x = Math.abs(Math.cos(viewangle_horizontal))*180;
rot_z = Math.abs(Math.sin(viewangle_horizontal))*180;

But this turns out VERY bad, the gun just flings aroundwith no clear pattern (I have no idea ;( )

Can you guys give me some pointers to a tutorial that deals with this kind of math?

Thanks

You can just display the gun not in world coordinats, reset the view matrix and place the gun directly in front of your view.
Perhaps you also want to reset the depthbuffer before rendering your gun so it won’t intersect with world geometrie

That sounds like a great idea.

There are two things that I’d like to know:

  1. How exactly do you render something “not in world coordinates”? Is there some gl* command that tells OpenGL to go to player coordinates?
  2. How would this work in multiplayer? Say I have 3 people running around, I have to draw 3 guns facing away from each player. In the case of multiplayer I can’t just use my view - is there a way to go to a point P, set the view towards another point V, then render the gun with respect to the view, and then go back again?

Thanks for the help :wink:

EDIT: If this healps: I use JOGL.

Everything you draw is relative to the camera looking down the Z axis through the origin. When you apply the camera transform, you’re moving everything to where it should be based on the camera’s assumed position and orientation (even though it never really moves).

Since the gun is going to superimpose over the rest of the world, you’re probably going to want to draw it last (then you can avoid having to depth-test against it). To draw something always in front of the camera, simply undo the camera transform by either applying its inverse or loading identity or otherwise restoring the pre-camera coordinate system.

In multiplayer you can just draw other players’ model with their equipped weapon like you would any other model. It’s just the first-person view that doesn’t need the full player model, just the gun (and probably a more detailed pair of hands).

Ah, I got it working. Indeed, all I needed was


glLoadIdentity();

glEnableClientState(GL.GL_POINTS); 
glPointSize(25);
		  
glBegin(GL.GL_POINTS);	  //Instead of POINTS render an object here
glVertex3d(0, 0, -1);  
glEnd();

glDisableClientState(GL.GL_POINTS); 

(The code is just if someone later finds this thread and would like a copy-paste solution)

Thanks again!