×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Clicking a 3D object in-game

Clicking a 3D object in-game

Clicking a 3D object in-game

(OP)
I'm attempting to be able to "target" a 3D object in-game.  For example, let's say my game is a 3D field with a moose standing in it.  When I click the moose with my mouse (no pun intended), I want the game to realize that he has been selected and show "A Moose" in a part of the game's interface.  I'm not worried about the interface, I just cannot figure out how to take 2-dimensional mouse coordinates and decide whether an object is clicked in a 3-dimensional world.  Obviously the distance from the object greatly affects the way it is selected, because the farther you are from the object, the smaller it is, and ultimately you have a smaller "hotspot", so to speak.  I attempted this myself and it went very poorly.  I could turn away from the moose and click anywhere on the screen and it would detect that I'd clicked the moose.  This is because of the mouse coordinates.  It doesn't matter which direction you're facing, the coordinates will always be the same. Here is how I presume it could be done, but I'm not sure, so I'm asking for assistance:

CODE

'This is not a language, just easier to explain!

'This is how far the moose is
   DistanceFromMoose = Moose.Z - Me.Z;

'This is how much space is on each side of the moose
'Just to make sure I can actually see him on my screen
   BlankScreenRight = (Screen.Width - Moose.X) + Moose.Width;
   BlankScreenLeft = Screen.Width - Moose.X;

'I know these are wrong.. my head hurts :(
   HotSpotWidth = Moose.Width \ DistanceFromMoose;
   HotSpotHeight = Moose.Height \ DistanceFromMoose;
   HotSpotY = Screen.Height - DistanceFromMoose;

'Try to see if we've clicked him
   if (Me.X >= (Moose.X - BlankScreenLeft) and Me.X <= (Moose.X + BlackScreenRight)) {
      if (ClickX >= Moose.X and ClickX <= (Moose.X + HotSpotWidth) and ClickY >= HotSpotY and ClickY <= (HotSpotY + HotSpotHeight)) {
         'The moose was clicked
      }
   }
Now I know the code above is probably way off, but this is why I need your help :)  Anyone?

RE: Clicking a 3D object in-game

(OP)
Now that I'm re-reading my post, the code to make sure the moose is on the screen won't work :\

RE: Clicking a 3D object in-game

This is why 3D graphics is much easier when you know the math behind it :).  If you're up for a challenge and really want to learn the math, write a simple ray tracer.  I had to for a class assignment once, and I learned a lot from it.

Anyway, if your moose is a D3DXMesh, you can look in the Pick sample in the DX SDK and see an example of how this is done.  Picking objects is so much easier in OpenGL than D3D; I don't know why they don't provide any better implementation.  In OGL you could do this without too much hassle, in maybe 30 lines of code, but as you will see, it takes about 150 lines to get it to work here.

RE: Clicking a 3D object in-game

Indeed the pick example is the one you should look at.
I would like to add to that that the concept of the
"ray trace" is simple: you determine a line from the
camera to the point where the mouse click is (transformed
to the 3d world) and check for every triangle of the
moose if there is an intersection. However, the
implementation is complicated. You have to have
at least a notion of what object space, world space,
view space and projection space is and how the
corresponding matrices in the render pipeline transform
from one to the other. For example, see how in the Pick
function of the pick example the pick ray is determined from the mouse position:

    // Get the pick ray from the mouse position
    if( GetCapture() )
    {
        D3DXMATRIX matProj;
        m_pd3dDevice->GetTransform(
                        D3DTS_PROJECTION, &matProj );

        POINT ptCursor;
        GetCursorPos( &ptCursor );
        ScreenToClient( m_hWnd, &ptCursor );

        // Compute the vector of the pick
        // ray in screen space
        D3DXVECTOR3 v;
        v.x =  ( ( ( 2.0f * ptCursor.x ) /
           m_d3dsdBackBuffer.Width  ) - 1 ) / matProj._11;
        v.y = -( ( ( 2.0f * ptCursor.y ) /
           m_d3dsdBackBuffer.Height ) - 1 ) / matProj._22;
        v.z =  1.0f;

        // Get the inverse view matrix
        D3DXMATRIX matView, m;
        m_pd3dDevice->GetTransform( D3DTS_VIEW, &matView );
        D3DXMatrixInverse( &m, NULL, &matView );

        // Transform the screen space pick ray
        // into 3D space
        vPickRayDir.x  = v.x*m._11 + v.y*m._21 + v.z*m._31;
        vPickRayDir.y  = v.x*m._12 + v.y*m._22 + v.z*m._32;
        vPickRayDir.z  = v.x*m._13 + v.y*m._23 + v.z*m._33;
        vPickRayOrig.x = m._41;
        vPickRayOrig.y = m._42;
        vPickRayOrig.z = m._43;
    }


I use this but must say I do not fully understand it.....
Can someone clarify this? I am interested too.....

The part hereafter is more straightforward and
understandable (the checking if the ray intersected with
a triangle of the object). See the example.

RE: Clicking a 3D object in-game

This code takes the point where you click and creates a vector starting at the camera position and going in the direction you clicked, with the center of the screen corresponding to the vector [0, 0, 1]. It then transforms the vector into view coordinates by taking the view matrix and multiplying by the vector.  After this code, the vector starts at the camera position and points in the direction clicked.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close