Sign in to follow this  

[XNA] Vertex Picking

Recommended Posts

I'm trying to get per vertex selection to work in my xna based terrain editor. I figured I can get vertex selection to work by using my pre-existing triangle picking code. Basically what I plan to do is find the exact point in 3d space in which the ray intersects the triangle and return whichever vertex of that triangle is closest to that point. However I have to admit that I do not completely understand the math behind the triangle picking and am unsure how to get the exact intersection point. I'm using the code straight out of the triangle picking tutorial but I'll post it here anyways. I really hope someone tell me how or at least point me in the right direction.

Triangle Picking code:
static void RayIntersectsTriangle(ref Ray ray,
ref Vector3 vertex1,
ref Vector3 vertex2,
ref Vector3 vertex3, out float? result)
// Compute vectors along two edges of the triangle.
Vector3 edge1, edge2;

Vector3.Subtract(ref vertex2, ref vertex1, out edge1);
Vector3.Subtract(ref vertex3, ref vertex1, out edge2);

// Compute the determinant.
Vector3 directionCrossEdge2;
Vector3.Cross(ref ray.Direction, ref edge2, out directionCrossEdge2);

float determinant;
Vector3.Dot(ref edge1, ref directionCrossEdge2, out determinant);

// If the ray is parallel to the triangle plane, there is no collision.
if (determinant > -float.Epsilon && determinant < float.Epsilon)
result = null;

float inverseDeterminant = 1.0f / determinant;

// Calculate the U parameter of the intersection point.
Vector3 distanceVector;
Vector3.Subtract(ref ray.Position, ref vertex1, out distanceVector);

float triangleU;
Vector3.Dot(ref distanceVector, ref directionCrossEdge2, out triangleU);
triangleU *= inverseDeterminant;

// Make sure it is inside the triangle.
if (triangleU < 0 || triangleU > 1)
result = null;

// Calculate the V parameter of the intersection point.
Vector3 distanceCrossEdge1;
Vector3.Cross(ref distanceVector, ref edge1, out distanceCrossEdge1);

float triangleV;
Vector3.Dot(ref ray.Direction, ref distanceCrossEdge1, out triangleV);
triangleV *= inverseDeterminant;

// Make sure it is inside the triangle.
if (triangleV < 0 || triangleU + triangleV > 1)
result = null;

// Compute the distance along the ray to the triangle.
float rayDistance;
Vector3.Dot(ref edge2, ref distanceCrossEdge1, out rayDistance);
rayDistance *= inverseDeterminant;

// Is the triangle behind the ray origin?
if (rayDistance < 0)
result = null;

result = rayDistance;

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this