/// <summary>
        /// Creates the smallest BoundingSphere that can contain a specified BoundingBox.
        /// </summary>
        /// <param name="box">The BoundingBox to create the BoundingSphere from.</param><param name="result">[OutAttribute] The created BoundingSphere.</param>
        public static void CreateFromBoundingBox(ref BoundingBox box, out BoundingSphere result)
        {
            // Find the center of the box.
            Vector3 center = new Vector3((box.Min.X + box.Max.X) / 2.0f,
                                         (box.Min.Y + box.Max.Y) / 2.0f,
                                         (box.Min.Z + box.Max.Z) / 2.0f);

            // Find the distance between the center and one of the corners of the box.
            float radius = Vector3.Distance(center, box.Max);

            result = new BoundingSphere(center, radius);
        }
 /// <summary>
 /// Checks whether the current BoundingFrustum intersects a BoundingSphere.
 /// </summary>
 /// <param name="sphere">The BoundingSphere to check for intersection with.</param><param name="result">[OutAttribute] true if the BoundingFrustum and BoundingSphere intersect; false otherwise.</param>
 public void Intersects(ref BoundingSphere sphere, out bool result)
 {
     ContainmentType containment;
     Contains(ref sphere, out containment);
     result = containment != ContainmentType.Disjoint;
 }
        /// <summary>
        /// Checks whether the current BoundingFrustum contains the specified BoundingSphere.
        /// </summary>
        /// <param name="sphere">The BoundingSphere to test for overlap.</param><param name="result">[OutAttribute] Enumeration indicating the extent of overlap.</param>
        public void Contains(ref BoundingSphere sphere, out ContainmentType result)
        {
            CreatePlanes();

            var intersects = false;
            for (var i = 0; i < PlaneCount; ++i)
            {
                PlaneIntersectionType planeIntersectionType;
                sphere.Intersects(ref _planes[i], out planeIntersectionType);

                switch (planeIntersectionType)
                {
                    case PlaneIntersectionType.Front:
                        result = ContainmentType.Disjoint;
                        return;
                    case PlaneIntersectionType.Intersecting:
                        intersects = true;
                        break;
                }
            }
            result = intersects ? ContainmentType.Intersects : ContainmentType.Contains;
        }
 public bool Intersects(BoundingSphere sphere)
 {
     bool result;
     Intersects(ref sphere, out result);
     return result;
 }
        public void AssertThat_Inflate_ByNegativeValue_DecreasesRadius()
        {
            BoundingSphere s = new BoundingSphere(Vector3.Zero, 10);

            Assert.AreEqual(5, s.Inflate(-10).Radius);
        }
 /// <summary>
 /// Creates the smallest BoundingBox that will contain the specified BoundingSphere.
 /// </summary>
 /// <param name="sphere">The BoundingSphere to contain.</param><param name="result">[OutAttribute] The created BoundingBox.</param>
 public static void CreateFromSphere(ref BoundingSphere sphere, out BoundingBox result)
 {
     var corner = new Vector3(sphere.Radius);
     result.Min = sphere.Center - corner;
     result.Max = sphere.Center + corner;
 }
        /// <summary>
        /// Tests whether the BoundingBox contains a BoundingSphere.
        /// </summary>
        /// <param name="sphere">The BoundingSphere to test for overlap.</param><param name="result">[OutAttribute] Enumeration indicating the extent of overlap.</param>
        public void Contains(ref BoundingSphere sphere, out ContainmentType result)
        {
            if (sphere.Center.X - Min.X >= sphere.Radius
                && sphere.Center.Y - Min.Y >= sphere.Radius
                && sphere.Center.Z - Min.Z >= sphere.Radius
                && Max.X - sphere.Center.X >= sphere.Radius
                && Max.Y - sphere.Center.Y >= sphere.Radius
                && Max.Z - sphere.Center.Z >= sphere.Radius)
            {
                result = ContainmentType.Contains;
                return;
            }

            double dmin = 0;

            double e = sphere.Center.X - Min.X;
            if (e < 0)
            {
                if (e < -sphere.Radius)
                {
                    result = ContainmentType.Disjoint;
                    return;
                }
                dmin += e * e;
            }
            else
            {
                e = sphere.Center.X - Max.X;
                if (e > 0)
                {
                    if (e > sphere.Radius)
                    {
                        result = ContainmentType.Disjoint;
                        return;
                    }
                    dmin += e * e;
                }
            }

            e = sphere.Center.Y - Min.Y;
            if (e < 0)
            {
                if (e < -sphere.Radius)
                {
                    result = ContainmentType.Disjoint;
                    return;
                }
                dmin += e * e;
            }
            else
            {
                e = sphere.Center.Y - Max.Y;
                if (e > 0)
                {
                    if (e > sphere.Radius)
                    {
                        result = ContainmentType.Disjoint;
                        return;
                    }
                    dmin += e * e;
                }
            }

            e = sphere.Center.Z - Min.Z;
            if (e < 0)
            {
                if (e < -sphere.Radius)
                {
                    result = ContainmentType.Disjoint;
                    return;
                }
                dmin += e * e;
            }
            else
            {
                e = sphere.Center.Z - Max.Z;
                if (e > 0)
                {
                    if (e > sphere.Radius)
                    {
                        result = ContainmentType.Disjoint;
                        return;
                    }
                    dmin += e * e;
                }
            }

            if (dmin <= sphere.Radius * sphere.Radius)
            {
                result = ContainmentType.Intersects;
                return;
            }

            result = ContainmentType.Disjoint;
        }
        /// <summary>
        /// Creates a BoundingSphere that contains the two specified BoundingSphere instances.
        /// </summary>
        /// <param name="original">BoundingSphere to be merged.</param><param name="additional">BoundingSphere to be merged.</param><param name="result">[OutAttribute] The created BoundingSphere.</param>
        public static void CreateMerged(ref BoundingSphere original, ref BoundingSphere additional, out BoundingSphere result)
        {
            Vector3 ocenterToaCenter = Vector3.Subtract(additional.Center, original.Center);
            float distance = ocenterToaCenter.Length();
            if (distance <= original.Radius + additional.Radius)//intersect
            {
                if (distance <= original.Radius - additional.Radius)//original contain additional
                {
                    result = original;
                    return;
                }
                if (distance <= additional.Radius - original.Radius)//additional contain original
                {
                    result = additional;
                    return;
                }
            }
            //else find center of new sphere and radius
            float leftRadius = Math.Max(original.Radius - distance, additional.Radius);
            float rightradius = Math.Max(original.Radius + distance, additional.Radius);
            ocenterToaCenter = ocenterToaCenter + (((leftRadius - rightradius) / (2 * ocenterToaCenter.Length())) * ocenterToaCenter);//oCenterToResultCenter

            result = new BoundingSphere
            {
                Center = original.Center + ocenterToaCenter,
                Radius = (leftRadius + rightradius) / 2
            };
        }
        /// <summary>
        /// Expand bounding sphere diameter by distance
        /// </summary>
        /// <param name="sphere">The sphere to mutate</param>
        /// <param name="distance"></param>
        /// <returns></returns>
        public static void Inflate(ref BoundingSphere sphere, float distance)
        {
            var r = sphere.Radius + distance / 2;
            if (r < 0)
                throw new ArgumentOutOfRangeException("distance", "Distance specified to inflate sphere is a negative value larger than the total diameter (this would cause a negative radius!)");

            sphere.Radius = r;
        }
