• Create Account

## Getting Intersected Triangle

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

11 replies to this topic

### #1Medo3337  Members

891
Like
0Likes
Like

Posted 26 January 2013 - 07:58 AM

I'm triangle to use raycasting to get the intersected triangle, here is the code that I'm using:

LPD3DXMESH pMesh = GetMesh();
pMesh->CloneMeshFVF( D3DXMESH_MANAGED, pMesh->GetFVF(), d3ddev, &pMesh );

LPDIRECT3DVERTEXBUFFER9 pVB;
LPDIRECT3DINDEXBUFFER9 pIB;

pMesh->GetVertexBuffer( &pVB );
pMesh->GetIndexBuffer( &pIB );

WORD* pIndices;
D3DVERTEX* pVertices;

// Lock
pIB->Lock( 0, 0, ( void** )&pIndices, 0 );
pVB->Lock( 0, 0, ( void** )&pVertices, 0 );

BOOL pHit;
DWORD pFaceIndex;
FLOAT pU, pV, pDist;
D3DXIntersect(pMesh, &rayFrom, &rayTo, &pHit, &pFaceIndex, &pU, &pV, &pDist, NULL, NULL);
if (pHit)
{
DWORD dwNumFaces = pMesh->GetNumFaces();
for(DWORD i = 0; i < dwNumFaces; i++)
{
D3DXVECTOR3 v0 = pVertices[pIndices[3 * i + 0]].p;
D3DXVECTOR3 v1 = pVertices[pIndices[3 * i + 1]].p;
D3DXVECTOR3 v2 = pVertices[pIndices[3 * i + 2]].p;

if ( D3DXIntersectTri(&v0, &v1, &v2, &rayFrom, &rayTo, &pU, &pV, &pDist) )
{
// Intersected triangle found
}
}
}

// Unlock
pMesh->UnlockVertexBuffer();
pMesh->UnlockIndexBuffer();

Why the above code doesn't work as expected?
I'm not getting a valid intersected triangle in (v0, v1, v2).

### #2eppo  Members

4601
Like
0Likes
Like

Posted 27 January 2013 - 04:20 AM

Is 'pHit' ever true? What is the HRESULT of D3DXIntersect()?

Have you checked the validity of the data behind two Lock()-pointers? If you assign the indices to a WORD, the buffer should be created as a 16 bit buffer.

Also, I don't see why you would test all faces individually once D3DXIntersect() has determined an intersection.

### #3Medo3337  Members

891
Like
0Likes
Like

Posted 27 January 2013 - 07:36 AM

Is 'pHit' ever true? What is the HRESULT of D3DXIntersect()?

I'm getting intersected triangle in (v0, v1, v2) but it's invalid, D3DXIntersect() HRESULT is S_OK.

Have you checked the validity of the data behind two Lock()-pointers? If you assign the indices to a WORD, the buffer should be created as a 16 bit buffer.

I tried using byte* instead of WORD*, same problem.

Also, I don't see why you would test all faces individually once D3DXIntersect() has determined an intersection.

I use break; after working on the intersection:

if ( D3DXIntersectTri(&v0, &v1, &v2, &rayFrom, &rayTo, &pU, &pV, &pDist) )
{
// Process intersection...
break;
}


### #4Postie  Members

1459
Like
1Likes
Like

Posted 27 January 2013 - 09:02 AM

You've called the 3rd parameter passed to D3DXIntersect, "rayTo", which worries me slightly. The 3rd parameter is actually the direction of the ray, which is a vector, not a point in space. If rayTo is actually a point, you'll need to pass in (rayTo - rayFrom).

Also, you shouldn't need to scan through the faces after the initial test, the output value in pFaceIndex should contain the index of the face hit, if D3DXIntersect returns a hit.

Currently working on an open world survival RPG - For info check out my Development blog:

### #5Medo3337  Members

891
Like
0Likes
Like

Posted 27 January 2013 - 11:12 AM

@Postie:

First, I use bullet physics raycasting to check for intersection, then I use D3DXIntersect() to get the intersected triangle, rayFrom and rayTo are D3DXVECTOR3 that I use with bullet physics raycasting.

I changed the code to something like this:

LPD3DXMESH pMesh = GetMesh();
pMesh->CloneMeshFVF( D3DXMESH_MANAGED, pMesh->GetFVF(), d3ddev, &pMesh );

WORD* pIndices;
D3DVERTEX* pVertices;

BOOL pHit;
DWORD pFaceIndex;
FLOAT pU, pV, pDist;
HRESULT hr = D3DXIntersect(pMesh, &rayFrom, &rayTo, &pHit, &pFaceIndex, &pU, &pV, &pDist, NULL, NULL);
assert(hr == S_OK);
if (pHit)
{
D3DXVECTOR3 v0 = pVertices[pIndices[3 * pFaceIndex + 0]].p;
D3DXVECTOR3 v1 = pVertices[pIndices[3 * pFaceIndex + 1]].p;
D3DXVECTOR3 v2 = pVertices[pIndices[3 * pFaceIndex + 2]].p;
}

