// Developed by Neil Kemp: http://neilkemp.us // Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php // Convert a mouse point in window client space to world space ray position and direction void mouse_point_to_ray(IDirect3DDevice9* device_pointer, const CRect &window_client_rect, const D3DXVECTOR2 &mouse_point, D3DXVECTOR3 &ray_position_out, D3DXVECTOR3 &ray_direction_out) { // Assertions _ASSERT(device_pointer != 0); // Local data D3DXMATRIX projection_matrix, view_matrix, inverse_view_matrix; D3DXVECTOR3 v; // Get projection and view matricies device_pointer->GetTransform(D3DTS_PROJECTION, &projection_matrix); device_pointer->GetTransform(D3DTS_VIEW, &view_matrix); // Inverse view matrix D3DXMatrixInverse(&inverse_view_matrix, 0, &view_matrix); // Get pick ray in screen space v.x = (((2.0f * mouse_point.x) / (float)window_client_rect.Width()) - 1.0f) / projection_matrix._11; v.y = -(((2.0f * mouse_point.y) / (float)window_client_rect.Height()) - 1.0f) / projection_matrix._22; v.z = 1.0f; // Transform screen space pick ray to world space ray_position_out.x = inverse_view_matrix._41; ray_position_out.y = inverse_view_matrix._42; ray_position_out.z = inverse_view_matrix._43; ray_direction_out.x = v.x * inverse_view_matrix._11 + v.y * inverse_view_matrix._21 + v.z * inverse_view_matrix._31; ray_direction_out.y = v.x * inverse_view_matrix._12 + v.y * inverse_view_matrix._22 + v.z * inverse_view_matrix._32; ray_direction_out.z = v.x * inverse_view_matrix._13 + v.y * inverse_view_matrix._23 + v.z * inverse_view_matrix._33; // Normalize direction vector D3DXVec3Normalize(&ray_direction_out, &ray_direction_out); } /* Example usage: IDirect3DDevice9* device; D3DXVECTOR3 mouse_point, ray, dir, hit, p0, p1; D3DXPLANE plane; CRect d3d_window_rect; // ... Initialize device, rect, and plane ... // Get ray from mouse point mouse_point_to_ray(device, d3d_window_rect, mouse_point, ray, dir); // Intersect plane with line p0 = ray; p1 = dir * 1000.0f; D3DXPlaneIntersectLine(&hit, &plane, &p0, &p1); // Can also be used with other D3D functions // ID3DX10Mesh::Intersect() // ID3DX10Mesh::IntersectSubset() // D3DXIntersectSubset() // D3DXIntersect() // D3DXboxBoundProbe() // D3DXSphereBoundProbe() // D3DXIntersectTri() // ID3DXPRTEngine::ClosestRayIntersects() */