Example #10
0
        /// <summary>
        /// Checks whether the current Ray intersects a BoundingSphere.
        /// </summary>
        /// <param name="sphere">The BoundingSphere to check for intersection with.</param><param name="result">[OutAttribute] Distance at which the ray intersects the BoundingSphere or null if there is no intersection.</param>
        public void Intersects(ref BoundingSphere sphere, out float? result)
        {
            // Find the vector between where the ray starts the the sphere's centre
            Vector3 difference = sphere.Center - Position;

            float differenceLengthSquared = difference.LengthSquared();
            float sphereRadiusSquared = sphere.Radius * sphere.Radius;

            // If the distance between the ray start and the sphere's centre is less than
            // the radius of the sphere, it means we've intersected. N.B. checking the LengthSquared is faster.
            if (differenceLengthSquared < sphereRadiusSquared)
            {
                result = 0.0f;
                return;
            }

            var distanceAlongRay = Vector3.Dot(Direction, difference);
            // If the ray is pointing away from the sphere then we don't ever intersect
            if (distanceAlongRay < 0)
            {
                result = null;
                return;
            }

            // Next we kinda use Pythagoras to check if we are within the bounds of the sphere
            // if x = radius of sphere
            // if y = distance between ray position and sphere centre
            // if z = the distance we've travelled along the ray
            // if x^2 + z^2 - y^2 < 0, we do not intersect
            float dist = sphereRadiusSquared + distanceAlongRay * distanceAlongRay - differenceLengthSquared;

            result = (dist < 0) ? null : distanceAlongRay - (float?)Math.Sqrt(dist);
        }
 /// <summary>
 /// Creates a BoundingSphere that contains the two specified BoundingSphere instances.
 /// </summary>
 /// <param name="original">BoundingSphere to be merged.</param><param name="additional">BoundingSphere to be merged.</param>
 public static BoundingSphere CreateMerged(BoundingSphere original, BoundingSphere additional)
 {
     BoundingSphere result;
     CreateMerged(ref original, ref additional, out result);
     return result;
 }
