예제 #1
0
        /// <summary>
        /// Determine whether two spheres intersect.
        /// </summary>
        /// <param name="firstSphere">The first sphere</param>
        /// <param name="secondSphere">The second sphere</param>
        public static bool SphereSphereCollision(SphereBody firstSphere, SphereBody secondSphere)
        {
            var maxDistanceSquared = Math.Pow(firstSphere.Radius + secondSphere.Radius, 2);
            var distanceSquared    = Vector3.DistanceSquared(firstSphere.Position, secondSphere.Position);

            return(distanceSquared < maxDistanceSquared);
        }
예제 #2
0
        /// <summary>
        /// Determine whether a box and a sphere intersect.
        /// </summary>
        /// <param name="box">Box physics object</param>
        /// <param name="sphere">Sphere physics object</param>
        public static bool BoxSphereCollision(BoxBody box, SphereBody sphere)
        {
            // reference frame: box at (0, 0, 0), sides aligned with axes
            var sphereCoordsRelative = sphere.Position - box.Position;

            // to transform coordinate system to have box be axis-aligned, we apply
            // the reverse of the rotation to the sphere coordinates
            var inverse = new Quaternion(box.Rotation.X, box.Rotation.Y, box.Rotation.Z, -box.Rotation.W);
            var sphereCoordsTransformed = Vector3.Transform(sphereCoordsRelative, inverse);

            // to check collision, we need to know if the shortest distance between the box
            // and the center of the sphere is smaller than the radius of the sphere
            // X coordinate of closest point = sphere.X if sphere.x is between the minimum
            // and maximum x coordinate of the box - same for y and z
            var boxMinX = -box.Size.X / 2;
            var boxMaxX = +box.Size.X / 2;
            var boxMinY = -box.Size.Y / 2;
            var boxMaxY = +box.Size.Y / 2;
            var boxMinZ = -box.Size.Z / 2;
            var boxMaxZ = +box.Size.Z / 2;

            var closestPointToSphereX = Math.Clamp(sphereCoordsTransformed.X, boxMinX, boxMaxX);
            var closestPointToSphereY = Math.Clamp(sphereCoordsTransformed.Y, boxMinY, boxMaxY);
            var closestPointToSphereZ = Math.Clamp(sphereCoordsTransformed.Z, boxMinZ, boxMaxZ);

            return(Vector3.DistanceSquared(sphereCoordsTransformed, new Vector3(closestPointToSphereX, closestPointToSphereY, closestPointToSphereZ))
                   < Math.Pow(sphere.Radius, 2));
        }
예제 #3
0
        /// <summary>
        /// Creates a sphere body.
        /// </summary>
        /// <param name="simulation">The simulation to use.</param>
        /// <param name="position">The position of the body.</param>
        /// <param name="radius">The radius of the sphere.</param>
        /// <returns>The sphere body that was created.</returns>
        public static SphereBody Create(PhysicsSimulation simulation, Vector3 position, float radius)
        {
            var obj = new SphereBody(simulation);

            obj.Position = position;
            obj.Radius   = radius;
            simulation.Register(obj);
            return(obj);
        }
예제 #4
0
        /// <summary>
        /// Determine whether a capsule and a sphere intersect.
        /// </summary>
        /// <param name="capsule">Capsule physics object</param>
        /// <param name="sphere">Sphere physics object</param>
        public static bool CapsuleSphereCollision(CapsuleBody capsule, SphereBody sphere)
        {
            // reference frame: capsule at (0, 0, 0), pointing in positive y direction
            var sphereCoordsRelative = sphere.Position - capsule.Position;

            // to transform coordinate system to have capsule be axis-aligned, we apply
            // the reverse of the rotation to the sphere coordinates
            var inverse = new Quaternion(capsule.Rotation.X, capsule.Rotation.Y, capsule.Rotation.Z, -capsule.Rotation.W);
            var sphereCoordsTransformed = Vector3.Transform(sphereCoordsRelative, inverse);

            // coordinates of the line in the centre of the cylinder part
            const int capsuleMinY = 0;
            var       capsuleMaxY = capsule.Height;

            const int closestPointToSphereX = 0;
            var       closestPointToSphereY = Math.Clamp(sphereCoordsTransformed.Y, capsuleMinY, capsuleMaxY);
            const int closestPointToSphereZ = 0;

            return(Vector3.DistanceSquared(sphereCoordsTransformed,
                                           new Vector3(closestPointToSphereX, closestPointToSphereY, closestPointToSphereZ))
                   < Math.Pow(capsule.Radius + sphere.Radius, 2));
        }