Sign in to follow this  
ankhd

Should I use the D3DXVec3Unproject 2 times to get a ray for theD3DXIntersectTri func

Recommended Posts

Hey all, well still doing damn ray inersections, well the mesh intersect now works good and I thought I would try one with triangles so I looked it up, set one up fine, should work no,??????? Now the question is, is it how I create my ray this is how its done Call D3DXVec3Unproject two times, once with MouseX,MouseY,0 and MouseX,MouseY,1. This returns you two points in 3d space which form a ray. Use that ray to do intersection tests.
		rt = D3DXVec3Unproject(&tempdir,//rayDir,//D3DXVECTOR3 *pOut,
							&vmouse,//CONST D3DXVECTOR3 *pV,
							ViewPort,//CONST D3DVIEWPORT9 *pViewport,
							matProj,//CONST D3DXMATRIX *pProjection,
							matView,//CONST D3DXMATRIX *pView,
							pWorld);//CONST D3DXMATRIX *pWorld

		if(rt == NULL)
		{
			
			return false;
		}


	

	
		vmouse.z = 1;//ViewPort->MaxZ;//0.99f;

	


		rt = D3DXVec3Unproject(&RayPos,//rayOrigin,//D3DXVECTOR3 *pOut,
				       &vmouse,//CONST D3DXVECTOR3 *pV,
								ViewPort,//CONST D3DVIEWPORT9 *pViewport,
		matProj,//CONST D3DXMATRIX *pProjection,
		matView,//CONST D3DXMATRIX *pView,
		pWorld);//CONST D3DXMATRIX *pWorld

		if(rt == NULL)
		{
			
			return false;//error
		}


RayDir = tempdir - RayPos;

//OK THATS THE RAY CREATED

		//ok lock the vertex buffer and get the positions of the verties for the first triangle
		//fill the vertex buffers 
		COLUM_VERTEX *pvertices = NULL;
		if(FAILED(VBuff->Lock(0, 0, (void**)&pvertices, 0 ) ) )
			return false;
   

		short *indexdata = NULL;
		if(FAILED(IBuff->Lock(0,0, (void**)&indexdata,0)))
		{
			VBuff->Unlock();
			MessageBeep(MB_OK);
			return false;//error
		}


		//memcpy(indexdata, &indices, sizeof(indices));
			 //indexdata[0] = 0;
			 //indexdata[1] = 1;
			 //indexdata[2] = 3;

			 //indexdata[3] = 3;
			 //indexdata[4] = 1;
			 //indexdata[5] = 2;
			 
		 

		
		p0 = pvertices[indexdata[0]].p;
		p1 = pvertices[indexdata[1]].p;
		p2 = pvertices[indexdata[2]].p;
		//pvertices[1] = vertices[1];
		//pvertices[2] = vertices[2];
		//pvertices[3] = vertices[3];

    
		VBuff->Unlock();
		IBuff->Unlock();


		BOOL val = D3DXIntersectTri(&p0,//const D3DXVECTOR3 *p0,
									&p1,//const D3DXVECTOR3 *p1,
									&p2,//const D3DXVECTOR3 *p2,
	&RayPos,
	&RayDir,
									&u,//FLOAT *pU,
									&v,//FLOAT *pV,
									&dist);//FLOAT *pDist


and here is the triangles vertices V0 = {-1,-1,0} V1 = {-1,1,0} V2 = {1,-1,0} The Rays Position = {-0.39046, 0.27304, 0.99310} RayDirection = {0,0,0} it looks like is a ccw triangle could it be the winding order may be it is that I'll look into that now

Share this post


Link to post
Share on other sites
On the whole, your code looks okay, but something's clearly amiss: (0, 0, 0) isn't a valid ray direction. Are you sure vmouse.z is being initialised to 0 before the first unprojection?

Also, according to MSDN, D3DXVec3Unproject isn't allowed to return NULL, so that test is redundant.

Admiral

