Sign in to follow this  
leggyguy

Implementing Ortho Radar

Recommended Posts

I want to implement a radar, but I am struggling on how to get each bitmap drawn in the right position. Another thread mentioned this calculation:
        float x = radar.centre.x;
        float y = radar.centre.y;

        CVector3 Offset = Enemy.Position - Player.Position;

	float cos_angle = (Offset.x * Player.Direction.x + Offset.z * Player.zDirection.z);
	float sin_angle = (Offset.x * Player.Direction.z - Offset.z * Player.Direction.x);
	float angle = atan2(sin_angle, cos_angle);
	float altitude_diff = Offset.y;
Ok, this tells me an angle, but how do I then use that within Ortho mode to draw my little bitmap in the right position? Anyone able to tell me? I would appreciate the help.

Share this post


Link to post
Share on other sites
translate(-playerPosition.x, 0, -playerPosition.z )
rotate(-playerViewAngle, 0.0, 1.0, 0.0)
drawPlayer(PlayerPos)
drawEnemy(EnemyPos)

I think it's as simple as this.

this is the second behaviour, that is described in jyk's post.
Read jyk's post
||
\/

[Edited by - Kwak on April 30, 2006 8:30:52 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by leggyguy
I want to implement a radar, but I am struggling on how to get each bitmap drawn in the right position.

Another thread mentioned this calculation:


float x = radar.centre.x;
float y = radar.centre.y;

CVector3 Offset = Enemy.Position - Player.Position;

float cos_angle = (Offset.x * Player.Direction.x + Offset.z * Player.zDirection.z);
float sin_angle = (Offset.x * Player.Direction.z - Offset.z * Player.Direction.x);
float angle = atan2(sin_angle, cos_angle);
float altitude_diff = Offset.y;


Ok, this tells me an angle, but how do I then use that within Ortho mode to draw my little bitmap in the right position?

Anyone able to tell me? I would appreciate the help.
The angle itself isn't necessarily important, per se. What is of more interest is the target position expressed in the proper frame of reference.

What sort of behavior do you want? I can think of a couple of kinds:

1. Player proxy in center of radar rotates to represent orientation; target objects don't rotate around player
2. Player proxy in center of radar maintains fixed orientation (perhaps pointing up); target objects rotate around player

Are you after one of these? Or something else?

Share this post


Link to post
Share on other sites
I am after:

Player is always the centre of the radar. Not interested in height of enemy, just its x and z position.

If the player is directly ahead of the player, the dot appears above the player's position on the radar. So yes, the 2nd option.

So, Kwak, I use those rotation and translation commands in Ortho mode? Because using glRotate seems to screw everything up.


jyk, do you have a technique to implement the 2nd method you mentioned?

Share this post


Link to post
Share on other sites
Eh no!
I made a terrible mistake, it should be:

rotate(-playerViewAngle, 0.0, 1.0, 0.0)
translate(-playerPosition.x, 0, -playerPosition.z )
drawPlayer(PlayerPos)
drawEnemy(EnemyPos)

i always get confused with the rotate and translate order :S

[Edited by - Kwak on April 30, 2006 8:54:16 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by leggyguy
jyk, do you have a technique to implement the 2nd method you mentioned?
Kwak may have already given you a working solution (I didn't look at it too carefully), but here's how I'd do it.

1. Transform target position into player local space

This requires at minimum a little linear algebra, specifically having the player matrix, inverse matrix, or basis vectors and position available. Could also be simplified in a 2d-ish context such as an FPS or tank game.

2. Map resulting coordinates to 'radar space'

First discard the height component (if it's not of interest) to get 2D coordinates. Also discard coordinates outside of the maximum radar range. Then, map the remaining coordinates from the range [-max_radar_range, max_radar_range] to [-screen_radar_radius, screen_radar_radius] using some simple algebra. This gives you the coordinates with respect to a radar display of the appropriate size, but centered at the origin. Note that you may also need to map between different axes; for example, if +z is forward for your character, but you want that to be +y in radar space.

3. Add the radar onscreen origin to the coordinates to position them correctly onscreen.

If that seems complicated, I suppose it might be a little; you might be able to get similar results more easily with a few OpenGL commands (perhaps Kwak's method). However, for various reasons I'd probably still do it the above way.

Share this post


Link to post
Share on other sites
Ok, well thansk for the replies.

I can do the first method, whereby the objects do not rotate around the player on the radar, without complex algebra. Simply rotate a sprite at the center of the radar to represent the player's facing direction.


It's not what I had imagined, but it works well enough.

Another option I had would be to simply calculate the distance between each opponent and the player, and list them in a text box, the same way Microsoft's Freelancer does it (a space game similar to my project). Both of these are much simpler to implement by the sound of it.

Or perhaps I could render it to a texture the same way as my first method, and then rotate the texture by the player's facing, which would give my initial effect, but would involve a rendering to a texture every frame, which isn't very efficient.



And Kwak, the second I use glRotatef in Ortho mode, the next sprite I draw never actually works, I have no idea why.

Share this post


Link to post
Share on other sites
This is really not my day. I still wasn't right about the code.
It should be translate(-playerPosition.x, 0, -playerPosition.z ) since height is y axis. Sorry about that.

float playerViewAngle = atan2(-Player.Direction.x, -Player.Direction.z);

-|
/ |
\/ |
----------------------> X
|
| playerViewAngle = 0 if looking along negative z-axis
| playerViewAngle goes counterclockwise
v
Z

loadidentity(modelview)
rotate(-playerViewAngle*360/(2*pi), 0.0, 1.0, 0.0)
translate(-playerPosition.x, 0, -playerPosition.z )
drawPlayer(PlayerPos)
for all enemies
{
drawEnemy(EnemyPos)
}




Hope this helps.

[Edited by - Kwak on May 1, 2006 8:02:35 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this