pMesh->UnlockVertexBuffer();
pMesh->UnlockIndexBuffer();


Anything wrong with the above code?

### #6Medo3337  Members

891
Like
0Likes
Like

Posted 29 January 2013 - 04:33 PM

UP! Any help would be appreciated, I'm still having this problem.

### #7L. Spiro  Members

24842
Like
2Likes
Like

Posted 29 January 2013 - 05:22 PM

@Postie:

First, I use bullet physics raycasting to check for intersection, then I use D3DXIntersect() to get the intersected triangle, rayFrom and rayTo are D3DXVECTOR3 that I use with bullet physics raycasting.

You didn’t address the issue he mentioned at all, and doing so would have likely solved your problem by now.
You are passing a starting point for the ray and an ending point for the ray when you are supposed to be passing a starting point and a direction.
D3DXIntersect() doesn’t care if the same ray points work in Bullet. Justifying passing incorrect parameters by saying, “But it works in Bullet,” is not going to convince DirectX to start working.

Bullet takes a ray start point and a ray end point (which means it is not actually a ray but a line segment).
DirectX D3DXIntersect() takes a ray start point and a ray direction.  As was already pointed out to you.

L. Spiro

### #8Medo3337  Members

891
Like
0Likes
Like

Posted 31 January 2013 - 05:44 AM

@L. Spiro:

So that means I have to pass (rayTo - rayFrom) as a direction.

I tried:

HRESULT hr = D3DXIntersect(pMesh, &rayFrom, &(rayTo - rayFrom), &pHit, &pFaceIndex, &pU, &pV, &pDist, NULL, NULL);
assert(hr == S_OK);
if (pHit)
{
D3DXVECTOR3 v0 = pVertices[pIndices[3 * pFaceIndex + 0]].p;
D3DXVECTOR3 v1 = pVertices[pIndices[3 * pFaceIndex + 1]].p;
D3DXVECTOR3 v2 = pVertices[pIndices[3 * pFaceIndex + 2]].p;
}


Still not getting a valid intersected triangle.

### #9L. Spiro  Members

24842
Like
0Likes
Like

Posted 31 January 2013 - 07:02 AM

I expected as much but I did not want to overload you.

Also you need to normalize the direction vector, which means you should store it in a temporary.  This helps with debugging anyway, which is a skill you need to be a good developer in the first place.

I expect you have yet another problem which is much more complicated to explain.

Are you drawing the target object with a world matrix other than identity?

If so you need to translate the ray into the frame-of-reference of that object (and each object in your scene when you have more than one) before doing the ray cast.

That means translating the ray’s position by the inverse world matrix of each object, and translating the ray’s direction vector by the inverse transpose of the inverse world matrix.

L. Spiro

Edited by L. Spiro, 31 January 2013 - 07:05 AM.

### #10Medo3337  Members

891
Like
0Likes
Like

Posted 01 February 2013 - 06:29 AM

When I switch to Wirefire mode, I notice that I'm getting a valid intersected triangle for the terrain ONLY, but none of the other meshes are getting a valid intersected triangle.

Here is the code that I tried:

// Get ray direction
D3DXVECTOR3 direction = rayTo - rayFrom;
D3DXVec3Normalize(&direction, &direction);

// Inverse matrix
D3DXMATRIX matWorld = mesh->worldMatrix();
D3DXMATRIX matInverse;
D3DXMatrixInverse(&matInverse, NULL, &matWorld);

D3DXVECTOR3 modelRayOrigin, modelRayDir;
D3DXVec3TransformCoord(&modelRayOrigin, &hits.origin, &matInverse);
D3DXVec3TransformNormal(&modelRayDir, &direction, &matInverse);

hr = D3DXIntersect(pMesh, &modelRayOrigin, &modelRayDir, &pHit, &pFaceIndex, &pU, &pV, &pDist, NULL, NULL);
assert(hr == S_OK);

### #11Medo3337  Members

891
Like
0Likes
Like

Posted 04 February 2013 - 06:16 PM

Still unresolved, up.

### #12L. Spiro  Members

24842
Like
0Likes
Like

Posted 04 February 2013 - 06:28 PM

I have never used D3DXIntersect(); it is typically better to do this manually.

Print debug information related to the world location of the object, the world location of the ray (and its direction), and the final ray position/direction after transforming it by the inverse of the world.

Really, from here out it is just a matter of debugging, which means you are on your own. You will have to learn how to debug.

L. Spiro

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.