Jump to content
  • Advertisement
Sign in to follow this  
stewypeza

D3DXIntersect and pick ray.

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

Hey, This problem is driving me crazy. I have used the code from the Pick example with the directx9 sdk, and put it into my program. I have changed it to fit with my engine but im having a bit of a problem. The ray origin and the direction seem to be created correctly from the mouse. The problem i am having is that D3DXIntersect is only showing a collison when the ray is cast at the origin. This is where the models started but have been translated into their positions. There is only a collison at the origin and never at the actual models position. It is as though the models have not actually moved. Any help will be much appreciated. Stuart P.s I have read similar topics about inversing the ray but i dont know why this would be necessary in this case because the ray produced is correct, its just as tho the models have not actually moved. I am using c++ directX 9.0

Share this post


Link to post
Share on other sites
Advertisement
Sounds like you are not transforming the ray back through the inverse of the world matrix. To get to object space you have to unproject thr ray through projection, view and world. You can only omit one of those if it happens to be the identity

Share this post


Link to post
Share on other sites
"Sounds like you are not transforming the ray back through the inverse of the world matrix."


Do you have any sample code of how to do that. sorry this is new to me and not quite sure how to do it?

Thanks

Share this post


Link to post
Share on other sites
This is my code

HRESULT Engine::Pick()
{
HRESULT hr;
D3DXVECTOR3 vPickRayDir;
D3DXVECTOR3 vPickRayOrig;

m_dwNumIntersections = 0L;

// Get the pick ray from the mouse position
if( GetCapture() )
{
D3DXMATRIXA16 matProj;
g_pd3dDeviceN->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 ) / /*d3dpp.BackBufferWidth*/800 ) - 1 ) / matProj._11;
v.y = -( ( ( 2.0f * ptCursor.y ) / /*d3dpp.BackBufferHeight*/600 ) - 1 ) / matProj._22;
v.z = 1.0f;

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

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

}

D3DXIntersect(pMesh, &vPickRayOrig, &vPickRayDir, &bHit, &dwFace, &fBary1, &fBary2, &fDist,
NULL, NULL);

Share this post


Link to post
Share on other sites
To the issue of transforming the ray back through the inverse of the world matrix. I have altered the code to be shown below but now im not getting any intersections. Any ideas??


D3DXMATRIXA16 matProj;
g_pd3dDeviceN->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 ) / /*d3dpp.BackBufferWidth*/800 ) - 1 ) / matProj._11;
v.y = -( ( ( 2.0f * ptCursor.y ) / /*d3dpp.BackBufferHeight*/600 ) - 1 ) / matProj._22;
v.z = 1.0f;

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

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

D3DXMATRIXA16 m_inv, ma;
D3DXVECTOR3 v1_tr, v2_tr;
g_pd3dDeviceN->SetTransform( D3DTS_WORLD, &ma);
D3DXMatrixInverse( &m_inv, NULL, &ma );
D3DXVec3TransformCoord( &v1_tr, &vPickRayOrig, &m_inv );
D3DXVec3TransformCoord( &v2_tr, &vPickRayDir, &m_inv );

D3DXIntersect(pMesh, &v1_tr, &v2_tr, &bHit, &dwFace, &fBary1, &fBary2, &fDist,
NULL, NULL);

Share this post


Link to post
Share on other sites
You should use D3DXVec3TransformNormal for the direction vector. You don't want it to get translated.

Share this post


Link to post
Share on other sites
Quote:
Original post by stewypeza
"You should use D3DXVec3TransformNormal for the direction vector. You don't want it to get translated."


In what context? Sorry im really new to this and cant quite get my head around it.

Share this post


Link to post
Share on other sites
Vectors have an implied 0 in the 4th component of a D3DXVECTOR3. Points have an implied 1. Since vectors have direction put no position, you don't want them to be translated. Points have position and need to be translated. The books on 3D math explain this better.

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!