Jump to content
  • Advertisement
Sign in to follow this  

Picking Ray without D3DXIntersect

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

I have a series of vertex buffers and I am trying to do a picking ray so I can select one of these vertex buffers. Is there an alternative solution to using D3DXIntersect?

Share this post

Link to post
Share on other sites
I assume you're concerned with the speed of picking.

If so, and if the data from which you create the meshes is available ( in a memory array ) you can write your own pick routine which will likely be faster. If not, and you have to lock each vertex buffer to access the data, it may be difficult to write a faster routine.

If the mesh shapes are very complex, you can create a simpler mesh for each complex mesh and pick those at faster speed. That might narrow down which meshes to run through the D3DXIntersect method. If a simple mesh gets hit, shoot the corresponding complex mesh.

If your only consideration is knowing which mesh gets picked and not which face is hit or the distance to the hit, it's almost certain you can write a faster routine or, at least, narrow down which meshes need to be tested further (perhaps with D3DXIntersect). That would save some time.

Store data for the bounding boxes of each mesh and use a formula for the intersection of a vector (the pick ray) and a cube (the bounding box for the mesh). If the ray doesn't intersect the bounding box, no need to shoot that mesh.

If the ray always comes from the same direction (say, you're only interested in what's below a position so the pick ray is always ( 0, -1, 0 ) ), the bounding box test becomes trivial.

Share this post

Link to post
Share on other sites
I do not want to pick meshes though, I want to pick be able to pick a vertex buffer (basically a triangle fan that is being drawn). Here is what I do to render it:

IDirect3DVertexDeclaration9 *m_vdVertexDecl;
IDirect3DTexture9 *m_tSquareTexture;
IDirect3DVertexBuffer9 *m_vbSquareBuff;

struct sWallVertex
float size;
D3DCOLOR color;

lpD3DDevice->SetTexture(0, m_tSquareTexture);

lpD3DDevice->SetStreamSource(0, m_vbSquareBuff, 0, sizeof(sWallVertex));
lpD3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 4);

Share this post

Link to post
Share on other sites
You mentioned an alternative to D3DXIntersect, which is for meshes, so I read "mesh" where you clearly said "vertex buffer."

I believe you'll have to write your own pick routine for your VBs. The bounding box method will get you a start and you can follow up with a more precise pick routine if you need to know which face, etc., for a VB that's hit.

Share this post

Link to post
Share on other sites
The two examples on Direct X SDK don't even compile (Pick and Tutorial 04). I wrote a little bit of code to do the picking and I know the actual picking is correct but I am not sure how to check the intersection.

void CPickingRay::Pick(CWall *pShade, BOOL &phit)
CMouse *pMouse = CMouse::GetInstance();
int nMouseX = pMouse->GetMouseX();
int nMouseY = pMouse->GetMouseY();
tRay ray;
D3DXMATRIX matView, matWorld, matInverse, tempPick;
CalculatePickingRay(&ray, nMouseX, nMouseY);

CDirect3D::GetInstance()->GetDirect3DDevice()->GetTransform(D3DTS_VIEW, &matView);
matWorld = *D3DXMatrixIdentity(&tempPick);
matWorld._41 = pShade->GetXLocation();
matWorld._42 = pShade->GetYLocation();
matWorld._43 = pShade->GetZLocation();
matWorld *= matView;

D3DXMatrixInverse(&matInverse, 0, &matWorld);
TransformRay(&ray, &ray, &matInverse);

// If the x is inbetween the sides (not a good way to do this).
if(ray.vDirection.x > -matInverse._41 + matView._41)
if(ray.vDirection.x < matInverse._41 + pShade->GetWidth())
int a = 0;

void CPickingRay::TransformRay(tRay *pRayOut, tRay *pRayIn, D3DXMATRIX *pMat)
if(!pRayIn || !pMat)

D3DXVec3TransformCoord(&pRayOut->vPosition, &pRayIn->vPosition, pMat);

D3DXVec3TransformNormal(&pRayOut->vDirection, &pRayIn->vDirection, pMat);

D3DXVec3Normalize(&pRayOut->vDirection, &pRayOut->vDirection);

void CPickingRay::CalculatePickingRay(tRay *pRayOut, long lX, long lY)
LPDIRECT3DDEVICE9 pD3Dev = CDirect3D::GetInstance()->GetDirect3DDevice();

pD3Dev->GetTransform(D3DTS_PROJECTION, &matProj);
pRayOut->vPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f);

float pX, pY;
pX = (((2.0f * lX) / vp.Width) - 1.0f) / matProj(0, 0);
pY = (((-2.0f * lY) / vp.Height) + 1.0f) / matProj(1, 1);

pRayOut->vDirection = D3DXVECTOR3(pX, pY, 1.0f);

Share this post

Link to post
Share on other sites
I was thinking that since what I am trying to do might not be possible, maybe get my four vertices and make it seem like a mesh. Is this possible?

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!