Problem with picking

Started by
8 comments, last by MefistoManna 11 years, 10 months ago
Hi guys, sorry for my English,
I have this problems with picking ray on multiple mesh:
1) if I get the world matrix in this way (with GetTrasform) , the picking result is wrong when I traslate or scale the meshes (work on original position or size)
2) Else if I pass in the function the single meshes 's world matrix (array) the result is correct but if I scale the mesh, the ray pick more distant mesh and I have to get close for get the correct result.

Here is my code (I have other function that get the closest mesh, but I am sure that the problems is here):
[source lang="cpp"]

if(m_Input::MouseButtonDown(0))
{
g_D3DDevice_->GetTransform(D3DTS_PROJECTION, &matProj );
g_D3DDevice_->GetTransform(D3DTS_VIEW, &matView);
g_D3DDevice_->GetTransform(D3DTS_WORLD, &matWorld);
g_D3DDevice_->GetViewport( &m_Viewport );

D3DXMatrixInverse(&ImatView, NULL, &matView );
D3DXMatrixInverse(&ImatWorld,NULL,&matWorld);

v.x = ( ( ( 2.0f * Cursor.x ) / m_Viewport.Width ) - 1 ) / matProj._11;
v.y = -( ( ( 2.0f * Cursor.y ) / m_Viewport.Height ) - 1 ) / matProj._22;
v.z = 1.0f;

rayDir.x = v.x*ImatView._11 + v.y*ImatView._21 + v.z*ImatView._31;
rayDir.y = v.x*ImatView._12 + v.y*ImatView._22 + v.z*ImatView._32;
rayDir.z = v.x*ImatView._13 + v.y*ImatView._23 + v.z*ImatView._33;
rayOrigin.x = ImatView._41;
rayOrigin.y = ImatView._42;
rayOrigin.z = ImatView._43;

D3DXVec3TransformCoord(&rayOrigin,&rayOrigin,&ImatWorld);
D3DXVec3TransformNormal(&rayDir,&rayDir,&ImatWorld);
D3DXVec3Normalize(&rayDir,&rayDir);

D3DXIntersect(g_Mesh[NumModel], &rayOrigin, &rayDir, &picked, NULL, NULL, NULL, &dist, NULL, NULL);

if(picked)
{
NumMeshHit[NumHit] = NumModel;
MeshDist[NumHit] = dist;
NumHit++;
}
}
[/source]

Sorry again for my bad English.
Advertisement
Hi there.
here http://msdn.microsoft.com/en-us/library/windows/desktop/bb172882(v=vs.85).aspx
it say's that the member ppAllHits may hold 1 or more D3DXINTERSECTINFO structure.

you then need to loop through the ppallhits by this many times pCountOfHits
you then need to compare the ppAllHits[ctr]->Dist to the camera's pos.
Thanks ankhd,
I do this, and it works perfectly, but the problem is when the mesh is traformed. I think that it' s a wrong use of matrix. Do I have to use the inverse of matrix obtained with the function GetTrasform or the matrix of single mesh?
I think you need to do this.
[size="2"]D3DXMATRIX matWorld = world;

[size="2"]D3DXMATRIX mWorldView = matWorld * matView;
[size="2"]D3DXMATRIX m;
[size="2"]D3DXMatrixInverse( &m, NULL, &mWorldView );
[size="2"]that should work.
oops and this
[size="2"][color="#008000"][size="2"][color="#008000"]// Transform the screen space pick ray into 3D space
[size="2"]rayDir.x = v.x * m._11 + v.y * m._21 + v.z * m._31;
[size="2"]rayDir.y = v.x * m._12 + v.y * m._22 + v.z * m._32;
[size="2"]rayDir.z = v.x * m._13 + v.y * m._23 + v.z * m._33;
[size="2"]rayOrigin.x = m._41;
[size="2"]rayOrigin.y = m._42;
[size="2"]rayOrigin.z = m._43;

[size="2"]and no transforming off coords
It still don't work
wacko.png .I am doing in this way:
[source lang="cpp"]
g_D3DDevice_->GetTransform(D3DTS_PROJECTION, &matProj );
g_D3DDevice_->GetTransform(D3DTS_VIEW, &matView);
g_D3DDevice_->GetTransform(D3DTS_WORLD, &matWorld);
g_D3DDevice_->GetViewport( &m_Viewport );

D3DXMatrixInverse(&ImatView, NULL, &matView );
D3DXMatrixInverse(&ImatWorld, NULL, &matWorld);

v.x = ( ( ( 2.0f * Cursor.x ) / m_Viewport.Width ) - 1 ) / matProj._11;
v.y = -( ( ( 2.0f * Cursor.y ) / m_Viewport.Height ) - 1 ) / matProj._22;
v.z = 1.0f;

D3DXMATRIX mWorldView = matWorld * matView;
D3DXMATRIX m;
D3DXMatrixInverse( &m, NULL, &mWorldView );

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;

D3DXVec3TransformCoord(&rayOrigin,&rayOrigin,&ImatWorld);
D3DXVec3TransformNormal(&rayDir,&rayDir,&ImatWorld);
D3DXVec3Normalize(&rayDir,&rayDir);

D3DXIntersect(g_Mesh[NumModel], &rayOrigin, &rayDir, &picked, NULL, NULL, NULL, &dist, AllHit, HitCount);
[/source]
If I multiply matworld and matview the picking is completly wrong.
I think you need to have a copy of your transform matrix and not use the [color="#000000"]GetTransform its for rendering each time u render a mesh
you will set the transform right so you would need to set the transform to the device each time you do a new mesh pick.

My code works for my meshes they all scaled and rotated and translation.
Thanks again,
I modified my code like you said...it's incredible still don't work for scaled mesh... I did some research and this is my same problem http://www.gamedev.n...t-mesh-problem/ but a concrete solution I did't find.

EDIT. I solved by multiply the maximum scale factor of 3 dimensions (x,y,z) for the distance, thanks for your help.
Oh I see from the post link you set. You don't have a picking problem it's more of a selecting the nearest object problem.
As in the link he trys to pick the wall but the ground is picked. this is due to the fact that the camera is near the ground based on how the camera is looking.
ahhh for the moment it's working, but if there is a clearest method it' s better.

This topic is closed to new replies.

Advertisement