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\$ – Josh Aug 22 '18 at 19:57
  • \$\begingroup\$ Thank you, I try to do that and not to loose the context. \$\endgroup\$ – Jan Pazdera Aug 22 '18 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\$ – Josh Aug 22 '18 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\$ – Jan Pazdera Aug 22 '18 at 20:22
  • \$\begingroup\$ I edited it in the second post \$\endgroup\$ – Jan Pazdera Aug 22 '18 at 20:29

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.