3D Compass

Started by
5 comments, last by SAE Superman 17 years, 6 months ago
I have a 3D compass (always pointing north) that I want to have on my HUD (upper right corner of the screen). What's the best way to get this? Would it be better to figure out coordinates in world space to always have it in front of the camera at a certain spot, or would it be better to draw in in ortho mode (but then how do I get it to alway point north). I've tried both of these ways and here's the problem I'm having with each. Finding world space coordinates other than right in front of the camera is hard for me. Maybe I just don't know the math... This way it always points north as I want, but it's not positioned right. I can position the compass in the upper right corner easily in ortho mode but then I lose all the rotations and I have to figure out the rotation to point it north. Again, maybe I just don't know the math... So which way is better? Thanks in advance!
Advertisement
You could just disable the depth test and switch to another perspective mode that maps more closely to your screen.
Would it help to save the model view matrix and extract the rotations somehow and then load that matrix after I do my ortho mode?

I see this in games all the time (but they usually point to a waypoint or objective)... This is for a flying game I'm doing...

Ravuya - how would I switch to a persp mode that more closely matches my screen? And I don't care about depth testing as I'll be in the air the majority of the time...

Thanks!
So here's what I'm doing for the compass part of my hud:

    glMatrixMode(GL_PROJECTION);            // Select Projection    glPushMatrix();                         // Push The Matrix    glLoadIdentity();                       // Reset The Matrix    glOrtho( -m_iWindowWidth/2, m_iWindowWidth/2, -m_iWindowHeight/2, m_iWindowHeight/2, -100, 100 );    // Select Ortho Mode    glMatrixMode(GL_MODELVIEW);             // Select Modelview Matrix    glPushMatrix();                         // Push The Matrix    glLoadIdentity();                       // Reset The Matrix    glTranslatef(m_iWindowWidth/2 - 50,m_iWindowHeight/2 - 50,-3.0f);    m_pCompass->Render();    glMatrixMode( GL_PROJECTION );      // Select Projection    glPopMatrix();                      // Pop The Matrix    glMatrixMode( GL_MODELVIEW );       // Select Modelview    glPopMatrix();                      // Pop The Matrix


This puts the compass arrow in the right spot, but it loses all rotations. I can't figure out how to get it rotated to always point north. Maybe this should have been in the graphics and math theory forums...
Well, assuming the compass's render method is not doing any rotation, it seems to me that putting a glRotate3f(0,0,bearing) in after the glTranslate(...) might be what you're after. (Disclaimer: the axis and sign of the rotate, and order of transformations, may be wrong as I haven't done any GL stuff for ages.)
To get the compass in 3D coords, try this:

You have the Camera position [x,y,z] and the Camera's direction vectors. If you don't keep the direction vectors (it helps a LOT), you can compute them from your Camera's rotation (I won't describe it here) without much difficulty. I always recompute them each time the Camera's rotation changes.

Once you know those vectors, positioning the compass in 3D space is easy. For instance, if you want it in the upper-right corner of the screen d distance in front of the camera, you can simply say:

Compass.position = Camera.position + Camera.rightVec + Camera.upVec + Camera.frontVec*d;

The frontVec is scaled by d to move the compass d distance directly in front of you, then you simply add the up and right vectors to get it to the upper-right corner, and add the camera's 3D position and viola, it is positioned in world space and is always in the upper right corner of your screen.

Having said all that, it is probably more intuitive to just use screen space coords, since it is a HUD object, not a game object. That way, you can position it on the screen, instead of in the world. Making it always point north shouldn't be a problem, though. Just apply a rotation in the opposite direction as your camera. For instance, if your camera is facing north, the compass points straight ahead. As the camera rotates left, the compass should rotate right with the same angle, so that when the Camera is facing south, the compass is facing straight back.

Sounds like a cool HUD object to have. Good luck making it work!
- Enosch
Thanks for the input Enosch! I have tried both of those ways you mentioned and they work good except when my pitch gets close to -90 or 90 degrees...then it doesn't look right (it looks like it's always pointing straight instead of north).

The problem with the first method you mentioned is kind of the same thing. When my pitch is close to -90 or 90 degrees, the compass goes to the center and doesn't stay at the upper right (I'm guessing because of the camera forward vector).

Thanks for the help guys, I'm getting closer!

This topic is closed to new replies.

Advertisement