Sign in to follow this  

Directx 10 3D Objects to screen coords.

Recommended Posts

Fargo    100

I would like to program to use the cursor to click on a 3D object and know that It clicked on it..Im using DirectX 10.. Is there a DX function to do this ? I have not had much luck searching for this on the web.. It might be I cant describe what Im trying ot do in the search.

I can find where my cursor is no problem as I use my own class with a quad for my cursor.. just need to figure out 3D objects to screen coord I guess. A nudge in the right direction will be greatly appeciated.. Im using C++

Share this post

Link to post
Share on other sites
iedoc    2525
If you haven't found what your looking for yet, you might want to use the intersect method of the mesh interface (ID3DX10Mesh->Intersect()).

First you will need to transform the screen space (x,y) coordinate that you picked with the mouse to Projection space by doing something like this:

[code]D3DXVECTOR3 pickRayProjectionSpace;
pickRayProjectionSpace.x = ((( 2.0f * mouseX) / ClientWidth ) - 1 ) / Projection(0,0);
pickRayProjectionSpace.y = -((( 2.0f * mouseY) / ClientHeight) - 1 ) / Projection(1,1);
pickRayProjectionSpace.z = 1.0f;

D3DXVECTOR3 pickRayProjectionSpacePos(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 pickRayProjectionSpaceDir(pickRayProjectionSpace.x, pickRayProjectionSpace.y, pickRayProjectionSpace.z);[/code]

Now that you have a 3d pick ray in projection space, you'll need to get it into world space by transforming it with the inverse of the view space matrix. something like this:

[code]D3DXMATRIX pickRayWorldSpace; // This will hold the inverse of the view matrix (which is the world space matrix (the cameras position and orientation and stuff in world space))
D3DXMatrixInverse(&pickRayWorldSpace, 0, &View); // Your view space matrix (basically your camera's matrix)

// Pick ray in world space
D3DXVec3TransformCoord(&pickRayProjectionSpacePos, &pickRayProjectionSpacePos, &pickRayProjectionSpacePos);
D3DXVec3TransformNormal(&pickRayProjectionSpaceDir, &pickRayProjectionSpaceDir, &pickRayProjectionSpaceDir);[/code]

Now that we have the pick ray in world space, we need to transform it into each objects space, by looping through each object we want to check for an intersection with the pick ray, and by multiplying the pick ray by the inverse of each objects world space matrix. All the above stuff only needs to be done once per click, but the next stuff needs to be done once for every object you want to check for picking with.

[code]D3DXMATRIX pickRayLocalSpace;

// ObjectLocalSpace is a matrix that defines the object position, orientation and size in world space. [i] is because it's an array of matrices so that you can easily loop through all the world matrices of each object in the scene

D3DXVECTOR3 pickRayLocalSpacePos,pickRayLocalSpaceDir;

// Transform the world space pick ray into the objects space

Now that we have the pick ray in object space, you need to check to see if the ray intersected with the mesh. To do this, you can use an handy function (if you are using the ID3DXMesh interface for the objects in your scene):

[code]UINT numHits = 0;
float hitDistance;
meshes[1]->Intersect(&pickRayLocalSpacePos, &pickRayLocalSpaceDir, &numHits, 0, 0, 0, &hitDistance, 0);[/code]

numHits is the number of times the object was intersected by the ray. if this is "0" (zero), then the ray missed the object. hitDistance is the distance from the origin of the ray (the camera's position in this case) to the first intersection with the object.

I took this information pretty much straight from my lesson on picking in direct3d 10:

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