예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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);
            }
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
 /// <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));
 }
예제 #7
0
 /// <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));
 }
예제 #8
0
        /// <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));
        }