• Advertisement
Sign in to follow this  

ray picking

This topic is 4320 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