Reputation: 75
// get the current transform matrices
D3DXMATRIX matProjection, matView, matWorld, matInverse;
ENGINE.GetDevice()->GetDevice()->GetTransform(D3DTS_PROJECTION, &matProjection);
ENGINE.GetDevice()->GetDevice()->GetTransform(D3DTS_VIEW, &matView);
ENGINE.GetDevice()->GetDevice()->GetTransform(D3DTS_WORLD, &matWorld);
// use the mouse coordinates to get the mouse angle
float xAngle = (((2.0f * ENGINE.GetInputManager()->GetMousePos()->x) / WINDOW_WIDTH) - 1.0f) / matProjection(0, 0);
float yAngle = (((-2.0f * ENGINE.GetInputManager()->GetMousePos()->y) / WINDOW_HEIGHT) + 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;
std :: list<CEntity*> :: iterator iter = MAINMANAGER.GetLegoObjectManager()->GetObjList().begin();
CResource* g_pResource = NULL;
while(iter != MAINMANAGER.GetLegoObjectManager()->GetObjList().end())
{
g_pResource = static_cast<CEntity*>(*iter)->GetResource();
D3DXIntersect( static_cast<PassiveMesh*>(g_pResource)->GetMesh(), &origin, &direction, &hit, NULL, NULL, NULL, NULL, NULL, NULL);
if(hit)
{
ENGINE.GetDevice()->GetDevice()->SetRenderState(D3DRS_LIGHTING, FALSE);
break;
}
else
{
ENGINE.GetDevice()->GetDevice()->SetRenderState(D3DRS_LIGHTING, TRUE);
}
++iter;
}
This is my picking sample source code. I have a problem.
if I create three 3D objects. so picking works third object. not working first, second object.
if I create only one Object. picking works well!
if I create two object. picking works second object not first.
only create last obejct works picking well.
I don't find why this problem is coming.
please give me some advice.
Upvotes: 0
Views: 542
Reputation: 1
ENGINE.GetDevice()->GetDevice()->GetTransform(D3DTS_WORLD, &matWorld);
This is the last rendered mesh's transforms. (because all meshes use device->SetTransform(D3DTS_WORLD, &something);
)
You need get transform matrix of your target mesh after draw and use that.
yourtargetmesh->DrawSubset(0);
device->GetTransform(D3DTS_WORLD, &yourtargetmeshmatWorld);
Upvotes: 0
Reputation: 1598
What I'm guessing is that your list is not ordered by distance to camera, which is normal but because of this, you simply check a mesh and if there is a hit, you break. Instead, because you don't know the order of the list, you should check all meshes in the list, and then take the shortest one. The way you are doing things now makes the picking dependent on the list and not at all where the camera is.
Upvotes: 1