Share this post


Link to post
Share on other sites
I'm not good with C++ but here is my code for VB/MDX, maybe it will help.


Dim vN As Vector3 ' near vector
Dim vF As Vector3 ' far vector
Dim vD As Vector3 ' direction vector
' get near and far vectors by unprojecting mouse
vN = Vector3.Unproject(New Vector3(e.X, e.Y, 0), dev.Viewport, dev.Transform.Projection, dev.Transform.View, dev.Transform.World)
vF = Vector3.Unproject(New Vector3(e.X, e.Y, 1), dev.Viewport, dev.Transform.Projection, dev.Transform.View, dev.Transform.World)
' get direction vector
vD = Vector3.Subtract(vF, vN)
' check for intersection
Dim temphit as IntersectInformation
If Geometry.IntersectTri(v0, v1, v2, vN, vD, temphit) Then
Console.WriteLine(temphit.Dist)
End If




[Edited by - iosys on May 7, 2007 5:29:25 PM]

Share this post


Link to post
Share on other sites
The Ray Direction is zero because the two D3DXVec3Unproject calls return the same value How can this be I set vmouse.z to 0 first and then 1 and it returns the same value whats wrong with it.

Share this post


Link to post
Share on other sites
Quote:
Original post by ankhd
The Ray Direction is zero because the two D3DXVec3Unproject calls return the same value How can this be I set vmouse.z to 0 first and then 1 and it returns the same value whats wrong with it.

What value is being returned? Is it realistic? For example, if the ray being cast is contained on the screen, do the unprojected coordinates reflect this?

I've seen D3DXVec3Unproject fail in the past, and it seems to return nonsense values. This will happen if you pass it an invalid parameter. Trace your code and rigorously check the function arguments: Make sure that the world, view and projection matrices look right - no floating point exceptions in the matrices - and that the viewport has znear < zfar. If the IDirect3DDevice9->GetViewport call succeeds (you are calling it, right?), then it should be fine.

If you're still stuck, show us an example case including values for all the matrices, the viewport and the input & output vectors.

Admiral

Share this post


Link to post
Share on other sites
Hey thanks all,
Here is the out put
ViewPort
Width = 800
Hieght = 600
Maxz = 1.0f
MinZ = 0.0f

ViewPort Checks ok

Projection
_11 = 1.8106600
_22 = 2.4142134
_33 = 1.0101010
_34 = 1.0000000
_43 = 10.101009

all other members = 0.0000000
looks ok to me

View
checks out ok

but the world has large values
World
_11 = 19.696
_12 = -3.4729
-22 = 120.00
_41 = -120.00 //x
_42 = 50.000 //y
_43 = 15.00 //z
_44 = 1.000


vectors
direction = {0.39283931, 0.28449842, 0.99309124}
Pos = {0.39283931, 0.28449842, 0.99309124}
then I do this to get the direction
RayDir = tempdir - RayPos;

this is = 0,0,0
would it have any thing to to with the culling mode
the triangles are ccw I think
p0 = pvertices[indexdata[0]].p;
p1 = pvertices[indexdata[1]].p;
p2 = pvertices[indexdata[2]].p;

Share this post


Link to post
Share on other sites
Vector transformations have nothing to do with culling modes.

But everything there seems to be in order, so we'll need to zoom out a little. Post a bigger sample of code, so that we can see where vmouse is assigned. Also show us where you create the projection matrix.

I'm not sure if it's indicative of a deeper misunderstanding or not, but your variable naming is very confusing:

RayPos and tempdir aren't really the ray's position and direction, but two points along the ray. They'd be better named near_point and far_point or something. This is a little cosmetic, perhaps, but good habits are always wise.

Also, I trust matProj and matView are indeed pointers to matrices, as pWorld is, or it wouldn't compile. You should strive to be more consistent in your notation.

One last thought is to make sure you have the Direct3D debug runtimes enabled. If D3DX is failing for some reason, it would probably let you know in the output window.

