/// <summary>
        /// Computes an intersection of the ray and the sphere
        /// </summary>
        public static bool RaySphere(Vector3 rayOrigin, Vector3 rayDirection, Vector3 sphereCenter, float sphereRadius,
                                     out IntersectionRaySphere intersection)
        {
            Vector3 originToCenter   = sphereCenter - rayOrigin;
            float   centerProjection = Vector3.Dot(rayDirection, originToCenter);

            if (centerProjection + sphereRadius < -Geometry.Epsilon)
            {
                intersection = IntersectionRaySphere.None();
                return(false);
            }

            float sqrDistanceToLine         = originToCenter.sqrMagnitude - centerProjection * centerProjection;
            float sqrDistanceToIntersection = sphereRadius * sphereRadius - sqrDistanceToLine;

            if (sqrDistanceToIntersection < -Geometry.Epsilon)
            {
                intersection = IntersectionRaySphere.None();
                return(false);
            }
            if (sqrDistanceToIntersection < Geometry.Epsilon)
            {
                if (centerProjection < -Geometry.Epsilon)
                {
                    intersection = IntersectionRaySphere.None();
                    return(false);
                }
                intersection = IntersectionRaySphere.Point(rayOrigin + rayDirection * centerProjection);
                return(true);
            }

            // Line intersection
            float distanceToIntersection = Mathf.Sqrt(sqrDistanceToIntersection);
            float distanceA = centerProjection - distanceToIntersection;
            float distanceB = centerProjection + distanceToIntersection;

            if (distanceA < -Geometry.Epsilon)
            {
                if (distanceB < -Geometry.Epsilon)
                {
                    intersection = IntersectionRaySphere.None();
                    return(false);
                }
                intersection = IntersectionRaySphere.Point(rayOrigin + rayDirection * distanceB);
                return(true);
            }

            Vector3 pointA = rayOrigin + rayDirection * distanceA;
            Vector3 pointB = rayOrigin + rayDirection * distanceB;

            intersection = IntersectionRaySphere.TwoPoints(pointA, pointB);
            return(true);
        }
 /// <summary>
 /// Computes an intersection of the ray and the sphere
 /// </summary>
 public static bool RaySphere(Ray ray, Sphere sphere, out IntersectionRaySphere intersection)
 {
     return(RaySphere(ray.origin, ray.direction, sphere.center, sphere.radius, out intersection));
 }