Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


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.

  • You cannot reply to this topic
11 replies to this topic

#1 Medo3337   Members   -  Reputation: 671

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).


Sponsor:

#2 eppo   Crossbones+   -  Reputation: 2508

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.



#3 Medo3337   Members   -  Reputation: 671

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


#4 Postie   Members   -  Reputation: 1045

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: ByteWrangler

#5 Medo3337   Members   -  Reputation: 671

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;
pMesh->LockVertexBuffer(D3DLOCK_READONLY, (void**)&pVertices);
pMesh->LockIndexBuffer(D3DLOCK_READONLY, (void**)&pIndices);

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?



#6 Medo3337   Members   -  Reputation: 671

Like
0Likes
Like

Posted 29 January 2013 - 04:33 PM

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



#7 L. Spiro   Crossbones+   -  Reputation: 13958

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


It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#8 Medo3337   Members   -  Reputation: 671

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.



#9 L. Spiro   Crossbones+   -  Reputation: 13958

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.

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#10 Medo3337   Members   -  Reputation: 671

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


#11 Medo3337   Members   -  Reputation: 671

Like
0Likes
Like

Posted 04 February 2013 - 06:16 PM

Still unresolved, up.



#12 L. Spiro   Crossbones+   -  Reputation: 13958

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
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums




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.



PARTNERS