Hi jack.
I've had this exact problem myself, though I can't say it's fully solved, but, it's close.
So, the first thing you have to consider is that once you click the screen, you have to make some kind of world space ray, which could be done like this:
// PS. I always use the transposed versions of my view and projection matrices.
//getting projection matrix
D3DXMATRIX projMat = *Camera->getProjection();
float vx = (+2.0f*mouseX/viewport.Width - 1.0f)/projMat._11;
float vy = (-2.0f*mouseY/viewport.Height + 1.0f)/projMat._22;
CEVector3f Origin(0.0f, 0.0f, 0.0f);
CEVector3f Direction(vx, vy, 1.0f);
D3DXMATRIX viewMat = *Camera->getView();
D3DXMatrixTranspose(&viewMat, &viewMat); // Transposing the view matrix (To the original one)
D3DXMATRIX iviewMat;
D3DXMatrixInverse(&iviewMat, 0, &viewMat);
D3DXVec3TransformCoord(&Origin, &Origin, &iviewMat);
D3DXVec3TransformNormal(&Direction, &Direction, &iviewMat);
D3DXVec3Normalize(&Direction, &Direction);
Now the next step can be optimized in many ways, but I'll present a simple way:
- Loop over all object
- Does this objects bounding box/sphere collide with this ray?
- Add it to my vector
- Loop over all objects in vector
- Loop over all triangles in this object
- Does the ray collide with this triangle
- Store the triangle and the distance (ray start to ray end)
- Then find the triangle for which the ray had to travel the shortest distance, and we assume that that's our users preferred drop position.
Now this is only one way of accomplishing this, but, it should work.
Hope this can help you.
-MIGI0027