/// <summary>
        /// Calculates the first occuring collision event on this object's track using the collisionrules.
        /// </summary>
        internal void CalculateClosestCollision()
        {
            ClosestCollisionSpeedFraction = float.PositiveInfinity;

            //no (more) collision checking this step please
            if (SpeedLeft == 0f || Speed == Point.Zero)
            {
                SpeedLeft = 0f;
                return;
            }

            float touchingSpeedLeftFraction = float.PositiveInfinity;
            Point intersectionAxis;

            //decide which target of the rules is closest and within collision range
            foreach (CollisionRule cRule in CollisionRules)
            {
                //skip if this rule doesn't have to be checked anyway
                if (!cRule.Active)
                {
                    continue;
                }

                //get collision candidates once if they will be checked (JIT)
                if (CollisionCandidates == null && (cRule.Type == CollisionRuleType.Object || cRule.Type == CollisionRuleType.ObjectType || cRule.Type == CollisionRuleType.Objectmap))
                {
                    CollisionCandidates = Game.QuadTree.GetCollisionCandidates(this);
                }

                switch (cRule.Type)
                {
                case CollisionRuleType.Shape:
                    if (Bounds.IntersectsWith((Shape)cRule.Target, Speed, out touchingSpeedLeftFraction, out intersectionAxis) &&
                        touchingSpeedLeftFraction > 0f &&
                        touchingSpeedLeftFraction <= SpeedLeft &&
                        touchingSpeedLeftFraction < ClosestCollisionSpeedFraction)
                    {
                        ClosestCollisionSpeedFraction = touchingSpeedLeftFraction * SpeedLeft;
                        ClosestCollisionTouchingAxis  = intersectionAxis;
                        ClosestCollisionRule          = cRule;
                        ClosestCollisionMethodArg     = cRule.Target;
                        ClosestCollisionRelativeSpeed = Speed;
                    }
                    break;

                case CollisionRuleType.Object:
                    if (CollisionCandidates.Contains((PhysicalObject)cRule.Target) &&
                        Bounds.IntersectsWith(((PhysicalObject)cRule.Target).Bounds, Speed - ((PhysicalObject)cRule.Target).Speed, out touchingSpeedLeftFraction, out intersectionAxis) &&
                        touchingSpeedLeftFraction > 0f &&
                        touchingSpeedLeftFraction <= SpeedLeft &&
                        (touchingSpeedLeftFraction <= ((PhysicalObject)cRule.Target).SpeedLeft ||
                         ((PhysicalObject)cRule.Target).Speed == Point.Zero) &&
                        touchingSpeedLeftFraction < ClosestCollisionSpeedFraction)
                    {
                        ClosestCollisionSpeedFraction = touchingSpeedLeftFraction * SpeedLeft;
                        ClosestCollisionTouchingAxis  = intersectionAxis;
                        ClosestCollisionRule          = cRule;
                        ClosestCollisionMethodArg     = cRule.Target;
                        ClosestCollisionRelativeSpeed = Speed - ((PhysicalObject)cRule.Target).Speed;
                    }
                    break;

                case CollisionRuleType.ObjectType:
                    foreach (PhysicalObject obj in Resources.PhysicalObjectsByType[(Type)cRule.Target])
                    {
                        if (CollisionCandidates.Contains(obj) &&
                            Bounds.IntersectsWith(obj.Bounds, Speed - obj.Speed, out touchingSpeedLeftFraction, out intersectionAxis) &&
                            touchingSpeedLeftFraction > 0f &&
                            touchingSpeedLeftFraction <= SpeedLeft &&
                            (touchingSpeedLeftFraction <= obj.SpeedLeft ||
                             obj.Speed == Point.Zero) &&
                            touchingSpeedLeftFraction < ClosestCollisionSpeedFraction)
                        {
                            ClosestCollisionSpeedFraction = touchingSpeedLeftFraction * SpeedLeft;
                            ClosestCollisionTouchingAxis  = intersectionAxis;
                            ClosestCollisionRule          = cRule;
                            ClosestCollisionMethodArg     = obj;
                            ClosestCollisionRelativeSpeed = Speed - obj.Speed;
                        }
                    }
                    break;

                case CollisionRuleType.Objectmap:
                    foreach (PhysicalObject obj in ((Objectmap)cRule.Target).ActivePhysicalObjects)
                    {
                        //whether the object should be checked if the filter is enabled
                        if (!cRule.FilterEnabled || cRule.ObjectmapFilter.Contains(obj.GetType()))                                 //account for inheritance
                        {
                            if (CollisionCandidates.Contains(obj) &&
                                Bounds.IntersectsWith(obj.Bounds, Speed - obj.Speed, out touchingSpeedLeftFraction, out intersectionAxis) &&
                                touchingSpeedLeftFraction > 0f &&
                                touchingSpeedLeftFraction <= SpeedLeft &&
                                (touchingSpeedLeftFraction <= obj.SpeedLeft ||
                                 obj.Speed == Point.Zero) &&
                                touchingSpeedLeftFraction < ClosestCollisionSpeedFraction)
                            {
                                ClosestCollisionSpeedFraction = touchingSpeedLeftFraction * SpeedLeft;
                                ClosestCollisionTouchingAxis  = intersectionAxis;
                                ClosestCollisionRule          = cRule;
                                ClosestCollisionMethodArg     = obj;
                                ClosestCollisionRelativeSpeed = Speed - obj.Speed;
                            }
                        }
                    }
                    break;

                case CollisionRuleType.Spritemap:
                    foreach (ManagedSprite sprite in ((Spritemap)cRule.Target).ManagedSprites)
                    {
                        //whether the object should be checked if the filter is enabled
                        if (!cRule.FilterEnabled || cRule.SpritemapFilter.Contains(sprite.TargetSprite))                                 //account for inheritance
                        {
                            if (Bounds.IntersectsWith(sprite, Speed, out touchingSpeedLeftFraction, out intersectionAxis) &&
                                touchingSpeedLeftFraction > 0f &&
                                touchingSpeedLeftFraction <= SpeedLeft &&
                                touchingSpeedLeftFraction < ClosestCollisionSpeedFraction)
                            {
                                ClosestCollisionSpeedFraction = touchingSpeedLeftFraction;
                                ClosestCollisionTouchingAxis  = intersectionAxis;
                                ClosestCollisionRule          = cRule;
                                ClosestCollisionMethodArg     = sprite;
                                ClosestCollisionRelativeSpeed = Speed;
                            }
                        }
                    }
                    break;
                }
            }
        }
        /// <summary>
        /// Calculates the first occuring collision event on this object's track using the collisionrules.
        /// </summary>
        internal void CalculateClosestCollision()
        {
            ClosestCollisionSpeedFraction = float.PositiveInfinity;

            //no (more) collision checking this step please
            if (SpeedLeft == 0f || Speed == Point.Zero)
            {
                SpeedLeft = 0f;
                return;
            }

            //decide which target of the rules is closest and within collision range
            foreach(CollisionRule cRule in CollisionRules)
            {
                //skip if this rule doesn't have to be checked anyway
                if (!cRule.Active)
                    continue;

                //get collision candidates once if they will be checked (JIT)
                if (CollisionCandidates == null && (cRule.Type == CollisionRuleType.Object || cRule.Type == CollisionRuleType.ObjectType || cRule.Type == CollisionRuleType.Objectmap))
                    CollisionCandidates = Game.QuadTree.GetCollisionCandidates(this);

                float touchingSpeedLeftFraction;
                Point intersectionAxis;
                switch (cRule.Type)
                {
                    case CollisionRuleType.Shape:
                        if (Bounds.IntersectsWith((Shape)cRule.Target, Speed, out touchingSpeedLeftFraction, out intersectionAxis)
                            && touchingSpeedLeftFraction > 0f
                            && touchingSpeedLeftFraction <= SpeedLeft
                            && touchingSpeedLeftFraction < ClosestCollisionSpeedFraction)
                        {
                            ClosestCollisionSpeedFraction = touchingSpeedLeftFraction * SpeedLeft;
                            _closestCollisionTouchingAxis = intersectionAxis;
                            _closestCollisionRule = cRule;
                            _closestCollisionMethodArg = cRule.Target;
                            _closestCollisionRelativeSpeed = Speed;
                        }
                        break;

                    case CollisionRuleType.Object:
                        if (CollisionCandidates.Contains((PhysicalObject)cRule.Target)
                            && Bounds.IntersectsWith(((PhysicalObject)cRule.Target).Bounds, Speed - ((PhysicalObject)cRule.Target).Speed, out touchingSpeedLeftFraction, out intersectionAxis)
                            && touchingSpeedLeftFraction > 0f
                            && touchingSpeedLeftFraction <= SpeedLeft
                            && (touchingSpeedLeftFraction <= ((PhysicalObject)cRule.Target).SpeedLeft
                            || ((PhysicalObject)cRule.Target).Speed == Point.Zero)
                            && touchingSpeedLeftFraction < ClosestCollisionSpeedFraction)
                        {
                            ClosestCollisionSpeedFraction = touchingSpeedLeftFraction * SpeedLeft;
                            _closestCollisionTouchingAxis = intersectionAxis;
                            _closestCollisionRule = cRule;
                            _closestCollisionMethodArg = cRule.Target;
                            _closestCollisionRelativeSpeed = Speed - ((PhysicalObject)cRule.Target).Speed;
                        }
                        break;

                    case CollisionRuleType.ObjectType:
                        foreach (PhysicalObject obj in Resources.PhysicalObjectsByType[(Type)cRule.Target])
                        {
                            if (!CollisionCandidates.Contains(obj) ||
                                !Bounds.IntersectsWith(obj.Bounds, Speed - obj.Speed, out touchingSpeedLeftFraction, out intersectionAxis) ||
                                !(touchingSpeedLeftFraction > 0f) || !(touchingSpeedLeftFraction <= SpeedLeft) ||
                                (!(touchingSpeedLeftFraction <= obj.SpeedLeft) && obj.Speed != Point.Zero) ||
                                !(touchingSpeedLeftFraction < ClosestCollisionSpeedFraction))
                                continue;

                            ClosestCollisionSpeedFraction = touchingSpeedLeftFraction * SpeedLeft;
                            _closestCollisionTouchingAxis = intersectionAxis;
                            _closestCollisionRule = cRule;
                            _closestCollisionMethodArg = obj;
                            _closestCollisionRelativeSpeed = Speed - obj.Speed;
                        }
                        break;

                    case CollisionRuleType.Objectmap:
                        foreach (PhysicalObject obj in ((GameObjectCollection)cRule.Target).ActivePhysicalObjects)
                        {
                            //whether the object should be checked if the filter is enabled
                            if (!cRule.FilterEnabled || cRule.ObjectmapFilter.Contains(obj.GetType())) //account for inheritance
                            {
                                if (!CollisionCandidates.Contains(obj) ||
                                    !Bounds.IntersectsWith(obj.Bounds, Speed - obj.Speed, out touchingSpeedLeftFraction, out intersectionAxis) ||
                                    !(touchingSpeedLeftFraction > 0f) || !(touchingSpeedLeftFraction <= SpeedLeft) ||
                                    (!(touchingSpeedLeftFraction <= obj.SpeedLeft) && obj.Speed != Point.Zero) ||
                                    !(touchingSpeedLeftFraction < ClosestCollisionSpeedFraction))
                                    continue;

                                ClosestCollisionSpeedFraction = touchingSpeedLeftFraction * SpeedLeft;
                                _closestCollisionTouchingAxis = intersectionAxis;
                                _closestCollisionRule = cRule;
                                _closestCollisionMethodArg = obj;
                                _closestCollisionRelativeSpeed = Speed - obj.Speed;
                            }
                        }
                        break;
                }
            }
        }