Example #12
0
 /// <summary>
 /// Checks whether the Ray intersects a specified BoundingSphere.
 /// </summary>
 /// <param name="sphere">The BoundingSphere to check for intersection with the Ray.</param>
 public float? Intersects(BoundingSphere sphere)
 {
     float? result;
     Intersects(ref sphere, out result);
     return result;
 }
Example #13
0
        public IEnumerable<string> Intersections(BoundingSphere sphere)
        {
            return _model
                .Model
                .SkinningData
                .Bounds
                .Select((b, i) =>
                {
                    Matrix4x4 transform;
                    Matrix4x4.Invert(_worldTransforms[i], out transform);

                    var center = Vector3.Transform(sphere.Center, transform);                   //Transform sphere center into bone space

                    var intersects = b.Intersects(new BoundingSphere(center, sphere.Radius));   //Intersect new sphere in bone space
                    var name = _model.Model.SkinningData.Names[i];

                    return new KeyValuePair<bool, string>(intersects, name);

                })
                .Where(a => a.Key)
                .Select(a => a.Value);
        }
        public void AssertThat_Inflate_IncreasesRadius()
        {
            BoundingSphere s = new BoundingSphere(Vector3.Zero, 10);

            Assert.AreEqual(15, s.Inflate(10).Radius);
        }
