Archived

This topic is now archived and is closed to further replies.

ktuluorion

Map Coord picking in 3d

Recommended Posts

I created a map made up of squares a la RollerCoaster Tycoon with DirectXGraphics. It is in 3d, and the tiles are made up of tiled meshes. The tiles are all of equal size, just as in any isometric game, with different heights created by simply stacking them on top of each other for different heights. Basically what i need to do is find a way to figure out what block the mouse cursor is on top of. I have the world matrix rotated so that the world is being looked down upon at a 45 degree angle. I''m not really sure about how to go about this, transforming 2d coords to 3d coords, in addition to figuring out how to take into consideration the rotation. Any ideas/tutorials I could look at on this?

Share this post


Link to post
Share on other sites

If you work with OpenGL try reading the "selection and picking" of the OpenGL Programming Guide (Red Book). For 3d to 2d coordinates transformation use gluProject.

I hope this helps you,

c_gatzman

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
Try the "Pick" sample in the DirectX SDK.

Jim



Here''s the thing: I''m just redrawing the same mesh over and over again to make several squares. So thats not exactly what I need. What I need to know is what map coords match up to the boxes I need.

Share this post


Link to post
Share on other sites
ktuluorion-

I would suggest you take another look at the "pick" example in the SDK.

All you need to use is:
D3DXIntersectTri

For all cells in the map
Figure out the 4 corners/points for that cell (a, b, c ,d)
Call D3DXIntersectTri twice passing in
1. a, b, c
2. b, c, d

If either of these two calls returns true, your user just clicked on that cell.

Share this post


Link to post
Share on other sites
quote:
Original post by Doolwind
ktuluorion-

I would suggest you take another look at the "pick" example in the SDK.

All you need to use is:
D3DXIntersectTri

For all cells in the map
Figure out the 4 corners/points for that cell (a, b, c ,d)
Call D3DXIntersectTri twice passing in
1. a, b, c
2. b, c, d

If either of these two calls returns true, your user just clicked on that cell.



OK now I see what you are saying. I''ll check it out once I get to work, but it sounds about right. Thanks a lot! I was thinking of it in the wrong way. The only problem I can think of is the fact that that may be taxing on the cpu, but I could probably narrow that down to a general area in some way.

Thx!

Share this post


Link to post
Share on other sites
quote:
Original post by ktuluorion
The only problem I can think of is the fact that that may be taxing on the cpu, but I could probably narrow that down to a general area in some way.



Nah, it shouldn''t be an issue, if it is however you just need to use some algorithm to cut down how you search for the square.

A simple way would be a binary search. Get the entire map, split it in half and test each half (the user must have clicked somewhere in either one). Whichever half D3DXIntersectTri returns true for, break that half into half again and test it etc etc until you get down to a small enough square to see exactly where they clicked, that should seriously reduce the number of D3DXIntersectTri calls you make.

However you shouldn''t need to worry about it, just depends how lightening fast you need your code to be, and seeing as it is only run when the user clicks the button, not every frame, it isn''t THAT much of an issue.

Doolwind

Share this post


Link to post
Share on other sites
quote:
Original post by Doolwind
[quote]Original post by ktuluorion
The only problem I can think of is the fact that that may be taxing on the cpu, but I could probably narrow that down to a general area in some way.



Nah, it shouldn''t be an issue, if it is however you just need to use some algorithm to cut down how you search for the square.

A simple way would be a binary search. Get the entire map, split it in half and test each half (the user must have clicked somewhere in either one). Whichever half D3DXIntersectTri returns true for, break that half into half again and test it etc etc until you get down to a small enough square to see exactly where they clicked, that should seriously reduce the number of D3DXIntersectTri calls you make.

However you shouldn''t need to worry about it, just depends how lightening fast you need your code to be, and seeing as it is only run when the user clicks the button, not every frame, it isn''t THAT much of an issue.

Doolwind

It actually IS run every frame


Share this post


Link to post
Share on other sites
quote:
Original post by ktuluorion
Basically what i need to do is find a way to figure out what block the mouse cursor is on top of.




Sorry I didn''t read the post exactly . I was thinking you would be doing this whenever you clicked the button.

Anyway, just try it out the simplest way and you can always optimize later (with the binary search). I would not be suprised however if it runs just fine checking every cell every frame.

Doolwind

Share this post


Link to post
Share on other sites
quote:
Original post by Doolwind
[quote]Original post by ktuluorion
Basically what i need to do is find a way to figure out what block the mouse cursor is on top of.




Sorry I didn''t read the post exactly . I was thinking you would be doing this whenever you clicked the button.

Anyway, just try it out the simplest way and you can always optimize later (with the binary search). I would not be suprised however if it runs just fine checking every cell every frame.

Doolwind


The only thing is that function doesn''t exist. There is one called D3DXIntersect, but it works on Meshes, and that won''t work.

Share this post


Link to post
Share on other sites
quote:
Original post by ktuluorion
[quote]Original post by Doolwind
[quote]Original post by ktuluorion
Basically what i need to do is find a way to figure out what block the mouse cursor is on top of.




Sorry I didn''t read the post exactly . I was thinking you would be doing this whenever you clicked the button.

Anyway, just try it out the simplest way and you can always optimize later (with the binary search). I would not be suprised however if it runs just fine checking every cell every frame.

Doolwind


The only thing is that function doesn''t exist. There is one called D3DXIntersect, but it works on Meshes, and that won''t work.

OK, the function DOES exist, just its in DX 8.1. I''m running 8.0. on this machine. Time to upgrade

Share this post


Link to post
Share on other sites
Yeah sorry I didn''t specify that I was using 8.1. Tell me how it goes, I am currently checking every cell and so far I have tested with 250x250 cells and everything runs perfectly.

Doolwind

Share this post


Link to post
Share on other sites
quote:
Original post by Doolwind
Yeah sorry I didn''t specify that I was using 8.1. Tell me how it goes, I am currently checking every cell and so far I have tested with 250x250 cells and everything runs perfectly.

Doolwind


Great! Thanks for all your help! I''m going to try to get it in tonight and see how it works. The only thing I am unsure of is how I should set the position and direction variables for the call. I need to figure out some way to convert the coords on the screen to something in the 3d space. Shouldn''t be that big of a deal though.

-Mike

Share this post


Link to post
Share on other sites
ktuluorion-

I just stole that code straight from the SDK "picking" example. I literally cut the code and pasted it and only changed the bits to the actual D3DXIntersectTri call, where I looped through all the cells passing in the coordinates of each cell.

If you have any troubles, when I get home from work I can put up the code I used for mine if that would help at all.

Doolwind

Share this post


Link to post
Share on other sites