Jump to content
  • Advertisement
Sign in to follow this  
BS-er

when targeting reticles move off-screen

This topic is 3893 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Its pretty easy to calculate X Y screen coordinates to place a 2D reticle given world X Y Z coordinates: Multiply projection matrix by (view matrix multiplied by position), and the X and Y of the result are your X and Y screen coordinates (zero centered). However I'm struggling with the target position being off-screen especially directly left, right, above or below the camera. I'd like to have a reticle on the edge of the window consistent with the target's off-screen relative position. However its quite jumpy, and irregular. I'm convinced that there is an appropriate calculation because I've seen it done quite well in games. Would anyone happen to know the magic formula?

Share this post


Link to post
Share on other sites
Advertisement
Mmm, the best way to do this is find the position of the object in view space. Then project onto the xy-plane (assuming you look down the z-axis in view space). You can then create a vector in view space from the origin to the projected position. In screen space use this same vector from the center of the screen to find the intersection with the edge of the screen using cohen sutherland clipping or some other sort of clipping.

Share this post


Link to post
Share on other sites
Thanks a bunch for the tip. You lit a spark and sent me off in the right direction when you mentioned intersection with the edge.

I didn't need to mess with a clipping algorithm though, although its good to know about it now. The following approach works nicely :).


Vector3 EyeSpacePos = mCamera->getViewMatrix(true) * Position;
Vector3 ScreenSpacePos = mCamera->getProjectionMatrix() * EyeSpacePos;

x = ScreenSpacePos.x;
y = ScreenSpacePos.y;
float abs_x = fabs(x);
float abs_y = fabs(y);

// check if not in the forward or backward view frustum
if ((abs_x > 1) || (abs_y > 1))
{
if (abs_x > abs_y)
{
// abs_x is greater, so its either the left or right edge
x = (ScreenSpacePos.x > 0)? 1.0 : -1.0;
y = ScreenSpacePos.y / abs_x;
}
else
{
// abs_y is greater, so its either the top or bottom edge
y = (ScreenSpacePos.y > 0)? 1.0 : -1.0;
x = ScreenSpacePos.x / abs_y;
}
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!