Admiral

Share this post


Link to post
Share on other sites
Thanks for your time all, here is the code

void Camera2::getViewMatrix(D3DXMATRIX* V)
{
D3DXMatrixIdentity(V);
// Keep camera's axes orthogonal to eachother
D3DXVec3Normalize(&_look, &_look);

D3DXVec3Cross(&_up, &_look, &_right);
D3DXVec3Normalize(&_up, &_up);

D3DXVec3Cross(&_right, &_up, &_look);
D3DXVec3Normalize(&_right, &_right);

// Build the view matrix:
float x = -D3DXVec3Dot(&_right, &_pos);
float y = -D3DXVec3Dot(&_up, &_pos);
float z = -D3DXVec3Dot(&_look, &_pos);

(*V)(0,0) = _right.x; (*V)(0, 1) = _up.x; (*V)(0, 2) = _look.x; (*V)(0, 3) = 0.0f;
(*V)(1,0) = _right.y; (*V)(1, 1) = _up.y; (*V)(1, 2) = _look.y; (*V)(1, 3) = 0.0f;
(*V)(2,0) = _right.z; (*V)(2, 1) = _up.z; (*V)(2, 2) = _look.z; (*V)(2, 3) = 0.0f;
(*V)(3,0) = x; (*V)(3, 1) = y; (*V)(3, 2) = z; (*V)(3, 3) = 1.0f;

}//end getViewMatrix
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////


Camera->getViewMatrix(&matView);
Device->SetTransform(D3DTS_VIEW, &matView);






// For the projection matrix, we set up a perspective transform (which
// transforms geometry from 3D view space to 2D viewport space, with
// a perspective divide making objects smaller in the distance). To build
// a perpsective transform, we need the field of view (1/4 pi is common),
// the aspect ratio, and the near and far clipping planes (which define at
// what distances geometry should be no longer be rendered).
//D3DXMATRIXA16 matProj;
FLOAT fAspect = (FLOAT)Window.Width / (FLOAT)Window.Height;
D3DXMatrixIdentity(&matProj);
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, fAspect, 1.0f, 10000.0f);
Device->SetTransform( D3DTS_PROJECTION, &matProj );







//-----------------------------------------------------------------------------
//this will do collision for the columns
//-----------------------------------------------------------------------------
void intersect(D3DXMATRIXA16 *World)
{
if(GetCapture() == NULL)
return;//no mouse

POINT ptCursor = {0, 0};
GetCursorPos(&ptCursor );
ScreenToClient(Window.Hwnd, &ptCursor);

bool val = Columns.ColumnInersect(ptCursor.x, ptCursor.y,//the mouse location
&ViewPort,
&matProj,
&matView,
World);


}//end intersect
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////


