Directx projection matrix

Started by
3 comments, last by MasterWorks 17 years, 1 month ago
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?
Advertisement
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;}
Is there a method to convert from 3d to 2d points?
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
Ring3 Circus - Diary of a programmer, journal of a hacker.
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.

This topic is closed to new replies.

Advertisement