Jump to content
  • Advertisement
Sign in to follow this  

ray picking

This topic is 4443 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all Directx9 c++ I have exhausted all possibilities of to this solution to solve it but i can not. Im simply trying to detect if the mouse has clicked on an object. The entire pick code is shown below:
HRESULT Engine::Pick(LPDIRECT3DDEVICE9 g_pd3dDevice)
    HRESULT hr;
    D3DXVECTOR3 vPickRayDir;
    D3DXVECTOR3 vPickRayOrig;
	D3DXMATRIX m_inv, ma;
	D3DXVECTOR3 v1_tr, v2_tr;
	D3DXVECTOR3 vLocalRayOrig;
	D3DXVECTOR3 vLocalRayDir;
	D3DXVECTOR3 rayObjOrigin,rayObjDirection;

    // Get the pick ray from the mouse position
    if( GetCapture() )

		D3DVIEWPORT9 m_mainViewport; 
		g_pd3dDevice->GetViewport( &m_mainViewport );
        D3DXMATRIX matProj;
        g_pd3dDevice->GetTransform( D3DTS_PROJECTION, &matProj );

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

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

		D3DXMATRIX matView, m, WorldMatrix, inv_WorldMatrix, matWorldView;
		D3DXVECTOR3 rayOrigin,rayDir;
		g_pd3dDevice->GetTransform( D3DTS_VIEW, &matView );
		D3DXMatrixInverse( &m, NULL, &matView );

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

		// Use inverse of matrix
		D3DXMATRIX matInverse, matWorld;
		g_pd3dDevice->GetTransform( D3DTS_WORLD, &matWorld );


		LPD3DXBASEMESH          pMesh = pDial[0].pModel->GetMesh();

        BOOL bHit;
        FLOAT fDist;
        D3DXIntersect(pMesh, &rayObjOrigin, &rayObjDirection, &bHit, NULL, NULL, NULL, &fDist, 
            NULL, NULL);
        if( bHit )
			int test = 6;
    return S_OK;
Pick is called in the render method, does it matter where it is called from? e.g HRESULT hr = Pick(g_pd3dDevice); ALso should the matrix for matView and world etc be specific to each mesh or is it in general termsn from the device? e.g g_pd3dDevice->GetTransform( D3DTS_WORLD, &matWorld ); The meshes themselves are created in a mesh class and controlled by another class. In this class the meshes are positioned via.
void Slider::Render(LPDIRECT3DDEVICE9 g_pd3dDevice)
	D3DXMATRIXA16 matWorld, matMove;
	D3DXMatrixTranslation(&matMove, getPosition().x, getPosition().y, getPosition().z);
	D3DXMatrixRotationY( &matWorld, getRotation().y);
	D3DXMatrixMultiply(&matWorld, &matWorld, &matMove);
	g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
Sorry for waffling but i just want to make sure ive given enough information for some help because i am COMPLETELY stuck. Thank you Stuart EDIT: Please remember to use [source] and [code] tags... [Edited by - jollyjeffers on May 21, 2006 2:02:34 PM]

Share this post

Link to post
Share on other sites

I have dug up some code from long ago that I used for ray-picking. I can't vouch for if it still works:

D3DXMATRIXA16 matProj;
POINT ptCursor;
D3DXMATRIXA16 matView, matWorld, m;

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

// Compute the vector of the pick ray in screen space
m_pd3dDevice->GetTransform( D3DTS_PROJECTION, &matProj );

v.x = ( ( ( 2.0f * ptCursor.x ) / m_dwRealWidth ) - 1 ) / matProj._11;
v.y = -( ( ( 2.0f * ptCursor.y ) / m_dwRealHeight ) - 1 ) / matProj._22;
v.z = 1.0f;

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

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

// calc origin as intersection with near frustum

And here is how I used that info to intersect:

if((D3DXIntersectTri(&vc0,&vc1,&vc2,&m_vRayPos,&m_vRayDir,NULL,NULL,&c)) == TRUE)
return true;

Now, I believe all of the above assumes everything is in world space.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!