0
        // 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.

user1658740
  • 75
  • 2
  • 5
  • I'm not understanding. How do you know if the intersect works if you only change lighting if there is a hit and then break? Also, what do you mean by seco? Because the list is obviously independent of where you trace the ray from. – Joseph Pla Jul 16 '13 at 21:26

2 Answers2

1

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.

Joseph Pla
  • 1,600
  • 1
  • 10
  • 21
0
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);
Werner Henze
  • 16,404
  • 12
  • 44
  • 69