HUD Indicator Arrows

Started by
4 comments, last by Hidden Asbestos 16 years, 7 months ago
I am trying to get indicating arrows to work in my HUD. So when an enemy ( or object of interest) is off screen, it will show an arrow on the edge of the screen closest to him indicating which direction to turn to see him. I am having some trouble trying to get this to work correctly. I have searched around this site and tried googling many different terms. I am not really sure what to search for really. In any case, I am not really getting anywhere with searching. I have tried some ideas already; none of them worked out all that well. Obviously just projecting and testing if it is on screen or not is not going to work. I have tried some stuff with vectors, but it seems like it just doesn't work out correctly. Do any of you have ideas on how to get this to work?
Advertisement
Quote:Original post by Lexdysic
Do any of you have ideas on how to get this to work?
Here is how I would proceed:

1. Transform the position of the target object into the player's local space (you can do this by transforming the position vector by the inverse of the model matrix associated with the player - which, I'm guessing, is also your view matrix).

2. Compute an appropriate direction and location for the HUD arrow from the local-space coordinates of the target.

The rest depends on how you want the arrow to behave. Is this essentially a 2-d environment (e.g. a tank simulator), or a 3-d environment (e.g. a space combat game)? Should the arrow just point in one of the cardinal directions (left/right and maybe down/up), or should it be radial (that is, it can point in any direction)? Should the arrow only appear when the target is off screen? Or should it always be visible?

Whatever behavior you're after, you should be able to compute any and all necessary information from the local-space coordinates of the target and the view parameters (field of view and aspect ratio). If you need more specific advice, perhaps you could provide answers to some of the above questions so that we have a better idea of what you're trying to do.
The game is a 3D space shooter. The camera is not directly attached to the player, but this should not matter. The arrow would have direction, its not important however. Its more important that the angle from the center of the screen to the "point on the edge" be in the same direction of the object of interest. I suppose it doesn't really matter what the "point on the edge" is. It could be the edge of the screen / viewport or a circle centered in the screen / viewport.

So, I guess I am a little confused on one issue still. After I transform into viewspace, I assume I would essentially project the point or line onto the z-plane to get the angle (use dot products or the like). Would this value be off from everything else that goes through the perspective projection?

Hi, sorry if this mostly overlaps what you've done already, but what I'd do is take the point in world space P (e.g. the centre of the enemy ship) and copy into a 4D vector with a W component of 1. Then transform it by the 4x4 World -> View transform and then the 4x4 View -> Projection transform.

From this you have a point in projection space. To get this into screen space you take P and divide the x,y and z components by w. Lets call this S.

You can check this is working by drawing a cross (or something) in 2D at these screen co-ordinates ( screen space is from +/- 1 around the screen centre so we need to do some scaling to get it into pixels ):

x = ( +( S.x ) * 0.5f + 0.5f ) * m_view_width + m_view_x;
y = ( -( S.y ) * 0.5f + 0.5f ) * m_view_height + m_view_y;

So, now you have this point S you can take the Z component and use this to determine if the point is in front or behind the view. The range of this value will either be 0 - 1 or -1 to 1 depending on whether you're using DirectX or OpenGL -- you'll have to experiment with this, I'd just colour the cross from above red or green based on the in front or behind check.

If your point is in front, then ignore it -- the ship is visible so you don't need a HUD pip to point you at it! For points behind though you now have a pair of X/Y values in S that will tell you where behind you the enemy is. We'll call this 2D vector R to make things clear.

Now if you want pips that hug the edge of the screen like FreeSpace etc. you need to take this point R and extend it to the screen edge. This can be done in several ways (remember that your values for R.x and R.y are +/- 1).

A dumb one I just made up (sorry if this bit doesn't work) is to determine which is the largest (absolute) value of the two components x or y, then take the sign of the component to work out the direction. From this you can work out the screen edge that the pip should sit on - then explicitly set either x or y to -1 or +1. Before you do that you need to work out where on this line your pip should lie and that should be equal to X/Y or Y/X depending on which is the major axis.

Then using the same expressions above you get the edge point in pixels:

x = ( +( R.x ) * 0.5f + 0.5f ) * m_view_width + m_view_x;
y = ( -( R.y ) * 0.5f + 0.5f ) * m_view_height + m_view_y;


I hope that helps?

[Edited by - Hidden Asbestos on October 2, 2007 8:58:33 AM]
Hey Hidden Asbestos, yes this is the first method I mentioned. It principle it seems like it would work. I just don't think this is always the case. If a point is outside of the view frustum, when you project, it will not always stay in a predictable place. For instance, if a point is behind the eye before projection, it will end up in front of the eye after projection. Yes, it will not be with in the NDC frame that you mentioned, I am just afraid that it will not be in any useful position for this.

I think I will try jyk's method and see where I can get with that. It seems pretty promising.
Good point, I forgot about the region in front of the Z=0 plane and outside the frustum ... I'll be honest and say I've never tried to do this before, I have done software projections for my HUD but only simply. I wonder why my method doesn't look right then? oh well, good luck!

This topic is closed to new replies.

Advertisement