public bool PickedTriangle(Ray cursorRay, ref Vector3 intersection, ref float distance, ref int[] triangle)
{
float pickDist = 0.0f; // distance from ray origin to intersection
float pickU = 0.0f; // barycentric coordinate of intersection
float pickV = 0.0f; // barycentric coordinate of intersection
for (int i = 0; i < (this._IndicesCount / 3); ++i)
{
// changed from left handed (DirectX) to right handed (XNA)
Vector3 tri0 = this._transformedVertices[this._Indices[3 * i + 0]];
Vector3 tri1 = this._transformedVertices[this._Indices[3 * i + 2]];
Vector3 tri2 = this._transformedVertices[this._Indices[3 * i + 1]];
// Check if the pick ray passes through this point
if (RayIntersectTriangle(cursorRay.Position, cursorRay.Direction, tri0, tri1, tri2, ref pickDist, ref pickU, ref pickV))
{
if (pickDist > 0.0f)
{
intersection = pickU * tri1 + pickV * tri2 + (1 - pickU - pickV) * tri0;
distance = pickDist;
triangle[0] = 3 * i + 0;
triangle[1] = 3 * i + 2;
triangle[2] = 3 * i + 1;
return true;
}
}
}
return false;
}
I have experience working with C++ and DirectX. I prefer working with C# and WPF. In my spare time I work with HTML, JS, CSS.
Showing posts with label Ray. Show all posts
Showing posts with label Ray. Show all posts
Friday, May 14, 2010
XNA Pick model triangle with ray
You can find GetMouseCursorRay and RayIntersectTriangle on this blog.
XNA Ray Intersect Triangle
private bool RayIntersectTriangle(Vector3 rayPosition, Vector3 rayDirection, Vector3 tri0, Vector3 tri1, Vector3 tri2,
ref float pickDistance, ref float barycentricU, ref float barycentricV)
{
// Find vectors for two edges sharing vert0
Vector3 edge1 = tri1 - tri0;
Vector3 edge2 = tri2 - tri0;
// Begin calculating determinant - also used to calculate barycentricU parameter
Vector3 pvec = Vector3.Cross(rayDirection, edge2);
// If determinant is near zero, ray lies in plane of triangle
float det = Vector3.Dot(edge1, pvec);
if (det < 0.0001f)
return false;
// Calculate distance from vert0 to ray origin
Vector3 tvec = rayPosition - tri0;
// Calculate barycentricU parameter and test bounds
barycentricU = Vector3.Dot(tvec, pvec);
if (barycentricU < 0.0f || barycentricU > det)
return false;
// Prepare to test barycentricV parameter
Vector3 qvec = Vector3.Cross(tvec, edge1);
// Calculate barycentricV parameter and test bounds
barycentricV = Vector3.Dot(rayDirection, qvec);
if (barycentricV < 0.0f || barycentricU + barycentricV > det)
return false;
// Calculate pickDistance, scale parameters, ray intersects triangle
pickDistance = Vector3.Dot(edge2, qvec);
float fInvDet = 1.0f / det;
pickDistance *= fInvDet;
barycentricU *= fInvDet;
barycentricV *= fInvDet;
return true;
}
Subscribe to:
Posts (Atom)