Screen space to world space

Posted by user13414 on Game Development See other posts from Game Development or by user13414
Published on 2012-03-24T18:21:18Z Indexed on 2012/03/25 11:42 UTC
Read the original article Hit count: 483

Filed under:
|
|

I am writing a 2D game where my game world has x axis running left to right, y axis running top to bottom, and z axis out of the screen:

enter image description here

Whilst my game world is top-down, the game is rendered on a slight tilt:

enter image description here

I'm working on projecting from world space to screen space, and vice-versa. I have the former working as follows:

var viewport = new Viewport(0, 0, this.ScreenWidth, this.ScreenHeight);
var screenPoint = viewport.Project(worldPoint.NegateY(), this.ProjectionMatrix, this.ViewMatrix, this.WorldMatrix);

The NegateY() extension method does exactly what it sounds like, since XNA's y axis runs bottom to top instead of top to bottom. The screenshot above shows this all working. Basically, I have a bunch of points in 3D space that I then render in screen space. I can modify camera properties in real time and see it animate to the new position. Obviously my actual game will use sprites rather than points and the camera position will be fixed, but I'm just trying to get all the math in place before getting to that.

Now, I am trying to convert back the other way. That is, given an x and y point in screen space above, determine the corresponding point in world space. So if I point the cursor at, say, the bottom-left of the green trapezoid, I want to get a world space reading of (0, 480). The z coordinate is irrelevant. Or, rather, the z coordinate will always be zero when mapping back to world space. Essentially, I want to implement this method signature:

public Vector2 ScreenPointToWorld(Vector2 point)

I've tried several things to get this working but am just having no luck. My latest thinking is that I need to call Viewport.Unproject twice with differing near/far z values, calculate the resultant Ray, normalize it, then calculate the intersection of the Ray with a Plane that basically represents ground-level of my world. However, I got stuck on the last step and wasn't sure whether I was over-complicating things.

Can anyone point me in the right direction on how to achieve this?

© Game Development or respective owner

Related posts about XNA

Related posts about c#