/// <summary>
 /// Intersect a segment with the world. If non-zero the predicate
 /// allows certain skins to be excluded
 /// </summary>
 /// <param name="seg"></param>
 /// <param name="collisionPredicate"></param>
 /// <returns></returns>
 public abstract bool SegmentIntersect(out float fracOut, out CollisionSkin skinOut, out Vector3 posOut, out Vector3 normalOut,
     Segment seg, CollisionSkinPredicate1 collisionPredicate);
        public override bool SegmentIntersect(out float fracOut,out CollisionSkin skinOut,out Vector3 posOut,out Vector3 normalOut, Segment seg, CollisionSkinPredicate1 collisionPredicate)
        {
            int numSkins = skins.Count;
            BoundingBox segBox = BoundingBoxHelper.InitialBox;
            BoundingBoxHelper.AddSegment(seg, ref segBox);

            //initialise the outputs
            fracOut = float.MaxValue;
            skinOut = null;
            posOut = normalOut = Vector3.Zero;

            // working vars
            float frac;
            Vector3 pos;
            Vector3 normal;

            for (int iskin = 0; iskin < numSkins; ++iskin)
            {
                CollisionSkin skin = skins[iskin];
                if ((collisionPredicate == null) ||
                    collisionPredicate.ConsiderSkin(skin))
                {
                    // basic bbox test
                    if (BoundingBoxHelper.OverlapTest(ref skin.WorldBoundingBox, ref segBox))
                    {
                        if (skin.SegmentIntersect(out frac, out pos, out normal, seg))
                        {
                            if (frac < fracOut)
                            {
                                posOut = pos;
                                normalOut = normal;
                                skinOut = skin;
                                fracOut = frac;
                            }
                        }

                    }
                }
            }

            if (fracOut > 1.0f) return false;
            fracOut = MathHelper.Clamp(fracOut, 0.0f, 1.0f);
            return true;
        }