cursor position on terrain

Started by
4 comments, last by Dragon_Strike 16 years, 5 months ago
i would like to calculate which point on a heightmapped terrain mesh the mouse is currently pointing on (lParam)... how would i do this? my only guess would be to transform every single point on the mesh to screenspace and compare it to the mouse coords and see which one is the closest match... but it doesnt seem very efficient...
Advertisement
easy way to do this, its:

gluUnproject for convert 2DMouse to 3DCoordinates in world, and later
use any function to intersectionTri (like, D3DXIntersectTri in DirectX).

U can also every point in heightmap convert to 2DScreenCoord 'gluProject' but its slower, if u have 256x256 heightmap, and every point will be converted.
im unsure how i would transform from screenspace to worldspace when i dont know the depth?

btw im using directx
When you unproject, what you get is a point which you can think of as being on the camera's "lens"... so you then cast a ray into the scene which starts at the camera's position (its focal point) and through the unprojected point (the spot on the lens the cursor lies on), and see what in the scene that ray strikes.

So, you'd test that ray against the terrain mesh. Look up ray-plane intersection and then point-triangle intersection to finish up the solution. Remember to do some kind of spatial partitioning if you want a semblance of efficiency.
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
i looked at the directx sdk and i found some code... but i dont get it to work properly... doesnt calculate the right pos... this is what ive got


what am i doin wrong?


void CTerrain::EditAlphaMap(UINT uMsg, WPARAM wParam, LPARAM lParam, CFirstPersonCamera* Camera){	static bool edit = false;	switch (uMsg)	{		case WM_RBUTTONDOWN: 			edit = true;		break;		case WM_RBUTTONUP:			edit = false;		break;	}	if (edit)	{		D3DXVECTOR3 vPickRayDir;		D3DXVECTOR3 vPickRayOrig;		const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetD3D9BackBufferSurfaceDesc();		D3DXVECTOR3 v0;		D3DXVECTOR3 v1;		D3DXVECTOR3 v2;		// Get the pick ray from the mouse position		const D3DXMATRIX *pmatProj = Camera->GetProjMatrix();		POINT ptCursor;		GetCursorPos( &ptCursor );		ScreenToClient( DXUTGetHWND(), &ptCursor );		// Compute the vector of the pick ray in screen space		D3DXVECTOR3 v;		v.x =  ( ( ( 2.0f * ptCursor.x ) / 1280.0f  ) - 1 ) / pmatProj->_11;		v.y = -( ( ( 2.0f * ptCursor.y ) / 768.0f ) - 1 ) / pmatProj->_22;		v.z =  1.0f;		// Get the inverse view matrix		const D3DXMATRIX matView = *Camera->GetViewMatrix();		const D3DXMATRIX matWorld = *Camera->GetWorldMatrix();		D3DXMATRIX mWorldView = matWorld * matView;		D3DXMATRIX m;		D3DXMatrixInverse( &m, NULL, &mWorldView );		// Transform the screen space pick ray into 3D space		vPickRayDir.x  = v.x*m._11 + v.y*m._21 + v.z*m._31;		vPickRayDir.y  = v.x*m._12 + v.y*m._22 + v.z*m._32;		vPickRayDir.z  = v.x*m._13 + v.y*m._23 + v.z*m._33;		vPickRayOrig.x = m._41;		vPickRayOrig.y = m._42;		vPickRayOrig.z = m._43;		bool intersect = false;        FLOAT fBary1, fBary2;        FLOAT fDist;		float x = 0;		float z = 0;		for (z = 0; z < MapSize-8 && (intersect == false); z+=8)		{			for (x = 0; x < MapSize-8 && (intersect == false); x+=8)			{				v0 = D3DXVECTOR3(x,	  GetHeight(x,z),	  z  );				v1 = D3DXVECTOR3(x+8, GetHeight(x+8,z),	  z  );				v2 = D3DXVECTOR3(x+8, GetHeight(x+8,z+8), z+8);				BOOL intersect1 = D3DXIntersectTri(  &v0, &v1, &v2, &vPickRayOrig, &vPickRayDir, &fDist, &fBary1, &fBary2 );				v0 = D3DXVECTOR3(x,	  GetHeight(x,z),	  z  );				v1 = D3DXVECTOR3(x,   GetHeight(x,z+8),	  z+8);				v2 = D3DXVECTOR3(x+8, GetHeight(x+8,z+8), z+8);				BOOL intersect2 = D3DXIntersectTri(  &v0, &v1, &v2, &vPickRayOrig, &vPickRayDir, &fDist, &fBary1, &fBary				intersect = intersect1 || intersect2;			}		}		if (intersect)		{			D3DLOCKED_RECT  lockedRect;			V(AlphaMap->LockRect(0, &lockedRect, NULL, 0));				unsigned char* imageData = (unsigned char*)lockedRect.pBits;											imageData[int(x+z*MapSize)*4+0] = 255; 					imageData[int(x+z*MapSize)*4+1] = 255; 					imageData[int(x+z*MapSize)*4+2] = 255; 					imageData[int(x+z*MapSize)*4+3] = 255; 				V(AlphaMap->UnlockRect(0));		}		}}
actually... i get intersections when there shouldnt be any at all...

This topic is closed to new replies.

Advertisement