Setting a new vector3 location with mouse

Anddos 103 Apr 16, 2012 at 11:06

What i want todo is set a new target to move to using the mouse, this is for the directx sdk sample , “multianimation” , when it picks a new location to move to it uses this function…

void CTiny::ChooseNewLocation( D3DXVECTOR3* pV )

        pV->x = ( float )( rand() % 256 ) / 256.f;
        pV->y = 0.f;
        pV->z = ( float )( rand() % 256 ) / 256.f;


so instead of using this i want to use my own which is take the mouse 2d point and turn it in to a 3d vector position …

void CTiny::SetNewClickTarge(D3DXVECTOR3* pV)
        src.x = (int)point.x;
        src.z = (int)point.y;


        pV->x = r.x;
        pV->y = r.y;
        pV->z = r.z;

when i run the sample and tick control , and move the mouse around nothing seems to happen?

4 Replies

Please log in or register to post a reply.

TheNut 179 Apr 16, 2012 at 15:58

When you unproject your mouse coordinates, you’re producing a vector, not a location. The vector is emitting from your camera. Think of an arrow pointing in the direction that particular pixel is looking at. What you need to do now is find a point of intersection in your game world. Typically you would do ray - plane, ray - sphere, ray - box, or ray - triangle tests to find out the exact point of intersection. Take a look at this website for some math routines you can use.

Anddos 103 Apr 18, 2012 at 04:47

what space does my ray need to be in then if the floor transform is like this

V( g_pEffect->SetTexture( "g_txScene", g_pTxFloor ) );
                V( g_pEffect->SetMatrix( "g_mWorld", &g_mxFloor ) );

this is my pick code

void detect_picking(IDirect3DDevice9* pd3dDevice)
    // get the current transform matrices
    D3DXMATRIX matProjection, matView, matWorld, matInverse;
    pd3dDevice->GetTransform(D3DTS_PROJECTION, &matProjection);
    pd3dDevice->GetTransform(D3DTS_VIEW, &matView);
    //pd3dDevice->GetTransform(D3DTS_WORLD, &matWorld);
        // use the mouse coordinates to get the mouse angle
    POINT MousePos;
    float xAngle = (((2.0f * MousePos.x) / 800) - 1.0f) / matProjection(0, 0);
    float yAngle = (((-2.0f * MousePos.y) / 600) + 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;
    D3DXIntersect(g_pMeshFloor, &origin, &direction, &hit, NULL, NULL, NULL, NULL, NULL, NULL);
            pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
            pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);

it seems to set the foor to wireframe no matter where the mouse is

TheNut 179 Apr 18, 2012 at 12:09

I keep my origin and ray in view space so that I can test against multiple objects. I don’t know much about the D3D API, but it looks like you have to go a step further and bring it into object space due to the limitations in D3DXIntersect(…). This can be quite a performance hit if you need to test for multiple object intersections.

You have your matrix operations a bit off. You need to multiply by the inverse projection matrix and not the inverse of the view matrix * world matrix. You have it backwards right now, which is what you do when you want to project a 3D object into screen space. It should be ViewportMousePoint * InverseProjection * View * InverseWorldMatrix, where ViewportMousePoint is ((x / width) * 2.0 - 1.0, (y / height) * 2.0 - 1.0, 0.0, 1.0).

By calling GetCursorPos, you are retrieving the screen coordinates of a mouse cursor. This means the top-left of your desktop is (0,0) and the bottom right is (width, height). You should convert your screen coordinates into client coordinates by calling ScreenToClient(…). This will map the coordinates relative to the top left of your window. So (0,0) = top left of window.

Anddos 103 Apr 23, 2012 at 05:10

from my understanding if your using Device->SeTransfrom on your objects than you use GetTransform to get the matrixs in the picking code, if you’re game using .fx effects then it seems like you have to inverse the view matrix to get the “World” matrix why is this?