Code:
D3DXMATRIX P = GetCamera().proj();
float vx = (+2.0f*g_MousePos_V.x/g_WindowDimensions_V.x - 1.0f)/P(0,0);// Compute picking ray in view space.
float vy = (-2.0f*g_MousePos_V.y/g_WindowDimensions_V.y + 1.0f)/P(1,1);
D3DXMATRIX V = GetCamera().view();
D3DXMATRIX inverseV;
D3DXMatrixInverse(&inverseV, 0, &V);// Tranform to world space.
D3DXVECTOR3 rayOrigin(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 rayDir(vx, vy, 1.0f);
D3DXVec3TransformCoord(&rayOrigin, &rayOrigin, &inverseV);// this function actually translated the point
D3DXVec3TransformNormal(&rayDir, &rayDir, &inverseV);// this function does no translate the vector, it only changes the direction into the new coordinate system
D3DXVECTOR3 srayOrigin(rayOrigin), srayDir(rayDir);// save these because I change them in the for loop. This way I dont need to recalc every iteration
// Transform to the mesh's local space for all meshes!!
// add tests for multiple intersections......
vector<cTargetInfo> targets;
vector<float> distances;
string empty;
for(size_t i(0); i< Mesh.size(); i++){
rayOrigin=srayOrigin;// restore original values
rayDir=srayDir;// same
D3DXMATRIX inverseW, wor(Mesh[i]->Scaling*Mesh[i]->Rotation* Mesh[i]->Translation);
D3DXMatrixInverse(&inverseW, 0, &wor);
D3DXVec3TransformCoord(&rayOrigin, &rayOrigin, &inverseW);// transform the origin into the objects space
D3DXVec3TransformNormal(&rayDir, &rayDir, &inverseW);// trasform ray into object space
rayDir*=FarPlane;// scale it to make sure it goes through the entire scene, when it is translated from view space it is a short dog... make it a big dog :)
// first, do a AABB intersection, if we hit, then do an extensive triangle intersection test to be sure
if(Mesh[i]->IntersectAABB(rayOrigin, rayDir)){// if ret true, we hit the AABB, now we can check triangles to be sure
rayDir/=FarPlane;// undo the scaling
ID3DX10Mesh* d3dxmesh = Mesh[i]->MeshData;
uint32_t picked, hitcount;
float u,v,t;
ID3D10Blob* allHits;
d3dxmesh->Intersect(&rayOrigin, &rayDir, &hitcount, &picked, &u, &v, &t, &allHits);
distances.push_back(t);
if(hitcount>0){
distances.push_back(t);// add the distance
} else {
distances.push_back(FLT_MAX);// otherwise, we missed add a huge distance
}
ReleaseCOM(allHits);
} else {
distances.push_back(FLT_MAX);// otherwise, we missed add a huge distance
}// else, we missed the AABB
}
// figure out which target we really hit
float cdist(FLT_MAX);
for(size_t i(0); i< distances.size(); i++){
if(distances[i] < cdist){
cdist=distances[i];
}
}