/**
   * Check if a Portal is in view of the frustum.
   *
   * @return Returns true if the portal is visible by this frustum
   */
  public boolean isPortalInFrustum(E3DPortal portal) {
    E3DVector3F[] proj = new E3DVector3F[4];

    E3DVector3F portalA = portal.getA();
    E3DVector3F portalB = portal.getB();
    E3DVector3F portalC = portal.getC();
    E3DVector3F portalD = portal.getD();

    // Project all the corners of the portal that we are trying to see is in this frustum

    proj[0] = viewport.projectPoint(portalA);
    proj[0].setZ(0.0);

    proj[1] = viewport.projectPoint(portalB);
    proj[1].setZ(0.0);

    proj[2] = viewport.projectPoint(portalC);
    proj[2].setZ(0.0);

    proj[3] = viewport.projectPoint(portalD);
    proj[3].setZ(0.0);

    /** 1. Check if a portal corner point is in the frustum */
    for (int i = 0; i < 4; i++) {
      if (projectedPointInFrustum(proj[i])) return true;
    }

    /** 2. Check if a frustum corner point is in the portal */
    E3DTriangle portalTriA = new E3DTriangle(getEngine(), proj[0], proj[1], proj[3]);
    E3DTriangle portalTriB = new E3DTriangle(getEngine(), proj[1], proj[2], proj[3]);

    if (portalTriA.isPointInTriangle(a)
        || portalTriB.isPointInTriangle(a)
        || portalTriA.isPointInTriangle(b)
        || portalTriB.isPointInTriangle(b)
        || portalTriA.isPointInTriangle(c)
        || portalTriB.isPointInTriangle(c)
        || portalTriA.isPointInTriangle(d)
        || portalTriB.isPointInTriangle(d)) return true;

    /** 3. Check if any of the line segments intersect */
    if (get2DLineIntersectionPt(a, b, proj[0], proj[1]) != null
        || get2DLineIntersectionPt(a, b, proj[1], proj[2]) != null
        || get2DLineIntersectionPt(a, b, proj[2], proj[3]) != null
        || get2DLineIntersectionPt(a, b, proj[3], proj[0]) != null
        || get2DLineIntersectionPt(b, c, proj[0], proj[1]) != null
        || get2DLineIntersectionPt(b, c, proj[1], proj[2]) != null
        || get2DLineIntersectionPt(b, c, proj[2], proj[3]) != null
        || get2DLineIntersectionPt(b, c, proj[3], proj[0]) != null
        || get2DLineIntersectionPt(c, d, proj[0], proj[1]) != null
        || get2DLineIntersectionPt(c, d, proj[1], proj[2]) != null
        || get2DLineIntersectionPt(c, d, proj[2], proj[3]) != null
        || get2DLineIntersectionPt(c, d, proj[3], proj[0]) != null
        || get2DLineIntersectionPt(d, a, proj[0], proj[1]) != null
        || get2DLineIntersectionPt(d, a, proj[1], proj[2]) != null
        || get2DLineIntersectionPt(d, a, proj[2], proj[3]) != null
        || get2DLineIntersectionPt(d, a, proj[3], proj[0]) != null) return true;

    return false;
  }