public static RaycastResult Raycast <T>(this IEnumerable <T> e, Func <T, Bounds> getLocalBoundingbox, Func <T, Matrix4x4> getTransform, Ray ray) where T : class
        {
            var closest   = new RaycastResult();
            var newResult = new RaycastResult();

            //IWorldSelectableProvider closestProvider = null;
            //Selectable closestSelectable = null;

            foreach (var s in e)
            {
                var   transformation = getTransform(s);
                var   localRay       = ray.Transform(Matrix4x4.Inverse(transformation));
                float dist;
                if (getLocalBoundingbox(s).IntersectRay(localRay, out dist))
                {
                    var localPoint = localRay.GetPoint(dist);
                    var point      = transformation.MultiplyPoint3x4(localPoint);
                    dist = Vector3.Distance(ray.origin, point);
                }

                newResult.Set(dist, s);

                if (newResult.IsCloser(closest))
                {
                    newResult.CopyTo(closest);
                }
            }

            return(closest);
        }
        public static RaycastResult Raycast <T>(this IEnumerable <T> e, Func <T, BoundingBox> getLocalBoundingbox, Func <T, Matrix> getTransform, Ray ray) where T : class
        {
            var closest   = new RaycastResult();
            var newResult = new RaycastResult();

            //IWorldSelectableProvider closestProvider = null;
            //Selectable closestSelectable = null;

            foreach (var s in e)
            {
                var transformation = getTransform(s);
                var localRay       = ray.Transform(Matrix.Invert(transformation));
                var dist           = localRay.xna().Intersects(getLocalBoundingbox(s).xna());
                if (dist != null)
                {
                    var localPoint = localRay.GetPoint(dist.Value);
                    var point      = Vector3.TransformCoordinate(localPoint, transformation);
                    dist = Vector3.Distance(ray.Position, point);
                }

                newResult.Set(dist, s);

                if (newResult.IsCloser(closest))
                {
                    newResult.CopyTo(closest);
                }
            }

            return(closest);
        }
        public static RaycastResult RaycastDetail <T>(this IEnumerable <T> e, Func <T, Ray, float?> intersect, Ray ray) where T : class
        {
            var closest   = new RaycastResult();
            var newResult = new RaycastResult();

            //IWorldSelectableProvider closestProvider = null;
            //Selectable closestSelectable = null;

            foreach (var s in e)
            {
                var dist = intersect(s, ray);

                newResult.Set(dist, s);

                if (newResult.IsCloser(closest))
                {
                    newResult.CopyTo(closest);
                }
            }

            return(closest);
        }
        public void UpdateTarget(Ray ray)
        {
            var closest   = new RaycastResult();
            var newResult = new RaycastResult();

            IWorldSelectableProvider closestProvider = null;
            Selectable closestSelectable             = null;

            foreach (var p in providers)
            {
                foreach (var s in p.GetSelectables())
                {
                    newResult = s.Intersects(ray);
                    if (newResult.IsCloser(closest))
                    {
                        newResult.CopyTo(closest);
                        closestProvider   = p;
                        closestSelectable = s;
                    }
                }
            }
            setTargeted(closestProvider, closestSelectable);
        }