Skip to main content
gamedev.net
🔒 Locked

D3DXIntersect Question

Started by dave May 2, 2004 at 8:42 AM 1 replies 500+ views
Original Post
dave
dave
I have a 7x7x7 block of cube meshes and want to have the mouse be able to select the one under the cursor. I have searched the forum and im still not completely clear on how to do this. - I know where the Camera is positioned and is facing. - I know the offset from the origin to which i have translated each of the cubes in the 7x7x7 block. - I am aware of the functionality of the D3DXIntersect function. - When ever the mouse button is pressed i loop through all 343 cubes using the D3DXIntersect function, checking the bHit return variable for true. I can then act upon the trueness. - I have tried some of the various explanations of how to transform the vPickOrig and vPickFacing vectors to allow for the translation of the cubes (and camera?). None of them seem to affect the selection process. These involved subtracting the position of each mesh and the camera from the vPickOrig and vPickFacing vectors. I won''t include my code cos it aint a syntax problem, i kinda need to know the principles behind how this works. I do get the picking registering in certain areas of the screen but not in others, and the areas are kinda always close to the cube meshes so i have a feeling i''m not far off. Can anyone please help me on this matter. If ya need some of my code i will post later. regards, ace
Trip99
Trip99
Hi, ok I have a few minutes, this is how I do it:

I have mouse x and y positions as mx and my, to create the ray position and direction:

You need to translate the mouse position so it is the position in the world as if a ray is cast from your eye through the screen, so we need to take the projection matrix (matProj) and the backbuffer sizes into account (w and h):

// Compute the vector of the pick ray in screen space
D3DXVECTOR3 v;
v.x = ( ( ( 2.0f * sx ) / w ) - 1 ) / matProj._11;
v.y = -( ( ( 2.0f * sy ) / h ) - 1 ) / matProj._22;
v.z = 1.0f;

// Get the inverse view matrix
D3DXMATRIX matView;
m_camera->GetViewMatrix(matView);
D3DXMatrixInverse( &matView, NULL, &matView );

// Transform the screen space pick ray into 3D space
rayDir->x = v.x*m._11 + v.y*m._21 + v.z*m._31;
rayDir->y = v.x*m._12 + v.y*m._22 + v.z*m._32;
rayDir->z = v.x*m._13 + v.y*m._23 + v.z*m._33;
rayOrigin->x = m._41;
rayOrigin->y = m._42;
rayOrigin->z = m._43;

Ok now you have the pick ray position and direction. Note: I do not include the world matrix in my calculation as this is specific to each object being tested and so I apply that later. Remember D3DXIntersect works in the object space not world space hence the conversion is required.

So when I come to test I loop through all my objects checking for a collision and remember the closest one (that is not negative distance) and that will be the hit.

So we need a fn that given an object with a mesh and a world position will return the distance to a collision with it (if there is one).

We now need to transform the ray into the objects space, something like this (matWorld is objects world matrix):


// Use inverse of matrix
D3DXMATRIXA16 matInverse;
D3DXMatrixInverse(&matInverse,NULL,&matWorld);

// Transform ray origin and direction by inv matrix
D3DXVECTOR3 rayObjOrigin,rayObjDirection;

D3DXVec3TransformCoord(&rayObjOrigin,&rayOrigin,&matInverse);
D3DXVec3TransformNormal&rayObjDirection,&rayDirection,&matInverse);
D3DXVec3Normalize(&rayObjDirection,&rayObjDirection);

Right, nearly there. The next step is to actually call the intersect:

BOOL hasHit;
DWORD dwFace;
FLOAT fBary1, fBary2;

D3DXIntersect(m_mesh, &rayOrigin, &rayDirection, &hasHit, NULL, NULL, NULL, distanceToCollision, NULL, NULL);

and thats it - works perfectly. Bare in mind that you would probably want to do some bounding box intersects first to speed things up. Hope this helps









------------------------See my games programming site at: www.toymaker.info
dave
dave
Thanx for the help that is ace!

regards, ace

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.