BOOL ColumnInersect(int x, int y,//the mouse location
D3DVIEWPORT9 *ViewPort,
D3DXMATRIX *matProj,
D3DXMATRIX *matView,
D3DXMATRIX *pWorld)
{

D3DXVECTOR3 p0, p1, p2;
D3DXVECTOR3 RayPos, RayDir;
FLOAT u, v, dist;

//build the ray
//ok we can set the rays locations based on the mouse points
POINT ptCursor = {x, y};


D3DXVECTOR3 *rt = NULL;//returned from call

D3DXVECTOR3 vmouse, tempdir;
vmouse.x = (FLOAT)ptCursor.x;// + GetSystemMetrics(SM_CXSIZEFRAME);
vmouse.y = (FLOAT)ptCursor.y;
vmouse.z = ViewPort->MinZ;//0.001f;//campos->z;



//Call D3DXVec3Unproject two times, once with MouseX,MouseY,0 and MouseX,MouseY,1.
//This returns you two points in 3d space which form a ray. Use that ray to do intersection tests.

rt = D3DXVec3Unproject(&tempdir,//rayDir,//D3DXVECTOR3 *pOut,
&vmouse,//CONST D3DXVECTOR3 *pV,
ViewPort,//CONST D3DVIEWPORT9 *pViewport,
matProj,//CONST D3DXMATRIX *pProjection,
matView,//CONST D3DXMATRIX *pView,
pWorld);//CONST D3DXMATRIX *pWorld

//if(rt == NULL)
//{
// MessageBeep(MB_OK);
// return false;
//}





vmouse.z = 1.0f;//ViewPort->MaxZ;//0.99f;

//Camera->getLook(&vmouse);


rt = D3DXVec3Unproject(&RayPos,//rayOrigin,//D3DXVECTOR3 *pOut,
&vmouse,//CONST D3DXVECTOR3 *pV,
ViewPort,//CONST D3DVIEWPORT9 *pViewport,
matProj,//CONST D3DXMATRIX *pProjection,
matView,//CONST D3DXMATRIX *pView,
pWorld);//CONST D3DXMATRIX *pWorld

//if(rt == NULL)
//{
// MessageBeep(MB_OK);
// return false;//error
//}

//vector_3d acts as a dummy vector here and does nothing
//D3DXVec3Project( &vector_2d, &vector_3d, &d3dvp, &proj_matrix, &view_matrix, &world_matrix );
//vector_2d holds accurate screen coords
//D3DXVec3Unproject( &vector_3d, &vector_2d, &d3dvp, &proj_matrix, &view_matrix, &world_matrix );
//vector_3d holds accurate world (object) coords


//Camera->getPosition(&RayPos);
//Camera->getLook(&tempdir);//_look;

RayDir =RayPos - tempdir ;

//OK THATS THE RAY CREATED

//ok lock the vertex buffer and get the positions of the verties for the first triangle
//fill the vertex buffers
COLUM_VERTEX *pvertices = NULL;
if(FAILED(VBuff->Lock(0, 0, (void**)&pvertices, 0 ) ) )
return false;


short *indexdata = NULL;
if(FAILED(IBuff->Lock(0,0, (void**)&indexdata,0)))
{
VBuff->Unlock();
MessageBeep(MB_OK);
return false;//error
}


//memcpy(indexdata, &indices, sizeof(indices));
//indexdata[0] = 0;
//indexdata[1] = 1;
//indexdata[2] = 3;

//indexdata[3] = 3;
//indexdata[4] = 1;
//indexdata[5] = 2;




p0 = pvertices[indexdata[0]].p;
p1 = pvertices[indexdata[1]].p;
p2 = pvertices[indexdata[2]].p;
//pvertices[1] = vertices[1];
//pvertices[2] = vertices[2];
//pvertices[3] = vertices[3];


VBuff->Unlock();
IBuff->Unlock();

BOOL val = D3DXIntersectTri(&p0,//const D3DXVECTOR3 *p0,
&p1,//const D3DXVECTOR3 *p1,
&p2,//const D3DXVECTOR3 *p2,
&RayPos,
&RayDir,
&u,//FLOAT *pU,
&v,//FLOAT *pV,
&dist);//FLOAT *pDist
//


//BOOL val = IntersectTriangle(RayPos,//const D3DXVECTOR3& orig,
// RayDir,// const D3DXVECTOR3& dir,
// p0,//D3DXVECTOR3& v0,
// p1, p2,// D3DXVECTOR3& v1, D3DXVECTOR3& v2,
// &dist, &u, &v );


if(val == FALSE)
return false;

MessageBox(NULL,"Hello there","Nope it not me", MB_OK);

return true;//it was a hit

}//end ColumnInersect
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////




Share this post


Link to post
Share on other sites
Hey all thanks for all your time I HAVE FOUND THE PROBLEM
it was in the objects world matix scale I had the z sacale to 0 and this did all that hmmm.
Any one know why.

D3DXMatrixScaling(&scale,
20,
120,
0); //Rx


all = (scale * Ry) * trans;

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