Original Post
Hello guys! I've got a huge problem! I'm new to DirectX9 and i have to implement some code to pick meshes with mouse in my program. I thought it was pretty easy (as it was in opengl) but... it just doesnt work as it was supposed to. That's what i'm doing: - I call ScreenToClient to get client relative mouse coords - I compute the ray origin and dir - I check if the ray is colliding with every visible object in my scene - To do this i trasform the ray to local object coordinates to use with D3DXIntersect! Well... it just doesnt work. My objects are just translated (not rotated, yet)... but it doent seem to work even if everything is at 0,0,0! (well, sometimes works if they are at 0,0,0) I really dont know what to think :( That's my code: [Edited by - Coder on December 27, 2004 12:35:48 PM]
// That's the function that computes ray origin and direction
void GetRayAtCursor(int iWidth, int iHeight, int xPos, int yPos, D3DXVECTOR3 &vPickOrigin, D3DXVECTOR3 &vPickDir)
{
// Adapted from DX9SDK
// Get the pick ray from the mouse position
D3DXMATRIXA16 matProj = gDirectGFX.m_matProjection;
// Compute the vector of the pick ray in screen space
D3DXVECTOR3 v;
v.x = ( ( ( 2.0f * xPos ) / iWidth ) - 1 ) / matProj._11;
v.y = -( ( ( 2.0f * yPos ) / iHeight ) - 1 ) / matProj._22;
v.z = 1.0f;
// Get the inverse view matrix
D3DXMATRIXA16 m;
D3DXMatrixInverse( &m, NULL, &gFreeCamera.m_matView );
// Transform the screen space pick ray into 3D space
vPickDir.x = v.x*m._11 + v.y*m._21 + v.z*m._31;
vPickDir.y = v.x*m._12 + v.y*m._22 + v.z*m._32;
vPickDir.z = v.x*m._13 + v.y*m._23 + v.z*m._33;
vPickOrigin.x = m._41;
vPickOrigin.y = m._42;
vPickOrigin.z = m._43;
D3DXVec3Normalize(&vPickDir, &vPickDir);
}
// That's the function which checks if object is being hit!
// m_matState is the matrix holding the trasformation for this
// object (just translation for now)
bool CBaseObject::IsHit(const D3DXVECTOR3 &vRayOrigin, const D3DXVECTOR3 &vRayDir, float &fDist)
{
// -> Get model rendered by this BaseObject instance
CD3DFile *pMeshFile = gMeshPool.GetMesh(m_pszName);
if(!pMeshFile)
return false;
BOOL bHit;
DWORD dwFace;
FLOAT fBary1, fBary2;
LPD3DXBASEMESH pMesh = NULL;
SENUMRESULT enumResult = { NULL, NULL };
D3DXVECTOR3 vRayOriginT, vRayDirT;
D3DXMATRIX matInverse;
// -> Convert our raydir/rayorigin into modelspace
D3DXMatrixInverse(&matInverse, NULL, &m_matState);
D3DXVec3TransformCoord(&vRayOriginT, &vRayOrigin, &matInverse);
D3DXVec3TransformNormal(&vRayDirT, &vRayDir, &matInverse);
// -> Which mesh is that X file using?
pMeshFile->EnumMeshes(EnumMeshesCB, &enumResult);
pMesh = ((CD3DMesh*)enumResult.m_pMeshAddress)->GetLocalMesh();
if(!pMesh)
return false;
// -> Real intersection
if(FAILED(D3DXIntersect(pMesh, &vRayOriginT, &vRayDirT, &bHit, &dwFace, &fBary1, &fBary2, &fDist, NULL, NULL)))
return false;
if(fDist > gDirectGFX.m_fFarPlane)
return false;
return (bool)bHit;
}