Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I want to calculate the intersection of a line segment with the view frustum.

Here's what I tried so far. The code works perfectly when the look direction vector is orthogonal to the line. E.g. camera at (0,0,-100) looking at (0,0,0) and line from (-500,0,0) to (+500,0,0). However, as soon as I turn the camera sideways, the algorithm calculates intersection points that are not even on the line (something like -1000,0,0).

Where is the problem with my intersection method? Alternatively, is there an easier way to accomplish the same thing?

public static bool ViewFrustumLineSegmentIntersection(Vector3 lineStart,
    Vector3 lineEnd, Matrix viewProjection,
    out Vector3 firstIntersection, out Vector3 secondIntersection)
{
    // we do all calculations in projective space,
            // and afterwards convert the calculated intersection points back to worldspace.
    lineStart = Vector3.TransformCoordinate(lineStart, viewProjection);
    lineEnd = Vector3.TransformCoordinate(lineEnd, viewProjection);
    firstIntersection = secondIntersection = Vector3.Zero;

    BoundingBox viewFrustum = new BoundingBox(new Vector3(-1, -1, 0), new Vector3(1, 1, 1));

    var direction = lineEnd - lineStart;
    direction.Normalize();

    // First, we shoot a ray from lineStart to lineEnd to get the first intersection
    Ray r = new Ray(lineStart, direction);
    float lineLength = (lineEnd - lineStart).Length();
    float distance;
    if (!BoundingBox.Intersects(viewFrustum, r, out distance) || distance > lineLength)
        return false;
    firstIntersection = r.Position + r.Direction * distance;

    // now do the same from the other side to get the second intersection.
    r = new Ray(lineEnd, -direction);
    BoundingBox.Intersects(viewFrustum, r, out distance);
    secondIntersection = r.Position + r.Direction * distance;

    // Now convert the intersection points back to world space.
    var ivp = Matrix.Invert(viewProjection);
    firstIntersection = Vector3.TransformCoordinate(firstIntersection, ivp);
    secondIntersection = Vector3.TransformCoordinate(secondIntersection, ivp);

    return true;
}
share|improve this question
add comment

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.