I am working on my first 3D game, which contains several vehicles placed on a board. I want to implement mouse picking of the vehicles. I found this great tutorial and used its code. But I don't understand part of the math.

Early in the function (listed below), I convert the input mouse coordinates into the -1 to +1 range:

// Create picking ray from camera position and mouse click
void VehiclePicker::SetPickingRay(LONG mouseX, LONG mouseY) {
    float pointX, pointY;

    /* Conversion to -1 to +1 here: */
    // Move the mouse cursor coordinates into the -1 to +1 range.
    pointX = ((2.0f * static_cast<float>(mouseX)) / static_cast<float>(SCREEN_WIDTH)) - 1.0f;
    pointY = (((2.0f * static_cast<float>(mouseY)) / static_cast<float>(SCREEN_HEIGHT)) - 1.0f) * -1.0f;


I don't understand why this is necessary, could somebody please explain it?

Here's the rest of the function, for context:

    // Adjust the points using the projection matrix to account for the aspect ratio of the viewport.
    XMFLOAT4X4 prMtrx;
    // Convert projectionMatrix from XMMATRIX into XMFLOAT4X4 in order to pick its members
    XMStoreFloat4x4(&prMtrx, _d3d->GetProjectionMatrix());
    pointX = pointX / prMtrx._11;
    pointY = pointY / prMtrx._22;

    // Get the inverse of the view matrix.
    XMFLOAT4X4 invViewMtrx;
    // Convert inverseViewMatrix from XMMATRIX into XMFLOAT4X4 in order to pick its members
    XMStoreFloat4x4(&invViewMtrx, XMMatrixInverse(nullptr, _camera->GetViewMatrix()));
    // Calculate the direction of the picking ray in view space.
    XMFLOAT3 dir;
    dir.x = (pointX * invViewMtrx._11) + (pointY * invViewMtrx._21) + invViewMtrx._31;
    dir.y = (pointX * invViewMtrx._12) + (pointY * invViewMtrx._22) + invViewMtrx._32;
    dir.z = (pointX * invViewMtrx._13) + (pointY * invViewMtrx._23) + invViewMtrx._33;
    _pickingRayDirection = XMLoadFloat3(&dir);

    // Get the origin of the picking ray which is the position of the camera.
    _pickingRayOrigin = _camera->GetPosition();

    // And finally I must normalize the final vector
    _pickingRayDirection = XMVector3Normalize(_pickingRayDirection);
  • \$\begingroup\$ Each of your sub-questions from the original post should be asked as a separate question; they're all fairly distinct even though they all are about the broader process of picking. I've edited this one down to include just the first query, but you'll have to re-post the others on your own. \$\endgroup\$
    – user1430
    Aug 22, 2018 at 19:57
  • \$\begingroup\$ Thank you, I try to do that and not to loose the context. \$\endgroup\$ Aug 22, 2018 at 20:14
  • \$\begingroup\$ For the two questions 'in the middle' (which may be okay as a single post, together, I'm not sure) it would also help if you explain what specifically you're confused about, since the comments immediately below your notes seem to indicate why/what you are doing the matrix operation for. \$\endgroup\$
    – user1430
    Aug 22, 2018 at 20:16
  • \$\begingroup\$ The comments come from the tutorial - they're not mine. I agree, it's confusing. I will edit the post. \$\endgroup\$ Aug 22, 2018 at 20:22
  • \$\begingroup\$ I edited it in the second post \$\endgroup\$ Aug 22, 2018 at 20:29


You must log in to answer this question.

Browse other questions tagged .