/// <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, AABBox 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> /// Sphere/Box intersection test. /// </summary> /// <param name="sphere"></param> /// <param name="box"></param> /// <returns>True if there was an intersection, false otherwise.</returns> public static bool Intersects(Sphere sphere, AABBox box) { if (box.IsNull) { return(false); } // Use splitting planes Vector3 center = sphere.Center; float radius = sphere.Radius; Vector3 min = box.Minimum; Vector3 max = box.Maximum; // just test facing planes, early fail if sphere is totally outside if (center.x < min.x && min.x - center.x > radius) { return(false); } if (center.x > max.x && center.x - max.x > radius) { return(false); } if (center.y < min.y && min.y - center.y > radius) { return(false); } if (center.y > max.y && center.y - max.y > radius) { return(false); } if (center.z < min.z && min.z - center.z > radius) { return(false); } if (center.z > max.z && center.z - max.z > radius) { return(false); } // Must intersect return(true); }
/// <summary> /// Tests an intersection between two boxes. /// </summary> /// <param name="boxA"> /// The primary box. /// </param> /// <param name="boxB"> /// The box to test intersection with boxA. /// </param> /// <returns> /// <list type="bullet"> /// <item> /// <description>None - There was no intersection between the 2 boxes.</description> /// </item> /// <item> /// <description>Contained - boxA is fully within boxB.</description> /// </item> /// <item> /// <description>Contains - boxB is fully within boxA.</description> /// </item> /// <item> /// <description>Partial - boxA is partially intersecting with boxB.</description> /// </item> /// </list> /// </returns> /// Submitted by: romout public static Intersection Intersects(AABBox boxA, AABBox boxB) { // grab the max and mix vectors for both boxes for comparison Vector3 minA = boxA.Minimum; Vector3 maxA = boxA.Maximum; Vector3 minB = boxB.Minimum; Vector3 maxB = boxB.Maximum; if ((minB.x < minA.x) && (maxB.x > maxA.x) && (minB.y < minA.y) && (maxB.y > maxA.y) && (minB.z < minA.z) && (maxB.z > maxA.z)) { // boxA is within boxB return(Intersection.Contained); } if ((minB.x > minA.x) && (maxB.x < maxA.x) && (minB.y > minA.y) && (maxB.y < maxA.y) && (minB.z > minA.z) && (maxB.z < maxA.z)) { // boxB is within boxA return(Intersection.Contains); } if ((minB.x > maxA.x) || (minB.y > maxA.y) || (minB.z > maxA.z) || (maxB.x < minA.x) || (maxB.y < minA.y) || (maxB.z < minA.z)) { // not interesting at all return(Intersection.None); } // if we got this far, they are partially intersecting return(Intersection.Partial); }
/// <summary> /// Allows for merging two boxes together (combining). /// </summary> /// <param name="box">Source box.</param> public void Merge(AABBox box) { // nothing to merge with in this case, just return if (box.IsNull) { return; } else if (isNull) { SetExtents(box.Minimum, box.Maximum); } else { Vector3 min = minVector; Vector3 max = maxVector; min.Floor(box.Minimum); max.Ceil(box.Maximum); SetExtents(min, max); } }
/// <summary> /// Returns whether or not this box intersects another. /// </summary> /// <param name="box2"></param> /// <returns>True if the 2 boxes intersect, false otherwise.</returns> public bool Intersects(AABBox box2) { // Early-fail for nulls if (this.IsNull || box2.IsNull) { return(false); } // Use up to 6 separating planes if (this.maxVector.x < box2.minVector.x) { return(false); } if (this.maxVector.y < box2.minVector.y) { return(false); } if (this.maxVector.z < box2.minVector.z) { return(false); } if (this.minVector.x > box2.maxVector.x) { return(false); } if (this.minVector.y > box2.maxVector.y) { return(false); } if (this.minVector.z > box2.maxVector.z) { return(false); } // otherwise, must be intersecting return(true); }
/// <summary> /// Returns whether or not this sphere interects a box. /// </summary> /// <param name="box"></param> /// <returns>True if the box intersects, false otherwise.</returns> public bool Intersects(AABBox box) { return(MathUtil.Intersects(this, box)); }
/// <summary> /// Tests whether this ray intersects the given box. /// </summary> /// <param name="box"></param> /// <returns> /// Struct containing info on whether there was a hit, and the distance from the /// origin of this ray where the intersect happened. /// </returns> public IntersectResult Intersects(AABBox box) { return(MathUtil.Intersects(this, box)); }
/// <summary> /// Tests an intersection between a ray and a box. /// </summary> /// <param name="ray"></param> /// <param name="box"></param> /// <returns>A Pair object containing whether the intersection occurred, and the distance between the 2 objects.</returns> public static IntersectResult Intersects(Ray ray, AABBox box) { if (box.IsNull) { return(new IntersectResult(false, 0)); } float lowt = 0.0f; float t; bool hit = false; Vector3 hitPoint; Vector3 min = box.Minimum; Vector3 max = box.Maximum; // check origin inside first if (ray.origin > min && ray.origin < max) { return(new IntersectResult(true, 0.0f)); } // check each face in turn, only check closest 3 // Min X if (ray.origin.x < min.x && ray.direction.x > 0) { t = (min.x - ray.origin.x) / ray.direction.x; if (t > 0) { // substitue t back into ray and check bounds and distance hitPoint = ray.origin + ray.direction * t; if (hitPoint.y >= min.y && hitPoint.y <= max.y && hitPoint.z >= min.z && hitPoint.z <= max.z && (!hit || t < lowt)) { hit = true; lowt = t; } } } // Max X if (ray.origin.x > max.x && ray.direction.x < 0) { t = (max.x - ray.origin.x) / ray.direction.x; if (t > 0) { // substitue t back into ray and check bounds and distance hitPoint = ray.origin + ray.direction * t; if (hitPoint.y >= min.y && hitPoint.y <= max.y && hitPoint.z >= min.z && hitPoint.z <= max.z && (!hit || t < lowt)) { hit = true; lowt = t; } } } // Min Y if (ray.origin.y < min.y && ray.direction.y > 0) { t = (min.y - ray.origin.y) / ray.direction.y; if (t > 0) { // substitue t back into ray and check bounds and distance hitPoint = ray.origin + ray.direction * t; if (hitPoint.x >= min.x && hitPoint.x <= max.x && hitPoint.z >= min.z && hitPoint.z <= max.z && (!hit || t < lowt)) { hit = true; lowt = t; } } } // Max Y if (ray.origin.y > max.y && ray.direction.y < 0) { t = (max.y - ray.origin.y) / ray.direction.y; if (t > 0) { // substitue t back into ray and check bounds and distance hitPoint = ray.origin + ray.direction * t; if (hitPoint.x >= min.x && hitPoint.x <= max.x && hitPoint.z >= min.z && hitPoint.z <= max.z && (!hit || t < lowt)) { hit = true; lowt = t; } } } // Min Z if (ray.origin.z < min.z && ray.direction.z > 0) { t = (min.z - ray.origin.z) / ray.direction.z; if (t > 0) { // substitue t back into ray and check bounds and distance hitPoint = ray.origin + ray.direction * t; if (hitPoint.x >= min.x && hitPoint.x <= max.x && hitPoint.y >= min.y && hitPoint.y <= max.y && (!hit || t < lowt)) { hit = true; lowt = t; } } } // Max Z if (ray.origin.z > max.z && ray.direction.z < 0) { t = (max.z - ray.origin.z) / ray.direction.z; if (t > 0) { // substitue t back into ray and check bounds and distance hitPoint = ray.origin + ray.direction * t; if (hitPoint.x >= min.x && hitPoint.x <= max.x && hitPoint.y >= min.y && hitPoint.y <= max.y && (!hit || t < lowt)) { hit = true; lowt = t; } } } return(new IntersectResult(hit, lowt)); }