Почему моя функция выбора ведет себя неожиданно?

#c #directx

#c #directx

Вопрос:

Я пытался заставить эту штуку работать в течение 2 часов, но безуспешно.

 BOOL Directx::Picking(HWND hWnd, AnimatedMesh *entity)
{
    D3DXMATRIX matProj;
    POINT pt;
    D3DVIEWPORT9 vp;
    D3DXMATRIX matWorld;
    D3DXMATRIX matView;

    GetCursorPos(amp;pt);
    ScreenToClient(hWnd, amp;pt);
    d3ddev->GetTransform(D3DTS_PROJECTION, amp;matProj);
    d3ddev->GetViewport(amp;vp);
    d3ddev->GetTransform(D3DTS_VIEW, amp;matView);

    d3ddev->GetTransform(D3DTS_WORLD, amp;matWorld);
    // Use inverse of matrix
    D3DXVECTOR3 rayPos((float)pt.x, (float)pt.y,0); // near-plane position
    D3DXVECTOR3 rayDir((float)pt.x, (float)pt.y,1); // far-plane position  
    D3DXVec3Unproject(amp;rayPos,amp;rayPos,amp;vp,amp;matProj,amp;matView,amp;matWorld);
    D3DXVec3Unproject(amp;rayDir,amp;rayDir,amp;vp,amp;matProj,amp;matView,amp;matWorld);
    rayDir -= rayPos; // make a direction from the 2 positions
    D3DXVec3Normalize(amp;rayDir,amp;rayDir);
    float distanceToCollision;
    BOOL hasHit = 0;
    if(FAILED(D3DXIntersect(entity->pDrawMesh, amp;rayPos, amp;rayDir, amp;hasHit, NULL, NULL, NULL, amp;distanceToCollision, NULL, NULL)))
    {
        PostQuitMessage(0);
    };

    if(hasHit!=0)
    {
        PostQuitMessage(0);
    }
    return hasHit;
}
  

Я думаю, проблема с matWorld в том, что я получаю преобразование мира вместо преобразования объекта, но это только предположение. Я обнаружил новую вещь, я загружаю 2 анимированных сетки, первая из которых представляет собой куб, а вторая — просто плоскость. У меня нет проблем с их отображением, но когда я проверяю выбор в кубе, он скажет, что он был выбран, даже если это не так. но для плоскости, когда вы нажимаете на нее, это говорит о том, что ‘
не был нажат.

Редактировать
Хорошо, я провел дополнительную отладку и получил некоторый результат по проблеме. Итак, я попытался нарисовать свой ray! Когда я рисую свой луч, предполагается, что он рисует точку там, где я щелкнул. Но когда я рисую свой луч, точка приближается к началу координат (0,0,0), я щелкнул еще раз, после чего она немного сместилась вниз, и она продолжала подниматься и опускаться.
Вот как я рисую свой луч

 ............
  D3DXVec3Normalize(amp;rayDir,amp;rayDir);
    Program::mesh1->FillInTransformation(0, 0, 0, 0, 0, 0, rayPos.x, rayPos.y, Program::z, true, false, false);  //HERE I TOOK X AND Y OF rayPos AND DRAW DOT ON IT'S POSITION
    float distanceToCollision;
    BOOL hasHit = 0;
    if(FAILED(D3DXIntersect(entity->pDrawMesh, amp;rayPos, amp;rayDir, amp;hasHit, NULL, NULL, NULL, amp;distanceToCollision, NULL, NULL)))
    {
        PostQuitMessage(0);
    };
........
  

Комментарии:

1. Если вы не зададите свой вопрос должным образом, то еще до 2 часов никто не сможет помочь!!

2. Я надеюсь, что предоставленная мной информация поможет.

3. Давайте, я предоставил всю информацию, которую могу предоставить вам, люди. Есть идеи?

4. Мне нравится ваша идея обработки ошибок. Если возникает ошибка, просто тихо завершите процесс!

5. LOL, она завершает работу, если выбран объект.

Ответ №1:

Что ж, попробуйте это:

 BOOL Directx::Picking(HWND hWnd, AnimatedMesh *entity)
{
    POINT pt;
    D3DVIEWPORT9 vp;
    D3DXMATRIX matProj, matView;

    GetCursorPos(amp;pt);
    ScreenToClient(hWnd, amp;pt);

    float w = (float)backBufferWidth;
    float h = (float)backBufferHeight;

    d3ddev->GetTransform(D3DTS_VIEW, amp;matView);
    d3ddev->GetTransform(D3DTS_PROJECTION, amp;matProj);
    d3ddev->GetViewport(amp;vp);

    //Transform cursor position to view space
    float x = (2.0f*pt.x/w - 1.0f) / matProj(0,0);
    float y = (-2.0f*pt.y/h   1.0f) / matProj(1,1);


    D3DXVECTOR3 rayOrigin(0.0f, 0.0f,0.0f); // near-plane position
    D3DXVECTOR3 rayDir(x, y, 1.0f); // far-plane position

    D3DXMATRIX matInvView;

    D3DXMatrixInverse(amp;matInvView, 0, amp;matView);

    D3DXVECTOR3 rayOriginW, rayDirW;

    // Transform picking ray to world space.
    D3DXVec3TransformCoord(amp;rayOriginW, amp;rayOrigin, amp;invView);
    D3DXVec3TransformNormal(amp;rayDirW, amp;rayDdir, amp;invView);
    D3DXVec3Normalize(amp;rayDirW, amp;rayDirW);

    BOOL hasHit;
    float distanceToCollision;

    if(FAILED(D3DXIntersect(entity->pDrawMesh, amp;rayOriginW, amp;rayDirW, amp;hasHit, NULL, NULL, NULL, amp;distanceToCollision, NULL, NULL)))
    {
        PostQuitMessage(0);
    };

    s=rayPos;

    return hasHit;
}