Jump to content


Setting a new vector3 location with mouse


4 replies to this topic

#1 Anddos

    Valued Member

  • Members
  • PipPipPip
  • 177 posts

Posted 16 April 2012 - 11:06 AM

What i want todo is set a new target to move to using the mouse, this is for the directx sdk sample , "multianimation" , when it picks a new location to move to it uses this function...
void CTiny::ChooseNewLocation( D3DXVECTOR3* pV )
{

		
		pV->x = ( float )( rand() % 256 ) / 256.f;
		pV->y = 0.f;
		pV->z = ( float )( rand() % 256 ) / 256.f;

}

so instead of using this i want to use my own which is take the mouse 2d point and turn it in to a 3d vector position ...

void CTiny::SetNewClickTarge(D3DXVECTOR3* pV)
{
		GetCursorPos(&point);
		src.x = (int)point.x;
		src.z = (int)point.y;
		DXUTGetD3D9Device()->GetTransform(D3DTS_VIEW,&viw);
		DXUTGetD3D9Device()->GetTransform(D3DTS_PROJECTION,&prj);
		DXUTGetD3D9Device()->GetTransform(D3DTS_WORLD,&wld);


		//D3DXMatrixIdentity(&wld);
		DXUTGetD3D9Device()->GetViewport(&v9);


		D3DXVec3Unproject(&r,&src,&v9,&prj,&viw,&wld);
		pV->x = r.x;
		pV->y = r.y;
		pV->z = r.z;
}
when i run the sample and tick control , and move the mouse around nothing seems to happen?

#2 TheNut

    Senior Member

  • Moderators
  • 1718 posts
  • LocationCyberspace

Posted 16 April 2012 - 03:58 PM

When you unproject your mouse coordinates, you're producing a vector, not a location. The vector is emitting from your camera. Think of an arrow pointing in the direction that particular pixel is looking at. What you need to do now is find a point of intersection in your game world. Typically you would do ray - plane, ray - sphere, ray - box, or ray - triangle tests to find out the exact point of intersection. Take a look at this website for some math routines you can use.
http://www.nutty.ca - Being a nut has its advantages.

#3 Anddos

    Valued Member

  • Members
  • PipPipPip
  • 177 posts

Posted 18 April 2012 - 04:47 AM

what space does my ray need to be in then if the floor transform is like this
V( g_pEffect->SetTexture( "g_txScene", g_pTxFloor ) );
				V( g_pEffect->SetMatrix( "g_mWorld", &g_mxFloor ) );

this is my pick code
void detect_picking(IDirect3DDevice9* pd3dDevice)
{
	// get the current transform matrices
	D3DXMATRIX matProjection, matView, matWorld, matInverse;
	pd3dDevice->GetTransform(D3DTS_PROJECTION, &matProjection);
	pd3dDevice->GetTransform(D3DTS_VIEW, &matView);
	//pd3dDevice->GetTransform(D3DTS_WORLD, &matWorld);
	g_pEffect->GetMatrix("g_mWorld",&matWorld);
	
		// use the mouse coordinates to get the mouse angle
	POINT MousePos;
	GetCursorPos(&MousePos);
	float xAngle = (((2.0f * MousePos.x) / 800) - 1.0f) / matProjection(0, 0);
	float yAngle = (((-2.0f * MousePos.y) / 600) + 1.0f) / matProjection(1, 1);

	D3DXVECTOR3 origin, direction;
	origin = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	direction = D3DXVECTOR3(xAngle, yAngle, 1.0f);

	// find the inverse matrix
	D3DXMatrixInverse(&matInverse, NULL, &(matWorld * matView));

	// convert origin and direction into model space
	D3DXVec3TransformCoord(&origin, &origin, &matInverse);
	D3DXVec3TransformNormal(&direction, &direction, &matInverse);
	D3DXVec3Normalize(&direction, &direction);

	// detect picking
	BOOL hit;
	D3DXIntersect(g_pMeshFloor, &origin, &direction, &hit, NULL, NULL, NULL, NULL, NULL, NULL);
	if(hit)
			pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
	else
			pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
}
it seems to set the foor to wireframe no matter where the mouse is

#4 TheNut

    Senior Member

  • Moderators
  • 1718 posts
  • LocationCyberspace

Posted 18 April 2012 - 12:09 PM

I keep my origin and ray in view space so that I can test against multiple objects. I don't know much about the D3D API, but it looks like you have to go a step further and bring it into object space due to the limitations in D3DXIntersect(...). This can be quite a performance hit if you need to test for multiple object intersections.

You have your matrix operations a bit off. You need to multiply by the inverse projection matrix and not the inverse of the view matrix * world matrix. You have it backwards right now, which is what you do when you want to project a 3D object into screen space. It should be ViewportMousePoint * InverseProjection * View * InverseWorldMatrix, where ViewportMousePoint is ((x / width) * 2.0 - 1.0, (y / height) * 2.0 - 1.0, 0.0, 1.0).

By calling GetCursorPos, you are retrieving the screen coordinates of a mouse cursor. This means the top-left of your desktop is (0,0) and the bottom right is (width, height). You should convert your screen coordinates into client coordinates by calling ScreenToClient(...). This will map the coordinates relative to the top left of your window. So (0,0) = top left of window.
http://www.nutty.ca - Being a nut has its advantages.

#5 Anddos

    Valued Member

  • Members
  • PipPipPip
  • 177 posts

Posted 23 April 2012 - 05:10 AM

from my understanding if your using Device->SeTransfrom on your objects than you use GetTransform to get the matrixs in the picking code, if you're game using .fx effects then it seems like you have to inverse the view matrix to get the "World" matrix why is this?





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users