Sign in to follow this  
durban

D3DXIntersect() problem

Recommended Posts

I'm simply trying to be able to pick an object with the mouse and change its render properties when its clicked. Problem : The results aren't correct, the mesh seems to be moved over. When I click the mesh nothing happens, however, if I click in the region that D3DXIntersect "thinks" the mesh is, I get the proper result. Anyone see a problem in this code? : Pick() - returns true if the user clicked the mesh :
bool CPick::Pick( LPDIRECT3DDEVICE9 device, LPD3DXMESH mesh, D3DXMATRIX matProj, D3DXMATRIX matView, HWND hWnd )
{
	D3DXVECTOR3 vecRay, vecDir, v;
	D3DXMATRIX m;

	D3DXMatrixInverse(&m, NULL, &matView);

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

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

	vecRay.x = m._41;
	vecRay.y = m._42;
	vecRay.z = m._43;
	vecDir.x = v.x*m._11 + v.y*m._21 + v.z*m._31;
	vecDir.y = v.x*m._12 + v.y*m._22 + v.z*m._32;
	vecDir.z = v.x*m._13 + v.y*m._23 + v.z*m._33;


	BOOL Hit;
	DWORD Face;
	float u, w, Dist;

	D3DXIntersect(mesh, &vecRay, &vecDir, &Hit, &Face, &u, &w, &Dist, NULL, NULL);
	
	if( Hit )
		return true;
	else
		return false;
}
Code Snippet from the Render() function where the call to Pick() is made :
if(drawMesh == TRUE )
{
	sMesh* temp = m_CObj->GetStartPtr();
	HWND hwnd;
	if( hwnd = GetCapture())
	{
		do
		{
			if( m_CPick->Pick( _device, temp->_mesh, matProj, matView, hwnd))
			{
				temp->bHit = TRUE;
				MessageBox(GetMainWndHandle(), "bHit=TRUE", "",MB_OK);
				break;
			}
			temp = temp->Next;
		}while( temp->Next != NULL );
			
		temp = m_CObj->GetStartPtr();
	}

	do
	{
		if( temp->bHit == TRUE )
		{
			_device->SetMaterial(&temp->_materials[0]);
			_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
			_device->SetRenderState(D3DRS_AMBIENT, 0x00FF00FF);
			temp->_mesh->DrawSubset(0);
			_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
			_device->SetRenderState(D3DRS_AMBIENT, 0x00000000);
		}
		else
		{
			for( DWORD i=0; i<temp->_numMaterials; i++)
			{
				_device->SetMaterial(&temp->_materials[i]);
				_device->SetTexture(0, temp->_textures[i]);

				temp->_mesh->DrawSubset(i);
			}
		}
		temp = temp->Next;
	}while( temp->Next != NULL );

	temp = m_CObj->GetStartPtr();			
}
The World/View/Projection matrices were defined earlier in the Render() function* I will appreciate any help/comments given, Thanks in advance

Share this post


Link to post
Share on other sites
You must transform your ray into the model space of your mesh. Typically, this is done by taking the inverse of the world matrix you use to position your model. Transform your ray's position and direction by this inverse matrix and you should be able to perform your ray-intersection test without a problem.

neneboricua

Share this post


Link to post
Share on other sites
It's still shifted after I did that. I'm using 4 different windows to show each perspective of the mesh with swap chains but that shouldn't matter since I'm passing the window's world/view/proj matrices to the function right? Here's the code I added:


D3DXMatrixInverse(&world, NULL, &matWorld);

D3DXVec3TransformCoord( &vecRay, &vecRay, &world );
D3DXVec3TransformCoord( &vecDir, &vecDir, &world );


I noticed that where D3DXIntersect thinks the mesh is, is actually a reflection of the mesh on the -y axis. I'm still stumped, any ideas?

Share this post


Link to post
Share on other sites
You need to transform the starting point of the ray using D3DXVec3TransformCoord, but the ray direction should be transformed using D3DXVec3TransformNormal. The reason for this is that each function assumes a different value for the "w" component of the vector.

neneboricua

Share this post


Link to post
Share on other sites
Quote:
Original post by neneboricua19
You need to transform the starting point of the ray using D3DXVec3TransformCoord, but the ray direction should be transformed using D3DXVec3TransformNormal. The reason for this is that each function assumes a different value for the "w" component of the vector.

neneboricua


Great, it works like a charm now. After doing what you said I noticed where D3DXIntersect thought the mesh was, was actually the mesh reflected upon the -y axis. so I simply changed

v.y = (((2.0f * ptCursor.y) / 300) - 1) / matProj._22;
to
v.y = -(((2.0f * ptCursor.y) / 300) - 1) / matProj._22;

Thanks alot for the help man :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this