Sign in to follow this  
spiffycrony

Directx projection matrix

Recommended Posts

spiffycrony    122
I am trying to find if the point clicked on the screen using the mouse, fall on the mesh body rendered using directx8(and vb). The points of the mesh nodes are in 3d which i have rendered using directx's draw primitives. The picked point is the 2d mouse point. I will have to convert the 3d(node's coordinates) points into the screen coordinates and check if the picked point falls on the mesh. My understanding is that i will have to get the projection matrix and multiply it with the 3d point i am interested to get its corresponding 2d screen coordinate. Is this correct? Can somebody suggest how to do this?

Share this post


Link to post
Share on other sites
Programmer101    199
You could render your mesh as a D3DXMesh and just use the D3DXIntersect function. Here is an example of how to use that function:

BOOL ClickMesh(int mousex,int mousey)
{
HRESULT hr;
D3DXVECTOR3 vPickRayDir;
D3DXVECTOR3 vPickRayOrig;

D3DXMATRIXA16 matProj;
g_pD3DDevice->GetTransform( D3DTS_PROJECTION, &matProj );

// Compute the vector of the pick ray in screen space
D3DXVECTOR3 v;
v.x = ( ( ( 2.0f * mousex ) / 350 ) - 1 ) / matProj._11;
v.y = -( ( ( 2.0f * mousey ) / 255 ) - 1 ) / matProj._22;
v.z = 1.0f;

// Get the inverse view matrix
D3DXMATRIXA16 matView, m;
D3DXMatrixRotationX(&matRotX, XAngle);
D3DXMatrixRotationY(&matRotY, YAngle);
D3DXMatrixRotationZ(&matRotZ, ZAngle);
D3DXMatrixTranslation(&matTrans, XPos, YPos, ZPos);
D3DXMatrixIdentity(&m);

D3DXMatrixMultiply(&m, &m, &matRotZ);
D3DXMatrixMultiply(&m, &m, &matRotY);
D3DXMatrixMultiply(&m, &m, &matRotX);
D3DXMatrixMultiply(&m, &m, &matTrans);

// 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;

BOOL Hit;
int i =0;
float hitdist=-1.0f,Dist,u,vr;
DWORD Face;
D3DXVECTOR3 vto, vtd;

vto.x = vPickRayOrig.x-meshXPos;
vto.y = vPickRayOrig.y-meshYPos;
vto.z = vPickRayOrig.z-meshZPos;

D3DXIntersect(theMesh, &vto, &vPickRayDir, &Hit, &Face, &u, &vr, &Dist, NULL, NULL);

return Hit;
}

Share this post


Link to post
Share on other sites
TheAdmiral    1122
The easiest way would be to unproject the point from screen-space to world-space (D3DXVec3Unproject).

In fact, if you do this twice, supplying the near- and far-clipping z-values, you will generate two points in world-space that define the line-segment corresponding to the ray constrained to the viewing frustum. From here, a ray-mesh intersection test (as described by Programmer101) will do the business.

The whole process is known as 'picking', if you want to do some Googling.

Admiral

Share this post


Link to post
Share on other sites
MasterWorks    496
Quote:
Original post by spiffycrony
Is there a method to convert from 3d to 2d points?

There's another thread right next to yours asking the same question. Use D3DXVec3Project, although as others have mentioned this may not be the best way to do picking.

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