/// <summary>
 /// Detects all collisions between the body and all the registered
 /// collision skins (which should have already had their
 /// positions/bounding volumes etc updated).  For each potential
 /// pair of skins then the predicate (if it exists) will be called
 /// to see whether or not to continue. If the skins are closer
 /// than collTolerance (+ve value means report objects that aren't
 /// quite colliding) then the functor will get called.
 /// You can't just loop over all your bodies calling this, because 
 /// that will double-detect collisions. Use DetectAllCollisions for 
 /// that.
 /// </summary>
 public abstract void DetectCollisions(Body body, CollisionFunctor collisionFunctor,
     CollisionSkinPredicate2 collisionPredicate, float collTolerance);
 /// <summary>
 /// As DetectCollisions but detects for all bodies, testing each pair 
 /// only once
 /// </summary>
 /// <param name="bodies"></param>
 /// <param name="collisionFunctor"></param>
 /// <param name="collisionPredicate"></param>
 /// <param name="collTolerance"></param>
 public abstract void DetectAllCollisions(List<Body> bodies, CollisionFunctor collisionFunctor,
     CollisionSkinPredicate2 collisionPredicate, float collTolerance);
        public override void DetectCollisions(Body body, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance)
        {
            if (!body.IsActive)
                return;

            CollDetectInfo info = new CollDetectInfo();
            info.Skin0 = body.CollisionSkin; //?!
            if (info.Skin0 == null) return;

            int bodyPrimitves = info.Skin0.NumPrimitives;
            int numSkins = skins.Count;

            for (int skin = 0; skin < numSkins; ++skin)
            {
                info.Skin1 = skins[skin];
                if ((info.Skin0 != info.Skin1) && CheckCollidables(info.Skin0, info.Skin1))
                {
                    int primitives = info.Skin1.NumPrimitives;

                    for (info.IndexPrim0 = 0; info.IndexPrim0 < bodyPrimitves; ++info.IndexPrim0)
                    {
                        for (info.IndexPrim1 = 0; info.IndexPrim1 < primitives; ++info.IndexPrim1)
                        {
                            DetectFunctor f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type,
                                info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type);

                            if (f != null) f.CollDetect(info, collTolerance, collisionFunctor);
                        }
                    }
                }
            }
        }
        public override void DetectAllCollisions(List<Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance)
        {
            int numSkins = skins.Count;
            int numBodies = bodies.Count;

            CollDetectInfo info = new CollDetectInfo();

            for (int ibody = 0; ibody < numBodies; ++ibody)
            {
                Body body = bodies[ibody];
                if(!body.IsActive)
                    continue;

                info.Skin0 = body.CollisionSkin;
                if (info.Skin0 == null)
                    continue;

                for (int skin = 0; skin < numSkins; ++skin)
                {
                    info.Skin1 = skins[skin];
                    if (info.Skin0 == info.Skin1)
                        continue;

                    // CHANGE
                    if (info.Skin1 == null)
                        continue;

                    bool skinSleeping = true;

                    if (info.Skin1.Owner != null && info.Skin1.Owner.IsActive)
                        skinSleeping = false;

                    if ((skinSleeping == false) && (info.Skin1.ID < info.Skin0.ID))
                        continue;

                    if((collisionPredicate != null) &&
                        collisionPredicate.ConsiderSkinPair(info.Skin0,info.Skin1) == false)
                    continue;

                    // basic bbox test
                    if(BoundingBoxHelper.OverlapTest(ref info.Skin0.WorldBoundingBox,
                        ref info.Skin1.WorldBoundingBox,collTolerance))
                    {
                        if (CheckCollidables(info.Skin0,info.Skin1))
                        {
                            int bodyPrimitives = info.Skin0.NumPrimitives;
                            int primitves = info.Skin1.NumPrimitives;

                            for(info.IndexPrim0 = 0; info.IndexPrim0 < bodyPrimitives; ++info.IndexPrim0)
                            {
                                for (info.IndexPrim1 = 0; info.IndexPrim1 < primitves; ++info.IndexPrim1)
                                {
                                    DetectFunctor f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type,
                                        info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type);
                                    if (f != null)
                                        f.CollDetect(info, collTolerance, collisionFunctor);
                                }
                            }
                        }
                    } // overlapt test
                } // loop over skins
            } // loop over bodies
        }
        public override void DetectAllCollisions(List<Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance)
        {
            int numBodies = bodies.Count;

            CollDetectInfo info = new CollDetectInfo();

            for (int iBody = 0; iBody < numBodies; ++iBody)
            {
                Body body = bodies[iBody];
                if (!body.IsActive)
                    continue;

                info.Skin0 = body.CollisionSkin;
                if (info.Skin0 == null)
                    continue;

                tempGridLists.Clear();
                GetListsToCheck(tempGridLists, info.Skin0);

                for (int iList = tempGridLists.Count; iList-- != 0; )
                {
                    // first one is a placeholder;
                    GridEntry entry = tempGridLists[iList];
                    for (entry = entry.Next; entry != null; entry = entry.Next)
                    {
                        info.Skin1 = entry.Skin;
                        if (info.Skin1 == info.Skin0)
                            continue;

                        // CHANGE
                        if (info.Skin1 == null)
                            continue;

                        bool skinSleeping = true;

                        if ((info.Skin1.Owner != null) && (info.Skin1.Owner.IsActive))
                            skinSleeping = false;

                        // only do one per pair
                        if ((skinSleeping == false) && (info.Skin1.ID < info.Skin0.ID))
                             continue;

                        if ((collisionPredicate != null) && (!collisionPredicate.ConsiderSkinPair(info.Skin0, info.Skin1)))
                            continue;

                        // basic bbox test
                        if (BoundingBoxHelper.OverlapTest(ref info.Skin1.WorldBoundingBox,
                            ref info.Skin0.WorldBoundingBox, collTolerance))
                        {
                            if (CheckCollidables(info.Skin0, info.Skin1))
                            {
                                int bodyPrimitives = info.Skin0.NumPrimitives;
                                int primitves = info.Skin1.NumPrimitives;

                                for (info.IndexPrim0 = 0; info.IndexPrim0 < bodyPrimitives; ++info.IndexPrim0)
                                {
                                    for (info.IndexPrim1 = 0; info.IndexPrim1 < primitves; ++info.IndexPrim1)
                                    {
                                        DetectFunctor f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type,
                                            info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type);
                                        if (f != null)
                                            f.CollDetect(info, collTolerance, collisionFunctor);
                                    }
                                }
                            } // check collidables
                        } // overlapt test
                    }// loop over entries
                } // loop over lists
            } // loop over bodies
        }