Exemplo n.º 1
0
        /// <summary>
        /// Determines if the ray intersects with the given sphere.
        /// </summary>
        /// <param name="sphere">Sphere to check intersection with</param>
        /// <returns></returns>
        public bool IntersectsWith(FSphere sphere, out float intersectionDist)
        {
            // From http://gamedev.stackexchange.com/questions/96459/fast-ray-sphere-collision-code

            // This is the ray origin's offset from the center of the sphere.
            Vector3 offsetFromSphereCenter = Origin - sphere.Center;

            float radiusSquared          = sphere.Radius * sphere.Radius;
            float offsetDotRadiusSquared = Vector3.Dot(offsetFromSphereCenter, Direction);

            // If either of these are true, that means the sphere is behind or surrounding the starting point.
            // Basically, the sphere is behind the ray's origin, or the ray's origin is within the sphere
            if (offsetDotRadiusSquared < 0 || Vector3.Dot(offsetFromSphereCenter, offsetFromSphereCenter) < radiusSquared)
            {
                intersectionDist = float.MaxValue;
                return(false);
            }

            // Flatten the ray offset onto the plan passing through the sphere's center perpendicular to the ray.
            // This gives the closest approach of the ray to the center of the sphere.
            Vector3 flattening = offsetFromSphereCenter - offsetDotRadiusSquared * Direction;

            float flatteningSquared = Vector3.Dot(flattening, flattening);

            // If this is true, the closest approach of the ray to the sphere is outside the sphere.
            // Basically, the ray doesn't intersect the sphere.
            if (flatteningSquared > radiusSquared)
            {
                intersectionDist = float.MaxValue;
                return(false);
            }

            // This is the distance from the plane where the ray enters and exits the sphere.
            float distanceFromPlane = (float)Math.Sqrt(radiusSquared - flatteningSquared);

            // This is the intersection point relative to the sphere center.
            Vector3 intersection = flattening - distanceFromPlane * Direction;

            Vector3 dirToIntersection = sphere.Center + intersection;

            dirToIntersection.Normalize();

            intersectionDist = (Origin - intersection).Length;
            return(true);
        }
        /// <summary>
        /// Determines if the ray intersects with the given sphere.
        /// </summary>
        /// <param name="sphere">Sphere to check intersection with</param>
        /// <returns></returns>
        public bool IntersectsWith(FSphere sphere, out float intersectionDist)
        {
            // From http://gamedev.stackexchange.com/questions/96459/fast-ray-sphere-collision-code

            // This is the ray origin's offset from the center of the sphere.
            Vector3 offsetFromSphereCenter = Origin - sphere.Center;

            float radiusSquared = sphere.Radius * sphere.Radius;
            float offsetDotRadiusSquared = Vector3.Dot(offsetFromSphereCenter, Direction);

            // If either of these are true, that means the sphere is behind or surrounding the starting point.
            // Basically, the sphere is behind the ray's origin, or the ray's origin is within the sphere
            if (offsetDotRadiusSquared < 0 || Vector3.Dot(offsetFromSphereCenter, offsetFromSphereCenter) < radiusSquared)
            {
                intersectionDist = float.MaxValue;
                return false;
            }

            // Flatten the ray offset onto the plan passing through the sphere's center perpendicular to the ray.
            // This gives the closest approach of the ray to the center of the sphere.
            Vector3 flattening = offsetFromSphereCenter - offsetDotRadiusSquared * Direction;

            float flatteningSquared = Vector3.Dot(flattening, flattening);

            // If this is true, the closest approach of the ray to the sphere is outside the sphere.
            // Basically, the ray doesn't intersect the sphere.
            if (flatteningSquared > radiusSquared)
            {
                intersectionDist = float.MaxValue;
                return false;
            }

            // This is the distance from the plane where the ray enters and exits the sphere.
            float distanceFromPlane = (float)Math.Sqrt(radiusSquared - flatteningSquared);

            // This is the intersection point relative to the sphere center.
            Vector3 intersection = flattening - distanceFromPlane * Direction;

            Vector3 dirToIntersection = sphere.Center + intersection;
            dirToIntersection.Normalize();

            intersectionDist = (Origin - intersection).Length;
            return true;
        }