问一下D3DXIntersect功能:(

时间:2013-07-16 15:50:31

标签: c++ directx directx-9 picking mouse-picking

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

这是我的挑选示例源代码。 我有一个问题。

如果我创建三个3D对象。所以采摘第三个对象。没有先工作,第二个对象。

如果我只创建一个Object。采摘效果很好!

如果我创建两个对象。挑选不是第一个工作第二个对象。

只创造最后的作品选择。

我不知道为什么会出现这个问题。

请给我一些建议。

2 个答案:

答案 0 :(得分:1)

我猜测的是你的列表没有按照相机的距离排序,这是正常的,但正因为如此,你只需检查一个网格,如果有一个点击,你就会中断。相反,因为您不知道列表的顺序,您应该检查列表中的所有网格,然后选择最短的网格。现在你做事的方式使得选择取决于列表而不是相机所在的位置。

答案 1 :(得分:0)

ENGINE.GetDevice()->GetDevice()->GetTransform(D3DTS_WORLD, &matWorld);

这是最后渲染的网格的变换。 (因为所有网格物体都使用device->SetTransform(D3DTS_WORLD, &something);

绘制后需要获取目标网格的变换矩阵并使用它。

yourtargetmesh->DrawSubset(0);
device->GetTransform(D3DTS_WORLD, &yourtargetmeshmatWorld);