Sign in to follow this  

cursor position on terrain

Recommended Posts

Dragon_Strike    264
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...

Share this post

Link to post
Share on other sites
ferdekk    100
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.

Share this post

Link to post
Share on other sites
Wyrframe    2426
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.

Share this post

Link to post
Share on other sites
Dragon_Strike    264
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)
edit = true;

edit = false;

if (edit)
D3DXVECTOR3 vPickRayDir;
D3DXVECTOR3 vPickRayOrig;
const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetD3D9BackBufferSurfaceDesc();

// 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
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;
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;




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