Example #15
0
        public static void AddBoundingSphere(BoundingSphere sphere, Color color, float life = 0f)
        {
            // Get a DebugShape we can use to draw the sphere
            DebugShape shape = GetShapeForLines(SPHERE_LINE_COUNT, life);

            // Iterate our unit sphere vertices
            for (int i = 0; i < _unitSphere.Length; i++)
            {
                // Compute the vertex position by transforming the point by the radius and center of the sphere
                Vector3 vertPos = _unitSphere[i] * sphere.Radius + sphere.Center;

                // Add the vertex to the shape
                shape.Vertices[i] = new VertexPositionColor(vertPos.ToXNA(), color);
            }
        }
        /// <summary>
        /// Checks whether the current BoundingSphere contains the specified BoundingSphere.
        /// </summary>
        /// <param name="sphere">The BoundingSphere to test for overlap.</param><param name="result">[OutAttribute] Enumeration indicating the extent of overlap.</param>
        public void Contains(ref BoundingSphere sphere, out ContainmentType result)
        {
            float sqDistance = Vector3.DistanceSquared(sphere.Center, Center);

            if (sqDistance > (sphere.Radius + Radius) * (sphere.Radius + Radius))
                result = ContainmentType.Disjoint;

            else if (sqDistance <= (Radius - sphere.Radius) * (Radius - sphere.Radius))
                result = ContainmentType.Contains;

            else
                result = ContainmentType.Intersects;
        }
 /// <summary>
 /// Creates the smallest BoundingBox that will contain the specified BoundingSphere.
 /// </summary>
 /// <param name="sphere">The BoundingSphere to contain.</param>
 public static BoundingBox CreateFromSphere(BoundingSphere sphere)
 {
     BoundingBox result;
     CreateFromSphere(ref sphere, out result);
     return result;
 }
 /// <summary>
 /// Determines whether the specified BoundingSphere is equal to the current BoundingSphere.
 /// </summary>
 /// <param name="other">The BoundingSphere to compare with the current BoundingSphere.</param>
 public bool Equals(BoundingSphere other)
 {
     return Radius.Equals(other.Radius) && Center.Equals(other.Center);
 }
 public ContainmentType Contains(BoundingSphere sphere)
 {
     ContainmentType result;
     Contains(ref sphere, out result);
     return result;
 }
        /// <summary>
        /// Checks whether the current BoundingSphere intersects another BoundingSphere.
        /// </summary>
        /// <param name="sphere">The BoundingSphere to check for intersection with.</param><param name="result">[OutAttribute] true if the BoundingSphere instances intersect; false otherwise.</param>
        public void Intersects(ref BoundingSphere sphere, out bool result)
        {
            float sqDistance = Vector3.DistanceSquared(sphere.Center, Center);

            var totalRadius = sphere.Radius + Radius;
            result = sqDistance < totalRadius * totalRadius;
        }
 /// <summary>
 /// Creates an instance of BoundingBox around a BoundingSphere
 /// </summary>
 /// <param name="sphere">The sphere to constain within this box</param>
 public BoundingBox(BoundingSphere sphere)
     : this(sphere.Center - new Vector3(sphere.Radius), sphere.Center + new Vector3(sphere.Radius))
 {
 }
 /// <summary>
 /// Translates and scales the BoundingSphere using a given Matrix.
 /// </summary>
 /// <param name="matrix">A transformation matrix that might include translation, rotation, or uniform scaling. Note that BoundingSphere.Transform will not return correct results if there are non-uniform scaling, shears, or other unusual transforms in this transformation matrix. This is because there is no way to shear or non-uniformly scale a sphere. Such an operation would cause the sphere to lose its shape as a sphere.</param><param name="result">[OutAttribute] The transformed BoundingSphere.</param>
 public void Transform(ref Matrix4x4 matrix, out BoundingSphere result)
 {
     result.Center = Vector3.Transform(Center, matrix);
     result.Radius = Radius * ((float)Math.Sqrt(Math.Max(((matrix.M11 * matrix.M11) + (matrix.M12 * matrix.M12)) + (matrix.M13 * matrix.M13), Math.Max(((matrix.M21 * matrix.M21) + (matrix.M22 * matrix.M22)) + (matrix.M23 * matrix.M23), ((matrix.M31 * matrix.M31) + (matrix.M32 * matrix.M32)) + (matrix.M33 * matrix.M33)))));
 }
        /// <summary>
        /// Checks whether the current BoundingBox intersects a BoundingSphere.
        /// </summary>
        /// <param name="sphere">The BoundingSphere to check for intersection with.</param><param name="result">[OutAttribute] true if the BoundingBox and BoundingSphere intersect; false otherwise.</param>
        public void Intersects(ref BoundingSphere sphere, out bool result)
        {
            if (sphere.Center.X - Min.X > sphere.Radius
                && sphere.Center.Y - Min.Y > sphere.Radius
                && sphere.Center.Z - Min.Z > sphere.Radius
                && Max.X - sphere.Center.X > sphere.Radius
                && Max.Y - sphere.Center.Y > sphere.Radius
                && Max.Z - sphere.Center.Z > sphere.Radius)
            {
                result = true;
                return;
            }

            double dmin = 0;

            if (sphere.Center.X - Min.X <= sphere.Radius)
                dmin += (sphere.Center.X - Min.X) * (sphere.Center.X - Min.X);
            else if (Max.X - sphere.Center.X <= sphere.Radius)
                dmin += (sphere.Center.X - Max.X) * (sphere.Center.X - Max.X);

            if (sphere.Center.Y - Min.Y <= sphere.Radius)
                dmin += (sphere.Center.Y - Min.Y) * (sphere.Center.Y - Min.Y);
            else if (Max.Y - sphere.Center.Y <= sphere.Radius)
                dmin += (sphere.Center.Y - Max.Y) * (sphere.Center.Y - Max.Y);

            if (sphere.Center.Z - Min.Z <= sphere.Radius)
                dmin += (sphere.Center.Z - Min.Z) * (sphere.Center.Z - Min.Z);
            else if (Max.Z - sphere.Center.Z <= sphere.Radius)
                dmin += (sphere.Center.Z - Max.Z) * (sphere.Center.Z - Max.Z);

            if (dmin <= sphere.Radius * sphere.Radius)
            {
                result = true;
                return;
            }

            result = false;
        }
        public void AssertThat_Inflate_ByNegativeValueLargerThanDiameter_Throws()
        {
            BoundingSphere s = new BoundingSphere(Vector3.Zero, 10);

            var result = s.Inflate(-50);
        }