/// <summary> /// Plane/Box intersection test. /// </summary> /// <param name="plane"></param> /// <param name="box"></param> /// <returns>True if there was an intersection, false otherwise.</returns> public static bool Intersects(Plane plane, AxisAlignedBox box) { if (box.IsNull) { return(false); } // Get corners of the box Vector3[] corners = box.Corners; // Test which side of the plane the corners are // Intersection occurs when at least one corner is on the // opposite side to another PlaneSide lastSide = plane.GetSide(corners[0]); for (int corner = 1; corner < 8; corner++) { if (plane.GetSide(corners[corner]) != lastSide) { return(true); } } return(false); }
/// <summary> /// Intersection test with an <see cref="AxisAlignedBox"/>. /// </summary> /// <remarks> /// May return false positives but will never miss an intersection. /// </remarks> /// <param name="box">Box to test.</param> /// <returns>True if interesecting, false otherwise.</returns> public bool Intersects(AxisAlignedBox box) { if (box.IsNull) { return(false); } // If all points are on outside of any plane, we fail Vector3[] points = box.Corners; for (int i = 0; i < planes.Count; i++) { Plane plane = planes[i]; // Test which side of the plane the corners are // Intersection fails when at all corners are on the // outside of one plane bool splittingPlane = true; for (int corner = 0; corner < 8; corner++) { if (plane.GetSide(points[corner]) != outside) { // this point is on the wrong side splittingPlane = false; break; } } if (splittingPlane) { // Found a splitting plane therefore return not intersecting return(false); } } // couldn't find a splitting plane, assume intersecting return(true); }
/// <summary> /// Ray/PlaneBoundedVolume intersection test. /// </summary> /// <param name="ray"></param> /// <param name="volume"></param> /// <returns>Struct that contains a bool (hit?) and distance.</returns> public static IntersectResult Intersects(Ray ray, PlaneBoundedVolume volume) { List <Plane> planes = volume.planes; float maxExtDist = 0.0f; float minIntDist = float.PositiveInfinity; float dist, denom, nom; for (int i = 0; i < planes.Count; i++) { Plane plane = planes[i]; denom = plane.Normal.Dot(ray.Direction); if (MathUtil.Abs(denom) < float.Epsilon) { // Parallel if (plane.GetSide(ray.Origin) == volume.outside) { return(new IntersectResult(false, 0)); } continue; } nom = plane.Normal.Dot(ray.Origin) + plane.D; dist = -(nom / denom); if (volume.outside == PlaneSide.Negative) { nom = -nom; } if (dist > 0.0f) { if (nom > 0.0f) { if (maxExtDist < dist) { maxExtDist = dist; } } else { if (minIntDist > dist) { minIntDist = dist; } } } else { //Ray points away from plane if (volume.outside == PlaneSide.Negative) { denom = -denom; } if (denom > 0.0f) { return(new IntersectResult(false, 0)); } } } if (maxExtDist > minIntDist) { return(new IntersectResult(false, 0)); } return(new IntersectResult(true, maxExtDist)); }